@12-apps/payments-frontend 3.5.0 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/components/checkout/checkout-flow.tsx +56 -23
- package/src/components/checkout/checkout-steps.tsx +60 -31
- package/src/components/checkout/method-capability.ts +27 -0
- package/src/components/checkout/method-choice.ts +64 -0
- package/src/components/checkout/payment-status.tsx +50 -62
- package/src/components/checkout/payments-unavailable.tsx +14 -5
- package/src/components/checkout/providers/capability-default.tsx +1 -35
- package/src/components/checkout/providers/hands-over.ts +43 -0
- package/src/components/checkout/providers/hosted-link.tsx +113 -12
- package/src/components/checkout/providers/registry.ts +30 -0
- package/src/components/checkout/providers/types.ts +19 -1
- package/src/components/checkout/pt-BR.ts +74 -0
- package/src/components/checkout/types.ts +11 -0
- package/src/components/checkout/view-copy.ts +94 -0
- package/src/flows/copy.ts +27 -3
- package/src/flows/create-payment-flows.tsx +1 -0
- package/src/flows/screens-buyer.tsx +6 -4
- package/src/flows/screens-pay.tsx +1 -0
- package/src/index.ts +14 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CheckoutViewCopy,
|
|
3
|
+
PaymentsUnavailableCopy,
|
|
4
|
+
PaymentStatusCopy,
|
|
5
|
+
} from "./view-copy";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The pt-BR pack — the exact sentences these views compiled in until 6.0.0,
|
|
9
|
+
* now NAMED exports a host passes by hand, never defaults. The filename is
|
|
10
|
+
* what exempts this file from the copy-portability gate: Portuguese may ship,
|
|
11
|
+
* it may not be silent.
|
|
12
|
+
*/
|
|
13
|
+
export const PT_BR_PAYMENTS_UNAVAILABLE_COPY: PaymentsUnavailableCopy = {
|
|
14
|
+
title: "Pagamento online indisponível",
|
|
15
|
+
body: "Esta loja não recebe pagamentos pelo site. Combine o pagamento diretamente com a loja para concluir seu pedido.",
|
|
16
|
+
remedyTitle: "Pagamento com o garçom",
|
|
17
|
+
remedyBody: "Esta loja não recebe pagamentos pelo site. Chame o garçom para fechar a conta na mesa.",
|
|
18
|
+
callAction: "Chamar garçom",
|
|
19
|
+
callingAction: "Chamando...",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const PT_BR_PAYMENT_STATUS_COPY: PaymentStatusCopy = {
|
|
23
|
+
paid: {
|
|
24
|
+
heading: "Pedido confirmado",
|
|
25
|
+
support: "Recebemos seu pagamento e já registramos o pedido.",
|
|
26
|
+
},
|
|
27
|
+
awaiting: {
|
|
28
|
+
heading: "Confirmando seu pagamento",
|
|
29
|
+
support: "Isso costuma levar alguns segundos. Pode deixar esta tela aberta.",
|
|
30
|
+
},
|
|
31
|
+
failed: {
|
|
32
|
+
// Said plainly and first: the fear on this screen is having been charged
|
|
33
|
+
// for an order that failed.
|
|
34
|
+
heading: "Pagamento não concluído",
|
|
35
|
+
support: "Nenhum valor foi cobrado. Você pode tentar novamente.",
|
|
36
|
+
},
|
|
37
|
+
expired: {
|
|
38
|
+
heading: "O código expirou",
|
|
39
|
+
support: "Nenhum valor foi cobrado. Gere um novo código para continuar.",
|
|
40
|
+
},
|
|
41
|
+
awaitingTimedOut: {
|
|
42
|
+
heading: "Ainda não recebemos a confirmação",
|
|
43
|
+
support:
|
|
44
|
+
"Se você já pagou, o pedido é confirmado assim que a operadora avisar — " +
|
|
45
|
+
"não pague de novo. Você pode fechar esta tela.",
|
|
46
|
+
},
|
|
47
|
+
retryAction: "Tentar novamente",
|
|
48
|
+
regenerateAction: "Gerar novo código",
|
|
49
|
+
backAction: "Voltar ao cardápio",
|
|
50
|
+
amountLabel: "Valor pago",
|
|
51
|
+
referenceLabel: "Pedido",
|
|
52
|
+
receiptEmailLabel: "Comprovante enviado para",
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const PT_BR_CHECKOUT_VIEW_COPY: CheckoutViewCopy = {
|
|
56
|
+
steps: {
|
|
57
|
+
dados: "Dados",
|
|
58
|
+
payment: "Pagamento",
|
|
59
|
+
status: "Confirmação",
|
|
60
|
+
},
|
|
61
|
+
dados: {
|
|
62
|
+
saveProfile: "Salvar meus dados para a próxima compra",
|
|
63
|
+
cannotContinueTitle: "Não foi possível continuar",
|
|
64
|
+
continueAction: "Continuar",
|
|
65
|
+
secureNotice: "Pagamento seguro",
|
|
66
|
+
keepShopping: "Continuar comprando",
|
|
67
|
+
back: "Voltar",
|
|
68
|
+
},
|
|
69
|
+
emptyCart: {
|
|
70
|
+
title: "Seu carrinho está vazio.",
|
|
71
|
+
action: "Ver cardápio",
|
|
72
|
+
},
|
|
73
|
+
status: PT_BR_PAYMENT_STATUS_COPY,
|
|
74
|
+
};
|
|
@@ -250,6 +250,17 @@ export interface CheckoutCustomerField {
|
|
|
250
250
|
*/
|
|
251
251
|
export interface CheckoutChainLink {
|
|
252
252
|
provider: string;
|
|
253
|
+
/**
|
|
254
|
+
* The provider's own name as a BUYER should read it ("InfinitePay"), which
|
|
255
|
+
* `GET /api/checkout/config` publishes per entry.
|
|
256
|
+
*
|
|
257
|
+
* Optional, and the DEGRADE DIRECTION IS "SAY NOTHING": an older host serves
|
|
258
|
+
* no name, and a hand-off screen then describes where the buyer is going
|
|
259
|
+
* without naming it, rather than printing the internal `provider` id — a
|
|
260
|
+
* buyer shown "infinitepay" learns less than one shown nothing, and learns
|
|
261
|
+
* it in a vocabulary that is ours rather than theirs.
|
|
262
|
+
*/
|
|
263
|
+
displayName?: string | null;
|
|
253
264
|
tokenization: "NONE" | "PUBLIC_KEY" | "SDK" | "REDIRECT";
|
|
254
265
|
publicKey: string | null;
|
|
255
266
|
mockTokenization: boolean;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every string the legacy checkout views render — required props, with NO
|
|
3
|
+
* defaults, deliberately (the payments extraction's own doctrine, FUT-760):
|
|
4
|
+
* a default in the origin host's language reads as finished to the next host
|
|
5
|
+
* right up until a buyer sees it. These three views proved the point — the
|
|
6
|
+
* flows factory's copy port existed, was REQUIRED, declared
|
|
7
|
+
* `unavailableWithRemedyTitle` and `emptyCartAction`, and the views simply
|
|
8
|
+
* never read it, so a host that dutifully passed copy still rendered another
|
|
9
|
+
* product's voice.
|
|
10
|
+
*
|
|
11
|
+
* A pt-BR host imports {@link PT_BR_CHECKOUT_VIEW_COPY} from `./pt-BR` (the
|
|
12
|
+
* package root re-exports it) and passes it by hand — one reviewable line,
|
|
13
|
+
* never a silence.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** The screen shown when the store cannot take money online. */
|
|
17
|
+
export interface PaymentsUnavailableCopy {
|
|
18
|
+
/** No remedy: the store simply does not charge online. */
|
|
19
|
+
title: string;
|
|
20
|
+
body: string;
|
|
21
|
+
/** A remedy exists (the origin host: the waiter; a clinic: the front desk). */
|
|
22
|
+
remedyTitle: string;
|
|
23
|
+
remedyBody: string;
|
|
24
|
+
/** The remedy button, idle and in flight. */
|
|
25
|
+
callAction: string;
|
|
26
|
+
callingAction: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** The stepper's three labels, in flow order. */
|
|
30
|
+
export interface CheckoutStepperCopy {
|
|
31
|
+
dados: string;
|
|
32
|
+
payment: string;
|
|
33
|
+
status: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The buyer-details step: its bar, its refusal, and the slim header. */
|
|
37
|
+
export interface DadosStepCopy {
|
|
38
|
+
/** The save-my-details checkbox. */
|
|
39
|
+
saveProfile: string;
|
|
40
|
+
/** The refusal Alert's title (its body is the server's own sentence). */
|
|
41
|
+
cannotContinueTitle: string;
|
|
42
|
+
/** The sticky bar's one action. */
|
|
43
|
+
continueAction: string;
|
|
44
|
+
/**
|
|
45
|
+
* The reassurance caption under it. OPTIONAL, on the flows port's
|
|
46
|
+
* `secureNotice` precedent: a host that has not written the sentence gets
|
|
47
|
+
* NO caption rather than someone else's.
|
|
48
|
+
*/
|
|
49
|
+
secureNotice?: string;
|
|
50
|
+
/** The slim header's back control, on Dados and after it. */
|
|
51
|
+
keepShopping: string;
|
|
52
|
+
back: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Nothing to check out (cart mode only). */
|
|
56
|
+
export interface EmptyCartCopy {
|
|
57
|
+
title: string;
|
|
58
|
+
action: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** One outcome's headline and its single supporting line. */
|
|
62
|
+
export interface StatusOutcomeCopy {
|
|
63
|
+
heading: string;
|
|
64
|
+
support: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The confirmation screen. Icons and tones stay the component's — they are
|
|
69
|
+
* visual grammar, not language; every SENTENCE is the host's, including the
|
|
70
|
+
* timed-out wait's "do not pay again", which is the one instruction on this
|
|
71
|
+
* screen that matters (FUT-556).
|
|
72
|
+
*/
|
|
73
|
+
export interface PaymentStatusCopy {
|
|
74
|
+
paid: StatusOutcomeCopy;
|
|
75
|
+
awaiting: StatusOutcomeCopy;
|
|
76
|
+
failed: StatusOutcomeCopy;
|
|
77
|
+
expired: StatusOutcomeCopy;
|
|
78
|
+
awaitingTimedOut: StatusOutcomeCopy;
|
|
79
|
+
retryAction: string;
|
|
80
|
+
regenerateAction: string;
|
|
81
|
+
backAction: string;
|
|
82
|
+
/** The paid receipt's three row labels. */
|
|
83
|
+
amountLabel: string;
|
|
84
|
+
referenceLabel: string;
|
|
85
|
+
receiptEmailLabel: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** What the legacy `CheckoutFlow` itself renders and must be handed. */
|
|
89
|
+
export interface CheckoutViewCopy {
|
|
90
|
+
steps: CheckoutStepperCopy;
|
|
91
|
+
dados: DadosStepCopy;
|
|
92
|
+
emptyCart: EmptyCartCopy;
|
|
93
|
+
status: PaymentStatusCopy;
|
|
94
|
+
}
|
package/src/flows/copy.ts
CHANGED
|
@@ -18,8 +18,20 @@
|
|
|
18
18
|
* the port and nothing else.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import type { CheckoutViewCopy } from "../components/checkout/view-copy";
|
|
22
|
+
|
|
23
|
+
export type { CheckoutViewCopy };
|
|
24
|
+
|
|
21
25
|
/** Every buyer-facing string the factory's own screens render. */
|
|
22
26
|
export interface CheckoutCopyFE {
|
|
27
|
+
/**
|
|
28
|
+
* Everything the wrapped `CheckoutFlow` itself renders — stepper labels,
|
|
29
|
+
* the Dados step, the empty cart, the whole confirmation screen. FUT-741
|
|
30
|
+
* scoped those screens out as "already carried their own product copy";
|
|
31
|
+
* that copy was one application's Portuguese, so the scope-out WAS the
|
|
32
|
+
* leak. A pt-BR host passes `PT_BR_CHECKOUT_VIEW_COPY` here by hand.
|
|
33
|
+
*/
|
|
34
|
+
views: CheckoutViewCopy;
|
|
23
35
|
/** No provider connected AND no host remedy: the store simply does not charge. */
|
|
24
36
|
unavailableTitle: string;
|
|
25
37
|
unavailableBody: string;
|
|
@@ -47,11 +59,23 @@ export interface CheckoutCopyFE {
|
|
|
47
59
|
* part only a host can own.
|
|
48
60
|
*/
|
|
49
61
|
returnTimedOut?: string;
|
|
50
|
-
/** Nothing to check out (cart mode only). */
|
|
51
|
-
emptyCartTitle: string;
|
|
52
|
-
emptyCartAction: string;
|
|
53
62
|
/** The Dados step's primary action. */
|
|
54
63
|
continueAction: string;
|
|
64
|
+
/**
|
|
65
|
+
* The reassurance caption under that action.
|
|
66
|
+
*
|
|
67
|
+
* The screen rendered "Pagamento seguro" inline — one line below a sibling
|
|
68
|
+
* reading `runtime.copy.continueAction`, so the port was already there and
|
|
69
|
+
* already required; this string simply never asked it. That is the shape
|
|
70
|
+
* FUT-760 left behind: defaults removed from the CONFIG surface without the
|
|
71
|
+
* rendering being rewired, so a host that dutifully passes copy still gets
|
|
72
|
+
* the origin product's voice.
|
|
73
|
+
*
|
|
74
|
+
* OPTIONAL, on the {@link CheckoutCopyFE.returnTimedOut} precedent: a host
|
|
75
|
+
* that has not written the sentence gets NO caption rather than someone
|
|
76
|
+
* else's. Reassurance nobody chose is worth less than silence.
|
|
77
|
+
*/
|
|
78
|
+
secureNotice?: string;
|
|
55
79
|
/** The add-card screen (FUT-183): putting a card on file outside a purchase. */
|
|
56
80
|
addCardTitle: string;
|
|
57
81
|
addCardAction: string;
|
|
@@ -87,9 +87,11 @@ function buildBuyerDetails(runtime: FlowsRuntime): CheckoutScreens["BuyerDetails
|
|
|
87
87
|
{runtime.copy.continueAction}
|
|
88
88
|
</Button>
|
|
89
89
|
</Box>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
{runtime.copy.secureNotice ? (
|
|
91
|
+
<Text variant="caption" size="xs" color="secondary" as="p">
|
|
92
|
+
{runtime.copy.secureNotice}
|
|
93
|
+
</Text>
|
|
94
|
+
) : null}
|
|
93
95
|
</Box>
|
|
94
96
|
);
|
|
95
97
|
}
|
|
@@ -155,7 +157,7 @@ function buildEmptyCart(runtime: FlowsRuntime): CheckoutScreens["EmptyCart"] {
|
|
|
155
157
|
return function EmptyCart() {
|
|
156
158
|
return (
|
|
157
159
|
<FlowsShell runtime={runtime}>
|
|
158
|
-
<EmptyCartView onBack={runtime.config.ports.exitToCatalog} />
|
|
160
|
+
<EmptyCartView copy={runtime.copy.views.emptyCart} onBack={runtime.config.ports.exitToCatalog} />
|
|
159
161
|
</FlowsShell>
|
|
160
162
|
);
|
|
161
163
|
};
|
|
@@ -82,6 +82,7 @@ function buildPaymentStatus(runtime: FlowsRuntime): CheckoutScreens["PaymentStat
|
|
|
82
82
|
return (
|
|
83
83
|
<FlowsShell runtime={runtime}>
|
|
84
84
|
<PaymentStatusView
|
|
85
|
+
copy={runtime.copy.views.status}
|
|
85
86
|
status={status}
|
|
86
87
|
totalLabel={payable?.totalLabel ?? ""}
|
|
87
88
|
orderId={payable?.orderId}
|
package/src/index.ts
CHANGED
|
@@ -85,6 +85,20 @@ export {
|
|
|
85
85
|
} from './components/checkout/transport';
|
|
86
86
|
export { type CheckoutHostPorts } from './components/checkout/use-checkout-controller';
|
|
87
87
|
export { PaymentsUnavailable } from './components/checkout/payments-unavailable';
|
|
88
|
+
export type {
|
|
89
|
+
CheckoutStepperCopy,
|
|
90
|
+
CheckoutViewCopy,
|
|
91
|
+
DadosStepCopy,
|
|
92
|
+
EmptyCartCopy,
|
|
93
|
+
PaymentStatusCopy,
|
|
94
|
+
PaymentsUnavailableCopy,
|
|
95
|
+
StatusOutcomeCopy,
|
|
96
|
+
} from './components/checkout/view-copy';
|
|
97
|
+
export {
|
|
98
|
+
PT_BR_CHECKOUT_VIEW_COPY,
|
|
99
|
+
PT_BR_PAYMENTS_UNAVAILABLE_COPY,
|
|
100
|
+
PT_BR_PAYMENT_STATUS_COPY,
|
|
101
|
+
} from './components/checkout/pt-BR';
|
|
88
102
|
export { fetchCheckoutConfig } from './components/checkout/client';
|
|
89
103
|
/**
|
|
90
104
|
* The `sessionStorage` key the hosted-checkout return leg parks the raised
|