@funnelfox/payments-sdk 0.1.2-beta.1 → 0.1.2-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 CHANGED
@@ -33,53 +33,187 @@ var CheckoutError = class extends Error {
33
33
  }
34
34
  };
35
35
 
36
- // src/providers/fastspring/index.ts
37
- var FastSpringProvider = class {
38
- constructor(config, callbacks) {
36
+ // src/providers/stripe/index.ts
37
+ var import_stripe_js = require("@stripe/stripe-js");
38
+
39
+ // src/http.ts
40
+ var HttpService = class {
41
+ constructor(baseUrl, headers = {}) {
42
+ this.baseUrl = baseUrl;
43
+ this.headers = headers;
44
+ this.baseUrl = baseUrl.replace(/\/$/, "");
45
+ }
46
+ baseUrl;
47
+ headers;
48
+ async post(path, body) {
49
+ return this.request("POST", path, body);
50
+ }
51
+ async get(path) {
52
+ return this.request("GET", path);
53
+ }
54
+ async request(method, path, body) {
55
+ const url = `${this.baseUrl}${path}`;
56
+ const headers = new Headers(this.headers);
57
+ headers.set("Content-Type", "application/json");
58
+ let response;
59
+ try {
60
+ response = await fetch(url, {
61
+ method,
62
+ headers,
63
+ body: body !== void 0 ? JSON.stringify(body) : void 0
64
+ });
65
+ } catch (err) {
66
+ throw new CheckoutError(`Network error: ${err instanceof Error ? err.message : String(err)}`);
67
+ }
68
+ if (!response.ok) {
69
+ const text = await response.text().catch(() => response.statusText);
70
+ throw new CheckoutError(`Backend error ${response.status}: ${text}`);
71
+ }
72
+ return response.json();
73
+ }
74
+ };
75
+
76
+ // src/providers/stripe/service.ts
77
+ var StripeCheckoutService = class extends HttpService {
78
+ constructor(baseUrl, headers) {
79
+ super(baseUrl, headers);
80
+ }
81
+ async getSession(sessionId, account) {
82
+ const query = account ? `?account=${encodeURIComponent(account)}` : "";
83
+ return this.get(`/stripe/session/${sessionId}${query}`);
84
+ }
85
+ async createCheckoutSession(params) {
86
+ const query = `?account=${encodeURIComponent(params.accountId)}`;
87
+ const data = await this.post(`/stripe/purchase${query}`, {
88
+ price_id: params.priceId,
89
+ managed: params.managed,
90
+ customer_id: params.customerId,
91
+ customer: params.customer,
92
+ return_url: params.returnUrl
93
+ });
94
+ if (!data.client_secret) {
95
+ throw new CheckoutError("Backend returned no client_secret");
96
+ }
97
+ return data.client_secret;
98
+ }
99
+ };
100
+
101
+ // src/providers/stripe/index.ts
102
+ var StripeProvider = class {
103
+ constructor(config, callbacks, baseUrl, headers) {
39
104
  this.config = config;
40
105
  this.callbacks = callbacks;
106
+ this.service = new StripeCheckoutService(baseUrl, headers);
41
107
  }
42
108
  config;
43
109
  callbacks;
110
+ stripe = null;
111
+ embeddedCheckout = null;
112
+ service;
113
+ clientSecret = null;
44
114
  async init() {
115
+ const stripe = await (0, import_stripe_js.loadStripe)(this.config.publishableKey);
116
+ if (!stripe) {
117
+ throw new CheckoutError("Failed to load Stripe.js \u2014 verify your publishableKey");
118
+ }
119
+ this.stripe = stripe;
45
120
  }
46
- render(container, options) {
47
- container.innerHTML = `<div>Hello World from FastSpring (${options.paymentMethodType})</div>`;
121
+ async render(container, options) {
122
+ if (!this.stripe) {
123
+ throw new CheckoutError("Provider not initialized \u2014 call init() before render()");
124
+ }
125
+ if (this.embeddedCheckout) {
126
+ throw new CheckoutError("Already rendered \u2014 call destroy() before rendering again");
127
+ }
128
+ try {
129
+ this.embeddedCheckout = await this.stripe.createEmbeddedCheckoutPage({
130
+ fetchClientSecret: () => this.fetchClientSecret(),
131
+ onComplete: () => this.handleComplete(),
132
+ onAnalyticsEvent: (event) => console.log("[stripe analytics]", event.eventType, event)
133
+ });
134
+ } catch (err) {
135
+ this.callbacks.onError?.({ provider: "stripe", error: err });
136
+ if (err instanceof CheckoutError) throw err;
137
+ const detail = err instanceof Error ? err.message : String(err);
138
+ throw new CheckoutError(`Stripe checkout failed: ${detail}`);
139
+ }
140
+ this.embeddedCheckout.mount(container);
48
141
  }
49
- reset() {
50
- window.fastspring?.builder?.reset();
142
+ async reset() {
143
+ this.destroy();
51
144
  }
52
145
  destroy() {
53
- this.reset();
146
+ this.embeddedCheckout?.destroy();
147
+ this.embeddedCheckout = null;
148
+ }
149
+ async fetchClientSecret() {
150
+ const secret = await this.service.createCheckoutSession({
151
+ ...this.config,
152
+ returnUrl: this.config.returnUrl ?? window.location.href
153
+ });
154
+ this.clientSecret = secret;
155
+ return secret;
156
+ }
157
+ // Format: cs_test_{sessionId}_secret_{random}
158
+ parseSessionId(clientSecret) {
159
+ if (!clientSecret) return null;
160
+ const idx = clientSecret.indexOf("_secret_");
161
+ return idx !== -1 ? clientSecret.slice(0, idx) : null;
162
+ }
163
+ async handleComplete() {
164
+ const sessionId = this.parseSessionId(this.clientSecret);
165
+ if (!sessionId) {
166
+ this.callbacks.onComplete?.({ provider: "stripe" });
167
+ return;
168
+ }
169
+ try {
170
+ const session = await this.service.getSession(sessionId, this.config.accountId);
171
+ this.callbacks.onComplete?.({
172
+ provider: "stripe",
173
+ customerId: session.customer_id ?? void 0,
174
+ subscriptionId: session.subscription_id ?? void 0,
175
+ invoiceId: session.invoice_id ?? void 0,
176
+ amountPaid: session.amount_total ?? void 0,
177
+ currency: session.currency ?? void 0
178
+ });
179
+ } catch {
180
+ this.callbacks.onComplete?.({ provider: "stripe" });
181
+ }
54
182
  }
55
183
  };
56
184
 
57
- // src/providers/stripe/index.ts
58
- var StripeProvider = class {
59
- constructor(config, callbacks) {
185
+ // src/providers/fastspring/index.ts
186
+ var FastSpringProvider = class {
187
+ constructor(config, callbacks, baseUrl, headers = {}) {
60
188
  this.config = config;
61
189
  this.callbacks = callbacks;
190
+ this.baseUrl = baseUrl;
191
+ this.headers = headers;
62
192
  }
63
193
  config;
64
194
  callbacks;
195
+ baseUrl;
196
+ headers;
65
197
  async init() {
66
198
  }
67
- render(container, options) {
68
- container.innerHTML = `<div>Hello World from Stripe (${options.paymentMethodType})</div>`;
199
+ async render(container, options) {
200
+ container.innerHTML = `<div>Hello World from FastSpring [${options?.paymentMethodTypes?.join(", ")}]</div>`;
69
201
  }
70
- reset() {
202
+ async reset() {
203
+ window.fastspring?.builder?.reset();
71
204
  }
72
205
  destroy() {
206
+ this.reset();
73
207
  }
74
208
  };
75
209
 
76
210
  // src/providers/registry.ts
77
- function createProvider(provider, config, callbacks) {
211
+ function createProvider(provider, config, callbacks, baseUrl, headers) {
78
212
  switch (provider) {
79
213
  case "stripe":
80
- return new StripeProvider(config, callbacks);
214
+ return new StripeProvider(config, callbacks, baseUrl, headers);
81
215
  case "fastspring":
82
- return new FastSpringProvider(config, callbacks);
216
+ return new FastSpringProvider(config, callbacks, baseUrl, headers);
83
217
  default:
84
218
  throw new CheckoutError(`Unknown provider: ${provider}`);
85
219
  }
@@ -91,25 +225,35 @@ var CheckoutInstance = class {
91
225
  this.provider = provider;
92
226
  }
93
227
  provider;
94
- render(container, options) {
228
+ container = null;
229
+ options;
230
+ async render(container, options) {
95
231
  const el = typeof container === "string" ? document.querySelector(container) : container;
96
232
  if (!el) {
97
233
  throw new CheckoutError(`Container not found: ${container}`);
98
234
  }
99
- this.provider.render(el, options);
235
+ this.container = el;
236
+ this.options = options;
237
+ await this.provider.render(el, options);
100
238
  }
101
- reset() {
102
- this.provider.reset();
239
+ async reset() {
240
+ if (!this.container) {
241
+ throw new CheckoutError("Cannot reset: render() has not been called");
242
+ }
243
+ await this.provider.reset();
244
+ await this.provider.render(this.container, this.options);
103
245
  }
104
246
  destroy() {
105
247
  this.provider.destroy();
248
+ this.container = null;
249
+ this.options = void 0;
106
250
  }
107
251
  };
108
252
 
109
253
  // src/checkout.ts
110
254
  async function initCheckout(options) {
111
- const { provider: providerName, config, ...callbacks } = options;
112
- const provider = createProvider(providerName, config, callbacks);
255
+ const { provider: providerName, config, baseUrl, headers = {}, ...callbacks } = options;
256
+ const provider = createProvider(providerName, config, callbacks, baseUrl, headers);
113
257
  await provider.init();
114
258
  return new CheckoutInstance(provider);
115
259
  }
package/dist/index.d.cts CHANGED
@@ -1,39 +1,28 @@
1
1
  type PaymentMethodType = 'card' | 'google_pay' | 'apple_pay';
2
2
 
3
- interface CheckoutCompleteEvent {
4
- paymentMethodType: PaymentMethodType;
5
- orderId: string;
6
- }
7
- interface CheckoutErrorEvent {
8
- paymentMethodType: PaymentMethodType;
9
- error: unknown;
10
- }
11
- interface CheckoutCancelEvent {
12
- paymentMethodType: PaymentMethodType;
13
- }
14
-
15
- interface CheckoutCallbacks {
16
- onComplete?: (event: CheckoutCompleteEvent) => void;
17
- onError?: (event: CheckoutErrorEvent) => void;
18
- onCancel?: (event: CheckoutCancelEvent) => void;
3
+ interface StripeCustomer {
4
+ email?: string;
5
+ phone?: string;
6
+ address?: {
7
+ country?: string;
8
+ postal_code?: string;
9
+ };
19
10
  }
20
-
21
- interface PaymentProvider {
22
- init(): Promise<void>;
23
- render(container: HTMLElement, options: {
24
- paymentMethodType: PaymentMethodType;
25
- }): void;
26
- reset(): void;
27
- destroy(): void;
28
- }
29
-
30
- interface RenderOptions {
31
- paymentMethodType: PaymentMethodType;
32
- }
33
- interface CheckoutInstance {
34
- render(container: string | HTMLElement, options: RenderOptions): void;
35
- reset(): void;
36
- destroy(): void;
11
+ interface StripeConfig {
12
+ /** Stripe publishable key (pk_test_... or pk_live_...) */
13
+ publishableKey: string;
14
+ /** Stripe Price ID for the product being sold */
15
+ priceId: string;
16
+ /** Whether to use Stripe Managed Payments (embedded checkout, no upfront payment method needed) */
17
+ managed: boolean;
18
+ /** Stripe Connect account ID (acct_...) — required when price belongs to a connected account */
19
+ accountId: string;
20
+ /** Existing Stripe customer ID — if provided, a new customer will not be created */
21
+ customerId?: string;
22
+ /** New customer details — required when customerId is not provided */
23
+ customer?: StripeCustomer;
24
+ /** URL to redirect to after payment completes. Defaults to window.location.href for embedded checkout. */
25
+ returnUrl?: string;
37
26
  }
38
27
 
39
28
  interface FastSpringConfig {
@@ -55,19 +44,59 @@ declare global {
55
44
  }
56
45
  }
57
46
 
58
- interface StripeConfig {
59
- publishableKey: string;
60
- }
61
-
62
47
  type ProviderName = 'stripe' | 'fastspring';
63
48
  type ProviderConfigMap = {
64
49
  stripe: StripeConfig;
65
50
  fastspring: FastSpringConfig;
66
51
  };
67
52
 
53
+ interface CheckoutCompleteEvent {
54
+ provider: ProviderName;
55
+ paymentMethodType?: PaymentMethodType;
56
+ orderId?: string;
57
+ customerId?: string;
58
+ subscriptionId?: string;
59
+ invoiceId?: string;
60
+ amountPaid?: number;
61
+ currency?: string;
62
+ }
63
+ interface CheckoutErrorEvent {
64
+ provider: ProviderName;
65
+ paymentMethodType?: PaymentMethodType;
66
+ error: unknown;
67
+ }
68
+ interface CheckoutCancelEvent {
69
+ provider: ProviderName;
70
+ paymentMethodType?: PaymentMethodType;
71
+ }
72
+
73
+ interface CheckoutCallbacks {
74
+ onComplete?: (event: CheckoutCompleteEvent) => void;
75
+ onError?: (event: CheckoutErrorEvent) => void;
76
+ onCancel?: (event: CheckoutCancelEvent) => void;
77
+ }
78
+
79
+ interface RenderOptions {
80
+ paymentMethodTypes?: PaymentMethodType[];
81
+ }
82
+ interface CheckoutInstance {
83
+ render(container: string | HTMLElement, options?: RenderOptions): Promise<void>;
84
+ reset(): Promise<void>;
85
+ destroy(): void;
86
+ }
87
+
88
+ interface PaymentProvider {
89
+ init(): Promise<void>;
90
+ render(container: HTMLElement, options?: RenderOptions): Promise<void>;
91
+ reset(): Promise<void>;
92
+ destroy(): void;
93
+ }
94
+
68
95
  type InitCheckoutConfig<T extends ProviderName> = {
69
96
  provider: T;
70
97
  config: ProviderConfigMap[T];
98
+ baseUrl: string;
99
+ headers?: HeadersInit;
71
100
  } & CheckoutCallbacks;
72
101
  declare function initCheckout<T extends ProviderName>(options: InitCheckoutConfig<T>): Promise<CheckoutInstance>;
73
102
 
package/dist/index.d.ts CHANGED
@@ -1,39 +1,28 @@
1
1
  type PaymentMethodType = 'card' | 'google_pay' | 'apple_pay';
2
2
 
3
- interface CheckoutCompleteEvent {
4
- paymentMethodType: PaymentMethodType;
5
- orderId: string;
6
- }
7
- interface CheckoutErrorEvent {
8
- paymentMethodType: PaymentMethodType;
9
- error: unknown;
10
- }
11
- interface CheckoutCancelEvent {
12
- paymentMethodType: PaymentMethodType;
13
- }
14
-
15
- interface CheckoutCallbacks {
16
- onComplete?: (event: CheckoutCompleteEvent) => void;
17
- onError?: (event: CheckoutErrorEvent) => void;
18
- onCancel?: (event: CheckoutCancelEvent) => void;
3
+ interface StripeCustomer {
4
+ email?: string;
5
+ phone?: string;
6
+ address?: {
7
+ country?: string;
8
+ postal_code?: string;
9
+ };
19
10
  }
20
-
21
- interface PaymentProvider {
22
- init(): Promise<void>;
23
- render(container: HTMLElement, options: {
24
- paymentMethodType: PaymentMethodType;
25
- }): void;
26
- reset(): void;
27
- destroy(): void;
28
- }
29
-
30
- interface RenderOptions {
31
- paymentMethodType: PaymentMethodType;
32
- }
33
- interface CheckoutInstance {
34
- render(container: string | HTMLElement, options: RenderOptions): void;
35
- reset(): void;
36
- destroy(): void;
11
+ interface StripeConfig {
12
+ /** Stripe publishable key (pk_test_... or pk_live_...) */
13
+ publishableKey: string;
14
+ /** Stripe Price ID for the product being sold */
15
+ priceId: string;
16
+ /** Whether to use Stripe Managed Payments (embedded checkout, no upfront payment method needed) */
17
+ managed: boolean;
18
+ /** Stripe Connect account ID (acct_...) — required when price belongs to a connected account */
19
+ accountId: string;
20
+ /** Existing Stripe customer ID — if provided, a new customer will not be created */
21
+ customerId?: string;
22
+ /** New customer details — required when customerId is not provided */
23
+ customer?: StripeCustomer;
24
+ /** URL to redirect to after payment completes. Defaults to window.location.href for embedded checkout. */
25
+ returnUrl?: string;
37
26
  }
38
27
 
39
28
  interface FastSpringConfig {
@@ -55,19 +44,59 @@ declare global {
55
44
  }
56
45
  }
57
46
 
58
- interface StripeConfig {
59
- publishableKey: string;
60
- }
61
-
62
47
  type ProviderName = 'stripe' | 'fastspring';
63
48
  type ProviderConfigMap = {
64
49
  stripe: StripeConfig;
65
50
  fastspring: FastSpringConfig;
66
51
  };
67
52
 
53
+ interface CheckoutCompleteEvent {
54
+ provider: ProviderName;
55
+ paymentMethodType?: PaymentMethodType;
56
+ orderId?: string;
57
+ customerId?: string;
58
+ subscriptionId?: string;
59
+ invoiceId?: string;
60
+ amountPaid?: number;
61
+ currency?: string;
62
+ }
63
+ interface CheckoutErrorEvent {
64
+ provider: ProviderName;
65
+ paymentMethodType?: PaymentMethodType;
66
+ error: unknown;
67
+ }
68
+ interface CheckoutCancelEvent {
69
+ provider: ProviderName;
70
+ paymentMethodType?: PaymentMethodType;
71
+ }
72
+
73
+ interface CheckoutCallbacks {
74
+ onComplete?: (event: CheckoutCompleteEvent) => void;
75
+ onError?: (event: CheckoutErrorEvent) => void;
76
+ onCancel?: (event: CheckoutCancelEvent) => void;
77
+ }
78
+
79
+ interface RenderOptions {
80
+ paymentMethodTypes?: PaymentMethodType[];
81
+ }
82
+ interface CheckoutInstance {
83
+ render(container: string | HTMLElement, options?: RenderOptions): Promise<void>;
84
+ reset(): Promise<void>;
85
+ destroy(): void;
86
+ }
87
+
88
+ interface PaymentProvider {
89
+ init(): Promise<void>;
90
+ render(container: HTMLElement, options?: RenderOptions): Promise<void>;
91
+ reset(): Promise<void>;
92
+ destroy(): void;
93
+ }
94
+
68
95
  type InitCheckoutConfig<T extends ProviderName> = {
69
96
  provider: T;
70
97
  config: ProviderConfigMap[T];
98
+ baseUrl: string;
99
+ headers?: HeadersInit;
71
100
  } & CheckoutCallbacks;
72
101
  declare function initCheckout<T extends ProviderName>(options: InitCheckoutConfig<T>): Promise<CheckoutInstance>;
73
102
 
package/dist/index.js CHANGED
@@ -6,53 +6,187 @@ var CheckoutError = class extends Error {
6
6
  }
7
7
  };
8
8
 
9
- // src/providers/fastspring/index.ts
10
- var FastSpringProvider = class {
11
- constructor(config, callbacks) {
9
+ // src/providers/stripe/index.ts
10
+ import { loadStripe } from "@stripe/stripe-js";
11
+
12
+ // src/http.ts
13
+ var HttpService = class {
14
+ constructor(baseUrl, headers = {}) {
15
+ this.baseUrl = baseUrl;
16
+ this.headers = headers;
17
+ this.baseUrl = baseUrl.replace(/\/$/, "");
18
+ }
19
+ baseUrl;
20
+ headers;
21
+ async post(path, body) {
22
+ return this.request("POST", path, body);
23
+ }
24
+ async get(path) {
25
+ return this.request("GET", path);
26
+ }
27
+ async request(method, path, body) {
28
+ const url = `${this.baseUrl}${path}`;
29
+ const headers = new Headers(this.headers);
30
+ headers.set("Content-Type", "application/json");
31
+ let response;
32
+ try {
33
+ response = await fetch(url, {
34
+ method,
35
+ headers,
36
+ body: body !== void 0 ? JSON.stringify(body) : void 0
37
+ });
38
+ } catch (err) {
39
+ throw new CheckoutError(`Network error: ${err instanceof Error ? err.message : String(err)}`);
40
+ }
41
+ if (!response.ok) {
42
+ const text = await response.text().catch(() => response.statusText);
43
+ throw new CheckoutError(`Backend error ${response.status}: ${text}`);
44
+ }
45
+ return response.json();
46
+ }
47
+ };
48
+
49
+ // src/providers/stripe/service.ts
50
+ var StripeCheckoutService = class extends HttpService {
51
+ constructor(baseUrl, headers) {
52
+ super(baseUrl, headers);
53
+ }
54
+ async getSession(sessionId, account) {
55
+ const query = account ? `?account=${encodeURIComponent(account)}` : "";
56
+ return this.get(`/stripe/session/${sessionId}${query}`);
57
+ }
58
+ async createCheckoutSession(params) {
59
+ const query = `?account=${encodeURIComponent(params.accountId)}`;
60
+ const data = await this.post(`/stripe/purchase${query}`, {
61
+ price_id: params.priceId,
62
+ managed: params.managed,
63
+ customer_id: params.customerId,
64
+ customer: params.customer,
65
+ return_url: params.returnUrl
66
+ });
67
+ if (!data.client_secret) {
68
+ throw new CheckoutError("Backend returned no client_secret");
69
+ }
70
+ return data.client_secret;
71
+ }
72
+ };
73
+
74
+ // src/providers/stripe/index.ts
75
+ var StripeProvider = class {
76
+ constructor(config, callbacks, baseUrl, headers) {
12
77
  this.config = config;
13
78
  this.callbacks = callbacks;
79
+ this.service = new StripeCheckoutService(baseUrl, headers);
14
80
  }
15
81
  config;
16
82
  callbacks;
83
+ stripe = null;
84
+ embeddedCheckout = null;
85
+ service;
86
+ clientSecret = null;
17
87
  async init() {
88
+ const stripe = await loadStripe(this.config.publishableKey);
89
+ if (!stripe) {
90
+ throw new CheckoutError("Failed to load Stripe.js \u2014 verify your publishableKey");
91
+ }
92
+ this.stripe = stripe;
18
93
  }
19
- render(container, options) {
20
- container.innerHTML = `<div>Hello World from FastSpring (${options.paymentMethodType})</div>`;
94
+ async render(container, options) {
95
+ if (!this.stripe) {
96
+ throw new CheckoutError("Provider not initialized \u2014 call init() before render()");
97
+ }
98
+ if (this.embeddedCheckout) {
99
+ throw new CheckoutError("Already rendered \u2014 call destroy() before rendering again");
100
+ }
101
+ try {
102
+ this.embeddedCheckout = await this.stripe.createEmbeddedCheckoutPage({
103
+ fetchClientSecret: () => this.fetchClientSecret(),
104
+ onComplete: () => this.handleComplete(),
105
+ onAnalyticsEvent: (event) => console.log("[stripe analytics]", event.eventType, event)
106
+ });
107
+ } catch (err) {
108
+ this.callbacks.onError?.({ provider: "stripe", error: err });
109
+ if (err instanceof CheckoutError) throw err;
110
+ const detail = err instanceof Error ? err.message : String(err);
111
+ throw new CheckoutError(`Stripe checkout failed: ${detail}`);
112
+ }
113
+ this.embeddedCheckout.mount(container);
21
114
  }
22
- reset() {
23
- window.fastspring?.builder?.reset();
115
+ async reset() {
116
+ this.destroy();
24
117
  }
25
118
  destroy() {
26
- this.reset();
119
+ this.embeddedCheckout?.destroy();
120
+ this.embeddedCheckout = null;
121
+ }
122
+ async fetchClientSecret() {
123
+ const secret = await this.service.createCheckoutSession({
124
+ ...this.config,
125
+ returnUrl: this.config.returnUrl ?? window.location.href
126
+ });
127
+ this.clientSecret = secret;
128
+ return secret;
129
+ }
130
+ // Format: cs_test_{sessionId}_secret_{random}
131
+ parseSessionId(clientSecret) {
132
+ if (!clientSecret) return null;
133
+ const idx = clientSecret.indexOf("_secret_");
134
+ return idx !== -1 ? clientSecret.slice(0, idx) : null;
135
+ }
136
+ async handleComplete() {
137
+ const sessionId = this.parseSessionId(this.clientSecret);
138
+ if (!sessionId) {
139
+ this.callbacks.onComplete?.({ provider: "stripe" });
140
+ return;
141
+ }
142
+ try {
143
+ const session = await this.service.getSession(sessionId, this.config.accountId);
144
+ this.callbacks.onComplete?.({
145
+ provider: "stripe",
146
+ customerId: session.customer_id ?? void 0,
147
+ subscriptionId: session.subscription_id ?? void 0,
148
+ invoiceId: session.invoice_id ?? void 0,
149
+ amountPaid: session.amount_total ?? void 0,
150
+ currency: session.currency ?? void 0
151
+ });
152
+ } catch {
153
+ this.callbacks.onComplete?.({ provider: "stripe" });
154
+ }
27
155
  }
28
156
  };
29
157
 
30
- // src/providers/stripe/index.ts
31
- var StripeProvider = class {
32
- constructor(config, callbacks) {
158
+ // src/providers/fastspring/index.ts
159
+ var FastSpringProvider = class {
160
+ constructor(config, callbacks, baseUrl, headers = {}) {
33
161
  this.config = config;
34
162
  this.callbacks = callbacks;
163
+ this.baseUrl = baseUrl;
164
+ this.headers = headers;
35
165
  }
36
166
  config;
37
167
  callbacks;
168
+ baseUrl;
169
+ headers;
38
170
  async init() {
39
171
  }
40
- render(container, options) {
41
- container.innerHTML = `<div>Hello World from Stripe (${options.paymentMethodType})</div>`;
172
+ async render(container, options) {
173
+ container.innerHTML = `<div>Hello World from FastSpring [${options?.paymentMethodTypes?.join(", ")}]</div>`;
42
174
  }
43
- reset() {
175
+ async reset() {
176
+ window.fastspring?.builder?.reset();
44
177
  }
45
178
  destroy() {
179
+ this.reset();
46
180
  }
47
181
  };
48
182
 
49
183
  // src/providers/registry.ts
50
- function createProvider(provider, config, callbacks) {
184
+ function createProvider(provider, config, callbacks, baseUrl, headers) {
51
185
  switch (provider) {
52
186
  case "stripe":
53
- return new StripeProvider(config, callbacks);
187
+ return new StripeProvider(config, callbacks, baseUrl, headers);
54
188
  case "fastspring":
55
- return new FastSpringProvider(config, callbacks);
189
+ return new FastSpringProvider(config, callbacks, baseUrl, headers);
56
190
  default:
57
191
  throw new CheckoutError(`Unknown provider: ${provider}`);
58
192
  }
@@ -64,25 +198,35 @@ var CheckoutInstance = class {
64
198
  this.provider = provider;
65
199
  }
66
200
  provider;
67
- render(container, options) {
201
+ container = null;
202
+ options;
203
+ async render(container, options) {
68
204
  const el = typeof container === "string" ? document.querySelector(container) : container;
69
205
  if (!el) {
70
206
  throw new CheckoutError(`Container not found: ${container}`);
71
207
  }
72
- this.provider.render(el, options);
208
+ this.container = el;
209
+ this.options = options;
210
+ await this.provider.render(el, options);
73
211
  }
74
- reset() {
75
- this.provider.reset();
212
+ async reset() {
213
+ if (!this.container) {
214
+ throw new CheckoutError("Cannot reset: render() has not been called");
215
+ }
216
+ await this.provider.reset();
217
+ await this.provider.render(this.container, this.options);
76
218
  }
77
219
  destroy() {
78
220
  this.provider.destroy();
221
+ this.container = null;
222
+ this.options = void 0;
79
223
  }
80
224
  };
81
225
 
82
226
  // src/checkout.ts
83
227
  async function initCheckout(options) {
84
- const { provider: providerName, config, ...callbacks } = options;
85
- const provider = createProvider(providerName, config, callbacks);
228
+ const { provider: providerName, config, baseUrl, headers = {}, ...callbacks } = options;
229
+ const provider = createProvider(providerName, config, callbacks, baseUrl, headers);
86
230
  await provider.init();
87
231
  return new CheckoutInstance(provider);
88
232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funnelfox/payments-sdk",
3
- "version": "0.1.2-beta.1",
3
+ "version": "0.1.2-beta.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -20,6 +20,9 @@
20
20
  "build": "tsup",
21
21
  "dev": "tsup --watch"
22
22
  },
23
+ "dependencies": {
24
+ "@stripe/stripe-js": "^9.1.0"
25
+ },
23
26
  "devDependencies": {
24
27
  "tsup": "^8.4.0",
25
28
  "typescript": "^5.8.0"