@funnelfox/payments-sdk 0.2.0-beta.2 → 0.2.0-beta.3
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/dist/index.cjs +88 -9
- package/dist/index.d.cts +17 -6
- package/dist/index.d.ts +17 -6
- package/dist/index.js +88 -9
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -33,10 +33,44 @@ var CheckoutError = class extends Error {
|
|
|
33
33
|
this.name = "CheckoutError";
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
|
+
var CHECKOUT_BLOCK_REASONS = ["duplicated_subscription", "duplicated_payment"];
|
|
37
|
+
function isCheckoutBlockReason(reason) {
|
|
38
|
+
return CHECKOUT_BLOCK_REASONS.some((known) => known === reason);
|
|
39
|
+
}
|
|
40
|
+
var CheckoutBlockedError = class extends CheckoutError {
|
|
41
|
+
constructor(reason, buyerMessage) {
|
|
42
|
+
super(`Checkout blocked: ${reason}`);
|
|
43
|
+
this.reason = reason;
|
|
44
|
+
this.buyerMessage = buyerMessage;
|
|
45
|
+
this.name = "CheckoutBlockedError";
|
|
46
|
+
}
|
|
47
|
+
reason;
|
|
48
|
+
buyerMessage;
|
|
49
|
+
};
|
|
36
50
|
|
|
37
51
|
// src/providers/stripe/index.ts
|
|
38
52
|
var import_stripe_js = require("@stripe/stripe-js");
|
|
39
53
|
|
|
54
|
+
// src/providers/stripe/return-url.ts
|
|
55
|
+
var RETURNED_SESSION_PARAM = "ff_checkout_session";
|
|
56
|
+
var SESSION_ID_PLACEHOLDER = "{CHECKOUT_SESSION_ID}";
|
|
57
|
+
var SESSION_ID = /^cs_\w+$/;
|
|
58
|
+
function withReturnedSessionParam(href) {
|
|
59
|
+
const url = new URL(href);
|
|
60
|
+
url.searchParams.set(RETURNED_SESSION_PARAM, SESSION_ID_PLACEHOLDER);
|
|
61
|
+
return url.href.replace(encodeURIComponent(SESSION_ID_PLACEHOLDER), SESSION_ID_PLACEHOLDER);
|
|
62
|
+
}
|
|
63
|
+
function popSessionIdFromUrl() {
|
|
64
|
+
const url = new URL(window.location.href);
|
|
65
|
+
const sessionId = url.searchParams.get(RETURNED_SESSION_PARAM);
|
|
66
|
+
if (sessionId === null) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
url.searchParams.delete(RETURNED_SESSION_PARAM);
|
|
70
|
+
window.history.replaceState(window.history.state, "", url.href);
|
|
71
|
+
return SESSION_ID.test(sessionId) ? sessionId : null;
|
|
72
|
+
}
|
|
73
|
+
|
|
40
74
|
// src/providers/stripe/helpers.ts
|
|
41
75
|
function buildStripeCheckoutSessionBody(params) {
|
|
42
76
|
return {
|
|
@@ -62,6 +96,7 @@ function buildStripeCheckoutSessionBody(params) {
|
|
|
62
96
|
}
|
|
63
97
|
},
|
|
64
98
|
...params.upgrade && { upgrade: params.upgrade },
|
|
99
|
+
...params.isSubscription !== void 0 && { is_subscription: params.isSubscription },
|
|
65
100
|
...params.walletFirst && { wallet_first: params.walletFirst },
|
|
66
101
|
...params.uiMode && { ui_mode: params.uiMode }
|
|
67
102
|
};
|
|
@@ -119,6 +154,12 @@ var StripeCheckoutService = class extends HttpService {
|
|
|
119
154
|
`/stripe/purchase${query}`,
|
|
120
155
|
buildStripeCheckoutSessionBody(params)
|
|
121
156
|
);
|
|
157
|
+
if (data.status === "failed") {
|
|
158
|
+
if (isCheckoutBlockReason(data.reason)) {
|
|
159
|
+
throw new CheckoutBlockedError(data.reason, data.message || void 0);
|
|
160
|
+
}
|
|
161
|
+
throw new CheckoutError(`Checkout session refused: ${data.reason}`);
|
|
162
|
+
}
|
|
122
163
|
if (!data.client_secret) {
|
|
123
164
|
throw new CheckoutError("Backend returned no client_secret");
|
|
124
165
|
}
|
|
@@ -280,6 +321,7 @@ var StripeProvider = class {
|
|
|
280
321
|
ui;
|
|
281
322
|
stripe = null;
|
|
282
323
|
mounted = false;
|
|
324
|
+
blocked = false;
|
|
283
325
|
clientSecret = null;
|
|
284
326
|
snapshot = {};
|
|
285
327
|
async init() {
|
|
@@ -299,7 +341,17 @@ var StripeProvider = class {
|
|
|
299
341
|
throw new CheckoutError("Already rendered \u2014 call destroy() before rendering again");
|
|
300
342
|
}
|
|
301
343
|
this.mounted = true;
|
|
302
|
-
|
|
344
|
+
this.blocked = false;
|
|
345
|
+
const returned = await this.takeReturnedSession();
|
|
346
|
+
if (returned) {
|
|
347
|
+
this.reportComplete(returned);
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
try {
|
|
351
|
+
await this.ui.mount(this.stripe, container, this.host());
|
|
352
|
+
} catch (err) {
|
|
353
|
+
if (!this.blocked) throw err;
|
|
354
|
+
}
|
|
303
355
|
}
|
|
304
356
|
async reset() {
|
|
305
357
|
this.destroy();
|
|
@@ -323,18 +375,42 @@ var StripeProvider = class {
|
|
|
323
375
|
provider: "stripe",
|
|
324
376
|
paymentMethodType: this.snapshot.paymentMethodType
|
|
325
377
|
}),
|
|
326
|
-
renderFailed: (error, detail) =>
|
|
378
|
+
renderFailed: (error, detail) => {
|
|
379
|
+
if (!this.blocked) this.emitError("render", error, detail);
|
|
380
|
+
},
|
|
327
381
|
paymentFailed: (error, detail) => this.emitError("payment", error, detail),
|
|
328
382
|
succeeded: (outcome) => void this.emitComplete(outcome)
|
|
329
383
|
};
|
|
330
384
|
}
|
|
331
385
|
async createSession() {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
386
|
+
try {
|
|
387
|
+
const secret = await this.service.createCheckoutSession({
|
|
388
|
+
...this.config,
|
|
389
|
+
returnUrl: this.config.returnUrl || withReturnedSessionParam(window.location.href)
|
|
390
|
+
});
|
|
391
|
+
this.clientSecret = secret;
|
|
392
|
+
return secret;
|
|
393
|
+
} catch (err) {
|
|
394
|
+
if (err instanceof CheckoutBlockedError && this.callbacks.onBlocked && this.mounted) {
|
|
395
|
+
this.blocked = true;
|
|
396
|
+
this.ui.destroy();
|
|
397
|
+
this.callbacks.onBlocked({
|
|
398
|
+
provider: "stripe",
|
|
399
|
+
reason: err.reason,
|
|
400
|
+
message: err.buyerMessage
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
throw err;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
async takeReturnedSession() {
|
|
407
|
+
const sessionId = this.config.returnUrl ? null : popSessionIdFromUrl();
|
|
408
|
+
if (!sessionId) {
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
const lookup = () => this.service.getSession(sessionId, this.config.accountId);
|
|
412
|
+
const session = await lookup().catch(lookup).catch(() => null);
|
|
413
|
+
return session?.status === "complete" ? definedOnly(session) : null;
|
|
338
414
|
}
|
|
339
415
|
// Format: cs_test_{sessionId}_secret_{random}
|
|
340
416
|
sessionId() {
|
|
@@ -374,10 +450,13 @@ var StripeProvider = class {
|
|
|
374
450
|
session = {};
|
|
375
451
|
}
|
|
376
452
|
}
|
|
453
|
+
this.reportComplete({ ...fallback, ...session });
|
|
454
|
+
}
|
|
455
|
+
reportComplete(session) {
|
|
377
456
|
this.callbacks.onComplete?.({
|
|
378
457
|
provider: "stripe",
|
|
379
458
|
paymentMethodType: this.snapshot.paymentMethodType,
|
|
380
|
-
...toCompleteFields(
|
|
459
|
+
...toCompleteFields(session)
|
|
381
460
|
});
|
|
382
461
|
}
|
|
383
462
|
emitError(phase, error, detail) {
|
package/dist/index.d.cts
CHANGED
|
@@ -49,7 +49,7 @@ interface StripeConfig {
|
|
|
49
49
|
customerId?: string;
|
|
50
50
|
/** New customer details — required when customerId is not provided */
|
|
51
51
|
customer?: StripeCustomer;
|
|
52
|
-
/**
|
|
52
|
+
/** Where redirect-based methods return the buyer. A custom URL completes the session itself. */
|
|
53
53
|
returnUrl?: string;
|
|
54
54
|
/** When true, Stripe displays a promotional code input field in the embedded checkout */
|
|
55
55
|
allowPromoCodes?: boolean;
|
|
@@ -61,6 +61,8 @@ interface StripeConfig {
|
|
|
61
61
|
trial?: StripeCheckoutTrial;
|
|
62
62
|
/** When true, treats this as a subscription upgrade — requires customerId to be set */
|
|
63
63
|
upgrade?: boolean;
|
|
64
|
+
/** Enables the backend's one-subscription-per-email limit. */
|
|
65
|
+
isSubscription?: boolean;
|
|
64
66
|
/** When true, surfaces Apple Pay / Google Pay as the primary payment option (Wallet-First mode) */
|
|
65
67
|
walletFirst?: boolean;
|
|
66
68
|
/** Which checkout UI Stripe renders. Defaults to `embedded_page`. */
|
|
@@ -94,6 +96,12 @@ type ProviderConfigMap = {
|
|
|
94
96
|
fastspring: FastSpringConfig;
|
|
95
97
|
};
|
|
96
98
|
|
|
99
|
+
declare class CheckoutError extends Error {
|
|
100
|
+
constructor(message: string);
|
|
101
|
+
}
|
|
102
|
+
declare const CHECKOUT_BLOCK_REASONS: readonly ["duplicated_subscription", "duplicated_payment"];
|
|
103
|
+
type CheckoutBlockReason = (typeof CHECKOUT_BLOCK_REASONS)[number];
|
|
104
|
+
|
|
97
105
|
interface CheckoutCompleteEvent {
|
|
98
106
|
provider: ProviderName;
|
|
99
107
|
paymentMethodType?: PaymentMethodType;
|
|
@@ -119,6 +127,12 @@ interface CheckoutErrorEvent {
|
|
|
119
127
|
message?: string;
|
|
120
128
|
error: unknown;
|
|
121
129
|
}
|
|
130
|
+
/** The backend refused to open checkout for a repeat purchase. */
|
|
131
|
+
interface CheckoutBlockedEvent {
|
|
132
|
+
provider: ProviderName;
|
|
133
|
+
reason: CheckoutBlockReason;
|
|
134
|
+
message?: string;
|
|
135
|
+
}
|
|
122
136
|
interface CheckoutCancelEvent {
|
|
123
137
|
provider: ProviderName;
|
|
124
138
|
paymentMethodType?: PaymentMethodType;
|
|
@@ -153,6 +167,7 @@ interface CheckoutCallbacks {
|
|
|
153
167
|
onReady?: (event: CheckoutReadyEvent) => void;
|
|
154
168
|
onConfirm?: (event: CheckoutConfirmEvent) => void;
|
|
155
169
|
onChange?: (event: CheckoutChangeEvent) => void;
|
|
170
|
+
onBlocked?: (event: CheckoutBlockedEvent) => void;
|
|
156
171
|
}
|
|
157
172
|
|
|
158
173
|
interface RenderOptions {
|
|
@@ -179,13 +194,9 @@ type InitCheckoutConfig<T extends ProviderName> = {
|
|
|
179
194
|
} & CheckoutCallbacks;
|
|
180
195
|
declare function initCheckout<T extends ProviderName>(options: InitCheckoutConfig<T>): Promise<CheckoutInstance>;
|
|
181
196
|
|
|
182
|
-
declare class CheckoutError extends Error {
|
|
183
|
-
constructor(message: string);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
197
|
type CreateCheckoutSessionParams = Omit<StripeConfig, 'publishableKey' | 'returnUrl' | 'form'> & {
|
|
187
198
|
returnUrl: string;
|
|
188
199
|
};
|
|
189
200
|
declare function buildStripeCheckoutSessionBody(params: CreateCheckoutSessionParams): Record<string, unknown>;
|
|
190
201
|
|
|
191
|
-
export { type CheckoutCallbacks, type CheckoutCancelEvent, type CheckoutChangeEvent, type CheckoutCompleteEvent, type CheckoutConfirmEvent, CheckoutError, type CheckoutErrorEvent, type CheckoutErrorPhase, type CheckoutInstance, type CheckoutReadyEvent, type CreateCheckoutSessionParams, type FastSpringConfig, type PaymentMethodType, type PaymentProvider, type ProviderConfigMap, type ProviderName, type RenderOptions, type StripeCheckoutTrial, type StripeConfig, type StripeFormOptions, type StripeUiMode, buildStripeCheckoutSessionBody, initCheckout };
|
|
202
|
+
export { type CheckoutBlockReason, type CheckoutBlockedEvent, type CheckoutCallbacks, type CheckoutCancelEvent, type CheckoutChangeEvent, type CheckoutCompleteEvent, type CheckoutConfirmEvent, CheckoutError, type CheckoutErrorEvent, type CheckoutErrorPhase, type CheckoutInstance, type CheckoutReadyEvent, type CreateCheckoutSessionParams, type FastSpringConfig, type PaymentMethodType, type PaymentProvider, type ProviderConfigMap, type ProviderName, type RenderOptions, type StripeCheckoutTrial, type StripeConfig, type StripeFormOptions, type StripeUiMode, buildStripeCheckoutSessionBody, initCheckout };
|
package/dist/index.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ interface StripeConfig {
|
|
|
49
49
|
customerId?: string;
|
|
50
50
|
/** New customer details — required when customerId is not provided */
|
|
51
51
|
customer?: StripeCustomer;
|
|
52
|
-
/**
|
|
52
|
+
/** Where redirect-based methods return the buyer. A custom URL completes the session itself. */
|
|
53
53
|
returnUrl?: string;
|
|
54
54
|
/** When true, Stripe displays a promotional code input field in the embedded checkout */
|
|
55
55
|
allowPromoCodes?: boolean;
|
|
@@ -61,6 +61,8 @@ interface StripeConfig {
|
|
|
61
61
|
trial?: StripeCheckoutTrial;
|
|
62
62
|
/** When true, treats this as a subscription upgrade — requires customerId to be set */
|
|
63
63
|
upgrade?: boolean;
|
|
64
|
+
/** Enables the backend's one-subscription-per-email limit. */
|
|
65
|
+
isSubscription?: boolean;
|
|
64
66
|
/** When true, surfaces Apple Pay / Google Pay as the primary payment option (Wallet-First mode) */
|
|
65
67
|
walletFirst?: boolean;
|
|
66
68
|
/** Which checkout UI Stripe renders. Defaults to `embedded_page`. */
|
|
@@ -94,6 +96,12 @@ type ProviderConfigMap = {
|
|
|
94
96
|
fastspring: FastSpringConfig;
|
|
95
97
|
};
|
|
96
98
|
|
|
99
|
+
declare class CheckoutError extends Error {
|
|
100
|
+
constructor(message: string);
|
|
101
|
+
}
|
|
102
|
+
declare const CHECKOUT_BLOCK_REASONS: readonly ["duplicated_subscription", "duplicated_payment"];
|
|
103
|
+
type CheckoutBlockReason = (typeof CHECKOUT_BLOCK_REASONS)[number];
|
|
104
|
+
|
|
97
105
|
interface CheckoutCompleteEvent {
|
|
98
106
|
provider: ProviderName;
|
|
99
107
|
paymentMethodType?: PaymentMethodType;
|
|
@@ -119,6 +127,12 @@ interface CheckoutErrorEvent {
|
|
|
119
127
|
message?: string;
|
|
120
128
|
error: unknown;
|
|
121
129
|
}
|
|
130
|
+
/** The backend refused to open checkout for a repeat purchase. */
|
|
131
|
+
interface CheckoutBlockedEvent {
|
|
132
|
+
provider: ProviderName;
|
|
133
|
+
reason: CheckoutBlockReason;
|
|
134
|
+
message?: string;
|
|
135
|
+
}
|
|
122
136
|
interface CheckoutCancelEvent {
|
|
123
137
|
provider: ProviderName;
|
|
124
138
|
paymentMethodType?: PaymentMethodType;
|
|
@@ -153,6 +167,7 @@ interface CheckoutCallbacks {
|
|
|
153
167
|
onReady?: (event: CheckoutReadyEvent) => void;
|
|
154
168
|
onConfirm?: (event: CheckoutConfirmEvent) => void;
|
|
155
169
|
onChange?: (event: CheckoutChangeEvent) => void;
|
|
170
|
+
onBlocked?: (event: CheckoutBlockedEvent) => void;
|
|
156
171
|
}
|
|
157
172
|
|
|
158
173
|
interface RenderOptions {
|
|
@@ -179,13 +194,9 @@ type InitCheckoutConfig<T extends ProviderName> = {
|
|
|
179
194
|
} & CheckoutCallbacks;
|
|
180
195
|
declare function initCheckout<T extends ProviderName>(options: InitCheckoutConfig<T>): Promise<CheckoutInstance>;
|
|
181
196
|
|
|
182
|
-
declare class CheckoutError extends Error {
|
|
183
|
-
constructor(message: string);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
197
|
type CreateCheckoutSessionParams = Omit<StripeConfig, 'publishableKey' | 'returnUrl' | 'form'> & {
|
|
187
198
|
returnUrl: string;
|
|
188
199
|
};
|
|
189
200
|
declare function buildStripeCheckoutSessionBody(params: CreateCheckoutSessionParams): Record<string, unknown>;
|
|
190
201
|
|
|
191
|
-
export { type CheckoutCallbacks, type CheckoutCancelEvent, type CheckoutChangeEvent, type CheckoutCompleteEvent, type CheckoutConfirmEvent, CheckoutError, type CheckoutErrorEvent, type CheckoutErrorPhase, type CheckoutInstance, type CheckoutReadyEvent, type CreateCheckoutSessionParams, type FastSpringConfig, type PaymentMethodType, type PaymentProvider, type ProviderConfigMap, type ProviderName, type RenderOptions, type StripeCheckoutTrial, type StripeConfig, type StripeFormOptions, type StripeUiMode, buildStripeCheckoutSessionBody, initCheckout };
|
|
202
|
+
export { type CheckoutBlockReason, type CheckoutBlockedEvent, type CheckoutCallbacks, type CheckoutCancelEvent, type CheckoutChangeEvent, type CheckoutCompleteEvent, type CheckoutConfirmEvent, CheckoutError, type CheckoutErrorEvent, type CheckoutErrorPhase, type CheckoutInstance, type CheckoutReadyEvent, type CreateCheckoutSessionParams, type FastSpringConfig, type PaymentMethodType, type PaymentProvider, type ProviderConfigMap, type ProviderName, type RenderOptions, type StripeCheckoutTrial, type StripeConfig, type StripeFormOptions, type StripeUiMode, buildStripeCheckoutSessionBody, initCheckout };
|
package/dist/index.js
CHANGED
|
@@ -5,10 +5,44 @@ var CheckoutError = class extends Error {
|
|
|
5
5
|
this.name = "CheckoutError";
|
|
6
6
|
}
|
|
7
7
|
};
|
|
8
|
+
var CHECKOUT_BLOCK_REASONS = ["duplicated_subscription", "duplicated_payment"];
|
|
9
|
+
function isCheckoutBlockReason(reason) {
|
|
10
|
+
return CHECKOUT_BLOCK_REASONS.some((known) => known === reason);
|
|
11
|
+
}
|
|
12
|
+
var CheckoutBlockedError = class extends CheckoutError {
|
|
13
|
+
constructor(reason, buyerMessage) {
|
|
14
|
+
super(`Checkout blocked: ${reason}`);
|
|
15
|
+
this.reason = reason;
|
|
16
|
+
this.buyerMessage = buyerMessage;
|
|
17
|
+
this.name = "CheckoutBlockedError";
|
|
18
|
+
}
|
|
19
|
+
reason;
|
|
20
|
+
buyerMessage;
|
|
21
|
+
};
|
|
8
22
|
|
|
9
23
|
// src/providers/stripe/index.ts
|
|
10
24
|
import { loadStripe } from "@stripe/stripe-js";
|
|
11
25
|
|
|
26
|
+
// src/providers/stripe/return-url.ts
|
|
27
|
+
var RETURNED_SESSION_PARAM = "ff_checkout_session";
|
|
28
|
+
var SESSION_ID_PLACEHOLDER = "{CHECKOUT_SESSION_ID}";
|
|
29
|
+
var SESSION_ID = /^cs_\w+$/;
|
|
30
|
+
function withReturnedSessionParam(href) {
|
|
31
|
+
const url = new URL(href);
|
|
32
|
+
url.searchParams.set(RETURNED_SESSION_PARAM, SESSION_ID_PLACEHOLDER);
|
|
33
|
+
return url.href.replace(encodeURIComponent(SESSION_ID_PLACEHOLDER), SESSION_ID_PLACEHOLDER);
|
|
34
|
+
}
|
|
35
|
+
function popSessionIdFromUrl() {
|
|
36
|
+
const url = new URL(window.location.href);
|
|
37
|
+
const sessionId = url.searchParams.get(RETURNED_SESSION_PARAM);
|
|
38
|
+
if (sessionId === null) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
url.searchParams.delete(RETURNED_SESSION_PARAM);
|
|
42
|
+
window.history.replaceState(window.history.state, "", url.href);
|
|
43
|
+
return SESSION_ID.test(sessionId) ? sessionId : null;
|
|
44
|
+
}
|
|
45
|
+
|
|
12
46
|
// src/providers/stripe/helpers.ts
|
|
13
47
|
function buildStripeCheckoutSessionBody(params) {
|
|
14
48
|
return {
|
|
@@ -34,6 +68,7 @@ function buildStripeCheckoutSessionBody(params) {
|
|
|
34
68
|
}
|
|
35
69
|
},
|
|
36
70
|
...params.upgrade && { upgrade: params.upgrade },
|
|
71
|
+
...params.isSubscription !== void 0 && { is_subscription: params.isSubscription },
|
|
37
72
|
...params.walletFirst && { wallet_first: params.walletFirst },
|
|
38
73
|
...params.uiMode && { ui_mode: params.uiMode }
|
|
39
74
|
};
|
|
@@ -91,6 +126,12 @@ var StripeCheckoutService = class extends HttpService {
|
|
|
91
126
|
`/stripe/purchase${query}`,
|
|
92
127
|
buildStripeCheckoutSessionBody(params)
|
|
93
128
|
);
|
|
129
|
+
if (data.status === "failed") {
|
|
130
|
+
if (isCheckoutBlockReason(data.reason)) {
|
|
131
|
+
throw new CheckoutBlockedError(data.reason, data.message || void 0);
|
|
132
|
+
}
|
|
133
|
+
throw new CheckoutError(`Checkout session refused: ${data.reason}`);
|
|
134
|
+
}
|
|
94
135
|
if (!data.client_secret) {
|
|
95
136
|
throw new CheckoutError("Backend returned no client_secret");
|
|
96
137
|
}
|
|
@@ -252,6 +293,7 @@ var StripeProvider = class {
|
|
|
252
293
|
ui;
|
|
253
294
|
stripe = null;
|
|
254
295
|
mounted = false;
|
|
296
|
+
blocked = false;
|
|
255
297
|
clientSecret = null;
|
|
256
298
|
snapshot = {};
|
|
257
299
|
async init() {
|
|
@@ -271,7 +313,17 @@ var StripeProvider = class {
|
|
|
271
313
|
throw new CheckoutError("Already rendered \u2014 call destroy() before rendering again");
|
|
272
314
|
}
|
|
273
315
|
this.mounted = true;
|
|
274
|
-
|
|
316
|
+
this.blocked = false;
|
|
317
|
+
const returned = await this.takeReturnedSession();
|
|
318
|
+
if (returned) {
|
|
319
|
+
this.reportComplete(returned);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
try {
|
|
323
|
+
await this.ui.mount(this.stripe, container, this.host());
|
|
324
|
+
} catch (err) {
|
|
325
|
+
if (!this.blocked) throw err;
|
|
326
|
+
}
|
|
275
327
|
}
|
|
276
328
|
async reset() {
|
|
277
329
|
this.destroy();
|
|
@@ -295,18 +347,42 @@ var StripeProvider = class {
|
|
|
295
347
|
provider: "stripe",
|
|
296
348
|
paymentMethodType: this.snapshot.paymentMethodType
|
|
297
349
|
}),
|
|
298
|
-
renderFailed: (error, detail) =>
|
|
350
|
+
renderFailed: (error, detail) => {
|
|
351
|
+
if (!this.blocked) this.emitError("render", error, detail);
|
|
352
|
+
},
|
|
299
353
|
paymentFailed: (error, detail) => this.emitError("payment", error, detail),
|
|
300
354
|
succeeded: (outcome) => void this.emitComplete(outcome)
|
|
301
355
|
};
|
|
302
356
|
}
|
|
303
357
|
async createSession() {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
358
|
+
try {
|
|
359
|
+
const secret = await this.service.createCheckoutSession({
|
|
360
|
+
...this.config,
|
|
361
|
+
returnUrl: this.config.returnUrl || withReturnedSessionParam(window.location.href)
|
|
362
|
+
});
|
|
363
|
+
this.clientSecret = secret;
|
|
364
|
+
return secret;
|
|
365
|
+
} catch (err) {
|
|
366
|
+
if (err instanceof CheckoutBlockedError && this.callbacks.onBlocked && this.mounted) {
|
|
367
|
+
this.blocked = true;
|
|
368
|
+
this.ui.destroy();
|
|
369
|
+
this.callbacks.onBlocked({
|
|
370
|
+
provider: "stripe",
|
|
371
|
+
reason: err.reason,
|
|
372
|
+
message: err.buyerMessage
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
throw err;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
async takeReturnedSession() {
|
|
379
|
+
const sessionId = this.config.returnUrl ? null : popSessionIdFromUrl();
|
|
380
|
+
if (!sessionId) {
|
|
381
|
+
return null;
|
|
382
|
+
}
|
|
383
|
+
const lookup = () => this.service.getSession(sessionId, this.config.accountId);
|
|
384
|
+
const session = await lookup().catch(lookup).catch(() => null);
|
|
385
|
+
return session?.status === "complete" ? definedOnly(session) : null;
|
|
310
386
|
}
|
|
311
387
|
// Format: cs_test_{sessionId}_secret_{random}
|
|
312
388
|
sessionId() {
|
|
@@ -346,10 +422,13 @@ var StripeProvider = class {
|
|
|
346
422
|
session = {};
|
|
347
423
|
}
|
|
348
424
|
}
|
|
425
|
+
this.reportComplete({ ...fallback, ...session });
|
|
426
|
+
}
|
|
427
|
+
reportComplete(session) {
|
|
349
428
|
this.callbacks.onComplete?.({
|
|
350
429
|
provider: "stripe",
|
|
351
430
|
paymentMethodType: this.snapshot.paymentMethodType,
|
|
352
|
-
...toCompleteFields(
|
|
431
|
+
...toCompleteFields(session)
|
|
353
432
|
});
|
|
354
433
|
}
|
|
355
434
|
emitError(phase, error, detail) {
|