@12-apps/payments-frontend 3.9.0 → 3.10.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 +2 -2
- package/src/activation/charge-copy.ts +10 -0
- package/src/activation/use-activation-charge.ts +10 -8
- package/src/card/copy.ts +115 -0
- package/src/card/cpf.ts +12 -5
- package/src/card/fields.tsx +17 -12
- package/src/card/format.ts +32 -16
- package/src/card/index.ts +3 -1
- package/src/card/pt-BR.ts +51 -0
- package/src/card/stripe-token.ts +5 -6
- package/src/card/tokenize.ts +28 -32
- package/src/components/CheckoutPayment.tsx +37 -201
- package/src/components/ConfirmCredentialSave.tsx +8 -10
- package/src/components/ConnectionCard.tsx +23 -18
- package/src/components/ConnectionProbe.tsx +3 -1
- package/src/components/CredentialFieldStack.tsx +8 -2
- package/src/components/CredentialFields.tsx +13 -6
- package/src/components/CredentialFormAlerts.tsx +28 -19
- package/src/components/EnvironmentTabs.tsx +23 -15
- package/src/components/OAuthPanel.tsx +5 -6
- package/src/components/PaymentProviderSettings.tsx +45 -13
- package/src/components/ProviderConnection.tsx +37 -28
- package/src/components/ProviderList.tsx +6 -3
- package/src/components/ProviderPriorityList.tsx +18 -16
- package/src/components/ProviderStatusBar.tsx +24 -24
- package/src/components/SetupGuideSection.tsx +15 -6
- package/src/components/checkout/apple-pay-button.tsx +19 -9
- package/src/components/checkout/buyer-fields.ts +5 -3
- package/src/components/checkout/buyer-gate.ts +68 -0
- package/src/components/checkout/buyer-info-form.tsx +14 -15
- package/src/components/checkout/card-instruments.ts +31 -12
- package/src/components/checkout/card-view.tsx +11 -7
- package/src/components/checkout/checkout-flow.tsx +4 -1
- package/src/components/checkout/checkout-steps.tsx +3 -1
- package/src/components/checkout/client-context.tsx +28 -16
- package/src/components/checkout/client.ts +43 -16
- package/src/components/checkout/copy-context.tsx +83 -0
- package/src/components/checkout/google-pay-button.tsx +19 -7
- package/src/components/checkout/method-picker.tsx +34 -10
- package/src/components/checkout/payer-summary.tsx +8 -6
- package/src/components/checkout/payment-error-panel.tsx +8 -5
- package/src/components/checkout/pix-view.tsx +16 -9
- package/src/components/checkout/providers/hosted-link.tsx +26 -16
- package/src/components/checkout/pt-BR.ts +27 -0
- package/src/components/checkout/screens-copy.ts +201 -0
- package/src/components/checkout/screens-pt-BR.ts +101 -0
- package/src/components/checkout/transport.ts +34 -8
- package/src/components/checkout/use-card-checkout.ts +13 -5
- package/src/components/checkout/use-checkout-controller.ts +5 -48
- package/src/components/checkout/view-copy.ts +13 -0
- package/src/components/checkout/wallet-pane.tsx +13 -8
- package/src/components/checkout-payment-copy.ts +88 -0
- package/src/components/checkout-payment-pt-BR.ts +50 -0
- package/src/components/checkout-payment-types.ts +25 -0
- package/src/components/checkout-payment-views.tsx +225 -0
- package/src/components/connection-state.ts +22 -10
- package/src/components/credential-rules.ts +8 -3
- package/src/components/platform/ConnectApplicationPanel.tsx +6 -2
- package/src/components/platform/ConnectEnvironmentCard.tsx +19 -15
- package/src/components/platform/HomologacaoGuideCard.tsx +23 -19
- package/src/components/platform/HomologacaoOutcomeCard.tsx +24 -16
- package/src/components/platform/PlatformHomologacao.tsx +12 -8
- package/src/components/settings-copy-context.tsx +50 -0
- package/src/components/settings-copy.ts +304 -0
- package/src/components/settings-pt-BR.ts +169 -0
- package/src/flows/copy.ts +12 -0
- package/src/flows/create-payment-flows.tsx +8 -1
- package/src/flows/runtime.tsx +12 -4
- package/src/flows/screens-vault.tsx +10 -10
- package/src/flows/types.ts +5 -2
- package/src/flows/use-add-card.ts +10 -5
- package/src/index.ts +63 -0
|
@@ -45,9 +45,9 @@ export interface HomologacaoSaveState {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
const STATUS_LABEL: Record<PlatformHomologationStatus, string> = {
|
|
48
|
-
SUBMITTED: '
|
|
49
|
-
APPROVED: '
|
|
50
|
-
REJECTED: '
|
|
48
|
+
SUBMITTED: 'Submitted',
|
|
49
|
+
APPROVED: 'Approved',
|
|
50
|
+
REJECTED: 'Rejected',
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
const STATUS_COLOR: Record<PlatformHomologationStatus, 'warning' | 'success' | 'error'> = {
|
|
@@ -60,7 +60,7 @@ function StatusChip({ record }: { record: PlatformHomologationRecordView | null
|
|
|
60
60
|
if (record === null) {
|
|
61
61
|
return (
|
|
62
62
|
<Chip
|
|
63
|
-
label="
|
|
63
|
+
label="Not submitted"
|
|
64
64
|
size="small"
|
|
65
65
|
variant="outlined"
|
|
66
66
|
data-testid="homologacao-status-chip"
|
|
@@ -77,14 +77,22 @@ function StatusChip({ record }: { record: PlatformHomologationRecordView | null
|
|
|
77
77
|
);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
/**
|
|
81
|
+
* The trail's timestamps, in the READER's own locale.
|
|
82
|
+
*
|
|
83
|
+
* No tag passed, deliberately (FUT-760): this screen is the platform
|
|
84
|
+
* integrator's, and it was pinned to `pt-BR` — which showed a Brazilian date
|
|
85
|
+
* to an operator whose browser is set to anything else. The runtime default is
|
|
86
|
+
* the one thing here that is genuinely theirs.
|
|
87
|
+
*/
|
|
88
|
+
const formatDateTime = (iso: string): string => new Date(iso).toLocaleString();
|
|
81
89
|
|
|
82
90
|
function RecordTrail({ record }: { record: PlatformHomologationRecordView }): ReactNode {
|
|
83
91
|
return (
|
|
84
92
|
<Typography variant="caption" color="text.secondary" component="p">
|
|
85
|
-
{record.submittedAt ? `
|
|
86
|
-
{record.decidedAt ? `
|
|
87
|
-
{record.updatedBy ? `
|
|
93
|
+
{record.submittedAt ? `Submitted ${formatDateTime(record.submittedAt)}. ` : ''}
|
|
94
|
+
{record.decidedAt ? `Decided ${formatDateTime(record.decidedAt)}. ` : ''}
|
|
95
|
+
{record.updatedBy ? `Recorded by ${record.updatedBy}.` : ''}
|
|
88
96
|
</Typography>
|
|
89
97
|
);
|
|
90
98
|
}
|
|
@@ -106,7 +114,7 @@ export function HomologacaoOutcomeCard(props: HomologacaoOutcomeCardProps): Reac
|
|
|
106
114
|
<Stack spacing={1.5} data-testid="homologacao-outcome-card" sx={CARD_SX}>
|
|
107
115
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1.5 }}>
|
|
108
116
|
<Typography variant="body2" fontWeight={600}>
|
|
109
|
-
|
|
117
|
+
Homologation status
|
|
110
118
|
</Typography>
|
|
111
119
|
<StatusChip record={record} />
|
|
112
120
|
</Box>
|
|
@@ -115,7 +123,7 @@ export function HomologacaoOutcomeCard(props: HomologacaoOutcomeCardProps): Reac
|
|
|
115
123
|
<TextField
|
|
116
124
|
select
|
|
117
125
|
size="small"
|
|
118
|
-
label="
|
|
126
|
+
label="Status"
|
|
119
127
|
value={status}
|
|
120
128
|
onChange={(event) => setStatus(event.target.value as PlatformHomologationStatus)}
|
|
121
129
|
slotProps={{
|
|
@@ -131,16 +139,16 @@ export function HomologacaoOutcomeCard(props: HomologacaoOutcomeCardProps): Reac
|
|
|
131
139
|
</TextField>
|
|
132
140
|
<TextField
|
|
133
141
|
size="small"
|
|
134
|
-
aria-label="
|
|
135
|
-
placeholder="
|
|
142
|
+
aria-label="Protocol"
|
|
143
|
+
placeholder="Protocol (Pipefy card / ticket)"
|
|
136
144
|
value={protocol}
|
|
137
145
|
onChange={(event) => setProtocol(event.target.value)}
|
|
138
146
|
slotProps={{ htmlInput: { 'data-testid': 'homologacao-protocol' } }}
|
|
139
147
|
/>
|
|
140
148
|
<TextField
|
|
141
149
|
size="small"
|
|
142
|
-
aria-label="
|
|
143
|
-
placeholder="
|
|
150
|
+
aria-label="Notes"
|
|
151
|
+
placeholder="Notes (PagBank's reply, context…)"
|
|
144
152
|
value={notes}
|
|
145
153
|
onChange={(event) => setNotes(event.target.value)}
|
|
146
154
|
slotProps={{ htmlInput: { 'data-testid': 'homologacao-notes' } }}
|
|
@@ -152,7 +160,7 @@ export function HomologacaoOutcomeCard(props: HomologacaoOutcomeCardProps): Reac
|
|
|
152
160
|
onClick={() => onSave({ status, protocol, notes })}
|
|
153
161
|
data-testid="homologacao-save"
|
|
154
162
|
>
|
|
155
|
-
|
|
163
|
+
Record
|
|
156
164
|
</Button>
|
|
157
165
|
</Box>
|
|
158
166
|
{save.error !== null ? (
|
|
@@ -162,7 +170,7 @@ export function HomologacaoOutcomeCard(props: HomologacaoOutcomeCardProps): Reac
|
|
|
162
170
|
) : null}
|
|
163
171
|
{save.success ? (
|
|
164
172
|
<Alert severity="success" data-testid="homologacao-save-ok">
|
|
165
|
-
|
|
173
|
+
Record updated.
|
|
166
174
|
</Alert>
|
|
167
175
|
) : null}
|
|
168
176
|
</Stack>
|
|
@@ -28,9 +28,13 @@ import {
|
|
|
28
28
|
* mounted routes (`platformHomologacaoGuide`, `createHomologationRecordService`
|
|
29
29
|
* and `buildPlatformHomologacaoAnexo` in `@12-apps/payments-backend`), so the
|
|
30
30
|
* host page is a thin mount.
|
|
31
|
+
*
|
|
32
|
+
* English, like the rest of this platform surface (FUT-760) — see
|
|
33
|
+
* `ConnectApplicationPanel` for why. The only Portuguese that reaches the
|
|
34
|
+
* screen is PagBank's own form field names, carried on `guide.fieldLabels`.
|
|
31
35
|
*/
|
|
32
36
|
export interface PlatformHomologacaoProps {
|
|
33
|
-
/** The recorded outcome; null renders the honest "
|
|
37
|
+
/** The recorded outcome; null renders the honest "not submitted". */
|
|
34
38
|
record: PlatformHomologationRecordView | null;
|
|
35
39
|
/** The paste-ready answers, computed by the host's backend. */
|
|
36
40
|
guide: HomologacaoGuide;
|
|
@@ -58,7 +62,7 @@ function AnexoCard({ onGenerate }: { onGenerate: () => Promise<void> }): ReactNo
|
|
|
58
62
|
try {
|
|
59
63
|
await onGenerate();
|
|
60
64
|
} catch (cause) {
|
|
61
|
-
setError(cause instanceof Error ? cause.message : '
|
|
65
|
+
setError(cause instanceof Error ? cause.message : 'Could not generate the attachment.');
|
|
62
66
|
} finally {
|
|
63
67
|
setBusy(false);
|
|
64
68
|
}
|
|
@@ -67,13 +71,13 @@ function AnexoCard({ onGenerate }: { onGenerate: () => Promise<void> }): ReactNo
|
|
|
67
71
|
return (
|
|
68
72
|
<Stack spacing={1.5} data-testid="homologacao-anexo-card" sx={CARD_SX}>
|
|
69
73
|
<Typography variant="body2" fontWeight={600}>
|
|
70
|
-
|
|
74
|
+
Evidence attachment
|
|
71
75
|
</Typography>
|
|
72
76
|
<Typography variant="body2" color="text.secondary" component="p">
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
The form demands the requests and responses of the calls sent to PagBank's APIs. The
|
|
78
|
+
button below makes those calls for real against the test environment (Sandbox), on the
|
|
79
|
+
platform's own token — nothing is actually charged — and downloads the file ready to
|
|
80
|
+
attach, with the token redacted.
|
|
77
81
|
</Typography>
|
|
78
82
|
<Box>
|
|
79
83
|
<Button
|
|
@@ -83,7 +87,7 @@ function AnexoCard({ onGenerate }: { onGenerate: () => Promise<void> }): ReactNo
|
|
|
83
87
|
onClick={() => void generate()}
|
|
84
88
|
data-testid="homologacao-anexo-button"
|
|
85
89
|
>
|
|
86
|
-
|
|
90
|
+
Generate attachment
|
|
87
91
|
</Button>
|
|
88
92
|
</Box>
|
|
89
93
|
{error !== null ? (
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, type JSX, type ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
import type { PaymentsSettingsCopy } from './settings-copy';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The settings surface's words, for the fifteen components that render them
|
|
9
|
+
* (FUT-760).
|
|
10
|
+
*
|
|
11
|
+
* A CONTEXT rather than a prop, unlike `CheckoutViewCopy`: this screen is a
|
|
12
|
+
* tree of small pieces — the status bar, the environment tabs, the connection
|
|
13
|
+
* card, the credential form, the priority list, the walkthrough — and threading
|
|
14
|
+
* one object through all of them as props is how a copy port comes to exist,
|
|
15
|
+
* be required, and go unread. It stays a single REQUIRED prop at the mount
|
|
16
|
+
* (`PaymentProviderSettings`), which is the only place a host has to answer.
|
|
17
|
+
*/
|
|
18
|
+
const PaymentsSettingsCopyContext = createContext<PaymentsSettingsCopy | null>(null);
|
|
19
|
+
|
|
20
|
+
export function PaymentsSettingsCopyProvider({
|
|
21
|
+
copy,
|
|
22
|
+
children,
|
|
23
|
+
}: {
|
|
24
|
+
copy: PaymentsSettingsCopy;
|
|
25
|
+
children: ReactNode;
|
|
26
|
+
}): JSX.Element {
|
|
27
|
+
return (
|
|
28
|
+
<PaymentsSettingsCopyContext.Provider value={copy}>
|
|
29
|
+
{children}
|
|
30
|
+
</PaymentsSettingsCopyContext.Provider>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* The words this settings screen renders — THROWS outside a provider rather
|
|
36
|
+
* than falling back.
|
|
37
|
+
*
|
|
38
|
+
* A fallback could only be the origin host's Portuguese, handed silently to the
|
|
39
|
+
* next adopter's store owner. Failing at the mount is the point: it is the one
|
|
40
|
+
* moment a host can still be told it forgot.
|
|
41
|
+
*/
|
|
42
|
+
export function usePaymentsSettingsCopy(): PaymentsSettingsCopy {
|
|
43
|
+
const copy = useContext(PaymentsSettingsCopyContext);
|
|
44
|
+
if (!copy) {
|
|
45
|
+
throw new Error(
|
|
46
|
+
'usePaymentsSettingsCopy must be rendered inside a <PaymentsSettingsCopyProvider>',
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return copy;
|
|
50
|
+
}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every sentence the payments SETTINGS surface puts in front of a store owner
|
|
3
|
+
* (FUT-760).
|
|
4
|
+
*
|
|
5
|
+
* Required, with no defaults — this package's own doctrine, stated in
|
|
6
|
+
* `checkout/view-copy.ts`: a default in the origin host's language reads as
|
|
7
|
+
* finished to the next host right up until an owner sees it.
|
|
8
|
+
*
|
|
9
|
+
* The split is the one the whole port draws. WHICH state the connection is in
|
|
10
|
+
* — authorized but unverified, verified and paused, an authorization about to
|
|
11
|
+
* expire, an environment that moves real money — is knowledge of the payments
|
|
12
|
+
* lifecycle, and it stays here. The words are the host's.
|
|
13
|
+
*
|
|
14
|
+
* ## What is NOT in here
|
|
15
|
+
*
|
|
16
|
+
* The provider's own display name. It arrives as `displayName` from the
|
|
17
|
+
* adapter and is interpolated by the functions below, because "PagBank" is
|
|
18
|
+
* PagBank's name in every language.
|
|
19
|
+
*
|
|
20
|
+
* The dates. `Autorização válida até {when}` takes an already-formatted
|
|
21
|
+
* string, since how a host formats a date is a host decision it has already
|
|
22
|
+
* made elsewhere.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** The chip and the two lines under it — where this connection stands. */
|
|
26
|
+
export interface ConnectionStatusCopy {
|
|
27
|
+
/** A real charge has gone through — the strongest thing the chip can say. */
|
|
28
|
+
verified: string;
|
|
29
|
+
/** Nothing has been proven about this connection yet. */
|
|
30
|
+
unverified: string;
|
|
31
|
+
/** The credential probe passed; no charge has been made. */
|
|
32
|
+
connectionOk: string;
|
|
33
|
+
/**
|
|
34
|
+
* A connection that WAS working and stopped — the one red chip, because it
|
|
35
|
+
* is news rather than a step still to finish.
|
|
36
|
+
*/
|
|
37
|
+
reconnectRequired: string;
|
|
38
|
+
/** Not connected at all. */
|
|
39
|
+
notConnected: string;
|
|
40
|
+
/** The lead line before the three steps, for a provider not yet receiving. */
|
|
41
|
+
threeStepsAhead: string;
|
|
42
|
+
/** The same, when the store must connect and verify first. */
|
|
43
|
+
connectAndVerifyFirst: string;
|
|
44
|
+
/** Live: this provider is taking money. */
|
|
45
|
+
receiving: { state: string; sub: string };
|
|
46
|
+
/** Proven, and switched off by the owner. */
|
|
47
|
+
pausedByOwner: { state: string; sub: string };
|
|
48
|
+
/** The chip above that pair. */
|
|
49
|
+
pausedChip: string;
|
|
50
|
+
/** Proven, not switched on yet. */
|
|
51
|
+
readyNotReceiving: { state: string; sub: string };
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The provider LIST's badge — one word per row, and a different vocabulary
|
|
56
|
+
* from the panel's chip on purpose: the list answers "where does this store
|
|
57
|
+
* stand" and the panel answers "what is left to do".
|
|
58
|
+
*/
|
|
59
|
+
export interface ConnectionBadgeCopy {
|
|
60
|
+
/** Money can move through this provider right now. */
|
|
61
|
+
active: string;
|
|
62
|
+
/** Connected and proven, but not switched on. */
|
|
63
|
+
connected: string;
|
|
64
|
+
/** It was working and stopped. */
|
|
65
|
+
reconnect: string;
|
|
66
|
+
notConnected: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** The environment tabs, and what choosing one means. */
|
|
70
|
+
export interface EnvironmentCopy {
|
|
71
|
+
/** The two environments' names, as this host says them. */
|
|
72
|
+
production: string;
|
|
73
|
+
sandbox: string;
|
|
74
|
+
/** The tab group's own label (and its `aria-label`). */
|
|
75
|
+
groupLabel: string;
|
|
76
|
+
/** The line under the tabs: which environment, and what it costs. */
|
|
77
|
+
productionMeaning: string;
|
|
78
|
+
sandboxMeaning: string;
|
|
79
|
+
productionConsequence: string;
|
|
80
|
+
sandboxConsequence: string;
|
|
81
|
+
/**
|
|
82
|
+
* The store is CURRENTLY charging in the other environment — the sentence
|
|
83
|
+
* that stops an owner editing sandbox keys believing they are live.
|
|
84
|
+
*/
|
|
85
|
+
storeIsUsing(environmentName: string): string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** The OAuth half: connecting by authorization rather than by pasted keys. */
|
|
89
|
+
export interface OAuthConnectionCopy {
|
|
90
|
+
connectAction(displayName: string): string;
|
|
91
|
+
/** The same button once a connection exists — a re-grant, not a first one. */
|
|
92
|
+
reconnectAction: string;
|
|
93
|
+
/** Drop the connection entirely. */
|
|
94
|
+
removeAction: string;
|
|
95
|
+
/** The invitation, before anything is connected. */
|
|
96
|
+
invitation(displayName: string): string;
|
|
97
|
+
/** How long it takes and where the owner goes. */
|
|
98
|
+
roundTripNote: string;
|
|
99
|
+
/** Connected: what the authorization does and does not give us. */
|
|
100
|
+
connectedExplainer: string;
|
|
101
|
+
connectedNote(displayName: string): string;
|
|
102
|
+
connectedAt(when: string): string;
|
|
103
|
+
/** The authorization is still good, until this moment. */
|
|
104
|
+
validUntil(when: string): string;
|
|
105
|
+
/** It has already lapsed. */
|
|
106
|
+
expiredAt(when: string): string;
|
|
107
|
+
/** It lapses soon. */
|
|
108
|
+
expiresAt(when: string): string;
|
|
109
|
+
/** It lapsed or was revoked at the provider. */
|
|
110
|
+
revoked: string;
|
|
111
|
+
/**
|
|
112
|
+
* This DEPLOYMENT registered no OAuth application, so the button cannot
|
|
113
|
+
* work — the one sentence here about the installation rather than the store.
|
|
114
|
+
*/
|
|
115
|
+
notAvailableHere(displayName: string): string;
|
|
116
|
+
/**
|
|
117
|
+
* The whole PANEL's refusal, for a deployment with no registered provider
|
|
118
|
+
* application at all.
|
|
119
|
+
*
|
|
120
|
+
* Not the same sentence as {@link notAvailableHere}: that one sits beside a
|
|
121
|
+
* working credential form and points at it, this one replaces the connect
|
|
122
|
+
* card because there is no button to render.
|
|
123
|
+
*/
|
|
124
|
+
connectUnavailable: string;
|
|
125
|
+
/** The two links that swap between the grant and the credential form. */
|
|
126
|
+
preferOAuth: string;
|
|
127
|
+
preferCredentials: string;
|
|
128
|
+
/** What the grant lets this platform do, listed by scope. */
|
|
129
|
+
scopes: {
|
|
130
|
+
read: string;
|
|
131
|
+
create: string;
|
|
132
|
+
refund: string;
|
|
133
|
+
account: string;
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** The connection card, and the confirmation that removes it. */
|
|
138
|
+
export interface ConnectionCardCopy {
|
|
139
|
+
accountHeading(displayName: string): string;
|
|
140
|
+
/** The fact rows' own labels, down the left of the card. */
|
|
141
|
+
accountLabel: string;
|
|
142
|
+
connectionLabel: string;
|
|
143
|
+
authorizedAt(displayName: string): string;
|
|
144
|
+
environmentLabel: string;
|
|
145
|
+
connectedAtLabel: string;
|
|
146
|
+
/**
|
|
147
|
+
* Sandbox, as this card names it — the parenthetical is here and not in
|
|
148
|
+
* `EnvironmentCopy` because the tabs label a CHOICE and this labels a fact.
|
|
149
|
+
*/
|
|
150
|
+
sandboxWithNote: string;
|
|
151
|
+
/** The three steps a grant takes, for a store that has not connected yet. */
|
|
152
|
+
steps: { signIn(displayName: string): string; authorize: string; comeBack: string };
|
|
153
|
+
removeAction: string;
|
|
154
|
+
removeQuestion(displayName: string): string;
|
|
155
|
+
/**
|
|
156
|
+
* What removing costs. Two sentences, because a LIVE connection stops the
|
|
157
|
+
* store taking money the moment it goes — and that is not the same warning
|
|
158
|
+
* as "you can reconnect later".
|
|
159
|
+
*/
|
|
160
|
+
removeConsequenceLive: string;
|
|
161
|
+
removeConsequenceIdle: string;
|
|
162
|
+
/**
|
|
163
|
+
* The first itemised consequence, shown only for a LIVE connection: the
|
|
164
|
+
* store stops taking money the moment this is confirmed.
|
|
165
|
+
*
|
|
166
|
+
* Its own field rather than a clause of `removeConsequenceLive`, because
|
|
167
|
+
* the list beside it is what makes the irreversible item weigh more than
|
|
168
|
+
* the reversible ones — a single paragraph is what an owner skims.
|
|
169
|
+
*/
|
|
170
|
+
removeStopsChargingNow: string;
|
|
171
|
+
removeRevokes(displayName: string): string;
|
|
172
|
+
removeKeepsSettled(displayName: string): string;
|
|
173
|
+
removeRestartsSetup: string;
|
|
174
|
+
/**
|
|
175
|
+
* The way out of the removal dialog for an owner who only meant to stop
|
|
176
|
+
* taking orders — the offer that makes the destructive button safe to show.
|
|
177
|
+
*/
|
|
178
|
+
pauseInstead: string;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** The credential form: its fields, its probe, and what it says while testing. */
|
|
182
|
+
export interface CredentialFormCopy {
|
|
183
|
+
/** A stored secret, shown masked — leaving it blank keeps it. */
|
|
184
|
+
configuredKeepBlank: string;
|
|
185
|
+
/** The suffix on an `advanced` field most stores must leave empty. */
|
|
186
|
+
advancedSuffix: string;
|
|
187
|
+
probeAction: string;
|
|
188
|
+
/**
|
|
189
|
+
* What replacing a PROVEN connection's credentials costs.
|
|
190
|
+
*
|
|
191
|
+
* Takes the provider's display name: the sentence used to name "InfiniteTag"
|
|
192
|
+
* outright, and it renders above EVERY provider's credential form — so a
|
|
193
|
+
* Stripe store was told to be careful with a field it does not have. Rendered
|
|
194
|
+
* through `richText`, so `**…**` marks the two clauses that carry the cost.
|
|
195
|
+
*/
|
|
196
|
+
reverifyWarning(displayName: string): string;
|
|
197
|
+
probeRunning: string;
|
|
198
|
+
probeSaveNote: string;
|
|
199
|
+
probeIncompleteNote: string;
|
|
200
|
+
probeFailed(environmentName: string): string;
|
|
201
|
+
/** The per-credential marks beside each field. */
|
|
202
|
+
checkPass: string;
|
|
203
|
+
checkFail: string;
|
|
204
|
+
/** A credential the provider offers no way to check. */
|
|
205
|
+
uncheckable: string;
|
|
206
|
+
/**
|
|
207
|
+
* The save button's three forms. WHICH one is right is a fact this package
|
|
208
|
+
* establishes — a complete set is sent to the provider, a partial one is
|
|
209
|
+
* only written down, and a one-field provider names its field instead.
|
|
210
|
+
*/
|
|
211
|
+
saveAndTest: string;
|
|
212
|
+
save: string;
|
|
213
|
+
saveOnly(fieldLabel: string): string;
|
|
214
|
+
/** Reopen a finished credential step — unaccented, so only a reading found it. */
|
|
215
|
+
changeAction: string;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** Ordering the provider chain, and what a decline does at the end of it. */
|
|
219
|
+
export interface ProviderPriorityCopy {
|
|
220
|
+
moveUp(label: string): string;
|
|
221
|
+
moveDown(label: string): string;
|
|
222
|
+
saveFailed: string;
|
|
223
|
+
/** The head of the chain, captioned so the order is unmistakable. */
|
|
224
|
+
firstInChain: string;
|
|
225
|
+
/** The reorderable list's own heading. */
|
|
226
|
+
orderHeading: string;
|
|
227
|
+
/**
|
|
228
|
+
* What the order MEANS, naming the provider at the head of it.
|
|
229
|
+
*
|
|
230
|
+
* Rendered through `richText`, so `**…**` marks that name — the sentence is
|
|
231
|
+
* about which provider is tried first, and the name is the answer.
|
|
232
|
+
*/
|
|
233
|
+
chainExplainer(firstProviderLabel: string): string;
|
|
234
|
+
/** No provider is switched on, so nothing can be charged at all. */
|
|
235
|
+
noneActive: string;
|
|
236
|
+
/**
|
|
237
|
+
* The switch's label. Rendered through `richText`, so `**…**` emphasises the
|
|
238
|
+
* word the sentence is about — the same two-asterisk grammar the setup-guide
|
|
239
|
+
* steps use, and the only markup any copy in this package may carry.
|
|
240
|
+
*/
|
|
241
|
+
retryDeclinedLabel: string;
|
|
242
|
+
retryDeclinedOn: string;
|
|
243
|
+
retryDeclinedOff: string;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/** Choosing which provider to set up, before there is a connection at all. */
|
|
247
|
+
export interface ProviderListCopy {
|
|
248
|
+
heading: string;
|
|
249
|
+
/** What choosing one means — the setup that follows is shaped by it. */
|
|
250
|
+
subheading: string;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* The last look at the value that decides who gets paid.
|
|
255
|
+
*
|
|
256
|
+
* A mistyped account handle is the one failure on this screen with no
|
|
257
|
+
* recourse: the charge succeeds, the buyer is happy, and the money is in a
|
|
258
|
+
* stranger's account. So these sentences are not decoration, and a host that
|
|
259
|
+
* softens them has removed the only intervention available.
|
|
260
|
+
*/
|
|
261
|
+
export interface ConfirmCredentialSaveCopy {
|
|
262
|
+
title: string;
|
|
263
|
+
/**
|
|
264
|
+
* What saving this value means, naming the field it will be saved as — the
|
|
265
|
+
* provider's own name for it, as the credential schema spells it.
|
|
266
|
+
*/
|
|
267
|
+
body(fieldLabel: string): string;
|
|
268
|
+
/** What to call the field when the schema shipped no label for it. */
|
|
269
|
+
fieldFallback: string;
|
|
270
|
+
/** The irreversibility, said plainly and last. */
|
|
271
|
+
warning: string;
|
|
272
|
+
/** Cancel is the plain, first-reached option; confirm carries the verb. */
|
|
273
|
+
cancelAction: string;
|
|
274
|
+
confirmAction: string;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** The walkthrough's own controls — the confirmation only an owner can give. */
|
|
278
|
+
export interface SetupGuideCopy {
|
|
279
|
+
/**
|
|
280
|
+
* The fallback confirm label, for a guide whose section declares none.
|
|
281
|
+
*
|
|
282
|
+
* It names another vendor's product ("Checkout Integrado"), which is why a
|
|
283
|
+
* section that can say something truer declares `confirmLabel` itself.
|
|
284
|
+
*/
|
|
285
|
+
defaultConfirmLabel: string;
|
|
286
|
+
/** How a confirmed section reads once it has collapsed. */
|
|
287
|
+
confirmedByYou: string;
|
|
288
|
+
/** Reopen a section the owner already confirmed. */
|
|
289
|
+
reviewAction: string;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** The whole settings surface, in one object a host passes at the mount. */
|
|
293
|
+
export interface PaymentsSettingsCopy {
|
|
294
|
+
status: ConnectionStatusCopy;
|
|
295
|
+
listBadge: ConnectionBadgeCopy;
|
|
296
|
+
environment: EnvironmentCopy;
|
|
297
|
+
oauth: OAuthConnectionCopy;
|
|
298
|
+
card: ConnectionCardCopy;
|
|
299
|
+
credentials: CredentialFormCopy;
|
|
300
|
+
priority: ProviderPriorityCopy;
|
|
301
|
+
providerList: ProviderListCopy;
|
|
302
|
+
confirmSave: ConfirmCredentialSaveCopy;
|
|
303
|
+
setupGuide: SetupGuideCopy;
|
|
304
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import type { PaymentsSettingsCopy } from './settings-copy';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The pt-BR pack for the payments settings surface — a NAMED constant a host
|
|
5
|
+
* passes by hand, never a default.
|
|
6
|
+
*
|
|
7
|
+
* The filename is what exempts this file from the copy-portability gate:
|
|
8
|
+
* Portuguese may ship, it may not be silent. Every sentence is VERBATIM what
|
|
9
|
+
* the screen used to render, so a host adopting it sees no change — what
|
|
10
|
+
* changes is that the words are chosen in a diff.
|
|
11
|
+
*/
|
|
12
|
+
export const PT_BR_PAYMENTS_SETTINGS_COPY: PaymentsSettingsCopy = {
|
|
13
|
+
status: {
|
|
14
|
+
verified: 'VERIFICADO',
|
|
15
|
+
unverified: 'NÃO VERIFICADO',
|
|
16
|
+
connectionOk: 'CONEXÃO OK',
|
|
17
|
+
reconnectRequired: 'RECONECTAR',
|
|
18
|
+
notConnected: 'Não conectado',
|
|
19
|
+
threeStepsAhead: 'Este provedor só passa a receber vendas depois dos 3 passos abaixo.',
|
|
20
|
+
connectAndVerifyFirst: 'Conecte e verifique o provedor antes de ativar as vendas.',
|
|
21
|
+
receiving: {
|
|
22
|
+
state: 'Recebendo vendas',
|
|
23
|
+
sub: 'Sua loja está recebendo por este provedor.',
|
|
24
|
+
},
|
|
25
|
+
pausedByOwner: {
|
|
26
|
+
state: 'Pausado',
|
|
27
|
+
sub: 'Conexão pronta e pausada por você — nenhum pedido novo é cobrado aqui.',
|
|
28
|
+
},
|
|
29
|
+
pausedChip: 'Pausado',
|
|
30
|
+
readyNotReceiving: {
|
|
31
|
+
state: 'Ainda não está recebendo',
|
|
32
|
+
sub: 'Tudo pronto — ligue a chave para começar a receber.',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
listBadge: {
|
|
36
|
+
active: 'Ativo',
|
|
37
|
+
connected: 'Conectado',
|
|
38
|
+
reconnect: 'Reconectar',
|
|
39
|
+
notConnected: 'Não conectado',
|
|
40
|
+
},
|
|
41
|
+
environment: {
|
|
42
|
+
production: 'Produção',
|
|
43
|
+
sandbox: 'Sandbox',
|
|
44
|
+
groupLabel: 'Ambiente desta conexão',
|
|
45
|
+
productionMeaning: 'Produção — dinheiro real.',
|
|
46
|
+
sandboxMeaning: 'Sandbox — ambiente de teste.',
|
|
47
|
+
productionConsequence: 'Tudo o que você fizer aqui vale para as vendas da loja.',
|
|
48
|
+
sandboxConsequence: 'Nenhum valor sai ou entra de verdade.',
|
|
49
|
+
storeIsUsing: (environmentName) => ` Hoje a loja está usando ${environmentName}.`,
|
|
50
|
+
},
|
|
51
|
+
oauth: {
|
|
52
|
+
connectAction: (displayName) => `Conectar com ${displayName}`,
|
|
53
|
+
reconnectAction: 'Reconectar',
|
|
54
|
+
removeAction: 'Remover conexão',
|
|
55
|
+
invitation: (displayName) =>
|
|
56
|
+
`Conecte sua conta ${displayName} autorizando o acesso no site do provedor. Nenhuma chave precisa ser copiada.`,
|
|
57
|
+
roundTripNote: 'Você sai para o provedor e volta para cá — leva menos de um minuto.',
|
|
58
|
+
connectedExplainer:
|
|
59
|
+
'Sua conta está conectada. As cobranças são criadas em seu nome — nenhuma chave precisa ser copiada.',
|
|
60
|
+
connectedNote: (displayName) =>
|
|
61
|
+
`Conta ${displayName} conectada. Revogue quando quiser, aqui ou no painel do provedor.`,
|
|
62
|
+
connectedAt: (when) => `Conectada em ${when}`,
|
|
63
|
+
validUntil: (when) => `Autorização válida até ${when}`,
|
|
64
|
+
expiredAt: (when) =>
|
|
65
|
+
`A autorização expirou em ${when}. Reconecte para voltar a receber pagamentos.`,
|
|
66
|
+
expiresAt: (when) =>
|
|
67
|
+
`A autorização expira em ${when}. Se o aviso continuar, reconecte a conta.`,
|
|
68
|
+
revoked: 'A autorização expirou ou foi revogada. Reconecte para voltar a receber pagamentos.',
|
|
69
|
+
notAvailableHere: (displayName) =>
|
|
70
|
+
`A conexão automática com ${displayName} não está disponível nesta instalação — ` +
|
|
71
|
+
'o aplicativo de autorização não foi cadastrado. Para conectar agora, abra ' +
|
|
72
|
+
'“Prefiro informar as credenciais manualmente” abaixo e cole as suas próprias chaves.',
|
|
73
|
+
connectUnavailable:
|
|
74
|
+
'Este provedor conecta por autorização, mas o botão de conexão não está disponível nesta ' +
|
|
75
|
+
'instalação. Você ainda pode conectar informando as credenciais manualmente.',
|
|
76
|
+
preferOAuth: 'Prefiro conectar por autorização',
|
|
77
|
+
preferCredentials: 'Prefiro informar as credenciais manualmente',
|
|
78
|
+
scopes: {
|
|
79
|
+
read: 'Consultar pagamentos',
|
|
80
|
+
create: 'Criar cobranças',
|
|
81
|
+
refund: 'Estornar pagamentos',
|
|
82
|
+
account: 'Consultar dados da conta',
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
card: {
|
|
86
|
+
accountHeading: (displayName) => `Conta ${displayName}`,
|
|
87
|
+
accountLabel: 'Conta',
|
|
88
|
+
connectionLabel: 'Conexão',
|
|
89
|
+
authorizedAt: (displayName) => `Autorizada no ${displayName}`,
|
|
90
|
+
environmentLabel: 'Ambiente',
|
|
91
|
+
connectedAtLabel: 'Conectada em',
|
|
92
|
+
sandboxWithNote: 'Sandbox (testes)',
|
|
93
|
+
steps: {
|
|
94
|
+
signIn: (displayName) =>
|
|
95
|
+
`Entre na sua conta ${displayName} — dá para criar uma na hora, se ainda não tiver.`,
|
|
96
|
+
authorize: 'Autorize o acesso na tela do provedor.',
|
|
97
|
+
comeBack: 'Você volta para cá com a conta conectada.',
|
|
98
|
+
},
|
|
99
|
+
removeAction: 'Remover conexão',
|
|
100
|
+
removeQuestion: (displayName) => `Remover a conexão com ${displayName}?`,
|
|
101
|
+
removeConsequenceLive:
|
|
102
|
+
'A loja para de receber na hora e fica sem provedor ativo — pedidos novos não conseguem ser pagos até você conectar outro.',
|
|
103
|
+
removeConsequenceIdle: 'Esta conexão sai da loja. Você pode conectar de novo depois.',
|
|
104
|
+
removeStopsChargingNow: 'Pedidos novos deixam de ser cobrados imediatamente.',
|
|
105
|
+
removeRevokes: (displayName) =>
|
|
106
|
+
`A autorização é revogada no ${displayName}. Sua conta e seu histórico continuam lá, intactos.`,
|
|
107
|
+
removeKeepsSettled: (displayName) =>
|
|
108
|
+
`Pagamentos já aprovados e estornos em andamento seguem normalmente pelo ${displayName}.`,
|
|
109
|
+
removeRestartsSetup: 'Para reconectar, os passos recomeçam do zero.',
|
|
110
|
+
pauseInstead: 'Só pausar o recebimento',
|
|
111
|
+
},
|
|
112
|
+
credentials: {
|
|
113
|
+
configuredKeepBlank: 'Configurado — deixe em branco para manter o valor atual.',
|
|
114
|
+
advancedSuffix: ' · só para plataformas Connect',
|
|
115
|
+
probeAction: 'Testar conexão',
|
|
116
|
+
reverifyWarning: (displayName) =>
|
|
117
|
+
`Esta loja já está verificada. Trocar as credenciais **exige uma nova verificação** ` +
|
|
118
|
+
`e a loja **para de receber** pelo ${displayName} até que ela termine.`,
|
|
119
|
+
probeRunning: 'Testando a conexão…',
|
|
120
|
+
probeSaveNote: 'Salvamos e testamos as chaves no provedor antes de seguir.',
|
|
121
|
+
probeIncompleteNote: 'Guardamos o que você já preencheu. Complete os campos para testar.',
|
|
122
|
+
probeFailed: (environmentName) =>
|
|
123
|
+
`Não foi possível conectar em ${environmentName}. Confira as credenciais deste ambiente.`,
|
|
124
|
+
checkPass: 'Verificado',
|
|
125
|
+
checkFail: 'Corrigir',
|
|
126
|
+
uncheckable: 'Não verificável',
|
|
127
|
+
saveAndTest: 'Salvar e testar conexão',
|
|
128
|
+
save: 'Salvar',
|
|
129
|
+
saveOnly: (fieldLabel) => `Salvar ${fieldLabel}`,
|
|
130
|
+
changeAction: 'Alterar',
|
|
131
|
+
},
|
|
132
|
+
priority: {
|
|
133
|
+
moveUp: (label) => `Mover ${label} para cima`,
|
|
134
|
+
moveDown: (label) => `Mover ${label} para baixo`,
|
|
135
|
+
saveFailed: 'Não foi possível salvar a ordem.',
|
|
136
|
+
firstInChain: 'primeiro',
|
|
137
|
+
orderHeading: 'Ordem de tentativa',
|
|
138
|
+
chainExplainer: (firstProviderLabel) =>
|
|
139
|
+
`O checkout tenta **${firstProviderLabel}** primeiro. Se uma cobrança falhar por motivo ` +
|
|
140
|
+
'técnico, ele tenta o próximo da lista — mas só quando é possível comprovar que a ' +
|
|
141
|
+
'tentativa anterior não gerou cobrança.',
|
|
142
|
+
noneActive:
|
|
143
|
+
'Nenhum provedor está ativo. O checkout não conseguirá cobrar até que você ative ao menos um.',
|
|
144
|
+
retryDeclinedLabel: 'Tentar cartão **recusado** no próximo provedor',
|
|
145
|
+
retryDeclinedOn:
|
|
146
|
+
'Uma recusa passa para o próximo da lista. Isso pode aumentar custos de transação e sinais de fraude.',
|
|
147
|
+
retryDeclinedOff:
|
|
148
|
+
'Padrão: uma recusa encerra a cobrança. Só falhas técnicas passam para o próximo.',
|
|
149
|
+
},
|
|
150
|
+
providerList: {
|
|
151
|
+
heading: 'Escolha o provedor de pagamento',
|
|
152
|
+
subheading: 'Selecione onde sua loja recebe — a configuração é feita sob medida para ele.',
|
|
153
|
+
},
|
|
154
|
+
confirmSave: {
|
|
155
|
+
title: 'Confirme para onde vai o dinheiro',
|
|
156
|
+
body: (fieldLabel) =>
|
|
157
|
+
`Todo pagamento recebido por esta loja será depositado na conta desta ${fieldLabel}:`,
|
|
158
|
+
fieldFallback: 'credencial',
|
|
159
|
+
warning:
|
|
160
|
+
'Um valor errado envia os pagamentos desta loja para outra pessoa, e não há como reverter.',
|
|
161
|
+
cancelAction: 'Voltar e revisar',
|
|
162
|
+
confirmAction: 'É essa, salvar',
|
|
163
|
+
},
|
|
164
|
+
setupGuide: {
|
|
165
|
+
defaultConfirmLabel: 'Já habilitei o Checkout Integrado',
|
|
166
|
+
confirmedByYou: 'Confirmado por você',
|
|
167
|
+
reviewAction: 'Revisar',
|
|
168
|
+
},
|
|
169
|
+
};
|