@funnelfox/payments-sdk 0.1.2-beta.9 → 0.2.0-beta.2
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 +242 -46
- package/dist/index.d.cts +63 -3
- package/dist/index.d.ts +63 -3
- package/dist/index.js +242 -46
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -62,7 +62,8 @@ function buildStripeCheckoutSessionBody(params) {
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
...params.upgrade && { upgrade: params.upgrade },
|
|
65
|
-
...params.walletFirst && { wallet_first: params.walletFirst }
|
|
65
|
+
...params.walletFirst && { wallet_first: params.walletFirst },
|
|
66
|
+
...params.uiMode && { ui_mode: params.uiMode }
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
|
|
@@ -125,55 +126,209 @@ var StripeCheckoutService = class extends HttpService {
|
|
|
125
126
|
}
|
|
126
127
|
};
|
|
127
128
|
|
|
129
|
+
// src/providers/stripe/ui/embedded-page.ts
|
|
130
|
+
var StripeEmbeddedPageUi = class {
|
|
131
|
+
checkout = null;
|
|
132
|
+
async mount(stripe, container, host) {
|
|
133
|
+
try {
|
|
134
|
+
this.checkout = await stripe.createEmbeddedCheckoutPage({
|
|
135
|
+
fetchClientSecret: () => host.clientSecret(),
|
|
136
|
+
onComplete: () => host.succeeded()
|
|
137
|
+
});
|
|
138
|
+
} catch (err) {
|
|
139
|
+
host.renderFailed(err, { message: err instanceof Error ? err.message : void 0 });
|
|
140
|
+
if (err instanceof CheckoutError) throw err;
|
|
141
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
142
|
+
throw new CheckoutError(`Stripe checkout failed: ${detail}`);
|
|
143
|
+
}
|
|
144
|
+
this.checkout.mount(container);
|
|
145
|
+
}
|
|
146
|
+
destroy() {
|
|
147
|
+
this.checkout?.destroy();
|
|
148
|
+
this.checkout = null;
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
// src/providers/stripe/ui/form.ts
|
|
153
|
+
var CHECKOUT_FORM_BETA = "custom_checkout_payment_form_1";
|
|
154
|
+
var EXPRESS_CHECKOUT_SOURCE = "checkout-form-ece";
|
|
155
|
+
var StripeFormUi = class {
|
|
156
|
+
constructor(options = {}) {
|
|
157
|
+
this.options = options;
|
|
158
|
+
}
|
|
159
|
+
options;
|
|
160
|
+
loadOptions = { betas: [CHECKOUT_FORM_BETA] };
|
|
161
|
+
checkout = null;
|
|
162
|
+
form = null;
|
|
163
|
+
async mount(stripe, container, host) {
|
|
164
|
+
const { appearance, fonts, loader, layout, expressCheckout } = this.options;
|
|
165
|
+
const startedAt = Date.now();
|
|
166
|
+
try {
|
|
167
|
+
if (typeof stripe.initCheckoutFormSdk !== "function") {
|
|
168
|
+
throw new CheckoutError("Stripe has not granted this account access to Checkout Form");
|
|
169
|
+
}
|
|
170
|
+
this.checkout = stripe.initCheckoutFormSdk({
|
|
171
|
+
clientSecret: host.clientSecret(),
|
|
172
|
+
...appearance && { appearance },
|
|
173
|
+
...fonts?.length && { fonts },
|
|
174
|
+
...loader && { loader }
|
|
175
|
+
});
|
|
176
|
+
this.checkout.on("change", (session) => host.changed(fromSession(session)));
|
|
177
|
+
this.form = this.checkout.createForm({
|
|
178
|
+
...layout && { layout },
|
|
179
|
+
...expressCheckout && { expressCheckout }
|
|
180
|
+
});
|
|
181
|
+
this.form.on("ready", () => host.ready(Date.now() - startedAt));
|
|
182
|
+
this.form.on(
|
|
183
|
+
"loaderror",
|
|
184
|
+
(event) => host.renderFailed(event.error, { message: event.error.message })
|
|
185
|
+
);
|
|
186
|
+
this.form.on("change", (event) => host.changed(fromForm(event)));
|
|
187
|
+
this.form.on("cancel", () => host.cancelled());
|
|
188
|
+
this.form.mount(container);
|
|
189
|
+
const actions = await this.loadActions();
|
|
190
|
+
this.form.on("confirm", (event) => void this.confirm(actions, event, host));
|
|
191
|
+
} catch (err) {
|
|
192
|
+
host.renderFailed(err, { message: err instanceof Error ? err.message : void 0 });
|
|
193
|
+
if (err instanceof CheckoutError) throw err;
|
|
194
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
195
|
+
throw new CheckoutError(`Stripe checkout failed: ${detail}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
destroy() {
|
|
199
|
+
this.form?.destroy();
|
|
200
|
+
this.form = null;
|
|
201
|
+
this.checkout = null;
|
|
202
|
+
}
|
|
203
|
+
async loadActions() {
|
|
204
|
+
const result = await this.checkout.loadActions();
|
|
205
|
+
if (result.type !== "success") {
|
|
206
|
+
throw new CheckoutError(`Stripe checkout failed: ${result.error.message}`);
|
|
207
|
+
}
|
|
208
|
+
return result.actions;
|
|
209
|
+
}
|
|
210
|
+
async isFormValid(actions) {
|
|
211
|
+
try {
|
|
212
|
+
const validation = await actions.validateElements();
|
|
213
|
+
return validation.type !== "error";
|
|
214
|
+
} catch {
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async confirm(actions, event, host) {
|
|
219
|
+
const express = event.source === EXPRESS_CHECKOUT_SOURCE;
|
|
220
|
+
const paymentMethodType = express ? void 0 : event.paymentMethodType ?? void 0;
|
|
221
|
+
try {
|
|
222
|
+
const attempted = express || await this.isFormValid(actions);
|
|
223
|
+
if (attempted) {
|
|
224
|
+
host.confirmed({ paymentMethodType, express });
|
|
225
|
+
}
|
|
226
|
+
const result = await actions.confirm({ formConfirmEvent: event, redirect: "if_required" });
|
|
227
|
+
if (result.type === "error") {
|
|
228
|
+
if (result.error.code === "paymentFailed") {
|
|
229
|
+
host.paymentFailed(result.error, {
|
|
230
|
+
declineCode: result.error.paymentFailed.declineCode,
|
|
231
|
+
message: result.error.message
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
host.succeeded(fromSession(result.session));
|
|
237
|
+
} catch (err) {
|
|
238
|
+
host.paymentFailed(err, { message: err instanceof Error ? err.message : void 0 });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
function fromSession(session) {
|
|
243
|
+
return {
|
|
244
|
+
email: session.email ?? void 0,
|
|
245
|
+
currency: session.currency,
|
|
246
|
+
amountTotal: session.total?.total?.minorUnitsAmount
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function fromForm(event) {
|
|
250
|
+
const { payment, customerDetails, adaptivePricing } = event.value;
|
|
251
|
+
return {
|
|
252
|
+
paymentMethodType: payment?.type,
|
|
253
|
+
email: customerDetails?.email || void 0,
|
|
254
|
+
currency: adaptivePricing?.currency,
|
|
255
|
+
complete: event.complete
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// src/providers/stripe/ui/index.ts
|
|
260
|
+
function createStripeCheckoutUi(config) {
|
|
261
|
+
switch (config.uiMode) {
|
|
262
|
+
case "form":
|
|
263
|
+
return new StripeFormUi(config.form);
|
|
264
|
+
default:
|
|
265
|
+
return new StripeEmbeddedPageUi();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
128
269
|
// src/providers/stripe/index.ts
|
|
129
270
|
var StripeProvider = class {
|
|
130
271
|
constructor(config, callbacks, baseUrl, headers) {
|
|
131
272
|
this.config = config;
|
|
132
273
|
this.callbacks = callbacks;
|
|
133
274
|
this.service = new StripeCheckoutService(baseUrl, headers);
|
|
275
|
+
this.ui = createStripeCheckoutUi(config);
|
|
134
276
|
}
|
|
135
277
|
config;
|
|
136
278
|
callbacks;
|
|
137
|
-
stripe = null;
|
|
138
|
-
embeddedCheckout = null;
|
|
139
279
|
service;
|
|
280
|
+
ui;
|
|
281
|
+
stripe = null;
|
|
282
|
+
mounted = false;
|
|
140
283
|
clientSecret = null;
|
|
284
|
+
snapshot = {};
|
|
141
285
|
async init() {
|
|
142
|
-
const stripe = await (0, import_stripe_js.loadStripe)(this.config.publishableKey);
|
|
286
|
+
const stripe = await (0, import_stripe_js.loadStripe)(this.config.publishableKey, this.ui.loadOptions);
|
|
143
287
|
if (!stripe) {
|
|
144
|
-
|
|
288
|
+
const error = new CheckoutError("Failed to load Stripe.js \u2014 verify your publishableKey");
|
|
289
|
+
this.emitError("init", error, { message: error.message });
|
|
290
|
+
throw error;
|
|
145
291
|
}
|
|
146
292
|
this.stripe = stripe;
|
|
147
293
|
}
|
|
148
|
-
async render(container,
|
|
294
|
+
async render(container, _options) {
|
|
149
295
|
if (!this.stripe) {
|
|
150
296
|
throw new CheckoutError("Provider not initialized \u2014 call init() before render()");
|
|
151
297
|
}
|
|
152
|
-
if (this.
|
|
298
|
+
if (this.mounted) {
|
|
153
299
|
throw new CheckoutError("Already rendered \u2014 call destroy() before rendering again");
|
|
154
300
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
fetchClientSecret: () => this.fetchClientSecret(),
|
|
158
|
-
onComplete: () => this.handleComplete(),
|
|
159
|
-
onAnalyticsEvent: (event) => console.log("[stripe analytics]", event.eventType, event)
|
|
160
|
-
});
|
|
161
|
-
} catch (err) {
|
|
162
|
-
this.callbacks.onError?.({ provider: "stripe", error: err });
|
|
163
|
-
if (err instanceof CheckoutError) throw err;
|
|
164
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
165
|
-
throw new CheckoutError(`Stripe checkout failed: ${detail}`);
|
|
166
|
-
}
|
|
167
|
-
this.embeddedCheckout.mount(container);
|
|
301
|
+
this.mounted = true;
|
|
302
|
+
await this.ui.mount(this.stripe, container, this.host());
|
|
168
303
|
}
|
|
169
304
|
async reset() {
|
|
170
305
|
this.destroy();
|
|
171
306
|
}
|
|
172
307
|
destroy() {
|
|
173
|
-
this.
|
|
174
|
-
this.
|
|
308
|
+
this.ui.destroy();
|
|
309
|
+
this.mounted = false;
|
|
310
|
+
this.snapshot = {};
|
|
175
311
|
}
|
|
176
|
-
|
|
312
|
+
host() {
|
|
313
|
+
return {
|
|
314
|
+
clientSecret: () => this.createSession(),
|
|
315
|
+
ready: (durationMs) => this.callbacks.onReady?.({ provider: "stripe", durationMs }),
|
|
316
|
+
changed: (patch) => this.merge(patch),
|
|
317
|
+
confirmed: ({ paymentMethodType, express }) => this.callbacks.onConfirm?.({
|
|
318
|
+
provider: "stripe",
|
|
319
|
+
paymentMethodType: paymentMethodType ?? this.snapshot.paymentMethodType,
|
|
320
|
+
express
|
|
321
|
+
}),
|
|
322
|
+
cancelled: () => this.callbacks.onCancel?.({
|
|
323
|
+
provider: "stripe",
|
|
324
|
+
paymentMethodType: this.snapshot.paymentMethodType
|
|
325
|
+
}),
|
|
326
|
+
renderFailed: (error, detail) => this.emitError("render", error, detail),
|
|
327
|
+
paymentFailed: (error, detail) => this.emitError("payment", error, detail),
|
|
328
|
+
succeeded: (outcome) => void this.emitComplete(outcome)
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
async createSession() {
|
|
177
332
|
const secret = await this.service.createCheckoutSession({
|
|
178
333
|
...this.config,
|
|
179
334
|
returnUrl: this.config.returnUrl ?? window.location.href
|
|
@@ -182,33 +337,74 @@ var StripeProvider = class {
|
|
|
182
337
|
return secret;
|
|
183
338
|
}
|
|
184
339
|
// Format: cs_test_{sessionId}_secret_{random}
|
|
185
|
-
|
|
186
|
-
if (!clientSecret)
|
|
187
|
-
|
|
188
|
-
return idx !== -1 ? clientSecret.slice(0, idx) : null;
|
|
189
|
-
}
|
|
190
|
-
async handleComplete() {
|
|
191
|
-
const sessionId = this.parseSessionId(this.clientSecret);
|
|
192
|
-
if (!sessionId) {
|
|
193
|
-
this.callbacks.onComplete?.({ provider: "stripe" });
|
|
194
|
-
return;
|
|
340
|
+
sessionId() {
|
|
341
|
+
if (!this.clientSecret) {
|
|
342
|
+
return null;
|
|
195
343
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
email: session.email ?? void 0
|
|
206
|
-
});
|
|
207
|
-
} catch {
|
|
208
|
-
this.callbacks.onComplete?.({ provider: "stripe" });
|
|
344
|
+
const idx = this.clientSecret.indexOf("_secret_");
|
|
345
|
+
return idx !== -1 ? this.clientSecret.slice(0, idx) : null;
|
|
346
|
+
}
|
|
347
|
+
merge(patch) {
|
|
348
|
+
const next = { ...this.snapshot };
|
|
349
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
350
|
+
if (value !== void 0) {
|
|
351
|
+
Object.assign(next, { [key]: value });
|
|
352
|
+
}
|
|
209
353
|
}
|
|
354
|
+
this.snapshot = next;
|
|
355
|
+
this.callbacks.onChange?.({ provider: "stripe", ...next });
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Reads the session back for the ids only the backend can resolve, falling
|
|
359
|
+
* back to what the client already knows so a paid customer is never
|
|
360
|
+
* reported as a failure.
|
|
361
|
+
*/
|
|
362
|
+
async emitComplete(outcome) {
|
|
363
|
+
const sessionId = this.sessionId();
|
|
364
|
+
const fallback = {
|
|
365
|
+
amount_total: outcome?.amountTotal ?? null,
|
|
366
|
+
currency: outcome?.currency ?? null,
|
|
367
|
+
email: outcome?.email ?? null
|
|
368
|
+
};
|
|
369
|
+
let session = {};
|
|
370
|
+
if (sessionId) {
|
|
371
|
+
try {
|
|
372
|
+
session = definedOnly(await this.service.getSession(sessionId, this.config.accountId));
|
|
373
|
+
} catch {
|
|
374
|
+
session = {};
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
this.callbacks.onComplete?.({
|
|
378
|
+
provider: "stripe",
|
|
379
|
+
paymentMethodType: this.snapshot.paymentMethodType,
|
|
380
|
+
...toCompleteFields({ ...fallback, ...session })
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
emitError(phase, error, detail) {
|
|
384
|
+
this.callbacks.onError?.({
|
|
385
|
+
provider: "stripe",
|
|
386
|
+
phase,
|
|
387
|
+
paymentMethodType: this.snapshot.paymentMethodType,
|
|
388
|
+
error,
|
|
389
|
+
...detail
|
|
390
|
+
});
|
|
210
391
|
}
|
|
211
392
|
};
|
|
393
|
+
function definedOnly(session) {
|
|
394
|
+
return Object.fromEntries(
|
|
395
|
+
Object.entries(session).filter(([, value]) => value !== null && value !== void 0)
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
function toCompleteFields(session) {
|
|
399
|
+
return {
|
|
400
|
+
customerId: session.customer_id ?? void 0,
|
|
401
|
+
subscriptionId: session.subscription_id ?? void 0,
|
|
402
|
+
invoiceId: session.invoice_id ?? void 0,
|
|
403
|
+
amountPaid: session.amount_total ?? void 0,
|
|
404
|
+
currency: session.currency ?? void 0,
|
|
405
|
+
email: session.email ?? void 0
|
|
406
|
+
};
|
|
407
|
+
}
|
|
212
408
|
|
|
213
409
|
// src/providers/fastspring/index.ts
|
|
214
410
|
var FastSpringProvider = class {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
import { Appearance, CssFontSource, CustomFontSource, StripeCheckoutFormOptions } from '@stripe/stripe-js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Known values are suggested; providers may report their own ids
|
|
5
|
+
* (Stripe form reports e.g. `sepa_debit`, `link`, `klarna`).
|
|
6
|
+
*/
|
|
7
|
+
type PaymentMethodType = 'card' | 'google_pay' | 'apple_pay' | (string & {});
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* How Stripe renders checkout. Independent of `managed`, which decides
|
|
11
|
+
* merchant of record — Stripe treats them as two parameters of one session.
|
|
12
|
+
*/
|
|
13
|
+
type StripeUiMode = 'embedded_page' | 'form';
|
|
14
|
+
/** Client-side UI options for `uiMode: 'form'`. */
|
|
15
|
+
interface StripeFormOptions {
|
|
16
|
+
/** Form supports the whole Appearance API except `rules`. */
|
|
17
|
+
appearance?: Omit<Appearance, 'rules'>;
|
|
18
|
+
/** Font sources so `appearance.variables.fontFamily` resolves inside the iframe. */
|
|
19
|
+
fonts?: Array<CssFontSource | CustomFontSource>;
|
|
20
|
+
loader?: 'auto' | 'always' | 'never';
|
|
21
|
+
/** Omit to let Stripe pick the layout it expects to convert best. */
|
|
22
|
+
layout?: StripeCheckoutFormOptions['layout'];
|
|
23
|
+
expressCheckout?: StripeCheckoutFormOptions['expressCheckout'];
|
|
24
|
+
}
|
|
3
25
|
interface StripeCustomer {
|
|
4
26
|
email?: string;
|
|
5
27
|
phone?: string;
|
|
@@ -41,6 +63,10 @@ interface StripeConfig {
|
|
|
41
63
|
upgrade?: boolean;
|
|
42
64
|
/** When true, surfaces Apple Pay / Google Pay as the primary payment option (Wallet-First mode) */
|
|
43
65
|
walletFirst?: boolean;
|
|
66
|
+
/** Which checkout UI Stripe renders. Defaults to `embedded_page`. */
|
|
67
|
+
uiMode?: StripeUiMode;
|
|
68
|
+
/** UI options applied only when `uiMode` is `form`. */
|
|
69
|
+
form?: StripeFormOptions;
|
|
44
70
|
}
|
|
45
71
|
|
|
46
72
|
interface FastSpringConfig {
|
|
@@ -79,20 +105,54 @@ interface CheckoutCompleteEvent {
|
|
|
79
105
|
currency?: string;
|
|
80
106
|
email?: string;
|
|
81
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Where a checkout failed. `init`/`render` mean the UI never became usable;
|
|
110
|
+
* `payment` means the buyer's charge was declined or errored.
|
|
111
|
+
*/
|
|
112
|
+
type CheckoutErrorPhase = 'init' | 'render' | 'payment';
|
|
82
113
|
interface CheckoutErrorEvent {
|
|
83
114
|
provider: ProviderName;
|
|
84
115
|
paymentMethodType?: PaymentMethodType;
|
|
116
|
+
phase: CheckoutErrorPhase;
|
|
117
|
+
/** Provider decline code when it exposes one, for mapping to a failure reason. */
|
|
118
|
+
declineCode?: string | null;
|
|
119
|
+
message?: string;
|
|
85
120
|
error: unknown;
|
|
86
121
|
}
|
|
87
122
|
interface CheckoutCancelEvent {
|
|
88
123
|
provider: ProviderName;
|
|
89
124
|
paymentMethodType?: PaymentMethodType;
|
|
90
125
|
}
|
|
126
|
+
interface CheckoutReadyEvent {
|
|
127
|
+
provider: ProviderName;
|
|
128
|
+
/** Milliseconds from render() to the checkout UI being usable. */
|
|
129
|
+
durationMs: number;
|
|
130
|
+
}
|
|
131
|
+
/** The buyer authorized the payment; the charge is not confirmed yet. */
|
|
132
|
+
interface CheckoutConfirmEvent {
|
|
133
|
+
provider: ProviderName;
|
|
134
|
+
paymentMethodType?: PaymentMethodType;
|
|
135
|
+
/** Authorized through a wallet button rather than the pay button. */
|
|
136
|
+
express: boolean;
|
|
137
|
+
}
|
|
138
|
+
/** Latest snapshot of what the buyer selected and what they will be charged. */
|
|
139
|
+
interface CheckoutChangeEvent {
|
|
140
|
+
provider: ProviderName;
|
|
141
|
+
paymentMethodType?: PaymentMethodType;
|
|
142
|
+
email?: string;
|
|
143
|
+
/** Currency actually charged — Adaptive Pricing may differ from the listed one. */
|
|
144
|
+
currency?: string;
|
|
145
|
+
amountTotal?: number;
|
|
146
|
+
complete?: boolean;
|
|
147
|
+
}
|
|
91
148
|
|
|
92
149
|
interface CheckoutCallbacks {
|
|
93
150
|
onComplete?: (event: CheckoutCompleteEvent) => void;
|
|
94
151
|
onError?: (event: CheckoutErrorEvent) => void;
|
|
95
152
|
onCancel?: (event: CheckoutCancelEvent) => void;
|
|
153
|
+
onReady?: (event: CheckoutReadyEvent) => void;
|
|
154
|
+
onConfirm?: (event: CheckoutConfirmEvent) => void;
|
|
155
|
+
onChange?: (event: CheckoutChangeEvent) => void;
|
|
96
156
|
}
|
|
97
157
|
|
|
98
158
|
interface RenderOptions {
|
|
@@ -123,9 +183,9 @@ declare class CheckoutError extends Error {
|
|
|
123
183
|
constructor(message: string);
|
|
124
184
|
}
|
|
125
185
|
|
|
126
|
-
type CreateCheckoutSessionParams = Omit<StripeConfig, 'publishableKey' | 'returnUrl'> & {
|
|
186
|
+
type CreateCheckoutSessionParams = Omit<StripeConfig, 'publishableKey' | 'returnUrl' | 'form'> & {
|
|
127
187
|
returnUrl: string;
|
|
128
188
|
};
|
|
129
189
|
declare function buildStripeCheckoutSessionBody(params: CreateCheckoutSessionParams): Record<string, unknown>;
|
|
130
190
|
|
|
131
|
-
export { type CheckoutCallbacks, type CheckoutCancelEvent, type CheckoutCompleteEvent, CheckoutError, type CheckoutErrorEvent, type CheckoutInstance, type CreateCheckoutSessionParams, type FastSpringConfig, type PaymentMethodType, type PaymentProvider, type ProviderConfigMap, type ProviderName, type RenderOptions, type StripeCheckoutTrial, type StripeConfig, buildStripeCheckoutSessionBody, initCheckout };
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
|
-
|
|
1
|
+
import { Appearance, CssFontSource, CustomFontSource, StripeCheckoutFormOptions } from '@stripe/stripe-js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Known values are suggested; providers may report their own ids
|
|
5
|
+
* (Stripe form reports e.g. `sepa_debit`, `link`, `klarna`).
|
|
6
|
+
*/
|
|
7
|
+
type PaymentMethodType = 'card' | 'google_pay' | 'apple_pay' | (string & {});
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* How Stripe renders checkout. Independent of `managed`, which decides
|
|
11
|
+
* merchant of record — Stripe treats them as two parameters of one session.
|
|
12
|
+
*/
|
|
13
|
+
type StripeUiMode = 'embedded_page' | 'form';
|
|
14
|
+
/** Client-side UI options for `uiMode: 'form'`. */
|
|
15
|
+
interface StripeFormOptions {
|
|
16
|
+
/** Form supports the whole Appearance API except `rules`. */
|
|
17
|
+
appearance?: Omit<Appearance, 'rules'>;
|
|
18
|
+
/** Font sources so `appearance.variables.fontFamily` resolves inside the iframe. */
|
|
19
|
+
fonts?: Array<CssFontSource | CustomFontSource>;
|
|
20
|
+
loader?: 'auto' | 'always' | 'never';
|
|
21
|
+
/** Omit to let Stripe pick the layout it expects to convert best. */
|
|
22
|
+
layout?: StripeCheckoutFormOptions['layout'];
|
|
23
|
+
expressCheckout?: StripeCheckoutFormOptions['expressCheckout'];
|
|
24
|
+
}
|
|
3
25
|
interface StripeCustomer {
|
|
4
26
|
email?: string;
|
|
5
27
|
phone?: string;
|
|
@@ -41,6 +63,10 @@ interface StripeConfig {
|
|
|
41
63
|
upgrade?: boolean;
|
|
42
64
|
/** When true, surfaces Apple Pay / Google Pay as the primary payment option (Wallet-First mode) */
|
|
43
65
|
walletFirst?: boolean;
|
|
66
|
+
/** Which checkout UI Stripe renders. Defaults to `embedded_page`. */
|
|
67
|
+
uiMode?: StripeUiMode;
|
|
68
|
+
/** UI options applied only when `uiMode` is `form`. */
|
|
69
|
+
form?: StripeFormOptions;
|
|
44
70
|
}
|
|
45
71
|
|
|
46
72
|
interface FastSpringConfig {
|
|
@@ -79,20 +105,54 @@ interface CheckoutCompleteEvent {
|
|
|
79
105
|
currency?: string;
|
|
80
106
|
email?: string;
|
|
81
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Where a checkout failed. `init`/`render` mean the UI never became usable;
|
|
110
|
+
* `payment` means the buyer's charge was declined or errored.
|
|
111
|
+
*/
|
|
112
|
+
type CheckoutErrorPhase = 'init' | 'render' | 'payment';
|
|
82
113
|
interface CheckoutErrorEvent {
|
|
83
114
|
provider: ProviderName;
|
|
84
115
|
paymentMethodType?: PaymentMethodType;
|
|
116
|
+
phase: CheckoutErrorPhase;
|
|
117
|
+
/** Provider decline code when it exposes one, for mapping to a failure reason. */
|
|
118
|
+
declineCode?: string | null;
|
|
119
|
+
message?: string;
|
|
85
120
|
error: unknown;
|
|
86
121
|
}
|
|
87
122
|
interface CheckoutCancelEvent {
|
|
88
123
|
provider: ProviderName;
|
|
89
124
|
paymentMethodType?: PaymentMethodType;
|
|
90
125
|
}
|
|
126
|
+
interface CheckoutReadyEvent {
|
|
127
|
+
provider: ProviderName;
|
|
128
|
+
/** Milliseconds from render() to the checkout UI being usable. */
|
|
129
|
+
durationMs: number;
|
|
130
|
+
}
|
|
131
|
+
/** The buyer authorized the payment; the charge is not confirmed yet. */
|
|
132
|
+
interface CheckoutConfirmEvent {
|
|
133
|
+
provider: ProviderName;
|
|
134
|
+
paymentMethodType?: PaymentMethodType;
|
|
135
|
+
/** Authorized through a wallet button rather than the pay button. */
|
|
136
|
+
express: boolean;
|
|
137
|
+
}
|
|
138
|
+
/** Latest snapshot of what the buyer selected and what they will be charged. */
|
|
139
|
+
interface CheckoutChangeEvent {
|
|
140
|
+
provider: ProviderName;
|
|
141
|
+
paymentMethodType?: PaymentMethodType;
|
|
142
|
+
email?: string;
|
|
143
|
+
/** Currency actually charged — Adaptive Pricing may differ from the listed one. */
|
|
144
|
+
currency?: string;
|
|
145
|
+
amountTotal?: number;
|
|
146
|
+
complete?: boolean;
|
|
147
|
+
}
|
|
91
148
|
|
|
92
149
|
interface CheckoutCallbacks {
|
|
93
150
|
onComplete?: (event: CheckoutCompleteEvent) => void;
|
|
94
151
|
onError?: (event: CheckoutErrorEvent) => void;
|
|
95
152
|
onCancel?: (event: CheckoutCancelEvent) => void;
|
|
153
|
+
onReady?: (event: CheckoutReadyEvent) => void;
|
|
154
|
+
onConfirm?: (event: CheckoutConfirmEvent) => void;
|
|
155
|
+
onChange?: (event: CheckoutChangeEvent) => void;
|
|
96
156
|
}
|
|
97
157
|
|
|
98
158
|
interface RenderOptions {
|
|
@@ -123,9 +183,9 @@ declare class CheckoutError extends Error {
|
|
|
123
183
|
constructor(message: string);
|
|
124
184
|
}
|
|
125
185
|
|
|
126
|
-
type CreateCheckoutSessionParams = Omit<StripeConfig, 'publishableKey' | 'returnUrl'> & {
|
|
186
|
+
type CreateCheckoutSessionParams = Omit<StripeConfig, 'publishableKey' | 'returnUrl' | 'form'> & {
|
|
127
187
|
returnUrl: string;
|
|
128
188
|
};
|
|
129
189
|
declare function buildStripeCheckoutSessionBody(params: CreateCheckoutSessionParams): Record<string, unknown>;
|
|
130
190
|
|
|
131
|
-
export { type CheckoutCallbacks, type CheckoutCancelEvent, type CheckoutCompleteEvent, CheckoutError, type CheckoutErrorEvent, type CheckoutInstance, type CreateCheckoutSessionParams, type FastSpringConfig, type PaymentMethodType, type PaymentProvider, type ProviderConfigMap, type ProviderName, type RenderOptions, type StripeCheckoutTrial, type StripeConfig, buildStripeCheckoutSessionBody, initCheckout };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,8 @@ function buildStripeCheckoutSessionBody(params) {
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
...params.upgrade && { upgrade: params.upgrade },
|
|
37
|
-
...params.walletFirst && { wallet_first: params.walletFirst }
|
|
37
|
+
...params.walletFirst && { wallet_first: params.walletFirst },
|
|
38
|
+
...params.uiMode && { ui_mode: params.uiMode }
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
41
|
|
|
@@ -97,55 +98,209 @@ var StripeCheckoutService = class extends HttpService {
|
|
|
97
98
|
}
|
|
98
99
|
};
|
|
99
100
|
|
|
101
|
+
// src/providers/stripe/ui/embedded-page.ts
|
|
102
|
+
var StripeEmbeddedPageUi = class {
|
|
103
|
+
checkout = null;
|
|
104
|
+
async mount(stripe, container, host) {
|
|
105
|
+
try {
|
|
106
|
+
this.checkout = await stripe.createEmbeddedCheckoutPage({
|
|
107
|
+
fetchClientSecret: () => host.clientSecret(),
|
|
108
|
+
onComplete: () => host.succeeded()
|
|
109
|
+
});
|
|
110
|
+
} catch (err) {
|
|
111
|
+
host.renderFailed(err, { message: err instanceof Error ? err.message : void 0 });
|
|
112
|
+
if (err instanceof CheckoutError) throw err;
|
|
113
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
114
|
+
throw new CheckoutError(`Stripe checkout failed: ${detail}`);
|
|
115
|
+
}
|
|
116
|
+
this.checkout.mount(container);
|
|
117
|
+
}
|
|
118
|
+
destroy() {
|
|
119
|
+
this.checkout?.destroy();
|
|
120
|
+
this.checkout = null;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// src/providers/stripe/ui/form.ts
|
|
125
|
+
var CHECKOUT_FORM_BETA = "custom_checkout_payment_form_1";
|
|
126
|
+
var EXPRESS_CHECKOUT_SOURCE = "checkout-form-ece";
|
|
127
|
+
var StripeFormUi = class {
|
|
128
|
+
constructor(options = {}) {
|
|
129
|
+
this.options = options;
|
|
130
|
+
}
|
|
131
|
+
options;
|
|
132
|
+
loadOptions = { betas: [CHECKOUT_FORM_BETA] };
|
|
133
|
+
checkout = null;
|
|
134
|
+
form = null;
|
|
135
|
+
async mount(stripe, container, host) {
|
|
136
|
+
const { appearance, fonts, loader, layout, expressCheckout } = this.options;
|
|
137
|
+
const startedAt = Date.now();
|
|
138
|
+
try {
|
|
139
|
+
if (typeof stripe.initCheckoutFormSdk !== "function") {
|
|
140
|
+
throw new CheckoutError("Stripe has not granted this account access to Checkout Form");
|
|
141
|
+
}
|
|
142
|
+
this.checkout = stripe.initCheckoutFormSdk({
|
|
143
|
+
clientSecret: host.clientSecret(),
|
|
144
|
+
...appearance && { appearance },
|
|
145
|
+
...fonts?.length && { fonts },
|
|
146
|
+
...loader && { loader }
|
|
147
|
+
});
|
|
148
|
+
this.checkout.on("change", (session) => host.changed(fromSession(session)));
|
|
149
|
+
this.form = this.checkout.createForm({
|
|
150
|
+
...layout && { layout },
|
|
151
|
+
...expressCheckout && { expressCheckout }
|
|
152
|
+
});
|
|
153
|
+
this.form.on("ready", () => host.ready(Date.now() - startedAt));
|
|
154
|
+
this.form.on(
|
|
155
|
+
"loaderror",
|
|
156
|
+
(event) => host.renderFailed(event.error, { message: event.error.message })
|
|
157
|
+
);
|
|
158
|
+
this.form.on("change", (event) => host.changed(fromForm(event)));
|
|
159
|
+
this.form.on("cancel", () => host.cancelled());
|
|
160
|
+
this.form.mount(container);
|
|
161
|
+
const actions = await this.loadActions();
|
|
162
|
+
this.form.on("confirm", (event) => void this.confirm(actions, event, host));
|
|
163
|
+
} catch (err) {
|
|
164
|
+
host.renderFailed(err, { message: err instanceof Error ? err.message : void 0 });
|
|
165
|
+
if (err instanceof CheckoutError) throw err;
|
|
166
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
167
|
+
throw new CheckoutError(`Stripe checkout failed: ${detail}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
destroy() {
|
|
171
|
+
this.form?.destroy();
|
|
172
|
+
this.form = null;
|
|
173
|
+
this.checkout = null;
|
|
174
|
+
}
|
|
175
|
+
async loadActions() {
|
|
176
|
+
const result = await this.checkout.loadActions();
|
|
177
|
+
if (result.type !== "success") {
|
|
178
|
+
throw new CheckoutError(`Stripe checkout failed: ${result.error.message}`);
|
|
179
|
+
}
|
|
180
|
+
return result.actions;
|
|
181
|
+
}
|
|
182
|
+
async isFormValid(actions) {
|
|
183
|
+
try {
|
|
184
|
+
const validation = await actions.validateElements();
|
|
185
|
+
return validation.type !== "error";
|
|
186
|
+
} catch {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async confirm(actions, event, host) {
|
|
191
|
+
const express = event.source === EXPRESS_CHECKOUT_SOURCE;
|
|
192
|
+
const paymentMethodType = express ? void 0 : event.paymentMethodType ?? void 0;
|
|
193
|
+
try {
|
|
194
|
+
const attempted = express || await this.isFormValid(actions);
|
|
195
|
+
if (attempted) {
|
|
196
|
+
host.confirmed({ paymentMethodType, express });
|
|
197
|
+
}
|
|
198
|
+
const result = await actions.confirm({ formConfirmEvent: event, redirect: "if_required" });
|
|
199
|
+
if (result.type === "error") {
|
|
200
|
+
if (result.error.code === "paymentFailed") {
|
|
201
|
+
host.paymentFailed(result.error, {
|
|
202
|
+
declineCode: result.error.paymentFailed.declineCode,
|
|
203
|
+
message: result.error.message
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
host.succeeded(fromSession(result.session));
|
|
209
|
+
} catch (err) {
|
|
210
|
+
host.paymentFailed(err, { message: err instanceof Error ? err.message : void 0 });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
function fromSession(session) {
|
|
215
|
+
return {
|
|
216
|
+
email: session.email ?? void 0,
|
|
217
|
+
currency: session.currency,
|
|
218
|
+
amountTotal: session.total?.total?.minorUnitsAmount
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function fromForm(event) {
|
|
222
|
+
const { payment, customerDetails, adaptivePricing } = event.value;
|
|
223
|
+
return {
|
|
224
|
+
paymentMethodType: payment?.type,
|
|
225
|
+
email: customerDetails?.email || void 0,
|
|
226
|
+
currency: adaptivePricing?.currency,
|
|
227
|
+
complete: event.complete
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// src/providers/stripe/ui/index.ts
|
|
232
|
+
function createStripeCheckoutUi(config) {
|
|
233
|
+
switch (config.uiMode) {
|
|
234
|
+
case "form":
|
|
235
|
+
return new StripeFormUi(config.form);
|
|
236
|
+
default:
|
|
237
|
+
return new StripeEmbeddedPageUi();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
100
241
|
// src/providers/stripe/index.ts
|
|
101
242
|
var StripeProvider = class {
|
|
102
243
|
constructor(config, callbacks, baseUrl, headers) {
|
|
103
244
|
this.config = config;
|
|
104
245
|
this.callbacks = callbacks;
|
|
105
246
|
this.service = new StripeCheckoutService(baseUrl, headers);
|
|
247
|
+
this.ui = createStripeCheckoutUi(config);
|
|
106
248
|
}
|
|
107
249
|
config;
|
|
108
250
|
callbacks;
|
|
109
|
-
stripe = null;
|
|
110
|
-
embeddedCheckout = null;
|
|
111
251
|
service;
|
|
252
|
+
ui;
|
|
253
|
+
stripe = null;
|
|
254
|
+
mounted = false;
|
|
112
255
|
clientSecret = null;
|
|
256
|
+
snapshot = {};
|
|
113
257
|
async init() {
|
|
114
|
-
const stripe = await loadStripe(this.config.publishableKey);
|
|
258
|
+
const stripe = await loadStripe(this.config.publishableKey, this.ui.loadOptions);
|
|
115
259
|
if (!stripe) {
|
|
116
|
-
|
|
260
|
+
const error = new CheckoutError("Failed to load Stripe.js \u2014 verify your publishableKey");
|
|
261
|
+
this.emitError("init", error, { message: error.message });
|
|
262
|
+
throw error;
|
|
117
263
|
}
|
|
118
264
|
this.stripe = stripe;
|
|
119
265
|
}
|
|
120
|
-
async render(container,
|
|
266
|
+
async render(container, _options) {
|
|
121
267
|
if (!this.stripe) {
|
|
122
268
|
throw new CheckoutError("Provider not initialized \u2014 call init() before render()");
|
|
123
269
|
}
|
|
124
|
-
if (this.
|
|
270
|
+
if (this.mounted) {
|
|
125
271
|
throw new CheckoutError("Already rendered \u2014 call destroy() before rendering again");
|
|
126
272
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
fetchClientSecret: () => this.fetchClientSecret(),
|
|
130
|
-
onComplete: () => this.handleComplete(),
|
|
131
|
-
onAnalyticsEvent: (event) => console.log("[stripe analytics]", event.eventType, event)
|
|
132
|
-
});
|
|
133
|
-
} catch (err) {
|
|
134
|
-
this.callbacks.onError?.({ provider: "stripe", error: err });
|
|
135
|
-
if (err instanceof CheckoutError) throw err;
|
|
136
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
137
|
-
throw new CheckoutError(`Stripe checkout failed: ${detail}`);
|
|
138
|
-
}
|
|
139
|
-
this.embeddedCheckout.mount(container);
|
|
273
|
+
this.mounted = true;
|
|
274
|
+
await this.ui.mount(this.stripe, container, this.host());
|
|
140
275
|
}
|
|
141
276
|
async reset() {
|
|
142
277
|
this.destroy();
|
|
143
278
|
}
|
|
144
279
|
destroy() {
|
|
145
|
-
this.
|
|
146
|
-
this.
|
|
280
|
+
this.ui.destroy();
|
|
281
|
+
this.mounted = false;
|
|
282
|
+
this.snapshot = {};
|
|
147
283
|
}
|
|
148
|
-
|
|
284
|
+
host() {
|
|
285
|
+
return {
|
|
286
|
+
clientSecret: () => this.createSession(),
|
|
287
|
+
ready: (durationMs) => this.callbacks.onReady?.({ provider: "stripe", durationMs }),
|
|
288
|
+
changed: (patch) => this.merge(patch),
|
|
289
|
+
confirmed: ({ paymentMethodType, express }) => this.callbacks.onConfirm?.({
|
|
290
|
+
provider: "stripe",
|
|
291
|
+
paymentMethodType: paymentMethodType ?? this.snapshot.paymentMethodType,
|
|
292
|
+
express
|
|
293
|
+
}),
|
|
294
|
+
cancelled: () => this.callbacks.onCancel?.({
|
|
295
|
+
provider: "stripe",
|
|
296
|
+
paymentMethodType: this.snapshot.paymentMethodType
|
|
297
|
+
}),
|
|
298
|
+
renderFailed: (error, detail) => this.emitError("render", error, detail),
|
|
299
|
+
paymentFailed: (error, detail) => this.emitError("payment", error, detail),
|
|
300
|
+
succeeded: (outcome) => void this.emitComplete(outcome)
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
async createSession() {
|
|
149
304
|
const secret = await this.service.createCheckoutSession({
|
|
150
305
|
...this.config,
|
|
151
306
|
returnUrl: this.config.returnUrl ?? window.location.href
|
|
@@ -154,33 +309,74 @@ var StripeProvider = class {
|
|
|
154
309
|
return secret;
|
|
155
310
|
}
|
|
156
311
|
// Format: cs_test_{sessionId}_secret_{random}
|
|
157
|
-
|
|
158
|
-
if (!clientSecret)
|
|
159
|
-
|
|
160
|
-
return idx !== -1 ? clientSecret.slice(0, idx) : null;
|
|
161
|
-
}
|
|
162
|
-
async handleComplete() {
|
|
163
|
-
const sessionId = this.parseSessionId(this.clientSecret);
|
|
164
|
-
if (!sessionId) {
|
|
165
|
-
this.callbacks.onComplete?.({ provider: "stripe" });
|
|
166
|
-
return;
|
|
312
|
+
sessionId() {
|
|
313
|
+
if (!this.clientSecret) {
|
|
314
|
+
return null;
|
|
167
315
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
email: session.email ?? void 0
|
|
178
|
-
});
|
|
179
|
-
} catch {
|
|
180
|
-
this.callbacks.onComplete?.({ provider: "stripe" });
|
|
316
|
+
const idx = this.clientSecret.indexOf("_secret_");
|
|
317
|
+
return idx !== -1 ? this.clientSecret.slice(0, idx) : null;
|
|
318
|
+
}
|
|
319
|
+
merge(patch) {
|
|
320
|
+
const next = { ...this.snapshot };
|
|
321
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
322
|
+
if (value !== void 0) {
|
|
323
|
+
Object.assign(next, { [key]: value });
|
|
324
|
+
}
|
|
181
325
|
}
|
|
326
|
+
this.snapshot = next;
|
|
327
|
+
this.callbacks.onChange?.({ provider: "stripe", ...next });
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Reads the session back for the ids only the backend can resolve, falling
|
|
331
|
+
* back to what the client already knows so a paid customer is never
|
|
332
|
+
* reported as a failure.
|
|
333
|
+
*/
|
|
334
|
+
async emitComplete(outcome) {
|
|
335
|
+
const sessionId = this.sessionId();
|
|
336
|
+
const fallback = {
|
|
337
|
+
amount_total: outcome?.amountTotal ?? null,
|
|
338
|
+
currency: outcome?.currency ?? null,
|
|
339
|
+
email: outcome?.email ?? null
|
|
340
|
+
};
|
|
341
|
+
let session = {};
|
|
342
|
+
if (sessionId) {
|
|
343
|
+
try {
|
|
344
|
+
session = definedOnly(await this.service.getSession(sessionId, this.config.accountId));
|
|
345
|
+
} catch {
|
|
346
|
+
session = {};
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
this.callbacks.onComplete?.({
|
|
350
|
+
provider: "stripe",
|
|
351
|
+
paymentMethodType: this.snapshot.paymentMethodType,
|
|
352
|
+
...toCompleteFields({ ...fallback, ...session })
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
emitError(phase, error, detail) {
|
|
356
|
+
this.callbacks.onError?.({
|
|
357
|
+
provider: "stripe",
|
|
358
|
+
phase,
|
|
359
|
+
paymentMethodType: this.snapshot.paymentMethodType,
|
|
360
|
+
error,
|
|
361
|
+
...detail
|
|
362
|
+
});
|
|
182
363
|
}
|
|
183
364
|
};
|
|
365
|
+
function definedOnly(session) {
|
|
366
|
+
return Object.fromEntries(
|
|
367
|
+
Object.entries(session).filter(([, value]) => value !== null && value !== void 0)
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
function toCompleteFields(session) {
|
|
371
|
+
return {
|
|
372
|
+
customerId: session.customer_id ?? void 0,
|
|
373
|
+
subscriptionId: session.subscription_id ?? void 0,
|
|
374
|
+
invoiceId: session.invoice_id ?? void 0,
|
|
375
|
+
amountPaid: session.amount_total ?? void 0,
|
|
376
|
+
currency: session.currency ?? void 0,
|
|
377
|
+
email: session.email ?? void 0
|
|
378
|
+
};
|
|
379
|
+
}
|
|
184
380
|
|
|
185
381
|
// src/providers/fastspring/index.ts
|
|
186
382
|
var FastSpringProvider = class {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@funnelfox/payments-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dev": "tsup --watch"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@stripe/stripe-js": "^9.
|
|
24
|
+
"@stripe/stripe-js": "^9.14.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"tsup": "^8.4.0",
|