@asteby/storefront-react 0.16.1 → 0.18.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/README.md +58 -1
- package/dist/checkout.cjs +108 -20
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +15 -1
- package/dist/checkout.d.ts +15 -1
- package/dist/checkout.js +107 -21
- package/dist/checkout.js.map +1 -1
- package/dist/{chunk-ISEOCKIR.js → chunk-MNLROALF.js} +96 -8
- package/dist/chunk-MNLROALF.js.map +1 -0
- package/dist/{choices-DEPE9KRq.d.cts → csp-DZPuExzu.d.cts} +93 -55
- package/dist/{choices-DEPE9KRq.d.ts → csp-DZPuExzu.d.ts} +93 -55
- package/dist/payments-server.cjs +159 -12
- package/dist/payments-server.cjs.map +1 -1
- package/dist/payments-server.d.cts +23 -3
- package/dist/payments-server.d.ts +23 -3
- package/dist/payments-server.js +70 -13
- package/dist/payments-server.js.map +1 -1
- package/dist/payments.cjs +784 -160
- package/dist/payments.cjs.map +1 -1
- package/dist/payments.css +84 -0
- package/dist/payments.d.cts +227 -8
- package/dist/payments.d.ts +227 -8
- package/dist/payments.js +628 -102
- package/dist/payments.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-ISEOCKIR.js.map +0 -1
package/dist/payments.css
CHANGED
|
@@ -68,3 +68,87 @@
|
|
|
68
68
|
display: none !important;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
+
|
|
72
|
+
/* "Updating the total": the card form stays mounted; this layer only dims it and blocks input meanwhile. */
|
|
73
|
+
[data-sf-pay-card][data-sf-pay-updating] [data-sf-pay-container] {
|
|
74
|
+
opacity: 0.5;
|
|
75
|
+
pointer-events: none;
|
|
76
|
+
}
|
|
77
|
+
/* Notice of a payment that did not end well (<PaymentRecovery>). Neutral spacing only; colors come from `classNames`. */
|
|
78
|
+
[data-sf-pay-recovery] {
|
|
79
|
+
display: grid;
|
|
80
|
+
gap: 0.75rem;
|
|
81
|
+
}
|
|
82
|
+
[data-sf-pay-recovery] > p {
|
|
83
|
+
margin: 0;
|
|
84
|
+
}
|
|
85
|
+
[data-sf-pay-recovery] > div {
|
|
86
|
+
display: flex;
|
|
87
|
+
flex-wrap: wrap;
|
|
88
|
+
gap: 0.5rem;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/*
|
|
92
|
+
* 3DS challenge (`<PaymentChallenge>`): a near full-screen modal. Colors are fixed on purpose: the bank page inside
|
|
93
|
+
* the iframe is always white, and the dialog often lives in a themed (dark) panel. Override with a more specific rule.
|
|
94
|
+
*/
|
|
95
|
+
dialog[data-sf-challenge] {
|
|
96
|
+
margin: auto;
|
|
97
|
+
box-sizing: border-box;
|
|
98
|
+
width: min(60rem, calc(100% - 2rem));
|
|
99
|
+
max-width: none;
|
|
100
|
+
max-height: 94dvh;
|
|
101
|
+
overflow: auto;
|
|
102
|
+
border: 1px solid #c9d2ee;
|
|
103
|
+
border-radius: 0.75rem;
|
|
104
|
+
background: #ffffff;
|
|
105
|
+
color: #0b1220;
|
|
106
|
+
/* Claro aunque la página esté en oscuro: barras de desplazamiento y controles del navegador sobre fondo blanco. */
|
|
107
|
+
color-scheme: light;
|
|
108
|
+
padding: 1.25rem;
|
|
109
|
+
}
|
|
110
|
+
dialog[data-sf-challenge]::backdrop {
|
|
111
|
+
background: rgb(0 8 31 / 0.72);
|
|
112
|
+
}
|
|
113
|
+
dialog[data-sf-challenge] h2 {
|
|
114
|
+
margin: 0 0 0.75rem;
|
|
115
|
+
font-weight: 800;
|
|
116
|
+
color: #001963;
|
|
117
|
+
}
|
|
118
|
+
dialog[data-sf-challenge] h2:focus {
|
|
119
|
+
outline: none;
|
|
120
|
+
}
|
|
121
|
+
dialog[data-sf-challenge] [data-sf-challenge-frame] {
|
|
122
|
+
display: block;
|
|
123
|
+
height: min(70dvh, 40rem);
|
|
124
|
+
background: #ffffff;
|
|
125
|
+
}
|
|
126
|
+
dialog[data-sf-challenge] [data-sf-challenge-escape] {
|
|
127
|
+
margin-top: 0.75rem;
|
|
128
|
+
font-size: 0.875rem;
|
|
129
|
+
}
|
|
130
|
+
dialog[data-sf-challenge] [data-sf-challenge-escape]:empty {
|
|
131
|
+
margin: 0;
|
|
132
|
+
}
|
|
133
|
+
dialog[data-sf-challenge] [data-sf-challenge-escape] button {
|
|
134
|
+
margin-top: 0.5rem;
|
|
135
|
+
padding: 0 1rem;
|
|
136
|
+
background: #ffffff;
|
|
137
|
+
color: #0b1220;
|
|
138
|
+
border: 1px solid #8a94b3;
|
|
139
|
+
border-radius: 0.5rem;
|
|
140
|
+
font-weight: 600;
|
|
141
|
+
}
|
|
142
|
+
@media (max-width: 40rem) {
|
|
143
|
+
dialog[data-sf-challenge] {
|
|
144
|
+
width: 100%;
|
|
145
|
+
height: 100dvh;
|
|
146
|
+
max-height: 100dvh;
|
|
147
|
+
border-radius: 0;
|
|
148
|
+
border: 0;
|
|
149
|
+
padding: 1rem;
|
|
150
|
+
}
|
|
151
|
+
dialog[data-sf-challenge] [data-sf-challenge-frame] {
|
|
152
|
+
height: calc(100dvh - 8rem);
|
|
153
|
+
}
|
|
154
|
+
}
|
package/dist/payments.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, CSSProperties, RefObject } from 'react';
|
|
3
|
-
import { Money, PaymentAttemptResult, PaymentClient, PaymentOutcomeKind, PaymentOutcome, PaymentErrorView, PaymentMessages, PaymentErrorKind, PaymentOptionKey } from '@asteby/storefront';
|
|
4
|
-
import { a as PayChoices } from './
|
|
5
|
-
export { B as BuildPayChoicesOptions,
|
|
3
|
+
import { Money, PaymentAttemptResult, PaymentClient, PaymentErrorClassKind, PaymentOutcomeKind, PaymentOutcome, PaymentErrorView, PaymentMessages, PaymentErrorKind, PaymentOptionKey } from '@asteby/storefront';
|
|
4
|
+
import { h as PaymentRecoveryMessages, f as PaymentNoticeKind, P as PayChoice, a as PayChoices } from './csp-DZPuExzu.cjs';
|
|
5
|
+
export { B as BuildPayChoicesOptions, b as PayErrorBody, c as PayErrorOptions, d as PaymentCspMode, e as PaymentCspOptions, g as PaymentRecoveryMessageKey, V as VoucherRowLabels, i as buildPayChoices, j as cashProviderData, k as checkoutToAttempt, l as choiceValue, p as parseChoice, m as payErrorResponse, n as paymentCsp, o as paymentCspHeaderName, q as paymentCspHeaders, r as paymentCspMode, s as paymentNonce, t as paymentNonceFromHeaders, u as paymentRecoveryMessages, v as safeHttpStatus, w as voucherRows } from './csp-DZPuExzu.cjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Replaceable ports of the embedded payment. The shop (or another provider)
|
|
@@ -37,6 +37,8 @@ type PaymentFormMountOptions = {
|
|
|
37
37
|
colorScheme?: 'light' | 'dark';
|
|
38
38
|
onReady: () => void;
|
|
39
39
|
onError: (error: PaymentFormError) => void;
|
|
40
|
+
/** Aborted when this mount is no longer wanted (the form unmounted or was replaced). Adapters must not create after it. */
|
|
41
|
+
signal?: AbortSignal;
|
|
40
42
|
};
|
|
41
43
|
/** What a mounted form hands back at submit time. */
|
|
42
44
|
type PaymentFormData = {
|
|
@@ -48,6 +50,13 @@ type PaymentFormData = {
|
|
|
48
50
|
interface MountedPaymentForm {
|
|
49
51
|
/** Tokenises the card inside the provider iframes. Rejects when the form is invalid (the provider shows the field errors). */
|
|
50
52
|
collect(): Promise<PaymentFormData>;
|
|
53
|
+
/**
|
|
54
|
+
* Applies a new server total to the form that is already on screen, without remounting it. Rejects when the provider
|
|
55
|
+
* cannot (the hook then remounts, queued). Absent: the hook remounts on every total change.
|
|
56
|
+
*/
|
|
57
|
+
update?(next: {
|
|
58
|
+
amount: Money;
|
|
59
|
+
}): Promise<void>;
|
|
51
60
|
unmount(): void | Promise<void>;
|
|
52
61
|
}
|
|
53
62
|
interface PaymentFormAdapter {
|
|
@@ -89,7 +98,16 @@ declare class PaymentHttpError extends Error {
|
|
|
89
98
|
readonly name = "PaymentHttpError";
|
|
90
99
|
constructor(status: number, code: string, message?: string,
|
|
91
100
|
/** Raw `error.details` (e.g. the new `cost` of a `price_mismatch`); untrusted shape. */
|
|
92
|
-
details?: unknown | undefined
|
|
101
|
+
details?: unknown | undefined,
|
|
102
|
+
/** Optional classification from the shop's JSON body (`retryable`, `kind`). */
|
|
103
|
+
extra?: {
|
|
104
|
+
retryable?: boolean | undefined;
|
|
105
|
+
kind?: PaymentErrorClassKind | undefined;
|
|
106
|
+
});
|
|
107
|
+
/** `error.retryable` of the shop body: `true` repeat with the SAME key; `false` it is an answer. `undefined`: not said. */
|
|
108
|
+
readonly retryable: boolean | undefined;
|
|
109
|
+
/** `error.kind` of the shop body (`classifyPaymentError`). */
|
|
110
|
+
readonly kind: PaymentErrorClassKind | undefined;
|
|
93
111
|
}
|
|
94
112
|
type FetchTransportOptions = {
|
|
95
113
|
fetch?: typeof fetch;
|
|
@@ -135,7 +153,11 @@ type PaymentEvent = {
|
|
|
135
153
|
type UseEmbeddedPaymentOptions = {
|
|
136
154
|
/** Provider data from `paymentMethods[].client`. `null`/absent: nothing to mount (status `idle`). */
|
|
137
155
|
client: PaymentClient | null | undefined;
|
|
138
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* The total computed by the server. When it changes the form on screen is UPDATED in place (`MountedPaymentForm.update`)
|
|
158
|
+
* or, if the provider cannot, mounted again through the queue; never while a charge is in flight (applied after the
|
|
159
|
+
* answer). Never calculate it in the shop.
|
|
160
|
+
*/
|
|
139
161
|
amount: Money;
|
|
140
162
|
transport: PaymentTransport;
|
|
141
163
|
/** Mount only while the card option is selected. Default true. */
|
|
@@ -154,6 +176,12 @@ type UseEmbeddedPaymentOptions = {
|
|
|
154
176
|
autoRetries?: number;
|
|
155
177
|
/** Base delay for the backoff between automatic retries. Default 600. */
|
|
156
178
|
retryDelayMs?: number;
|
|
179
|
+
/** Longest wait for the provider's `create` before the form is declared failed. Default `sdkTimeoutMs`. */
|
|
180
|
+
createTimeoutMs?: number;
|
|
181
|
+
/** After an UNKNOWN outcome ("verifying"), how long the hook keeps reading `refresh`, with growing waits. Default 120000. */
|
|
182
|
+
verifyTimeoutMs?: number;
|
|
183
|
+
/** First wait of that check (doubles up to 15 s). Default 2000. */
|
|
184
|
+
verifyIntervalMs?: number;
|
|
157
185
|
/** Poll interval/timeout for a pending 3DS challenge or review when `transport.refresh` exists. */
|
|
158
186
|
pollIntervalMs?: number;
|
|
159
187
|
pollTimeoutMs?: number;
|
|
@@ -187,6 +215,8 @@ type EmbeddedPaymentState = {
|
|
|
187
215
|
attemptId: string | null;
|
|
188
216
|
/** `true` while loading, mounting or processing. */
|
|
189
217
|
busy: boolean;
|
|
218
|
+
/** `true` while the hook reads the payment state in the background after an unknown outcome. The attempt stays the same. */
|
|
219
|
+
verifying: boolean;
|
|
190
220
|
/** Attach to the element the provider renders into. */
|
|
191
221
|
containerRef: (el: HTMLElement | null) => void;
|
|
192
222
|
containerId: string;
|
|
@@ -196,6 +226,14 @@ type EmbeddedPaymentState = {
|
|
|
196
226
|
retry: () => Promise<void>;
|
|
197
227
|
/** After a rejection: clears the message (the form is remounted by the hook). */
|
|
198
228
|
dismiss: () => void;
|
|
229
|
+
/**
|
|
230
|
+
* Leaves a pending 3DS challenge (the buyer's emergency exit). The outcome is UNKNOWN (the bank may still approve the
|
|
231
|
+
* attempt the buyer just verified), so the attempt key is kept and no new payment can start: the hook verifies the
|
|
232
|
+
* payment state through `transport.refresh` (status `blocked`, `error.kind = 'payment_in_progress'`, `verifying`).
|
|
233
|
+
* Only a definitive answer settles it: approved, or rejected / expired / cancelled, which gives a new attempt and a
|
|
234
|
+
* fresh form. A still-pending challenge does not reopen the dialog.
|
|
235
|
+
*/
|
|
236
|
+
cancelChallenge: () => void;
|
|
199
237
|
};
|
|
200
238
|
/**
|
|
201
239
|
* Embedded payment state machine for one card form.
|
|
@@ -226,10 +264,20 @@ type PaymentChallengeProps = {
|
|
|
226
264
|
messages?: Partial<PaymentMessages>;
|
|
227
265
|
/** Replace the default iframe (e.g. mount the provider's status screen). */
|
|
228
266
|
render?: (outcome: PaymentOutcome) => ReactNode;
|
|
267
|
+
/**
|
|
268
|
+
* The buyer's emergency exit. The dialog is NOT dismissible (no Esc, no backdrop click) while the payment is in
|
|
269
|
+
* progress; this button only appears after `escapeAfterMs`, so a stuck bank page never traps the buyer (WCAG 2.2.1).
|
|
270
|
+
*/
|
|
229
271
|
onCancel?: () => void;
|
|
272
|
+
/** How long the dialog stays locked before the exit shows. Default 120000. */
|
|
273
|
+
escapeAfterMs?: number;
|
|
230
274
|
};
|
|
231
|
-
/**
|
|
232
|
-
|
|
275
|
+
/**
|
|
276
|
+
* 3DS inside the page: a near full-screen modal dialog (`showModal()`: focus trap, inert page) with an accessible title.
|
|
277
|
+
* Esc and backdrop clicks do nothing until the payment ends (the owner unmounts it). Default content is the bank's
|
|
278
|
+
* https iframe. Layout comes from `payments.css` (`dialog[data-sf-challenge]`), overridable with your own CSS.
|
|
279
|
+
*/
|
|
280
|
+
declare function PaymentChallenge({ outcome, locale, messages, render, onCancel, escapeAfterMs }: PaymentChallengeProps): react.JSX.Element;
|
|
233
281
|
type PaymentBrickHandle = EmbeddedPaymentState;
|
|
234
282
|
type PaymentBrickProps = Omit<UseEmbeddedPaymentOptions, 'amount'> & {
|
|
235
283
|
/** The server's total. Shown on the button and passed to the provider widget. */
|
|
@@ -272,11 +320,182 @@ declare const PaymentBrick: react.ForwardRefExoticComponent<Omit<UseEmbeddedPaym
|
|
|
272
320
|
style?: CSSProperties;
|
|
273
321
|
} & react.RefAttributes<EmbeddedPaymentState>>;
|
|
274
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Mount queue for provider forms. Provider SDKs (Mercado Pago Bricks among them) resolve their container by id,
|
|
325
|
+
* asynchronously, and unmount asynchronously too. Without care, a remount races the previous unmount on the same node
|
|
326
|
+
* and the provider answers `container_not_found`, leaves an empty form, or draws two.
|
|
327
|
+
*
|
|
328
|
+
* Guarantees, per container element:
|
|
329
|
+
* - ONE mount at a time: a new mount waits for the previous one to finish tearing down (`await unmount`) before `create`.
|
|
330
|
+
* - Each mount gets its OWN inner node with a unique id, so the provider never looks for an id React already replaced.
|
|
331
|
+
* - A mount that was cancelled (`signal`) or whose container left the DOM never calls the provider; one that finishes
|
|
332
|
+
* late is torn down instead of kept.
|
|
333
|
+
* - `create` has a time limit: a provider call that never resolves cannot freeze the chain.
|
|
334
|
+
*/
|
|
335
|
+
|
|
336
|
+
declare class PaymentMountCancelled extends Error {
|
|
337
|
+
readonly name = "PaymentMountCancelled";
|
|
338
|
+
constructor(message?: string);
|
|
339
|
+
}
|
|
340
|
+
declare class PaymentMountTimeout extends Error {
|
|
341
|
+
readonly name = "PaymentMountTimeout";
|
|
342
|
+
constructor(ms: number);
|
|
343
|
+
}
|
|
344
|
+
type MountQueueOptions = {
|
|
345
|
+
/** Longest wait for the provider's `create`. Default 10000. */
|
|
346
|
+
createTimeoutMs?: number;
|
|
347
|
+
};
|
|
348
|
+
/** Mounts `base` on `opts.container` through the queue. See the module comment for the guarantees. */
|
|
349
|
+
declare function mountQueued(base: PaymentFormAdapter, opts: PaymentFormMountOptions, queue?: MountQueueOptions): Promise<MountedPaymentForm>;
|
|
350
|
+
/** Wraps an adapter so every `mount` goes through the queue. The hook already does this for any adapter it uses. */
|
|
351
|
+
declare function withMountQueue(adapter: PaymentFormAdapter, queue?: MountQueueOptions): PaymentFormAdapter;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Browser transport to the shop's pay and status routes, with the retry policy a card payment needs.
|
|
355
|
+
*
|
|
356
|
+
* - A TRANSIENT failure (5xx, timeout, network, a proxy HTML page) is repeated up to `retries` times with the SAME
|
|
357
|
+
* idempotency key (`request.idempotencyKey`): OPS then answers with the result of the first attempt. A payment whose
|
|
358
|
+
* outcome is unknown is NEVER charged with another key.
|
|
359
|
+
* - If it is still unknown, the status route is read `statusPolls` times. A resolved answer (paid, failed, voucher,
|
|
360
|
+
* challenge...) is returned; otherwise a network error is thrown and the hook keeps the SAME attempt (retry button
|
|
361
|
+
* and background checks).
|
|
362
|
+
* - `retryable: false` (an answer from OPS) is ONE request: no repeat, no status read.
|
|
363
|
+
* - A body that is not JSON is treated as transient, never as a definitive error.
|
|
364
|
+
*/
|
|
365
|
+
|
|
366
|
+
/** What the screen is told while a payment is being repeated or checked, and when it ends with a problem. */
|
|
367
|
+
type PaymentIssue = {
|
|
368
|
+
kind: 'confirming';
|
|
369
|
+
message: string;
|
|
370
|
+
} | {
|
|
371
|
+
kind: 'verifying';
|
|
372
|
+
message: string;
|
|
373
|
+
} | {
|
|
374
|
+
kind: PaymentErrorClassKind;
|
|
375
|
+
message: string;
|
|
376
|
+
retryable: boolean;
|
|
377
|
+
status: number;
|
|
378
|
+
code: string;
|
|
379
|
+
};
|
|
380
|
+
type ResilientTransportOptions = {
|
|
381
|
+
/** Same-origin route that charges the card (`handlers.pay`). */
|
|
382
|
+
payUrl: string;
|
|
383
|
+
/** Same-origin route that re-reads the payment (`handlers.status`). Enables the status checks and `refresh`. */
|
|
384
|
+
statusUrl: string;
|
|
385
|
+
/** Fields of the page form (delivery, contact, payment choice) that travel with the charge. */
|
|
386
|
+
fields: () => Record<string, string>;
|
|
387
|
+
/** Called with the state of the retry/verification and with the final problem; `null` clears it. */
|
|
388
|
+
onIssue?: (issue: PaymentIssue | null) => void;
|
|
389
|
+
fetch?: typeof fetch;
|
|
390
|
+
sleep?: (ms: number) => Promise<void>;
|
|
391
|
+
/** Automatic repeats after the first request. Default 2. */
|
|
392
|
+
retries?: number;
|
|
393
|
+
/** Wait before each repeat (ms); the last value repeats. Default `[800, 2000]`. */
|
|
394
|
+
backoffMs?: readonly number[];
|
|
395
|
+
/** Status reads before declaring the result "verifying". Default 3. */
|
|
396
|
+
statusPolls?: number;
|
|
397
|
+
/** Wait between status reads (ms). Default 2000. */
|
|
398
|
+
statusPollMs?: number;
|
|
399
|
+
/** Extra headers for both routes. */
|
|
400
|
+
headers?: Record<string, string>;
|
|
401
|
+
locale?: string;
|
|
402
|
+
messages?: Partial<PaymentRecoveryMessages>;
|
|
403
|
+
};
|
|
404
|
+
/** Has OPS decided? `pending` without an action, and `none`, are NOT decisions. */
|
|
405
|
+
declare function isResolvedAttempt(result: PaymentAttemptResult): boolean;
|
|
406
|
+
declare function createResilientTransport(opts: ResilientTransportOptions): PaymentTransport;
|
|
407
|
+
|
|
408
|
+
type PaymentNotice = {
|
|
409
|
+
kind: PaymentNoticeKind;
|
|
410
|
+
};
|
|
411
|
+
/** Payment rows other than the in-page card: what the buyer can switch to. */
|
|
412
|
+
declare function alternativeChoices(choices: readonly PayChoice[]): PayChoice[];
|
|
413
|
+
/** Selects a payment row in the page form (the section's radios are the source of truth) and brings it into view. */
|
|
414
|
+
declare function pickChoice(form: HTMLFormElement | null | undefined, value: string): void;
|
|
415
|
+
type UsePaymentRecoveryOptions = {
|
|
416
|
+
/** Same `scope` as the payment section (usually the cart id): where the attempt key is kept. */
|
|
417
|
+
scope?: string;
|
|
418
|
+
/** Where the attempt key lives. Default `sessionStorage`; `null` = memory only. */
|
|
419
|
+
storage?: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'> | null;
|
|
420
|
+
/** Automatic remounts of the secure form before showing the "form failed" notice. Default 2. */
|
|
421
|
+
formAutoRetries?: number;
|
|
422
|
+
/** The shop is closed (409 `store_not_ready`) or the like: re-read the page data. */
|
|
423
|
+
onRevalidate?: () => void;
|
|
424
|
+
};
|
|
425
|
+
type PaymentRecoveryState = {
|
|
426
|
+
notice: PaymentNotice | null;
|
|
427
|
+
setNotice: (notice: PaymentNotice | null) => void;
|
|
428
|
+
/** Use as `key` of `<PaymentMethodSection>`: a new value mounts a fresh section (and a fresh card form). */
|
|
429
|
+
sectionKey: number;
|
|
430
|
+
/** Pass to `createResilientTransport({ onIssue })`. */
|
|
431
|
+
onIssue: (issue: PaymentIssue | null) => void;
|
|
432
|
+
/** Pass to `<PaymentMethodSection onEvent>` (or compose it with your own handler). */
|
|
433
|
+
onEvent: (event: PaymentEvent) => void;
|
|
434
|
+
/** Last problem reported by the transport. */
|
|
435
|
+
lastIssue: {
|
|
436
|
+
current: PaymentIssue | null;
|
|
437
|
+
};
|
|
438
|
+
/**
|
|
439
|
+
* New attempt: a NEW idempotency key and a fresh form. Only after a definitive failure; returns `false` (and does
|
|
440
|
+
* nothing) while the outcome of the last charge is still unknown.
|
|
441
|
+
*/
|
|
442
|
+
retry: () => boolean;
|
|
443
|
+
/** Clears the notice (e.g. after the buyer picked another way to pay). */
|
|
444
|
+
clear: () => void;
|
|
445
|
+
};
|
|
446
|
+
declare function usePaymentRecovery(options?: UsePaymentRecoveryOptions): PaymentRecoveryState;
|
|
447
|
+
type PaymentRecoveryClassNames = Partial<Record<'root' | 'title' | 'body' | 'actions' | 'primary' | 'secondary', string>>;
|
|
448
|
+
type PaymentRecoveryProps = {
|
|
449
|
+
notice: PaymentNotice | null;
|
|
450
|
+
/** Other ways to pay (`alternativeChoices(choices)`); they come from the published choices, never from this component. */
|
|
451
|
+
alternatives?: readonly PayChoice[];
|
|
452
|
+
/** "Retry payment": new key and fresh form (`usePaymentRecovery().retry`). */
|
|
453
|
+
onRetry: () => void;
|
|
454
|
+
/** A way to pay was picked. */
|
|
455
|
+
onPick: (choice: PayChoice) => void;
|
|
456
|
+
/** "Refresh my order": re-read the cart and checkout. */
|
|
457
|
+
onRefresh: () => void;
|
|
458
|
+
locale?: string;
|
|
459
|
+
messages?: Partial<PaymentRecoveryMessages>;
|
|
460
|
+
/** Text of the button of an alternative. Default: the `action.alternative` message with the row name. */
|
|
461
|
+
alternativeLabel?: (choice: PayChoice) => string;
|
|
462
|
+
classNames?: PaymentRecoveryClassNames;
|
|
463
|
+
testIds?: Partial<Record<'retry' | 'refresh', string>>;
|
|
464
|
+
/** Extra content after the buttons. */
|
|
465
|
+
children?: ReactNode;
|
|
466
|
+
};
|
|
467
|
+
/** Notice of a card payment that did not end well. `role="status"` while confirming, `role="alert"` (focused) otherwise. */
|
|
468
|
+
declare function PaymentRecovery(props: PaymentRecoveryProps): react.JSX.Element | null;
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* `shouldRevalidate` for the routes AROUND the checkout (root layout, header, cart badge...). The checkout page saves the
|
|
472
|
+
* chosen delivery with a `fetcher.submit` to its own route; by default a router then re-runs EVERY loader on the page
|
|
473
|
+
* (catalog, session, theme...), which is slow and makes the page jump while the buyer is paying. This keeps those loaders
|
|
474
|
+
* quiet for that submission and leaves everything else (their own forms, navigation) as the router decided.
|
|
475
|
+
*
|
|
476
|
+
* Do NOT use it on the checkout route itself: its loader must re-read the cart (the new total) after the submit.
|
|
477
|
+
* Framework-agnostic: it only reads the fields every router passes (`formMethod`, `formAction`, `defaultShouldRevalidate`).
|
|
478
|
+
*/
|
|
479
|
+
type RevalidateArgs = {
|
|
480
|
+
formMethod?: string | undefined;
|
|
481
|
+
formAction?: string | undefined;
|
|
482
|
+
defaultShouldRevalidate: boolean;
|
|
483
|
+
};
|
|
484
|
+
type CheckoutRevalidateOptions = {
|
|
485
|
+
/** Paths whose form submissions do not need the other loaders (e.g. `['/pagar']`). Matched on the pathname. */
|
|
486
|
+
paths: readonly string[];
|
|
487
|
+
};
|
|
488
|
+
declare function checkoutShouldRevalidate(options: CheckoutRevalidateOptions): (args: RevalidateArgs) => boolean;
|
|
489
|
+
|
|
275
490
|
/** The `PaymentClient.kind` the addon `mercadopago` declares. */
|
|
276
491
|
declare const MERCADOPAGO_BRICKS_KIND = "mercadopago_bricks";
|
|
277
492
|
type MpController = {
|
|
278
493
|
getFormData(): Promise<Record<string, unknown> | undefined | null>;
|
|
279
494
|
unmount(): void | Promise<void>;
|
|
495
|
+
/** Card Payment Brick: changes the amount without recreating the form. Absent in old SDK builds. */
|
|
496
|
+
update?(settings: {
|
|
497
|
+
amount: number;
|
|
498
|
+
}): void | Promise<void>;
|
|
280
499
|
};
|
|
281
500
|
type MpBricks = {
|
|
282
501
|
create(brick: string, containerId: string, settings: Record<string, unknown>): Promise<MpController>;
|
|
@@ -513,4 +732,4 @@ declare function readPaymentTheme(el: Element | null | undefined, tokens?: Recor
|
|
|
513
732
|
*/
|
|
514
733
|
declare function readPaymentScheme(el: Element | null | undefined): 'light' | 'dark' | null;
|
|
515
734
|
|
|
516
|
-
export { CASH_POINT_FIELD, type EmbeddedPaymentState, type EmbeddedPaymentStatus, type FetchTransportOptions, type LoadScriptOptions, MERCADOPAGO_BRICKS_KIND, type MercadoPagoAdapterOptions, type MercadoPagoCtor, type MountedPaymentForm, PAYMENT_CHOICE_FIELD, PAYMENT_THEME_TOKENS, PayChoices, PaymentBrick, type PaymentBrickHandle, type PaymentBrickProps, PaymentChallenge, type PaymentChallengeProps, type PaymentEvent, type PaymentFallbackReason, type PaymentFormAdapter, type PaymentFormData, type PaymentFormError, type PaymentFormMountOptions, PaymentHttpError, type PaymentMethodClassNames, type PaymentMethodMessages, PaymentMethodSection, type PaymentMethodSectionProps, type PaymentMethodTestIds, type PaymentSubmitRequest, type PaymentTransport, type UseEmbeddedPaymentOptions, VoucherCard, type VoucherCardProps, createFetchTransport, formFields, loadPaymentSdk, mercadoPagoBricksAdapter, paymentMethodMessages, readPaymentScheme, readPaymentTheme, resetPaymentSdkCache, sanitizeMercadoPagoFormData, useEmbeddedPayment };
|
|
735
|
+
export { CASH_POINT_FIELD, type CheckoutRevalidateOptions, type EmbeddedPaymentState, type EmbeddedPaymentStatus, type FetchTransportOptions, type LoadScriptOptions, MERCADOPAGO_BRICKS_KIND, type MercadoPagoAdapterOptions, type MercadoPagoCtor, type MountQueueOptions, type MountedPaymentForm, PAYMENT_CHOICE_FIELD, PAYMENT_THEME_TOKENS, PayChoice, PayChoices, PaymentBrick, type PaymentBrickHandle, type PaymentBrickProps, PaymentChallenge, type PaymentChallengeProps, type PaymentEvent, type PaymentFallbackReason, type PaymentFormAdapter, type PaymentFormData, type PaymentFormError, type PaymentFormMountOptions, PaymentHttpError, type PaymentIssue, type PaymentMethodClassNames, type PaymentMethodMessages, PaymentMethodSection, type PaymentMethodSectionProps, type PaymentMethodTestIds, PaymentMountCancelled, PaymentMountTimeout, type PaymentNotice, PaymentNoticeKind, PaymentRecovery, type PaymentRecoveryClassNames, PaymentRecoveryMessages, type PaymentRecoveryProps, type PaymentRecoveryState, type PaymentSubmitRequest, type PaymentTransport, type ResilientTransportOptions, type RevalidateArgs, type UseEmbeddedPaymentOptions, type UsePaymentRecoveryOptions, VoucherCard, type VoucherCardProps, alternativeChoices, checkoutShouldRevalidate, createFetchTransport, createResilientTransport, formFields, isResolvedAttempt, loadPaymentSdk, mercadoPagoBricksAdapter, mountQueued, paymentMethodMessages, pickChoice, readPaymentScheme, readPaymentTheme, resetPaymentSdkCache, sanitizeMercadoPagoFormData, useEmbeddedPayment, usePaymentRecovery, withMountQueue };
|