@12-apps/payments-frontend 3.2.0 → 3.2.1
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/components/checkout/hosted-return.ts +50 -6
- package/src/index.ts +11 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@12-apps/payments-frontend",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Browser half of the vendor-agnostic payments platform: plug-and-play MUI components for the per-provider settings page (credential form from each provider's schema, masked hints, verify/enable) and the checkout page (PIX QR + polling, card tokenization, hosted-checkout redirect), plus the headless hooks and fetch clients they build on. Talks only to the host's payments HTTP surface — never to a provider directly. Microfrontend-ready: no app coupling, host injects theme and auth.",
|
|
6
6
|
"exports": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"storybook:build": "storybook build"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@12-apps/payments-backend": "^4.
|
|
20
|
+
"@12-apps/payments-backend": "^4.5.0",
|
|
21
21
|
"react-qr-code": "^2.2.0"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
@@ -54,6 +54,33 @@ function isReturnTrip(): boolean {
|
|
|
54
54
|
return RETURN_MARKERS.some((marker) => params.has(marker));
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Whether a hand-off from THIS tab is still waiting to be resolved.
|
|
59
|
+
*
|
|
60
|
+
* Exported because a host needs it and was otherwise forced to reimplement it.
|
|
61
|
+
* `/menu/checkout` is a URL like any other, so a host may put a gate in front
|
|
62
|
+
* of it — a closed-shop curtain, a plan check — and every such gate has to
|
|
63
|
+
* stand aside for a buyer coming back from a payment, because that route is
|
|
64
|
+
* where the money is confirmed. Deciding that from the outside meant copying
|
|
65
|
+
* this module's marker list and its storage key into the host, which is
|
|
66
|
+
* precisely the drift this package exists to stop: the copy went stale the
|
|
67
|
+
* moment Stripe's 3-D Secure markers were added here.
|
|
68
|
+
*
|
|
69
|
+
* Read WITHOUT consuming. The gate asks on every render; only the flow may
|
|
70
|
+
* take the order.
|
|
71
|
+
*/
|
|
72
|
+
export function hostedCheckoutReturnPending(): boolean {
|
|
73
|
+
if (isReturnTrip()) return true;
|
|
74
|
+
try {
|
|
75
|
+
return Boolean(
|
|
76
|
+
window.sessionStorage?.getItem(HOSTED_ORDER_STORAGE_KEY) ??
|
|
77
|
+
window.sessionStorage?.getItem(LEGACY_KEY),
|
|
78
|
+
);
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
57
84
|
/** Park the raised order before handing the buyer to the provider's page. */
|
|
58
85
|
export function rememberHostedOrder(order: CheckoutOrder): void {
|
|
59
86
|
try {
|
|
@@ -66,12 +93,30 @@ export function rememberHostedOrder(order: CheckoutOrder): void {
|
|
|
66
93
|
}
|
|
67
94
|
|
|
68
95
|
/**
|
|
69
|
-
* The parked order,
|
|
96
|
+
* The parked order, cleared as it is read.
|
|
97
|
+
*
|
|
98
|
+
* This USED to require a marker on the URL, so that a buyer who abandoned the
|
|
99
|
+
* provider's page and reopened checkout got a fresh order rather than resuming
|
|
100
|
+
* one they never paid. That reasoning is inverted for the provider it matters
|
|
101
|
+
* most for, and the inversion is a money bug rather than a UX preference.
|
|
102
|
+
*
|
|
103
|
+
* Pressing the provider's "Continuar" is the ONLY thing that marks the URL.
|
|
104
|
+
* Closing the tab, hitting back, or retyping the store's address are all
|
|
105
|
+
* commoner, and all of them landed the buyer on a live payment step for an
|
|
106
|
+
* order that may already be paid — an invitation to pay twice. It cannot be
|
|
107
|
+
* decided by asking first, either: InfinitePay's `payment_check` refuses to
|
|
108
|
+
* answer without a `transaction_nsu` that only that same redirect carries, so
|
|
109
|
+
* "poll before resuming" reads PAID as PENDING and drops them on the pay
|
|
110
|
+
* button anyway.
|
|
111
|
+
*
|
|
112
|
+
* So a parked order is itself the signal. The cost is that a buyer who truly
|
|
113
|
+
* abandoned sees one confirmation screen reporting what the store actually
|
|
114
|
+
* knows — which is the truth — with the way back on it. The read-and-clear
|
|
115
|
+
* bounds it: the resume happens once per hand-off, and leaving and reopening
|
|
116
|
+
* checkout gives a fresh one.
|
|
70
117
|
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* of resuming one they never paid. Read-and-clear for the same reason: the
|
|
74
|
-
* resumed view belongs to exactly one return.
|
|
118
|
+
* `sessionStorage` already scopes this to one tab's round trip, so nothing
|
|
119
|
+
* here can resurface in a later, unrelated session.
|
|
75
120
|
*/
|
|
76
121
|
/**
|
|
77
122
|
* The key before the 2.0.0 rename, READ ONLY — decoded from base64 so no
|
|
@@ -128,7 +173,6 @@ function takeParkedPayload(): string | null {
|
|
|
128
173
|
}
|
|
129
174
|
|
|
130
175
|
export function takeHostedOrder(): CheckoutOrder | null {
|
|
131
|
-
if (!isReturnTrip()) return null;
|
|
132
176
|
const raw = takeParkedPayload();
|
|
133
177
|
if (!raw) return null;
|
|
134
178
|
try {
|
package/src/index.ts
CHANGED
|
@@ -93,6 +93,17 @@ export { fetchCheckoutConfig } from './components/checkout/client';
|
|
|
93
93
|
* literal and silently drifts when it changes.
|
|
94
94
|
*/
|
|
95
95
|
export { HOSTED_ORDER_STORAGE_KEY } from './components/checkout/hosted-return';
|
|
96
|
+
/**
|
|
97
|
+
* Whether a hand-off from this tab is still waiting to be resolved.
|
|
98
|
+
*
|
|
99
|
+
* For a HOST GATE in front of the checkout route — a closed-shop curtain, a
|
|
100
|
+
* plan check. Every such gate has to stand aside for a buyer coming back from
|
|
101
|
+
* a payment, because that route is where the money gets confirmed, and a host
|
|
102
|
+
* deciding it alone had to copy this package's marker list and storage key.
|
|
103
|
+
* That copy goes stale: it did, the moment Stripe's 3-D Secure markers were
|
|
104
|
+
* added here. Reads without consuming.
|
|
105
|
+
*/
|
|
106
|
+
export { hostedCheckoutReturnPending } from './components/checkout/hosted-return';
|
|
96
107
|
// ---------------------------------------------------------------------------
|
|
97
108
|
// Digital wallets (FUT-471/472) — the Google-branded button and the capability
|
|
98
109
|
// read it is gated on. `CheckoutFlow` wires these automatically; they are
|