@appfunnel-dev/sdk 2.0.0 → 2.1.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/CHANGELOG.md +69 -3
- package/dist/{checkout-BYcOfyg_.d.ts → checkout-BPYU4wXF.d.ts} +50 -16
- package/dist/{checkout-BM1T-u6_.d.cts → checkout-BzP__Mxe.d.cts} +50 -16
- package/dist/{chunk-PN7CRJAF.js → chunk-AW2YURFE.js} +60 -19
- package/dist/chunk-AW2YURFE.js.map +1 -0
- package/dist/{chunk-MBTHQP4Z.cjs → chunk-DTSLJ24T.cjs} +11 -3
- package/dist/chunk-DTSLJ24T.cjs.map +1 -0
- package/dist/{chunk-NA7DRFOA.cjs → chunk-MBSXEIXT.cjs} +60 -19
- package/dist/chunk-MBSXEIXT.cjs.map +1 -0
- package/dist/{chunk-KVMNVX6J.js → chunk-USAECFWO.js} +11 -3
- package/dist/chunk-USAECFWO.js.map +1 -0
- package/dist/driver-paddle.cjs +14 -14
- package/dist/driver-paddle.d.cts +1 -1
- package/dist/driver-paddle.d.ts +1 -1
- package/dist/driver-paddle.js +1 -1
- package/dist/driver-stripe.cjs +31 -15
- package/dist/driver-stripe.cjs.map +1 -1
- package/dist/driver-stripe.d.cts +1 -1
- package/dist/driver-stripe.d.ts +1 -1
- package/dist/driver-stripe.js +18 -2
- package/dist/driver-stripe.js.map +1 -1
- package/dist/index.cjs +78 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -6
- package/dist/index.d.ts +25 -6
- package/dist/index.js +13 -2
- package/dist/index.js.map +1 -1
- package/dist/{manifest-BajvtPWs.d.cts → manifest-Dp1oRvqp.d.cts} +23 -0
- package/dist/{manifest-BajvtPWs.d.ts → manifest-Dp1oRvqp.d.ts} +23 -0
- package/dist/manifest-entry.cjs +9 -1
- package/dist/manifest-entry.cjs.map +1 -1
- package/dist/manifest-entry.d.cts +15 -2
- package/dist/manifest-entry.d.ts +15 -2
- package/dist/manifest-entry.js +9 -1
- package/dist/manifest-entry.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-KVMNVX6J.js.map +0 -1
- package/dist/chunk-MBTHQP4Z.cjs.map +0 -1
- package/dist/chunk-NA7DRFOA.cjs.map +0 -1
- package/dist/chunk-PN7CRJAF.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,68 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.1.0
|
|
4
|
+
|
|
5
|
+
### `methods` is now `options`, and it styles the wallet button
|
|
6
|
+
|
|
7
|
+
`<Checkout>` and `<CheckoutButton>` take `options` where they took `methods`. Everything `methods`
|
|
8
|
+
did works the same under the new name, and `methods` keeps working.
|
|
9
|
+
|
|
10
|
+
New in `options`: `express`, the wallet button. It takes Stripe's own Express Checkout Element
|
|
11
|
+
options — which wallets show (`paymentMethods`), how many buttons per row and how many rows
|
|
12
|
+
(`layout`), and the buttons' height, colour and label (`buttonHeight`, `buttonTheme`, `buttonType`).
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
<Checkout
|
|
16
|
+
offering="plan"
|
|
17
|
+
options={{ express: { paymentMethods: { link: 'auto' }, layout: { maxColumns: 1 }, buttonHeight: 48 } }}
|
|
18
|
+
/>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### The wallet button offers Apple Pay and Google Pay only
|
|
22
|
+
|
|
23
|
+
The wallet button used to offer every wallet the Stripe account had turned on, Link, PayPal, Amazon
|
|
24
|
+
Pay and Klarna included. It now offers Apple Pay and Google Pay, both `'always'`; the others are off
|
|
25
|
+
unless a funnel names them in `options.express.paymentMethods`. Anything you name is merged over
|
|
26
|
+
that default, one wallet at a time.
|
|
27
|
+
|
|
28
|
+
`'always'` shows Apple Pay and Google Pay wherever the browser supports them, even before the
|
|
29
|
+
visitor has added a card. Set `'auto'` to show them only where a card is ready to pay.
|
|
30
|
+
|
|
31
|
+
## 2.0.1
|
|
32
|
+
|
|
33
|
+
A checkout that names no offering is now caught, in both places it can be caught.
|
|
34
|
+
|
|
35
|
+
### A missing `offering` fails the build
|
|
36
|
+
|
|
37
|
+
`<Checkout>`, `<CheckoutButton>` and `<UpsellButton>` must name the offering slot they charge.
|
|
38
|
+
A tag that doesn't now fails the build, with the file and line:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
checkout with no `offering`:
|
|
42
|
+
pages/paywall.tsx:27 <Checkout>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This closes a gap where such a tag was invisible end to end. It contributes no offering
|
|
46
|
+
reference, so the manifest's unknown/unassigned-slot validation never saw the slot and the
|
|
47
|
+
publish gate passed with nothing to check — while at runtime the charge resolved to nothing and
|
|
48
|
+
the page shipped with a dead paywall. A funnel build is a bundler transform, so types are
|
|
49
|
+
stripped rather than checked; nothing else in the deploy path was looking.
|
|
50
|
+
|
|
51
|
+
The shape that hits this most often is the pre-2.0 spelling `<Checkout product="plan">`, where
|
|
52
|
+
the offering arrives under the old prop name and `offering` is simply absent.
|
|
53
|
+
|
|
54
|
+
Tags whose offering cannot be read statically are unaffected: `offering={expr}` and a tag
|
|
55
|
+
carrying a spread (`<Checkout {...props} />`) both pass — the same relaxation the rest of the
|
|
56
|
+
page scan applies to anything it cannot enumerate.
|
|
57
|
+
|
|
58
|
+
### A missing `offering` is refused at runtime
|
|
59
|
+
|
|
60
|
+
For the cases no static scan can see — an `offering={expr}` that evaluated to nothing, a spread
|
|
61
|
+
that did not carry one — the components now refuse instead of resolving nothing. The refusal
|
|
62
|
+
reports through the normal failure path (`checkout.failed`, a non-retryable `processing_error`,
|
|
63
|
+
any `onFailed` routes) and renders nothing chargeable. On `<UpsellButton>` the trigger itself
|
|
64
|
+
never renders: an upsell charges off-session on the first tap, so there must be nothing to tap.
|
|
65
|
+
|
|
3
66
|
## 2.0.0
|
|
4
67
|
|
|
5
68
|
First stable release of the v2 SDK, and the first v2 release published to the `latest`
|
|
@@ -7,11 +70,14 @@ dist-tag. Everything from `2.0.0-canary.1` through `2.0.0-canary.36` is folded i
|
|
|
7
70
|
release; the canary line is closed.
|
|
8
71
|
|
|
9
72
|
**`npm install @appfunnel-dev/sdk` now resolves to 2.0.0, not 0.17.0.** v2 is a rewrite,
|
|
10
|
-
not an upgrade — a 0.17 funnel will not build against it.
|
|
11
|
-
|
|
73
|
+
not an upgrade — a 0.17 funnel will not build against it.
|
|
74
|
+
|
|
75
|
+
**The 2.0.x line is the only thing on the registry.** Every 0.x release and the whole
|
|
76
|
+
`2.0.0-canary.*` line have been unpublished, so there is no version to stay on: a funnel
|
|
77
|
+
still pinned to one of them fails its next build at install (`ETARGET`). Move the pin:
|
|
12
78
|
|
|
13
79
|
```json
|
|
14
|
-
{ "dependencies": { "@appfunnel-dev/sdk": "0.
|
|
80
|
+
{ "dependencies": { "@appfunnel-dev/sdk": "2.0.0" } }
|
|
15
81
|
```
|
|
16
82
|
|
|
17
83
|
### The v2 surface
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ComponentType, ReactElement } from 'react';
|
|
2
|
-
import { Appearance } from '@stripe/stripe-js';
|
|
2
|
+
import { Appearance, StripeExpressCheckoutElementOptions } from '@stripe/stripe-js';
|
|
3
3
|
import { CheckoutSettings } from '@paddle/paddle-js';
|
|
4
4
|
import { c as CheckoutProvider, b as CheckoutIntent, d as CheckoutSurface, U as UpsellKind, C as CheckoutError, a as CheckoutErrorCategory, h as PaymentMode, H as HostedPaymentMode, e as OpensIn, i as PaymentRendering } from './capabilities-BtnJi2JD.js';
|
|
5
5
|
|
|
@@ -99,10 +99,11 @@ interface CheckoutRequest {
|
|
|
99
99
|
*/
|
|
100
100
|
appearance?: CheckoutAppearance;
|
|
101
101
|
/**
|
|
102
|
-
* How the provider LISTS the payment methods
|
|
103
|
-
* as `appearance`: it never leaves
|
|
102
|
+
* How the provider LISTS the payment methods and draws the wallet button — the author's
|
|
103
|
+
* `options` (see {@link CheckoutOptions}). Display-only, same as `appearance`: it never leaves
|
|
104
|
+
* the browser.
|
|
104
105
|
*/
|
|
105
|
-
methods?:
|
|
106
|
+
methods?: CheckoutOptions;
|
|
106
107
|
/**
|
|
107
108
|
* Classes for the buttons the SDK renders itself — see {@link CheckoutClassNames}. Display-only.
|
|
108
109
|
*/
|
|
@@ -162,22 +163,22 @@ interface CheckoutAppearance {
|
|
|
162
163
|
paddle?: Pick<CheckoutSettings, 'theme' | 'frameStyle' | 'frameInitialHeight'>;
|
|
163
164
|
}
|
|
164
165
|
/**
|
|
165
|
-
* How the
|
|
166
|
+
* How the payment methods are PRESENTED — the method list and the wallet button — in the surfaces
|
|
167
|
+
* the SDK mounts itself.
|
|
166
168
|
*
|
|
167
169
|
* Normalized, unlike {@link CheckoutAppearance} — and the difference is real rather than an
|
|
168
170
|
* inconsistency. Appearance is a token bag whose true cross-provider intersection is roughly empty,
|
|
169
171
|
* so a shared shape there would be a lie. "Stack the methods and start them collapsed" is one idea
|
|
170
172
|
* with one meaning, so it gets one spelling.
|
|
171
173
|
*
|
|
172
|
-
* The DEFAULT is `{ layout: 'accordion', collapsed:
|
|
173
|
-
*
|
|
174
|
-
* card form with the wallet they'd have preferred hidden below it.
|
|
174
|
+
* The DEFAULT is `{ layout: 'accordion', collapsed: false }` — the first method open — and a wallet
|
|
175
|
+
* button offering Apple Pay and Google Pay (see {@link CheckoutOptions.express}).
|
|
175
176
|
*
|
|
176
177
|
* ```tsx
|
|
177
178
|
* <Checkout offering="plan" /> // accordion, collapsed
|
|
178
|
-
* <Checkout offering="plan"
|
|
179
|
-
* <Checkout offering="plan"
|
|
180
|
-
* <Checkout offering="plan"
|
|
179
|
+
* <Checkout offering="plan" options={{ collapsed: false }} /> // first method open
|
|
180
|
+
* <Checkout offering="plan" options={{ layout: 'tabs' }} /> // methods across the top
|
|
181
|
+
* <Checkout offering="plan" options={{ order: ['apple_pay', 'card'] }} /> // lead with Apple Pay
|
|
181
182
|
* ```
|
|
182
183
|
*
|
|
183
184
|
* **Only applies where the SDK mounts the method list** — `payment="card"`, and the `payment="auto"`
|
|
@@ -186,7 +187,7 @@ interface CheckoutAppearance {
|
|
|
186
187
|
* setting. Wallets also have to be able to appear at all before ordering them means anything — that
|
|
187
188
|
* needs the domain registered with Stripe as a payment method domain.
|
|
188
189
|
*/
|
|
189
|
-
interface
|
|
190
|
+
interface CheckoutOptions {
|
|
190
191
|
/** `'accordion'` (default) stacks the methods as rows; `'tabs'` runs them across the top. */
|
|
191
192
|
layout?: 'accordion' | 'tabs';
|
|
192
193
|
/** Start with every method closed, so the buyer chooses before any fields render. Default `true`. */
|
|
@@ -208,7 +209,32 @@ interface CheckoutMethods {
|
|
|
208
209
|
* nowhere else to go on this screen. Leave it on unless the funnel is deliberately wallet-only.
|
|
209
210
|
*/
|
|
210
211
|
payAnotherWay?: boolean;
|
|
212
|
+
/**
|
|
213
|
+
* The wallet BUTTON — Stripe's Express Checkout Element options, passed through as-is: which
|
|
214
|
+
* wallets it offers (`paymentMethods`), how many buttons per row and how many rows (`layout`),
|
|
215
|
+
* and the buttons' height, colour and label (`buttonHeight`, `buttonTheme`, `buttonType`).
|
|
216
|
+
*
|
|
217
|
+
* ```tsx
|
|
218
|
+
* <Checkout offering="plan" options={{ express: { paymentMethods: { link: 'auto' } } }} />
|
|
219
|
+
* <Checkout offering="plan" options={{ express: { layout: { maxColumns: 1 }, buttonHeight: 48 } }} />
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* `paymentMethods` defaults to Apple Pay and Google Pay (`'always'`) with Link, PayPal, Amazon Pay
|
|
223
|
+
* and Klarna off (`'never'`), merged per wallet over that default — `{ link: 'auto' }` adds Link
|
|
224
|
+
* and leaves the rest as they were. `'always'` shows Apple Pay / Google Pay wherever the browser
|
|
225
|
+
* supports them, even before the buyer has added a card; `'auto'` only where one is ready to pay.
|
|
226
|
+
* Everything else unset is Stripe's default. Stripe only.
|
|
227
|
+
*/
|
|
228
|
+
express?: CheckoutExpressOptions;
|
|
211
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* The part of Stripe's `StripeExpressCheckoutElementOptions` that decides what the wallet button
|
|
232
|
+
* offers and how it LOOKS. The rest (line items, shipping, email and phone collection) belongs to the
|
|
233
|
+
* charge, which the SDK sets, so it isn't offered here.
|
|
234
|
+
*/
|
|
235
|
+
type CheckoutExpressOptions = Pick<StripeExpressCheckoutElementOptions, 'paymentMethods' | 'paymentMethodOrder' | 'layout' | 'buttonHeight' | 'buttonTheme' | 'buttonType'>;
|
|
236
|
+
/** @deprecated Renamed to {@link CheckoutOptions}. */
|
|
237
|
+
type CheckoutMethods = CheckoutOptions;
|
|
212
238
|
interface CheckoutResult {
|
|
213
239
|
ok: boolean;
|
|
214
240
|
error?: CheckoutError;
|
|
@@ -222,6 +248,12 @@ interface CheckoutResult {
|
|
|
222
248
|
* source of truth for payment events; the SDK doesn't mint these.)
|
|
223
249
|
*/
|
|
224
250
|
eventId?: string;
|
|
251
|
+
/**
|
|
252
|
+
* Server-decided acquisition shape. A trial start reports `subscription.trial_started`
|
|
253
|
+
* (→ Meta/TikTok StartTrial), never `purchase.complete`/`subscription.created` — see
|
|
254
|
+
* {@link CheckoutSettlement.acquisition}.
|
|
255
|
+
*/
|
|
256
|
+
acquisition?: 'direct' | 'free_trial' | 'paid_trial';
|
|
225
257
|
}
|
|
226
258
|
interface CheckoutCallbacks {
|
|
227
259
|
onSuccess: (result: CheckoutResult) => void;
|
|
@@ -502,9 +534,11 @@ interface CheckoutCommonProps extends Omit<UseCheckoutOptions, 'managed'> {
|
|
|
502
534
|
* fields render in a cross-origin iframe the funnel's CSS can't reach.
|
|
503
535
|
*/
|
|
504
536
|
appearance?: CheckoutAppearance;
|
|
505
|
-
/** How the
|
|
506
|
-
*
|
|
507
|
-
|
|
537
|
+
/** How the payment methods are listed and how the wallet button looks ({@link CheckoutOptions}).
|
|
538
|
+
* Ignored on surfaces where the provider owns the whole UI. */
|
|
539
|
+
options?: CheckoutOptions;
|
|
540
|
+
/** @deprecated Renamed to `options`. */
|
|
541
|
+
methods?: CheckoutOptions;
|
|
508
542
|
}
|
|
509
543
|
/**
|
|
510
544
|
* The `managed` × `payment` constraint, as a type rather than a runtime rejection.
|
|
@@ -741,4 +775,4 @@ declare function UpsellButton(props: UpsellButtonProps): ReactNode;
|
|
|
741
775
|
*/
|
|
742
776
|
declare function CheckoutResume(options?: UseCheckoutOptions): ReactNode;
|
|
743
777
|
|
|
744
|
-
export {
|
|
778
|
+
export { createMockDriver as A, driverWithEmail as B, type CheckoutDriverContext as C, useCheckout as D, type FailureModalProps as F, type MockDriverOptions as M, type OnFailedMap as O, type PaymentAxis as P, type TriggerAxis as T, UpsellButton as U, type CheckoutDriver as a, Checkout as b, type CheckoutAppearance as c, CheckoutButton as d, type CheckoutButtonProps as e, type CheckoutCallbacks as f, type CheckoutClassNames as g, type CheckoutCommonProps as h, type CheckoutExpressOptions as i, type CheckoutHandle as j, type CheckoutInlineProps as k, type CheckoutMethods as l, type CheckoutOptions as m, type CheckoutProps as n, type CheckoutRequest as o, type CheckoutResult as p, CheckoutResume as q, CheckoutSpinner as r, type CheckoutStatus as s, type FailureRoute as t, type OpensAxis as u, type TriggerState as v, type UpsellButtonProps as w, type UpsellCommonProps as x, type UpsellRecovery as y, type UseCheckoutOptions as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, ComponentType, ReactElement } from 'react';
|
|
2
|
-
import { Appearance } from '@stripe/stripe-js';
|
|
2
|
+
import { Appearance, StripeExpressCheckoutElementOptions } from '@stripe/stripe-js';
|
|
3
3
|
import { CheckoutSettings } from '@paddle/paddle-js';
|
|
4
4
|
import { c as CheckoutProvider, b as CheckoutIntent, d as CheckoutSurface, U as UpsellKind, C as CheckoutError, a as CheckoutErrorCategory, h as PaymentMode, H as HostedPaymentMode, e as OpensIn, i as PaymentRendering } from './capabilities-BtnJi2JD.cjs';
|
|
5
5
|
|
|
@@ -99,10 +99,11 @@ interface CheckoutRequest {
|
|
|
99
99
|
*/
|
|
100
100
|
appearance?: CheckoutAppearance;
|
|
101
101
|
/**
|
|
102
|
-
* How the provider LISTS the payment methods
|
|
103
|
-
* as `appearance`: it never leaves
|
|
102
|
+
* How the provider LISTS the payment methods and draws the wallet button — the author's
|
|
103
|
+
* `options` (see {@link CheckoutOptions}). Display-only, same as `appearance`: it never leaves
|
|
104
|
+
* the browser.
|
|
104
105
|
*/
|
|
105
|
-
methods?:
|
|
106
|
+
methods?: CheckoutOptions;
|
|
106
107
|
/**
|
|
107
108
|
* Classes for the buttons the SDK renders itself — see {@link CheckoutClassNames}. Display-only.
|
|
108
109
|
*/
|
|
@@ -162,22 +163,22 @@ interface CheckoutAppearance {
|
|
|
162
163
|
paddle?: Pick<CheckoutSettings, 'theme' | 'frameStyle' | 'frameInitialHeight'>;
|
|
163
164
|
}
|
|
164
165
|
/**
|
|
165
|
-
* How the
|
|
166
|
+
* How the payment methods are PRESENTED — the method list and the wallet button — in the surfaces
|
|
167
|
+
* the SDK mounts itself.
|
|
166
168
|
*
|
|
167
169
|
* Normalized, unlike {@link CheckoutAppearance} — and the difference is real rather than an
|
|
168
170
|
* inconsistency. Appearance is a token bag whose true cross-provider intersection is roughly empty,
|
|
169
171
|
* so a shared shape there would be a lie. "Stack the methods and start them collapsed" is one idea
|
|
170
172
|
* with one meaning, so it gets one spelling.
|
|
171
173
|
*
|
|
172
|
-
* The DEFAULT is `{ layout: 'accordion', collapsed:
|
|
173
|
-
*
|
|
174
|
-
* card form with the wallet they'd have preferred hidden below it.
|
|
174
|
+
* The DEFAULT is `{ layout: 'accordion', collapsed: false }` — the first method open — and a wallet
|
|
175
|
+
* button offering Apple Pay and Google Pay (see {@link CheckoutOptions.express}).
|
|
175
176
|
*
|
|
176
177
|
* ```tsx
|
|
177
178
|
* <Checkout offering="plan" /> // accordion, collapsed
|
|
178
|
-
* <Checkout offering="plan"
|
|
179
|
-
* <Checkout offering="plan"
|
|
180
|
-
* <Checkout offering="plan"
|
|
179
|
+
* <Checkout offering="plan" options={{ collapsed: false }} /> // first method open
|
|
180
|
+
* <Checkout offering="plan" options={{ layout: 'tabs' }} /> // methods across the top
|
|
181
|
+
* <Checkout offering="plan" options={{ order: ['apple_pay', 'card'] }} /> // lead with Apple Pay
|
|
181
182
|
* ```
|
|
182
183
|
*
|
|
183
184
|
* **Only applies where the SDK mounts the method list** — `payment="card"`, and the `payment="auto"`
|
|
@@ -186,7 +187,7 @@ interface CheckoutAppearance {
|
|
|
186
187
|
* setting. Wallets also have to be able to appear at all before ordering them means anything — that
|
|
187
188
|
* needs the domain registered with Stripe as a payment method domain.
|
|
188
189
|
*/
|
|
189
|
-
interface
|
|
190
|
+
interface CheckoutOptions {
|
|
190
191
|
/** `'accordion'` (default) stacks the methods as rows; `'tabs'` runs them across the top. */
|
|
191
192
|
layout?: 'accordion' | 'tabs';
|
|
192
193
|
/** Start with every method closed, so the buyer chooses before any fields render. Default `true`. */
|
|
@@ -208,7 +209,32 @@ interface CheckoutMethods {
|
|
|
208
209
|
* nowhere else to go on this screen. Leave it on unless the funnel is deliberately wallet-only.
|
|
209
210
|
*/
|
|
210
211
|
payAnotherWay?: boolean;
|
|
212
|
+
/**
|
|
213
|
+
* The wallet BUTTON — Stripe's Express Checkout Element options, passed through as-is: which
|
|
214
|
+
* wallets it offers (`paymentMethods`), how many buttons per row and how many rows (`layout`),
|
|
215
|
+
* and the buttons' height, colour and label (`buttonHeight`, `buttonTheme`, `buttonType`).
|
|
216
|
+
*
|
|
217
|
+
* ```tsx
|
|
218
|
+
* <Checkout offering="plan" options={{ express: { paymentMethods: { link: 'auto' } } }} />
|
|
219
|
+
* <Checkout offering="plan" options={{ express: { layout: { maxColumns: 1 }, buttonHeight: 48 } }} />
|
|
220
|
+
* ```
|
|
221
|
+
*
|
|
222
|
+
* `paymentMethods` defaults to Apple Pay and Google Pay (`'always'`) with Link, PayPal, Amazon Pay
|
|
223
|
+
* and Klarna off (`'never'`), merged per wallet over that default — `{ link: 'auto' }` adds Link
|
|
224
|
+
* and leaves the rest as they were. `'always'` shows Apple Pay / Google Pay wherever the browser
|
|
225
|
+
* supports them, even before the buyer has added a card; `'auto'` only where one is ready to pay.
|
|
226
|
+
* Everything else unset is Stripe's default. Stripe only.
|
|
227
|
+
*/
|
|
228
|
+
express?: CheckoutExpressOptions;
|
|
211
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* The part of Stripe's `StripeExpressCheckoutElementOptions` that decides what the wallet button
|
|
232
|
+
* offers and how it LOOKS. The rest (line items, shipping, email and phone collection) belongs to the
|
|
233
|
+
* charge, which the SDK sets, so it isn't offered here.
|
|
234
|
+
*/
|
|
235
|
+
type CheckoutExpressOptions = Pick<StripeExpressCheckoutElementOptions, 'paymentMethods' | 'paymentMethodOrder' | 'layout' | 'buttonHeight' | 'buttonTheme' | 'buttonType'>;
|
|
236
|
+
/** @deprecated Renamed to {@link CheckoutOptions}. */
|
|
237
|
+
type CheckoutMethods = CheckoutOptions;
|
|
212
238
|
interface CheckoutResult {
|
|
213
239
|
ok: boolean;
|
|
214
240
|
error?: CheckoutError;
|
|
@@ -222,6 +248,12 @@ interface CheckoutResult {
|
|
|
222
248
|
* source of truth for payment events; the SDK doesn't mint these.)
|
|
223
249
|
*/
|
|
224
250
|
eventId?: string;
|
|
251
|
+
/**
|
|
252
|
+
* Server-decided acquisition shape. A trial start reports `subscription.trial_started`
|
|
253
|
+
* (→ Meta/TikTok StartTrial), never `purchase.complete`/`subscription.created` — see
|
|
254
|
+
* {@link CheckoutSettlement.acquisition}.
|
|
255
|
+
*/
|
|
256
|
+
acquisition?: 'direct' | 'free_trial' | 'paid_trial';
|
|
225
257
|
}
|
|
226
258
|
interface CheckoutCallbacks {
|
|
227
259
|
onSuccess: (result: CheckoutResult) => void;
|
|
@@ -502,9 +534,11 @@ interface CheckoutCommonProps extends Omit<UseCheckoutOptions, 'managed'> {
|
|
|
502
534
|
* fields render in a cross-origin iframe the funnel's CSS can't reach.
|
|
503
535
|
*/
|
|
504
536
|
appearance?: CheckoutAppearance;
|
|
505
|
-
/** How the
|
|
506
|
-
*
|
|
507
|
-
|
|
537
|
+
/** How the payment methods are listed and how the wallet button looks ({@link CheckoutOptions}).
|
|
538
|
+
* Ignored on surfaces where the provider owns the whole UI. */
|
|
539
|
+
options?: CheckoutOptions;
|
|
540
|
+
/** @deprecated Renamed to `options`. */
|
|
541
|
+
methods?: CheckoutOptions;
|
|
508
542
|
}
|
|
509
543
|
/**
|
|
510
544
|
* The `managed` × `payment` constraint, as a type rather than a runtime rejection.
|
|
@@ -741,4 +775,4 @@ declare function UpsellButton(props: UpsellButtonProps): ReactNode;
|
|
|
741
775
|
*/
|
|
742
776
|
declare function CheckoutResume(options?: UseCheckoutOptions): ReactNode;
|
|
743
777
|
|
|
744
|
-
export {
|
|
778
|
+
export { createMockDriver as A, driverWithEmail as B, type CheckoutDriverContext as C, useCheckout as D, type FailureModalProps as F, type MockDriverOptions as M, type OnFailedMap as O, type PaymentAxis as P, type TriggerAxis as T, UpsellButton as U, type CheckoutDriver as a, Checkout as b, type CheckoutAppearance as c, CheckoutButton as d, type CheckoutButtonProps as e, type CheckoutCallbacks as f, type CheckoutClassNames as g, type CheckoutCommonProps as h, type CheckoutExpressOptions as i, type CheckoutHandle as j, type CheckoutInlineProps as k, type CheckoutMethods as l, type CheckoutOptions as m, type CheckoutProps as n, type CheckoutRequest as o, type CheckoutResult as p, CheckoutResume as q, CheckoutSpinner as r, type CheckoutStatus as s, type FailureRoute as t, type OpensAxis as u, type TriggerState as v, type UpsellButtonProps as w, type UpsellCommonProps as x, type UpsellRecovery as y, type UseCheckoutOptions as z };
|
|
@@ -491,10 +491,23 @@ function interpolate(str, params) {
|
|
|
491
491
|
if (!params) return str;
|
|
492
492
|
return str.replace(/\{\{(\w+)\}\}/g, (_, k) => k in params ? String(params[k]) : `{{${k}}}`);
|
|
493
493
|
}
|
|
494
|
-
|
|
494
|
+
var baseLang = (locale) => locale.split("-")[0];
|
|
495
|
+
function lookupMessage(catalog, chain, key) {
|
|
495
496
|
for (const loc of chain) {
|
|
496
|
-
const
|
|
497
|
-
|
|
497
|
+
const lang = baseLang(loc);
|
|
498
|
+
const exact = catalog[loc]?.[key];
|
|
499
|
+
if (exact !== void 0) return exact;
|
|
500
|
+
if (lang !== loc) {
|
|
501
|
+
const wide = catalog[lang]?.[key];
|
|
502
|
+
if (wide !== void 0) return wide;
|
|
503
|
+
}
|
|
504
|
+
const siblings = Object.keys(catalog).filter(
|
|
505
|
+
(k) => k !== loc && k !== lang && baseLang(k) === lang
|
|
506
|
+
);
|
|
507
|
+
if (siblings.length === 1) {
|
|
508
|
+
const only = catalog[siblings[0]]?.[key];
|
|
509
|
+
if (only !== void 0) return only;
|
|
510
|
+
}
|
|
498
511
|
}
|
|
499
512
|
return void 0;
|
|
500
513
|
}
|
|
@@ -538,9 +551,11 @@ function useTranslation() {
|
|
|
538
551
|
}, [locale, config]);
|
|
539
552
|
const t = useMemo(() => {
|
|
540
553
|
const fn = ((key, params) => {
|
|
541
|
-
const raw =
|
|
554
|
+
const raw = lookupMessage(catalog, chain, key);
|
|
542
555
|
if (raw === void 0) {
|
|
543
|
-
devWarn(
|
|
556
|
+
devWarn(
|
|
557
|
+
`[appfunnel] missing translation: "${key}" (${locale}; tried ${chain.join(" \u2192 ")})`
|
|
558
|
+
);
|
|
544
559
|
return key;
|
|
545
560
|
}
|
|
546
561
|
return interpolate(raw, params);
|
|
@@ -6978,6 +6993,10 @@ function Modal(props) {
|
|
|
6978
6993
|
}
|
|
6979
6994
|
|
|
6980
6995
|
// src/commerce/checkout.tsx
|
|
6996
|
+
function refuseOffering(offering, as) {
|
|
6997
|
+
if (typeof offering === "string" && offering.trim() !== "") return void 0;
|
|
6998
|
+
return `<${as}> has no \`offering\` \u2014 there is nothing to charge. Name the offering slot (offering="plan"). If you are migrating from an older SDK, the prop used to be \`product\`.`;
|
|
6999
|
+
}
|
|
6981
7000
|
function refuseSurface(provider, surface, managed) {
|
|
6982
7001
|
if (!managed) return void 0;
|
|
6983
7002
|
const check = validateCheckout(provider, surface, { managed });
|
|
@@ -7158,20 +7177,31 @@ function useCheckout(opts = {}) {
|
|
|
7158
7177
|
funnel.data.set({ purchased: true });
|
|
7159
7178
|
const { productId, isSubscription } = productFacts(product);
|
|
7160
7179
|
const amount = result.amountMinor != null ? result.amountMinor / 100 : void 0;
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
productId,
|
|
7165
|
-
eventId: result.eventId
|
|
7166
|
-
// server-minted (browser↔CAPI dedup); undefined if none
|
|
7167
|
-
});
|
|
7168
|
-
if (isSubscription) {
|
|
7169
|
-
tracker.track("subscription.created", {
|
|
7180
|
+
const isTrialStart = result.acquisition === "free_trial" || result.acquisition === "paid_trial";
|
|
7181
|
+
if (isTrialStart) {
|
|
7182
|
+
tracker.track("subscription.trial_started", {
|
|
7170
7183
|
amount,
|
|
7171
7184
|
currency: result.currency,
|
|
7172
7185
|
productId,
|
|
7173
7186
|
eventId: result.eventId
|
|
7187
|
+
// server-minted (browser↔CAPI dedup)
|
|
7174
7188
|
});
|
|
7189
|
+
} else {
|
|
7190
|
+
tracker.track("purchase.complete", {
|
|
7191
|
+
amount,
|
|
7192
|
+
currency: result.currency,
|
|
7193
|
+
productId,
|
|
7194
|
+
eventId: result.eventId
|
|
7195
|
+
// server-minted (browser↔CAPI dedup); undefined if none
|
|
7196
|
+
});
|
|
7197
|
+
if (isSubscription) {
|
|
7198
|
+
tracker.track("subscription.created", {
|
|
7199
|
+
amount,
|
|
7200
|
+
currency: result.currency,
|
|
7201
|
+
productId,
|
|
7202
|
+
eventId: result.eventId
|
|
7203
|
+
});
|
|
7204
|
+
}
|
|
7175
7205
|
}
|
|
7176
7206
|
opts.onSuccess?.(result);
|
|
7177
7207
|
if (advance) nav.next();
|
|
@@ -7542,7 +7572,7 @@ function CheckoutImpl({
|
|
|
7542
7572
|
notePreviewCheckout(as, product);
|
|
7543
7573
|
checkout.callbacksFor(product, surface).onSuccess({ ok: true });
|
|
7544
7574
|
};
|
|
7545
|
-
const rejection = refuseSurface(driver.provider, surface, managed);
|
|
7575
|
+
const rejection = refuseOffering(offering, as) ?? refuseSurface(driver.provider, surface, managed);
|
|
7546
7576
|
const callbacksRef = useRef(checkout.callbacksFor);
|
|
7547
7577
|
callbacksRef.current = checkout.callbacksFor;
|
|
7548
7578
|
useEffect(() => {
|
|
@@ -7610,6 +7640,7 @@ function Checkout(props) {
|
|
|
7610
7640
|
payment,
|
|
7611
7641
|
className,
|
|
7612
7642
|
appearance,
|
|
7643
|
+
options: displayOptions,
|
|
7613
7644
|
methods,
|
|
7614
7645
|
classNames,
|
|
7615
7646
|
...options
|
|
@@ -7620,7 +7651,8 @@ function Checkout(props) {
|
|
|
7620
7651
|
offering,
|
|
7621
7652
|
className,
|
|
7622
7653
|
appearance,
|
|
7623
|
-
methods,
|
|
7654
|
+
// `options` is the prop; `methods` is its old name, still accepted.
|
|
7655
|
+
methods: displayOptions ?? methods,
|
|
7624
7656
|
classNames,
|
|
7625
7657
|
as: "Checkout",
|
|
7626
7658
|
// The axes resolve, and the result is always an INLINE rendering: `<Checkout>` is the payment
|
|
@@ -7638,6 +7670,7 @@ function CheckoutButton(props) {
|
|
|
7638
7670
|
children,
|
|
7639
7671
|
className,
|
|
7640
7672
|
appearance,
|
|
7673
|
+
options: displayOptions,
|
|
7641
7674
|
methods,
|
|
7642
7675
|
classNames,
|
|
7643
7676
|
...options
|
|
@@ -7648,7 +7681,7 @@ function CheckoutButton(props) {
|
|
|
7648
7681
|
offering,
|
|
7649
7682
|
className,
|
|
7650
7683
|
appearance,
|
|
7651
|
-
methods,
|
|
7684
|
+
methods: displayOptions ?? methods,
|
|
7652
7685
|
classNames,
|
|
7653
7686
|
asChild,
|
|
7654
7687
|
children,
|
|
@@ -7697,6 +7730,14 @@ function UpsellButton(props) {
|
|
|
7697
7730
|
);
|
|
7698
7731
|
const checkout = useCheckout({ ...options, intent: "upsell", recoverySurface });
|
|
7699
7732
|
const isSample = useOffering(offering)?.sample === true;
|
|
7733
|
+
const rejection = refuseOffering(offering, "UpsellButton");
|
|
7734
|
+
const callbacksRef = useRef(checkout.callbacksFor);
|
|
7735
|
+
callbacksRef.current = checkout.callbacksFor;
|
|
7736
|
+
useEffect(() => {
|
|
7737
|
+
if (!rejection) return;
|
|
7738
|
+
callbacksRef.current(product).onError(checkoutError("processing_error", rejection, { retryable: false }));
|
|
7739
|
+
}, []);
|
|
7740
|
+
if (rejection) return null;
|
|
7700
7741
|
return trigger(
|
|
7701
7742
|
() => {
|
|
7702
7743
|
if (isSample) {
|
|
@@ -9494,5 +9535,5 @@ function useGroupProgress() {
|
|
|
9494
9535
|
}
|
|
9495
9536
|
|
|
9496
9537
|
export { Checkout, CheckoutButton, CheckoutResume, CheckoutSpinner, EmbedBridge, FunnelProvider, FunnelToaster, FunnelView, Modal, Sheet, UpsellButton, VariableStore, attachBus, buildAcquisition, buildContext, createBus, createConsoleTracker, createFunnelStore, createMockDriver, defineModal, dismissAllModals, driverWithEmail, ensureCheckoutButtonStyles, exposurePayload, hideModal, isValidEmail, newEventId, registerModal, removeModal, showModal, toast, unregisterModal, useActiveLocale, useCheckout, useClickIds, useContextValue, useData, useDevice, useExperiment, useField, useFunnel, useGroupProgress, useLocale, useMarketingConsent, useModal, useNavigation, useOffering, useOfferings, usePage, useResponse, useSystem, useTracker, useTranslation, useUserAttribute, useUtm, withBus };
|
|
9497
|
-
//# sourceMappingURL=chunk-
|
|
9498
|
-
//# sourceMappingURL=chunk-
|
|
9538
|
+
//# sourceMappingURL=chunk-AW2YURFE.js.map
|
|
9539
|
+
//# sourceMappingURL=chunk-AW2YURFE.js.map
|