tf-checkout-react-native 2.0.0-beta.14 → 2.0.0-beta.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tf-checkout-react-native",
3
- "version": "2.0.0-beta.14",
3
+ "version": "2.0.0-beta.15",
4
4
  "description": "TheTicketFairy ReactNative Checkout library",
5
5
  "homepage": "https://github.com/theticketfairy/tf-shared-libraries#readme",
6
6
  "author": "The Ticket Fairy",
@@ -37,10 +37,12 @@
37
37
  "!**/.*",
38
38
  "!scripts/verify-wallet-context.cjs",
39
39
  "!scripts/verify-provider-uri.cjs",
40
- "!scripts/verify-native-textarea.cjs"
40
+ "!scripts/verify-native-textarea.cjs",
41
+ "!scripts/verify-frozen-select.cjs",
42
+ "!scripts/verify-payment-sheet.cjs"
41
43
  ],
42
44
  "scripts": {
43
- "test": "node scripts/verify-discussion-support.cjs && node scripts/verify-wallet-context.cjs && node scripts/verify-provider-uri.cjs && node scripts/verify-native-textarea.cjs && jest --passWithNoTests",
45
+ "test": "node scripts/verify-discussion-support.cjs && node scripts/verify-wallet-context.cjs && node scripts/verify-provider-uri.cjs && node scripts/verify-native-textarea.cjs && node scripts/verify-frozen-select.cjs && node scripts/verify-payment-sheet.cjs && jest --passWithNoTests",
44
46
  "typecheck": "tsc -p tsconfig.build.json",
45
47
  "lint": "eslint \"**/*.{js,ts,tsx}\"",
46
48
  "lint:fix": "eslint \"**/*.{js,ts,tsx}\" --fix",
package/src/confirmer.ts CHANGED
@@ -21,6 +21,9 @@ import {
21
21
  createPaymentMethod,
22
22
  handleNextAction,
23
23
  initStripe,
24
+ initPaymentSheet,
25
+ presentPaymentSheet,
26
+ LinkDisplay,
24
27
  PlatformPay,
25
28
  retrievePaymentIntent,
26
29
  type BillingDetails,
@@ -35,7 +38,30 @@ import {
35
38
  type CheckoutPorts,
36
39
  type NativeStripeErrorLike,
37
40
  type PaymentConfirmer,
41
+ type CardClaimStep,
42
+ type StripeCardPaymentContext,
43
+ stripeElementsPaymentContext,
38
44
  } from 'tf-checkout-shared'
45
+ import {
46
+ createPaymentSheetConfirmation,
47
+ NATIVE_SHEET_CARD_FIELD_REQUIRED,
48
+ NATIVE_SHEET_REVIEW_REQUIRED,
49
+ } from './paymentSheet'
50
+
51
+ export interface NativePaymentSheetOptions {
52
+ merchantDisplayName: string
53
+ /** Must match the host's registered scheme and Stripe callback handler. */
54
+ returnURL: string
55
+ }
56
+
57
+ export interface NativeStripeConfirmer extends PaymentConfirmer {
58
+ createPaymentSheetSession(options: NativePaymentSheetOptions): {
59
+ confirmer: PaymentConfirmer
60
+ cardFieldOperation<T>(operation: () => Promise<T>): Promise<T>
61
+ requiresCardField(): boolean
62
+ run<T>(operation: (claim: CardClaimStep) => Promise<T>): Promise<T>
63
+ }
64
+ }
39
65
 
40
66
  /** `CheckoutBilling` → the native SDK's `BillingDetails`. Mirrors the web
41
67
  * `stripeBillingDetails`; the SDK collects card data from `<CardField/>`. */
@@ -74,24 +100,190 @@ const stripeFailure = (
74
100
  * idempotent per key so an event on a connected Stripe account re-initializes
75
101
  * only when the key/account actually changes.
76
102
  */
77
- export const createRnStripeConfirmer = (): PaymentConfirmer => {
78
- let initKey: string | null = null
79
- let accountKey: string | null = null
80
- const listeners = new Set<() => void>()
103
+ // Stripe React Native has one native SDK instance, including when a host creates
104
+ // several confirmer adapters. Its account and presentation lease must be global.
105
+ let initKey: string | null = null
106
+ let accountKey: string | null = null
107
+ const listeners = new Set<() => void>()
108
+ let initializedScheme: string | undefined
109
+ let initializing = false
110
+ let sheetPresenting = false
111
+ let nativeOperationActive = false
112
+ let sheetOwner: { key: string; options: NativePaymentSheetOptions } | null = null
81
113
 
82
- return {
114
+ const assertNativeLeaseFree = () => {
115
+ if (sheetOwner || initializing || nativeOperationActive)
116
+ throw paymentProviderError(
117
+ 'The payment SDK is owned by another operation.',
118
+ 'notStarted'
119
+ )
120
+ }
121
+
122
+ const nativeSdkCall = async <T>(operation: () => Promise<T>): Promise<T> => {
123
+ assertNativeLeaseFree()
124
+ nativeOperationActive = true
125
+ try {
126
+ return await operation()
127
+ } finally {
128
+ nativeOperationActive = false
129
+ }
130
+ }
131
+
132
+ export const createRnStripeConfirmer = (): NativeStripeConfirmer => {
133
+ const adapter: NativeStripeConfirmer = {
83
134
  init: async ({ publishableKey, accountId, merchantIdentifier, urlScheme }) => {
84
- const key = `${publishableKey}:${accountId ?? ''}:${merchantIdentifier ?? ''}`
85
- if (initKey === key) return
86
- await initStripe({
135
+ const key = JSON.stringify([
87
136
  publishableKey,
88
- ...(accountId ? { stripeAccountId: accountId } : {}),
89
- ...(merchantIdentifier ? { merchantIdentifier } : {}),
90
- ...(urlScheme ? { urlScheme } : {}),
91
- })
92
- initKey = key
93
- accountKey = `${publishableKey}:${accountId ?? ''}`
94
- listeners.forEach((listener) => listener())
137
+ accountId ?? null,
138
+ merchantIdentifier ?? null,
139
+ urlScheme ?? null,
140
+ ])
141
+ if (initializing || (sheetOwner && sheetOwner.key !== key))
142
+ throw paymentProviderError(
143
+ 'The payment SDK is owned by another operation.',
144
+ 'notStarted'
145
+ )
146
+ if (initKey === key) return
147
+ if (nativeOperationActive)
148
+ throw paymentProviderError(
149
+ 'The payment SDK is owned by another operation.',
150
+ 'notStarted'
151
+ )
152
+ initializing = true
153
+ initKey = null
154
+ accountKey = null
155
+ initializedScheme = undefined
156
+ try {
157
+ await initStripe({
158
+ publishableKey,
159
+ ...(accountId ? { stripeAccountId: accountId } : {}),
160
+ ...(merchantIdentifier ? { merchantIdentifier } : {}),
161
+ ...(urlScheme ? { urlScheme } : {}),
162
+ })
163
+ initKey = key
164
+ initializedScheme = urlScheme
165
+ accountKey = `${publishableKey}:${accountId ?? ''}`
166
+ listeners.forEach((listener) => listener())
167
+ } finally {
168
+ initializing = false
169
+ }
170
+ },
171
+
172
+ createPaymentSheetSession: (options) => {
173
+ let running = false
174
+ let owner: typeof sheetOwner = null
175
+ let requiresCardField = false
176
+ let reviewed: StripeCardPaymentContext | undefined
177
+ return {
178
+ requiresCardField: () => requiresCardField,
179
+ cardFieldOperation: async (operation) => {
180
+ if (running) {
181
+ // The engine's authoritative review requested its MSI/CardField
182
+ // branch. It catches unavailable offers; never let that catch
183
+ // silently fall through to PaymentSheet instead.
184
+ requiresCardField = true
185
+ throw paymentProviderError('Use the card form for this order.', 'notStarted')
186
+ }
187
+ return operation()
188
+ },
189
+ confirmer: {
190
+ ...adapter,
191
+ prepareCardPayment: async (context) => {
192
+ if (!running) return
193
+ reviewed = stripeElementsPaymentContext(
194
+ context?.amountMinor,
195
+ context?.currency
196
+ )
197
+ if (!reviewed || !owner || sheetOwner !== owner) {
198
+ throw paymentProviderError(NATIVE_SHEET_REVIEW_REQUIRED, 'notStarted')
199
+ }
200
+ },
201
+ confirmCard: async (clientSecret, billing) => {
202
+ if (!running) return adapter.confirmCard(clientSecret, billing)
203
+ if (requiresCardField)
204
+ throw paymentProviderError(
205
+ 'Use the card form for this order.',
206
+ 'notStarted'
207
+ )
208
+ if (!owner || sheetOwner !== owner)
209
+ throw paymentProviderError(
210
+ 'The payment sheet was not claimed.',
211
+ 'notStarted'
212
+ )
213
+ {
214
+ if (sheetPresenting)
215
+ throw paymentProviderError(
216
+ 'Another payment sheet is active.',
217
+ 'notStarted'
218
+ )
219
+ const confirm = createPaymentSheetConfirmation(
220
+ {
221
+ initPaymentSheet,
222
+ presentPaymentSheet,
223
+ retrievePaymentIntent,
224
+ LinkDisplay,
225
+ },
226
+ {
227
+ ...owner.options,
228
+ reviewed,
229
+ assertCurrent: () => {
230
+ if (sheetOwner !== owner || initKey !== owner.key || initializing)
231
+ throw paymentProviderError(
232
+ 'The original payment owner changed.',
233
+ 'notStarted'
234
+ )
235
+ },
236
+ }
237
+ )
238
+ sheetPresenting = true
239
+ try {
240
+ return await confirm(clientSecret, toBillingDetails(billing))
241
+ } catch (error) {
242
+ if (
243
+ (error as { providerCode?: string })?.providerCode ===
244
+ NATIVE_SHEET_CARD_FIELD_REQUIRED
245
+ )
246
+ requiresCardField = true
247
+ throw error
248
+ } finally {
249
+ sheetPresenting = false
250
+ }
251
+ }
252
+ },
253
+ },
254
+ run: async (operation) => {
255
+ if (running)
256
+ throw paymentProviderError('This payment is already active.', 'notStarted')
257
+ running = true
258
+ reviewed = undefined
259
+ let admitted = true
260
+ const claim: CardClaimStep = () => {
261
+ if (
262
+ !admitted ||
263
+ nativeOperationActive ||
264
+ initializing ||
265
+ !initKey ||
266
+ sheetOwner ||
267
+ !initializedScheme ||
268
+ options.returnURL !== `${initializedScheme}://stripe-redirect` ||
269
+ !options.merchantDisplayName.trim()
270
+ )
271
+ return 'unavailable'
272
+ owner = { key: initKey, options: { ...options } }
273
+ sheetOwner = owner
274
+ return 'attached'
275
+ }
276
+ try {
277
+ return await operation(claim)
278
+ } finally {
279
+ admitted = false
280
+ if (owner && sheetOwner === owner) sheetOwner = null
281
+ owner = null
282
+ reviewed = undefined
283
+ running = false
284
+ }
285
+ },
286
+ }
95
287
  },
96
288
 
97
289
  // `publishableKey:accountId`, the shape `bundleConfirmerKey` expects.
@@ -106,20 +298,27 @@ export const createRnStripeConfirmer = (): PaymentConfirmer => {
106
298
 
107
299
  // Native statuses are already the port's PascalCase vocabulary — no normalize.
108
300
  getIntentStatus: async (clientSecret) => {
109
- const { paymentIntent } = await retrievePaymentIntent(clientSecret)
301
+ assertNativeLeaseFree()
302
+ const { paymentIntent } = await nativeSdkCall(() =>
303
+ retrievePaymentIntent(clientSecret)
304
+ )
110
305
  return paymentIntent?.status
111
306
  },
112
307
 
113
308
  confirmCard: async (clientSecret, billing) => {
114
- const { error, paymentIntent } = await confirmPayment(clientSecret, {
115
- paymentMethodType: 'Card',
116
- paymentMethodData: { billingDetails: toBillingDetails(billing) },
117
- })
309
+ assertNativeLeaseFree()
310
+ const { error, paymentIntent } = await nativeSdkCall(() =>
311
+ confirmPayment(clientSecret, {
312
+ paymentMethodType: 'Card',
313
+ paymentMethodData: { billingDetails: toBillingDetails(billing) },
314
+ })
315
+ )
118
316
  if (error) throw stripeFailure(error, 'Payment failed.')
119
317
  return confirmedStripeIntentStatus(paymentIntent)
120
318
  },
121
319
 
122
320
  confirmApplePay: async (clientSecret, total, currencyCode, merchant) => {
321
+ assertNativeLeaseFree()
123
322
  const context = stripeWalletPaymentContext(
124
323
  total,
125
324
  currencyCode,
@@ -130,24 +329,27 @@ export const createRnStripeConfirmer = (): PaymentConfirmer => {
130
329
  'The order wallet details are unavailable.',
131
330
  'notStarted'
132
331
  )
133
- const { error, paymentIntent } = await confirmPlatformPayPayment(clientSecret, {
134
- applePay: {
135
- merchantCountryCode: context.merchantCountry,
136
- currencyCode: context.currency,
137
- cartItems: [
138
- {
139
- label: merchant.merchantName ?? 'Order',
140
- amount: context.amount,
141
- paymentType: PlatformPay.PaymentType.Immediate,
142
- },
143
- ],
144
- },
145
- })
332
+ const { error, paymentIntent } = await nativeSdkCall(() =>
333
+ confirmPlatformPayPayment(clientSecret, {
334
+ applePay: {
335
+ merchantCountryCode: context.merchantCountry,
336
+ currencyCode: context.currency,
337
+ cartItems: [
338
+ {
339
+ label: merchant.merchantName ?? 'Order',
340
+ amount: context.amount,
341
+ paymentType: PlatformPay.PaymentType.Immediate,
342
+ },
343
+ ],
344
+ },
345
+ })
346
+ )
146
347
  if (error) throw stripeFailure(error, 'Apple Pay failed.')
147
348
  return confirmedStripeIntentStatus(paymentIntent)
148
349
  },
149
350
 
150
351
  confirmGooglePay: async (clientSecret, total, currencyCode, merchant) => {
352
+ assertNativeLeaseFree()
151
353
  const context = stripeWalletPaymentContext(
152
354
  total,
153
355
  currencyCode,
@@ -158,18 +360,21 @@ export const createRnStripeConfirmer = (): PaymentConfirmer => {
158
360
  'The order wallet details are unavailable.',
159
361
  'notStarted'
160
362
  )
161
- const { error, paymentIntent } = await confirmPlatformPayPayment(clientSecret, {
162
- googlePay: {
163
- testEnv: merchant.testEnv === true,
164
- merchantCountryCode: context.merchantCountry,
165
- currencyCode: context.currency,
166
- merchantName: merchant.merchantName ?? 'Order',
167
- },
168
- })
363
+ const { error, paymentIntent } = await nativeSdkCall(() =>
364
+ confirmPlatformPayPayment(clientSecret, {
365
+ googlePay: {
366
+ testEnv: merchant.testEnv === true,
367
+ merchantCountryCode: context.merchantCountry,
368
+ currencyCode: context.currency,
369
+ merchantName: merchant.merchantName ?? 'Order',
370
+ },
371
+ })
372
+ )
169
373
  if (error) throw stripeFailure(error, 'Google Pay failed.')
170
374
  return confirmedStripeIntentStatus(paymentIntent)
171
375
  },
172
376
  }
377
+ return adapter
173
378
  }
174
379
 
175
380
  /**
@@ -183,70 +388,94 @@ export const createRnPorts = (): Omit<CheckoutPorts, 'confirmer'> => ({
183
388
  openUrl: (url: string) => Linking.openURL(url).then(() => undefined),
184
389
 
185
390
  createCardPaymentMethod: async (billing) => {
186
- const { paymentMethod, error } = await createPaymentMethod({
187
- paymentMethodType: 'Card',
188
- paymentMethodData: { billingDetails: toBillingDetails(billing) },
189
- })
391
+ assertNativeLeaseFree()
392
+ const { paymentMethod, error } = await nativeSdkCall(() =>
393
+ createPaymentMethod({
394
+ paymentMethodType: 'Card',
395
+ paymentMethodData: { billingDetails: toBillingDetails(billing) },
396
+ })
397
+ )
190
398
  if (error || !paymentMethod?.id) throw failed(error?.message, 'Payment failed')
191
399
  return paymentMethod.id
192
400
  },
193
401
 
194
402
  createRedirectPaymentMethod: async (methodType, billing) => {
403
+ assertNativeLeaseFree()
195
404
  const details = toBillingDetails(billing)
196
405
  const result = await (() => {
197
406
  switch (methodType) {
198
407
  case 'klarna':
199
- return createPaymentMethod({
200
- paymentMethodType: 'Klarna',
201
- paymentMethodData: { billingDetails: details },
202
- })
408
+ return nativeSdkCall(() =>
409
+ createPaymentMethod({
410
+ paymentMethodType: 'Klarna',
411
+ paymentMethodData: { billingDetails: details },
412
+ })
413
+ )
203
414
  case 'afterpay_clearpay':
204
- return createPaymentMethod({
205
- paymentMethodType: 'AfterpayClearpay',
206
- paymentMethodData: { billingDetails: details, shippingDetails: details },
207
- })
415
+ return nativeSdkCall(() =>
416
+ createPaymentMethod({
417
+ paymentMethodType: 'AfterpayClearpay',
418
+ paymentMethodData: { billingDetails: details, shippingDetails: details },
419
+ })
420
+ )
208
421
  case 'affirm':
209
- return createPaymentMethod({
210
- paymentMethodType: 'Affirm',
211
- paymentMethodData: { billingDetails: details },
212
- })
422
+ return nativeSdkCall(() =>
423
+ createPaymentMethod({
424
+ paymentMethodType: 'Affirm',
425
+ paymentMethodData: { billingDetails: details },
426
+ })
427
+ )
213
428
  case 'ideal':
214
- return createPaymentMethod({
215
- paymentMethodType: 'Ideal',
216
- paymentMethodData: { billingDetails: details },
217
- })
429
+ return nativeSdkCall(() =>
430
+ createPaymentMethod({
431
+ paymentMethodType: 'Ideal',
432
+ paymentMethodData: { billingDetails: details },
433
+ })
434
+ )
218
435
  case 'bancontact':
219
- return createPaymentMethod({
220
- paymentMethodType: 'Bancontact',
221
- paymentMethodData: { billingDetails: details },
222
- })
436
+ return nativeSdkCall(() =>
437
+ createPaymentMethod({
438
+ paymentMethodType: 'Bancontact',
439
+ paymentMethodData: { billingDetails: details },
440
+ })
441
+ )
223
442
  case 'eps':
224
- return createPaymentMethod({
225
- paymentMethodType: 'Eps',
226
- paymentMethodData: { billingDetails: details },
227
- })
443
+ return nativeSdkCall(() =>
444
+ createPaymentMethod({
445
+ paymentMethodType: 'Eps',
446
+ paymentMethodData: { billingDetails: details },
447
+ })
448
+ )
228
449
  case 'p24':
229
- return createPaymentMethod({
230
- paymentMethodType: 'P24',
231
- paymentMethodData: { billingDetails: details },
232
- })
450
+ return nativeSdkCall(() =>
451
+ createPaymentMethod({
452
+ paymentMethodType: 'P24',
453
+ paymentMethodData: { billingDetails: details },
454
+ })
455
+ )
233
456
  case 'alipay':
234
- return createPaymentMethod({ paymentMethodType: 'Alipay' })
457
+ return nativeSdkCall(() => createPaymentMethod({ paymentMethodType: 'Alipay' }))
235
458
  case 'grabpay':
236
- return createPaymentMethod({
237
- paymentMethodType: 'GrabPay',
238
- paymentMethodData: { billingDetails: details },
239
- })
459
+ return nativeSdkCall(() =>
460
+ createPaymentMethod({
461
+ paymentMethodType: 'GrabPay',
462
+ paymentMethodData: { billingDetails: details },
463
+ })
464
+ )
240
465
  case 'cashapp':
241
- return createPaymentMethod({
242
- paymentMethodType: 'CashApp',
243
- paymentMethodData: { billingDetails: details },
244
- })
466
+ return nativeSdkCall(() =>
467
+ createPaymentMethod({
468
+ paymentMethodType: 'CashApp',
469
+ paymentMethodData: { billingDetails: details },
470
+ })
471
+ )
245
472
  case 'paypal':
246
- return createPaymentMethod({
247
- paymentMethodType: 'PayPal',
248
- paymentMethodData: { billingDetails: details },
249
- })
473
+ return nativeSdkCall(() =>
474
+ createPaymentMethod({
475
+ paymentMethodType: 'PayPal',
476
+ paymentMethodData: { billingDetails: details },
477
+ })
478
+ )
250
479
  default:
251
480
  throw new Error('This payment method is not available on this device.')
252
481
  }
@@ -257,25 +486,32 @@ export const createRnPorts = (): Omit<CheckoutPorts, 'confirmer'> => ({
257
486
  },
258
487
 
259
488
  handleNextAction: async (clientSecret) => {
260
- const { error } = await handleNextAction(clientSecret)
489
+ assertNativeLeaseFree()
490
+ const { error } = await nativeSdkCall(() => handleNextAction(clientSecret))
261
491
  if (error) throw stripeFailure(error, 'Payment failed')
262
492
  },
263
493
 
264
494
  confirmOxxo: async (clientSecret, billing) => {
265
- const { error, paymentIntent } = await confirmPayment(clientSecret, {
266
- paymentMethodType: 'Oxxo',
267
- paymentMethodData: { billingDetails: toBillingDetails(billing) },
268
- })
495
+ assertNativeLeaseFree()
496
+ const { error, paymentIntent } = await nativeSdkCall(() =>
497
+ confirmPayment(clientSecret, {
498
+ paymentMethodType: 'Oxxo',
499
+ paymentMethodData: { billingDetails: toBillingDetails(billing) },
500
+ })
501
+ )
269
502
  return { error: error?.message, nextAction: paymentIntent?.nextAction as unknown }
270
503
  },
271
504
 
272
505
  // Payment plan (new card): confirm the SetupIntent to SAVE the card (nothing
273
506
  // charged) and return its PaymentMethod id for the server-side plan.
274
507
  confirmPaymentPlanSetup: async (clientSecret, billing) => {
275
- const { setupIntent, error } = await confirmSetupIntent(clientSecret, {
276
- paymentMethodType: 'Card',
277
- paymentMethodData: { billingDetails: toBillingDetails(billing) },
278
- })
508
+ assertNativeLeaseFree()
509
+ const { setupIntent, error } = await nativeSdkCall(() =>
510
+ confirmSetupIntent(clientSecret, {
511
+ paymentMethodType: 'Card',
512
+ paymentMethodData: { billingDetails: toBillingDetails(billing) },
513
+ })
514
+ )
279
515
  const paymentMethodId = setupIntent?.paymentMethod?.id
280
516
  if (error || !paymentMethodId) throw failed(error?.message, 'Card setup failed')
281
517
  return paymentMethodId
@@ -284,10 +520,13 @@ export const createRnPorts = (): Omit<CheckoutPorts, 'confirmer'> => ({
284
520
  // Payment plan (saved-card 3DS): confirm the pending charge against the
285
521
  // existing PaymentMethod when the plan comes back requires_action.
286
522
  confirmSavedCardPayment: async (clientSecret, paymentMethodId) => {
287
- const { error } = await confirmPayment(clientSecret, {
288
- paymentMethodType: 'Card',
289
- paymentMethodData: { paymentMethodId },
290
- })
523
+ assertNativeLeaseFree()
524
+ const { error } = await nativeSdkCall(() =>
525
+ confirmPayment(clientSecret, {
526
+ paymentMethodType: 'Card',
527
+ paymentMethodData: { paymentMethodId },
528
+ })
529
+ )
291
530
  if (error) throw stripeFailure(error, 'Payment failed')
292
531
  },
293
532
  })
package/src/index.tsx CHANGED
@@ -13,7 +13,11 @@
13
13
  export * from 'tf-checkout-shared'
14
14
 
15
15
  // Native platform layer
16
- export { useCheckout, type UseCheckoutOptions } from './useCheckout'
16
+ export {
17
+ useCheckout,
18
+ type UseCheckoutOptions,
19
+ type NativeUseCheckout,
20
+ } from './useCheckout'
17
21
  export { configureCheckout, mmkvStorageAdapter } from './configure'
18
22
  export { createMmkvStorage } from './storage'
19
23
  export { CardInput, claimCardField, type CardInputProps } from './CardInput'
@@ -26,4 +30,8 @@ export { EmbeddedCheckout, type EmbeddedCheckoutProps } from './EmbeddedCheckout
26
30
 
27
31
  // Port instances/factories (bring-your-own ports, testing, custom flows).
28
32
  export { rnConfirmer, rnPorts } from './instance'
29
- export { createRnStripeConfirmer, createRnPorts } from './confirmer'
33
+ export {
34
+ createRnStripeConfirmer,
35
+ createRnPorts,
36
+ type NativePaymentSheetOptions,
37
+ } from './confirmer'
package/src/instance.ts CHANGED
@@ -2,12 +2,10 @@
2
2
  * The package-level native platform instances. Created once at module load, so
3
3
  * the hook and the UI components all bind to the SAME confirmer/ports.
4
4
  */
5
- import type { PaymentConfirmer } from 'tf-checkout-shared'
6
-
7
5
  import { createRnPorts, createRnStripeConfirmer } from './confirmer'
8
6
 
9
7
  /** The confirmer every `useCheckout`/`<CardInput/>` binds to. */
10
- export const rnConfirmer: PaymentConfirmer = createRnStripeConfirmer()
8
+ export const rnConfirmer = createRnStripeConfirmer()
11
9
 
12
10
  /** The native ports the alternative Stripe rails (OXXO / plan) run on. */
13
11
  export const rnPorts = createRnPorts()