mirror of
https://github.com/valitydev/checkout.git
synced 2024-11-06 02:25:18 +00:00
Add mobile flow for p2p qr code payment (#351)
Some checks are pending
Master / Build (push) Waiting to run
Some checks are pending
Master / Build (push) Waiting to run
This commit is contained in:
parent
ea8c8f8b0b
commit
b26baa0d23
@ -47,7 +47,9 @@
|
||||
"form.p2p.destination.bank.account.account": "رقم الحساب:",
|
||||
"form.p2p.destination.bank.account.bic": "BIC:",
|
||||
"form.p2p.destination.bank.account.purpose": "الغرض من الدفع:",
|
||||
"form.p2p.destination.qrCode.description": "يرجى مسح رمز الاستجابة السريعة باستخدام تطبيقك البنكي أو كاميرا الهاتف",
|
||||
"form.p2p.destination.qrCode.description": "امسح رمز الاستجابة السريعة باستخدام كاميرا الهاتف الافتراضية.",
|
||||
"form.p2p.destination.qrCode.button.redirect": "افتح في التطبيق",
|
||||
"form.p2p.destination.qrCode.button.copy": "نسخ الرابط",
|
||||
"form.p2p.complete.info": "بعد إتمام التحويل، اضغط على الزر أدناه.",
|
||||
"form.p2p.complete.button": "إكمال الدفع",
|
||||
"form.p2p.complete.loading": "يرجى الانتظار",
|
||||
|
@ -47,7 +47,9 @@
|
||||
"form.p2p.destination.bank.account.account": "Hesab nömrəsi:",
|
||||
"form.p2p.destination.bank.account.bic": "BIC:",
|
||||
"form.p2p.destination.bank.account.purpose": "Ödənişin təyinatı:",
|
||||
"form.p2p.destination.qrCode.description": "Zəhmət olmasa, QR kodunu bank tətbiqiniz və ya telefon kamerası ilə tarayın",
|
||||
"form.p2p.destination.qrCode.description": "QR kodunu telefonunuzun standart kamerası ilə tarayın.",
|
||||
"form.p2p.destination.qrCode.button.redirect": "Proqramda aç",
|
||||
"form.p2p.destination.qrCode.button.copy": "Linki kopyalayın",
|
||||
"form.p2p.complete.info": "Təqdim etdikdən sonra \"Köçürmə tamamlandı\" düyməsini basın. Ödənişin işlənməsi 5 dəqiqəyə qədər çəkir.",
|
||||
"form.p2p.complete.button": "Köçürmə tamamlandı",
|
||||
"form.p2p.complete.loading": "Lütfən, gözləyin",
|
||||
|
@ -47,7 +47,9 @@
|
||||
"form.p2p.destination.bank.account.account": "Account number:",
|
||||
"form.p2p.destination.bank.account.bic": "BIC:",
|
||||
"form.p2p.destination.bank.account.purpose": "Purpose:",
|
||||
"form.p2p.destination.qrCode.description": "Please scan the QR code with your banking app or phone camera",
|
||||
"form.p2p.destination.qrCode.description": "Scan the QR code with your phone's camera.",
|
||||
"form.p2p.destination.qrCode.button.redirect": "Open in the app",
|
||||
"form.p2p.destination.qrCode.button.copy": "Copy link",
|
||||
"form.p2p.complete.info": "After completing the transfer, press the button below.",
|
||||
"form.p2p.complete.button": "Complete payment",
|
||||
"form.p2p.complete.loading": "Please, wait",
|
||||
|
@ -47,7 +47,9 @@
|
||||
"form.p2p.destination.bank.account.account": "Número da conta:",
|
||||
"form.p2p.destination.bank.account.bic": "BIC:",
|
||||
"form.p2p.destination.bank.account.purpose": "Finalidade do pagamento:",
|
||||
"form.p2p.destination.qrCode.description": "Por favor, escaneie o código QR com seu aplicativo bancário ou câmera do telefone",
|
||||
"form.p2p.destination.qrCode.description": "Escaneie o código QR com a câmera padrão do seu telefone.",
|
||||
"form.p2p.destination.qrCode.button.redirect": "Abrir no aplicativo",
|
||||
"form.p2p.destination.qrCode.button.copy": "Copiar link",
|
||||
"form.p2p.complete.info": "Após completar a transferência, pressione o botão abaixo. O processamento do pagamento pode levar até 5 minutos.",
|
||||
"form.p2p.complete.button": "Transferência concluída",
|
||||
"form.p2p.complete.loading": "Por favor, aguarde",
|
||||
|
@ -47,7 +47,9 @@
|
||||
"form.p2p.destination.bank.account.account": "Номер счета:",
|
||||
"form.p2p.destination.bank.account.bic": "БИК:",
|
||||
"form.p2p.destination.bank.account.purpose": "Назначение платежа:",
|
||||
"form.p2p.destination.qrCode.description": "Отсканируйте QR-код в мобильном приложении банка или штатной камерой телефона",
|
||||
"form.p2p.destination.qrCode.description": "Отсканируйте QR-код штатной камерой телефона.",
|
||||
"form.p2p.destination.qrCode.button.redirect": "Перейти в приложение",
|
||||
"form.p2p.destination.qrCode.button.copy": "Копировать ссылку",
|
||||
"form.p2p.complete.info": "После совершения перевода нажмите кнопку ниже. Обработка платежа занимает до 5 минут.",
|
||||
"form.p2p.complete.button": "Перевод выполнен",
|
||||
"form.p2p.complete.loading": "Пожалуйста, подождите",
|
||||
|
@ -47,7 +47,9 @@
|
||||
"form.p2p.destination.bank.account.account": "Рақами ҳисоб:",
|
||||
"form.p2p.destination.bank.account.bic": "BIC:",
|
||||
"form.p2p.destination.bank.account.purpose": "Мақсади пардохт:",
|
||||
"form.p2p.destination.qrCode.description": "Лутфан рамзи QR-ро бо барномаи бонкии худ ё камераи телефон скан кунед",
|
||||
"form.p2p.destination.qrCode.description": "QR кодро бо камераи стандартии телефони худ скан кунед.",
|
||||
"form.p2p.destination.qrCode.button.redirect": "Дар барнома кушоед",
|
||||
"form.p2p.destination.qrCode.button.copy": "Ссылкаро нусхабардорӣ кунед",
|
||||
"form.p2p.complete.info": "Пас аз анҷом додани интиқол, тугмаи зерро пахш кунед. Коркарди пардохт то 5 дақиқа вақт мегирад.",
|
||||
"form.p2p.complete.button": "Интикол анҷом дода шуд",
|
||||
"form.p2p.complete.loading": "Лутфан интизор шавед",
|
||||
|
@ -47,7 +47,9 @@
|
||||
"form.p2p.destination.bank.account.account": "Hesap numarası:",
|
||||
"form.p2p.destination.bank.account.bic": "BIC:",
|
||||
"form.p2p.destination.bank.account.purpose": "Ödeme amacı:",
|
||||
"form.p2p.destination.qrCode.description": "Lütfen QR kodunu banka uygulamanız veya telefon kameranızla tarayın",
|
||||
"form.p2p.destination.qrCode.description": "QR kodunu telefonunuzun varsayılan kamerası ile tarayın.",
|
||||
"form.p2p.destination.qrCode.button.redirect": "Uygulamada aç",
|
||||
"form.p2p.destination.qrCode.button.copy": "Bağlantıyı kopyala",
|
||||
"form.p2p.complete.info": "Transferi tamamladıktan sonra aşağıdaki butona basın. Ödeme işleminin tamamlanması 5 dakikaya kadar sürebilir.",
|
||||
"form.p2p.complete.button": "Transfer tamamlandı",
|
||||
"form.p2p.complete.loading": "Lütfen bekleyin",
|
||||
|
@ -47,7 +47,9 @@
|
||||
"form.p2p.destination.bank.account.account": "Ҳисоб рақами:",
|
||||
"form.p2p.destination.bank.account.bic": "БИК:",
|
||||
"form.p2p.destination.bank.account.purpose": "Тўлов мақсади:",
|
||||
"form.p2p.destination.qrCode.description": "Iltimos, QR kodni banking ilovangiz yoki telefon kamerangiz bilan skaner qiling",
|
||||
"form.p2p.destination.qrCode.description": "QR kodni telefoningizning standart kamerasi bilan skaner qiling.",
|
||||
"form.p2p.destination.qrCode.button.redirect": "Ilovada oching",
|
||||
"form.p2p.destination.qrCode.button.copy": "Havolani nusxalash",
|
||||
"form.p2p.complete.info": "Ўтказишни амалга оширгач, пастдаги тугмани босинг. Тўловни қабул қилиш 5 дақиқагача вақт олади.",
|
||||
"form.p2p.complete.button": "Ўтказиш бажарилди",
|
||||
"form.p2p.complete.loading": "Илтимос, кутинг",
|
||||
|
@ -3,9 +3,10 @@ import kjua from 'kjua';
|
||||
|
||||
export type QRCodeProps = {
|
||||
text: string;
|
||||
size?: number;
|
||||
};
|
||||
|
||||
export function QRCode({ text }: QRCodeProps) {
|
||||
export function QRCode({ text, size = 224 }: QRCodeProps) {
|
||||
const {
|
||||
QRCode: { back, fill },
|
||||
} = useTheme();
|
||||
@ -13,7 +14,7 @@ export function QRCode({ text }: QRCodeProps) {
|
||||
<Center
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: kjua({
|
||||
size: 224,
|
||||
size,
|
||||
back,
|
||||
fill,
|
||||
rounded: 100,
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { isNil } from './isNil';
|
||||
|
||||
const locales = ['ru', 'en', 'pt', 'bn', 'tr', 'az', 'ar', 'tj', 'uz'];
|
||||
const locales = ['ru', 'en', 'pt', 'tr', 'az', 'ar', 'tj', 'uz'];
|
||||
|
||||
export const detectLocale = (locale: string | null): string => {
|
||||
let result;
|
||||
|
@ -65,7 +65,6 @@ export function DestinationInfo({ destination }: DestinationInfoProps) {
|
||||
value={destination.phoneNumber}
|
||||
/>
|
||||
)}
|
||||
{destination.destinationType === 'QRCode' && <DestinationQRCodeAccountInfo qrCode={destination.qrCode} />}
|
||||
{destination?.bankName && (
|
||||
<InfoItem
|
||||
icon={getGatewayIcon(destination.bankName)}
|
||||
@ -73,6 +72,7 @@ export function DestinationInfo({ destination }: DestinationInfoProps) {
|
||||
value={mapGatewayName(destination.bankName, l)}
|
||||
/>
|
||||
)}
|
||||
{destination.destinationType === 'QRCode' && <DestinationQRCodeAccountInfo qrCode={destination.qrCode} />}
|
||||
{destination?.recipientName && (
|
||||
<InfoItem
|
||||
isCopyable={true}
|
||||
|
@ -1,22 +1,67 @@
|
||||
import { VStack, Text, Divider } from '@chakra-ui/react';
|
||||
import { VStack, Text, Divider, Button, useClipboard, useToast } from '@chakra-ui/react';
|
||||
import isMobile from 'ismobilejs';
|
||||
import { decode } from 'js-base64';
|
||||
import { useContext, useMemo } from 'react';
|
||||
import { useContext, useEffect, useMemo } from 'react';
|
||||
import { FaSquareArrowUpRight } from 'react-icons/fa6';
|
||||
import { HiOutlineDuplicate } from 'react-icons/hi';
|
||||
|
||||
import { QRCode } from 'checkout/components';
|
||||
import { LocaleContext } from 'checkout/contexts';
|
||||
|
||||
const QR_CODE_SIZE = 192;
|
||||
|
||||
export type DestinationQRCodeAccountInfoProps = {
|
||||
qrCode: string;
|
||||
};
|
||||
|
||||
export function DestinationQRCodeAccountInfo({ qrCode }: DestinationQRCodeAccountInfoProps) {
|
||||
const { l } = useContext(LocaleContext);
|
||||
const decodedQRCode = useMemo(() => decode(qrCode), [qrCode]);
|
||||
const isRedirect = useMemo(() => isMobile(window.navigator).phone || isMobile(window.navigator).tablet, []);
|
||||
const decodedUrl = useMemo(() => decode(qrCode), [qrCode]);
|
||||
const { onCopy, hasCopied } = useClipboard(decodedUrl);
|
||||
const toast = useToast();
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasCopied) return;
|
||||
toast({
|
||||
title: l['form.p2p.copied'],
|
||||
status: 'success',
|
||||
variant: 'subtle',
|
||||
duration: 3000,
|
||||
});
|
||||
}, [hasCopied, l]);
|
||||
|
||||
const redirect = () => {
|
||||
window.open(decodedUrl, '_blank');
|
||||
};
|
||||
|
||||
return (
|
||||
<VStack align="stretch">
|
||||
<Text textAlign="center">{l['form.p2p.destination.qrCode.description']}</Text>
|
||||
<QRCode text={decodedQRCode} />
|
||||
<Text fontSize="sm" textAlign="center">
|
||||
{l['form.p2p.destination.qrCode.description']}
|
||||
</Text>
|
||||
<QRCode size={QR_CODE_SIZE} text={decodedUrl} />
|
||||
{isRedirect ? (
|
||||
<Button
|
||||
borderRadius="xl"
|
||||
colorScheme="brand"
|
||||
rightIcon={<FaSquareArrowUpRight />}
|
||||
variant="outline"
|
||||
onClick={redirect}
|
||||
>
|
||||
{l['form.p2p.destination.qrCode.button.redirect']}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
borderRadius="xl"
|
||||
colorScheme="brand"
|
||||
rightIcon={<HiOutlineDuplicate />}
|
||||
variant="outline"
|
||||
onClick={onCopy}
|
||||
>
|
||||
{l['form.p2p.destination.qrCode.button.copy']}
|
||||
</Button>
|
||||
)}
|
||||
<Divider />
|
||||
</VStack>
|
||||
);
|
||||
|
@ -38,7 +38,6 @@ export function Destinations({ destinations }: DestinationsProps) {
|
||||
<VStack align="stretch" minH="md" spacing={5}>
|
||||
<P2PAlert />
|
||||
<VStack align="stretch" spacing={3}>
|
||||
<Text fontWeight="medium">{l['form.p2p.destination.info']}</Text>
|
||||
{destinations.map((destination, index) => (
|
||||
<DestinationInfo key={index} destination={destination} />
|
||||
))}
|
||||
|
Loading…
Reference in New Issue
Block a user