framepayments-react-native 2.1.1 → 2.1.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.
Files changed (111) hide show
  1. package/README.md +81 -59
  2. package/android/build/intermediates/aar_main_jar/debug/syncDebugLibJars/classes.jar +0 -0
  3. package/android/build/intermediates/annotations_typedef_file/debug/extractDebugAnnotations/typedefs.txt +0 -0
  4. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  5. package/android/build/intermediates/incremental/debug-mergeJavaRes/merge-state +0 -0
  6. package/android/build/intermediates/merged_java_res/debug/mergeDebugJavaResource/feature-framepayments-react-native.jar +0 -0
  7. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
  8. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
  9. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
  10. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
  11. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
  12. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
  13. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
  14. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
  15. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
  16. package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
  17. package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
  18. package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
  19. package/android/build/outputs/aar/framepayments-react-native-debug.aar +0 -0
  20. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameCheckoutActivity$Companion.class +0 -0
  21. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameCheckoutActivity$tryShowCheckout$1.class +0 -0
  22. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameCheckoutActivity.class +0 -0
  23. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameFlowActivity$CartItemDto.class +0 -0
  24. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameFlowActivity$Companion.class +0 -0
  25. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameFlowActivity$parseCartItems$type$1.class +0 -0
  26. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameFlowActivity.class +0 -0
  27. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameGooglePayActivity$Companion.class +0 -0
  28. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameGooglePayActivity.class +0 -0
  29. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameOnboardingActivity$Companion.class +0 -0
  30. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameOnboardingActivity$parseCapabilities$type$1.class +0 -0
  31. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameOnboardingActivity.class +0 -0
  32. package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameSDKModule.class +0 -0
  33. package/android/build.gradle +3 -3
  34. package/android/src/main/java/com/framepayments/reactnativeframe/FrameCheckoutActivity.kt +17 -13
  35. package/android/src/main/java/com/framepayments/reactnativeframe/FrameFlowActivity.kt +18 -11
  36. package/android/src/main/java/com/framepayments/reactnativeframe/FrameGooglePayActivity.kt +31 -8
  37. package/android/src/main/java/com/framepayments/reactnativeframe/FrameSDKModule.kt +28 -35
  38. package/ios/ApplePayPresenter.swift +53 -28
  39. package/ios/FrameSDKBridge.m +7 -7
  40. package/ios/FrameSDKBridge.swift +62 -32
  41. package/lib/errors.d.ts +9 -1
  42. package/lib/errors.d.ts.map +1 -1
  43. package/lib/errors.js +9 -1
  44. package/lib/index.d.ts +1 -1
  45. package/lib/index.d.ts.map +1 -1
  46. package/lib/native.d.ts +37 -7
  47. package/lib/native.d.ts.map +1 -1
  48. package/lib/native.js +61 -9
  49. package/lib/types.d.ts +18 -45
  50. package/lib/types.d.ts.map +1 -1
  51. package/package.json +1 -1
  52. package/src/__tests__/native.test.ts +179 -25
  53. package/src/errors.ts +9 -1
  54. package/src/index.ts +1 -3
  55. package/src/native.ts +69 -17
  56. package/src/types.ts +19 -58
  57. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/results.bin +0 -1
  58. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/BuildConfig.dex +0 -0
  59. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameCheckoutActivity$Companion.dex +0 -0
  60. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameCheckoutActivity$tryShowCheckout$1.dex +0 -0
  61. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameCheckoutActivity.dex +0 -0
  62. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameFlowActivity$CartItemDto.dex +0 -0
  63. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameFlowActivity$Companion.dex +0 -0
  64. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameFlowActivity$parseCartItems$type$1.dex +0 -0
  65. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameFlowActivity.dex +0 -0
  66. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameGooglePayActivity$Companion.dex +0 -0
  67. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameGooglePayActivity.dex +0 -0
  68. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameOnboardingActivity$Companion.dex +0 -0
  69. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameOnboardingActivity$parseCapabilities$type$1.dex +0 -0
  70. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameOnboardingActivity.dex +0 -0
  71. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameSDKModule$Companion.dex +0 -0
  72. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameSDKModule.dex +0 -0
  73. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameSDKPackage.dex +0 -0
  74. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/JsonConvertersKt.dex +0 -0
  75. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameCheckoutActivity$$InternalSyntheticLambda$2$28045340ca5b91151bb937065eeb5817c0f8f911bb460e6e7ed8bb228b67ee83$0.globals +0 -0
  76. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameFlowActivity$$InternalSyntheticLambda$2$467cdf1dabffeaa07b76e313efb66791f50d3ff264e427e91d1358ac5865a7a9$0.globals +0 -0
  77. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameFlowActivity$$InternalSyntheticLambda$2$d15cc37cc08a853958a9c0baad49f7fce1ef84e92db9baa5103646939a0fe3e5$0.globals +0 -0
  78. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameFlowActivity$$InternalSyntheticLambda$2$ee6ef8e6758d1b8e67a54e3fecfb200ac5e867541a69809ec1db49f74ffcada1$0.globals +0 -0
  79. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameGooglePayActivity$$InternalSyntheticLambda$2$46cecf303f126f7c9f20b615fc49b2714ec2eb4f046ae009cfdbce53a1759f18$0.globals +0 -0
  80. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameGooglePayActivity$$InternalSyntheticLambda$2$46cecf303f126f7c9f20b615fc49b2714ec2eb4f046ae009cfdbce53a1759f18$1.globals +0 -0
  81. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameGooglePayActivity$$InternalSyntheticLambda$2$46cecf303f126f7c9f20b615fc49b2714ec2eb4f046ae009cfdbce53a1759f18$2.globals +0 -0
  82. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameGooglePayActivity$$InternalSyntheticLambda$2$cdad629ad452b3c7f7de1310d225629dafa75285ad515d55f056371066170154$0.globals +0 -0
  83. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameOnboardingActivity$$InternalSyntheticLambda$2$5d91d018c63f48735ba5e2a00b14bd815f4ce248aa924e4a58bf6addce311837$0.globals +0 -0
  84. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameOnboardingActivity$$InternalSyntheticLambda$2$c9ac604bc80e3afcbfad7417717ae97568874f4e33246863c0d688abb3e89865$0.globals +0 -0
  85. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameSDKModule$$InternalSyntheticLambda$2$1f479ca48bf3a1c66ff65b38aaaef67a97119b29ddce703f8104188682007f0d$0.globals +0 -0
  86. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameSDKModule$$InternalSyntheticLambda$2$984ab30558bc904ed37602fa6e3ebf28f1ed69df6712b31b00c4f26fc26d3b70$0.globals +0 -0
  87. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameSDKModule$$InternalSyntheticLambda$2$f4a55b70e496f422e1e03998843d62c7208f0229c2d5d080706056e98810c892$0.globals +0 -0
  88. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameSDKModule$$InternalSyntheticLambda$2$f8d46f7169c404d37a1d505f19439b83090fbed62b5bdaf1e86717fdddebf622$0.globals +0 -0
  89. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/FrameSDKModule$$InternalSyntheticLambda$2$f8d46f7169c404d37a1d505f19439b83090fbed62b5bdaf1e86717fdddebf622$1.globals +0 -0
  90. package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  91. package/android/build/intermediates/android_res_source_set_path_map/debug/mapDebugSourceSetPaths/file-map.txt +0 -10
  92. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  93. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
  94. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/META-INF/framepayments-react-native_debug.kotlin_module +0 -0
  95. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/BuildConfig.class +0 -0
  96. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameCheckoutActivity$Companion.class +0 -0
  97. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameCheckoutActivity$tryShowCheckout$1.class +0 -0
  98. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameCheckoutActivity.class +0 -0
  99. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameFlowActivity$CartItemDto.class +0 -0
  100. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameFlowActivity$Companion.class +0 -0
  101. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameFlowActivity$parseCartItems$type$1.class +0 -0
  102. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameFlowActivity.class +0 -0
  103. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameGooglePayActivity$Companion.class +0 -0
  104. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameGooglePayActivity.class +0 -0
  105. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameOnboardingActivity$Companion.class +0 -0
  106. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameOnboardingActivity$parseCapabilities$type$1.class +0 -0
  107. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameOnboardingActivity.class +0 -0
  108. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameSDKModule$Companion.class +0 -0
  109. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameSDKModule.class +0 -0
  110. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameSDKPackage.class +0 -0
  111. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/JsonConvertersKt.class +0 -0
package/README.md CHANGED
@@ -72,11 +72,12 @@ await Frame.initialize({
72
72
  debugMode: __DEV__,
73
73
  });
74
74
 
75
- // 2. Present a checkout modal
76
- const chargeIntent = await Frame.presentCheckout({ amount: 10000 }); // cents
75
+ // 2. Present a checkout modal — resolves with the transfer id string
76
+ const transferId = await Frame.presentCheckout({ amount: 10000, accountId: 'acct_xxx' });
77
77
 
78
- // 3. Present a cart flow
79
- const result = await Frame.presentCart({
78
+ // 3. Present a cart flow — also resolves with the transfer id string
79
+ const transferId2 = await Frame.presentCart({
80
+ accountId: 'acct_xxx',
80
81
  items: [{ id: '1', title: 'Hat', amountInCents: 5000, imageUrl: 'https://...' }],
81
82
  shippingAmountInCents: 500,
82
83
  });
@@ -114,30 +115,35 @@ await Frame.initialize({
114
115
 
115
116
  ### `Frame.presentCheckout(options)`
116
117
 
117
- Opens the native checkout modal. Resolves with a `ChargeIntent` when the user completes payment.
118
+ Opens the native checkout modal. Resolves with the created Transfer's id string when the user completes payment. Rejects with `USER_CANCELED` if the sheet is dismissed.
119
+
120
+ `accountId` is **required**: the bundled checkout creates a `Transfer`, which is account-scoped. If you need a customer/ChargeIntent flow, render your own UI and call `presentApplePay` / `presentGooglePay` directly with a customer owner instead.
118
121
 
119
122
  ```ts
120
- const chargeIntent = await Frame.presentCheckout({
121
- amount: 15000, // required, in cents
122
- customerId: 'cus_xxx', // optional
123
+ const transferId = await Frame.presentCheckout({
124
+ accountId: 'acct_xxx',
125
+ amount: 15000, // in cents
123
126
  });
124
127
  ```
125
128
 
126
129
  | Option | Type | Required | Description |
127
130
  |---|---|---|---|
131
+ | `accountId` | `string` | Yes | Frame account that the resulting Transfer is created against |
128
132
  | `amount` | `number` | Yes | Payment amount in cents |
129
- | `customerId` | `string` | No | Pre-associate the charge with a Frame customer |
130
133
 
131
- **Returns:** [`ChargeIntent`](#chargeintent)
134
+ **Returns:** `Promise<string>` — the created Transfer's `id`.
135
+
136
+ **Throws synchronously with `code: 'INVALID_ACCOUNT'`** if `accountId` is missing or empty.
132
137
 
133
138
  ---
134
139
 
135
140
  ### `Frame.presentCart(options)`
136
141
 
137
- Opens a cart review screen followed by the checkout flow. Resolves when the user completes payment or dismisses.
142
+ Opens a cart review screen followed by the checkout flow. Routes through the same checkout path as `presentCheckout`, so it requires the same `accountId` and resolves with the created Transfer's id string.
138
143
 
139
144
  ```ts
140
- const chargeIntent = await Frame.presentCart({
145
+ const transferId = await Frame.presentCart({
146
+ accountId: 'acct_xxx',
141
147
  items: [
142
148
  {
143
149
  id: '1',
@@ -147,15 +153,16 @@ const chargeIntent = await Frame.presentCart({
147
153
  },
148
154
  ],
149
155
  shippingAmountInCents: 500,
150
- customerId: 'cus_xxx', // optional
151
156
  });
152
157
  ```
153
158
 
154
159
  | Option | Type | Required | Description |
155
160
  |---|---|---|---|
161
+ | `accountId` | `string` | Yes | Frame account that the resulting Transfer is created against |
156
162
  | `items` | `FrameCartItem[]` | Yes | Array of items to display in the cart |
157
163
  | `shippingAmountInCents` | `number` | Yes | Shipping cost in cents |
158
- | `customerId` | `string` | No | Pre-associate the charge with a Frame customer |
164
+
165
+ **Returns:** `Promise<string>` — the created Transfer's `id`.
159
166
 
160
167
  **`FrameCartItem` shape:**
161
168
 
@@ -166,10 +173,6 @@ const chargeIntent = await Frame.presentCart({
166
173
  | `amountInCents` | `number` | Item price in cents |
167
174
  | `imageUrl` | `string` | URL of the product image |
168
175
 
169
- **Returns:** [`ChargeIntent`](#chargeintent)
170
-
171
- > **iOS limitation:** On iOS, `presentCart` resolves with an empty object (`{}`) rather than a full `ChargeIntent`. The underlying `FrameCartView` does not expose the charge intent from its nested checkout step. On Android, the full `ChargeIntent` is returned. Always guard with `intent?.id` before using the result.
172
-
173
176
  ---
174
177
 
175
178
  ### `Frame.presentOnboarding(options)`
@@ -222,28 +225,45 @@ if (result.status === 'completed') {
222
225
 
223
226
  ### `Frame.presentApplePay(options)` (iOS)
224
227
 
225
- Launches the native Apple Pay sheet, creates a Frame payment method from the authorized payment, and creates and confirms a charge intent. Resolves with the resulting `ChargeIntent`. Render your own button — Apple's `PKPaymentButton`, a community wrapper, or your own design-system component — and call this from its `onPress`.
228
+ Launches the native Apple Pay sheet, creates a Frame payment method from the authorized payment, and creates a charge against the owner. Resolves with the resulting resource's id string. Render your own button — Apple's `PKPaymentButton`, a community wrapper, or your own design-system component — and call this from its `onPress`.
229
+
230
+ The `owner` determines which downstream resource is created:
231
+
232
+ - `owner.type === 'customer'` → creates a `ChargeIntent` against the customer; resolves with the ChargeIntent's `id`.
233
+ - `owner.type === 'account'` → creates a `Transfer` charged into the account; resolves with the Transfer's `id`.
234
+
235
+ In both cases the resolved value is a `string`; the caller knows which resource the id refers to based on the owner passed in.
226
236
 
227
237
  ```tsx
228
238
  import Frame from 'framepayments-react-native';
229
239
 
230
- const intent = await Frame.presentApplePay({
240
+ // Account Transfer
241
+ const transferId = await Frame.presentApplePay({
242
+ amount: 15000,
243
+ currency: 'usd',
244
+ owner: { type: 'account', id: 'acct_xxx' },
245
+ merchantId: 'merchant.com.yourapp',
246
+ });
247
+
248
+ // Customer → ChargeIntent
249
+ const chargeIntentId = await Frame.presentApplePay({
231
250
  amount: 15000,
232
251
  currency: 'usd',
233
252
  owner: { type: 'customer', id: 'cus_xxx' },
234
253
  merchantId: 'merchant.com.yourapp',
235
254
  });
236
- console.log('Charge intent:', intent.id);
237
255
  ```
238
256
 
239
257
  | Option | Type | Required | Description |
240
258
  |---|---|---|---|
241
259
  | `amount` | `number` | Yes | Payment amount in cents |
242
260
  | `currency` | `string` | No | ISO 4217 currency code. Default `'usd'` |
243
- | `owner` | `{ type: 'customer' \| 'account', id: string }` | Yes | Frame customer or account that owns the resulting payment method |
261
+ | `owner` | `{ type: 'customer' \| 'account', id: string }` | Yes | Customer or account that owns the resulting payment method and charge |
244
262
  | `merchantId` | `string` | Yes | Apple Pay merchant ID configured in your Apple Developer account |
245
263
 
246
- The promise rejects with `code: 'USER_CANCELED'` when the user dismisses the sheet, `'APPLE_PAY_UNAVAILABLE'` if the device cannot make Apple Pay payments, `'NOT_ATTESTED'` if device attestation has not completed yet (try again in a moment), and `'PAYMENT_METHOD_FAILED'` / `'CHARGE_INTENT_FAILED'` for backend failures.
264
+ **Returns:** `Promise<string>` the created `ChargeIntent`'s `id` (for customer owners) or the `Transfer`'s `id` (for account owners).
265
+
266
+ The promise rejects with `code: 'USER_CANCELED'` when the user dismisses the sheet, `'INVALID_OWNER'` if the owner is missing or malformed, `'APPLE_PAY_UNAVAILABLE'` if the device cannot make Apple Pay payments, `'NOT_ATTESTED'` if device attestation has not completed yet (try again in a moment), `'PAYMENT_METHOD_FAILED'` when the wallet payment method could not be persisted, and `'PAYMENT_FAILED'` when the downstream ChargeIntent or Transfer could not be created.
247
267
 
248
268
  **Required iOS setup:**
249
269
 
@@ -263,27 +283,40 @@ On non-iOS platforms `Frame.presentApplePay` rejects synchronously with a not-su
263
283
 
264
284
  ### `Frame.presentGooglePay(options)` (Android)
265
285
 
266
- Launches the native Google Pay sheet, creates a Frame payment method from the wallet token, and creates and confirms a charge intent. Resolves with the resulting `ChargeIntent`. Render your own button (Google's `PayButton` from `play-services-pay`, a community wrapper, or your own component) and call this from its `onPress`.
286
+ Launches the native Google Pay sheet, creates a Frame payment method from the wallet token, and creates a charge against the owner. Resolves with the resulting resource's id string. Render your own button (Google's `PayButton` from `play-services-pay`, a community wrapper, or your own component) and call this from its `onPress`.
287
+
288
+ The `owner` mirrors `presentApplePay` and determines which downstream resource is created:
289
+
290
+ - `owner.type === 'customer'` → creates a `ChargeIntent` against the customer; resolves with the ChargeIntent's `id`.
291
+ - `owner.type === 'account'` → creates a `Transfer` charged into the account; resolves with the Transfer's `id`.
267
292
 
268
293
  ```tsx
269
294
  import Frame from 'framepayments-react-native';
270
295
 
271
- const intent = await Frame.presentGooglePay({
296
+ // Account Transfer
297
+ const transferId = await Frame.presentGooglePay({
272
298
  amountCents: 15000,
273
299
  currencyCode: 'USD',
274
- customerId: 'cus_xxx',
300
+ owner: { type: 'account', id: 'acct_xxx' },
301
+ });
302
+
303
+ // Customer → ChargeIntent
304
+ const chargeIntentId = await Frame.presentGooglePay({
305
+ amountCents: 15000,
306
+ owner: { type: 'customer', id: 'cus_xxx' },
275
307
  });
276
- console.log('Charge intent:', intent.id);
277
308
  ```
278
309
 
279
310
  | Option | Type | Required | Description |
280
311
  |---|---|---|---|
281
312
  | `amountCents` | `number` | Yes | Payment amount in cents |
282
- | `customerId` | `string` | No | Frame customer to associate the payment method with |
313
+ | `owner` | `{ type: 'customer' \| 'account', id: string }` | Yes | Customer or account that owns the resulting payment method and charge |
283
314
  | `currencyCode` | `string` | No | ISO 4217 currency code. Default `'USD'` |
284
315
  | `googlePayMerchantId` | `string` | No | Google Pay merchant ID override |
285
316
 
286
- The promise rejects with `code: 'USER_CANCELED'` when the user dismisses the sheet, `'GOOGLE_PAY_UNAVAILABLE'` if Google Pay is not ready on the device (no signed-in account, no test card, or Wallet API disabled), and `'PAYMENT_FAILED'` for backend failures.
317
+ **Returns:** `Promise<string>` the created `ChargeIntent`'s `id` (for customer owners) or the `Transfer`'s `id` (for account owners).
318
+
319
+ The promise rejects with `code: 'USER_CANCELED'` when the user dismisses the sheet, `'INVALID_OWNER'` if the owner is missing or malformed, `'GOOGLE_PAY_UNAVAILABLE'` if Google Pay is not ready on the device (no signed-in account, no test card, or Wallet API disabled), and `'PAYMENT_FAILED'` for backend failures.
287
320
 
288
321
  **Required Android setup:**
289
322
 
@@ -392,7 +425,7 @@ Apple and Google both require their official button artwork (with light/dark var
392
425
  import { Image, Platform, TouchableOpacity, useColorScheme } from 'react-native';
393
426
  import Frame from 'framepayments-react-native';
394
427
 
395
- export function WalletButton({ amountCents, customerId, merchantId }) {
428
+ export function WalletButton({ amountCents, accountId, merchantId }) {
396
429
  const colorScheme = useColorScheme();
397
430
  const isDark = colorScheme === 'dark';
398
431
 
@@ -402,11 +435,14 @@ export function WalletButton({ amountCents, customerId, merchantId }) {
402
435
  await Frame.presentApplePay({
403
436
  amount: amountCents,
404
437
  currency: 'usd',
405
- owner: { type: 'customer', id: customerId },
438
+ owner: { type: 'account', id: accountId },
406
439
  merchantId,
407
440
  });
408
441
  } else {
409
- await Frame.presentGooglePay({ amountCents, customerId });
442
+ await Frame.presentGooglePay({
443
+ amountCents,
444
+ owner: { type: 'account', id: accountId },
445
+ });
410
446
  }
411
447
  } catch (e: any) {
412
448
  if (e.code === 'USER_CANCELED') return;
@@ -434,27 +470,9 @@ A complete working example (including loading-state handling) lives in [example/
434
470
 
435
471
  ---
436
472
 
437
- ### `ChargeIntent`
473
+ ### Inspecting the full resource
438
474
 
439
- Returned from `presentCheckout` and `presentCart` (Android only for cart).
440
-
441
- | Field | Type | Description |
442
- |---|---|---|
443
- | `id` | `string` | Unique charge intent ID |
444
- | `amount` | `number` | Amount in cents |
445
- | `currency` | `string` | ISO currency code (e.g. `"usd"`) |
446
- | `status` | `ChargeIntentStatus` | Current status of the intent |
447
- | `created` | `number` | Unix timestamp |
448
- | `updated` | `number` | Unix timestamp |
449
- | `livemode` | `boolean` | `true` in production, `false` in sandbox |
450
- | `description` | `string \| undefined` | Optional description |
451
- | `authorizationMode` | `'automatic' \| 'manual' \| undefined` | Capture mode |
452
- | `failureDescription` | `string \| undefined` | Present when status is `failed` |
453
- | `customer` | `Customer \| undefined` | Associated customer object |
454
- | `paymentMethod` | `PaymentMethod \| undefined` | Payment method used |
455
- | `latestCharge` | `Charge \| undefined` | Most recent charge on this intent |
456
-
457
- **`ChargeIntentStatus` values:** `pending`, `succeeded`, `failed`, `canceled`, `incomplete`, `disputed`, `refunded`, `reversed`
475
+ The `present*` flows resolve with a string id only. If you need the full `Transfer` or `ChargeIntent` object after a checkout completes, fetch it server-side from the Frame API using the returned id — see [https://docs.framepayments.com/frameos/transfers](https://docs.framepayments.com/frameos/transfers) and the corresponding ChargeIntent docs for the response schemas. (This SDK doesn't ship TypeScript types for those objects; use the [`framepayments`](https://www.npmjs.com/package/framepayments) Node package if you want typed access from JS.)
458
476
 
459
477
  ---
460
478
 
@@ -466,7 +484,7 @@ All `present*` methods return Promises that reject with an error object containi
466
484
  import Frame, { ErrorCodes } from 'framepayments-react-native';
467
485
 
468
486
  try {
469
- const intent = await Frame.presentCheckout({ amount: 10000 });
487
+ const transferId = await Frame.presentCheckout({ amount: 10000, accountId: 'acct_xxx' });
470
488
  // handle success
471
489
  } catch (e: any) {
472
490
  if (e.code === ErrorCodes.USER_CANCELED) {
@@ -486,9 +504,17 @@ try {
486
504
  | `NO_ROOT_VC` | iOS: no root view controller available |
487
505
  | `NO_ACTIVITY` | Android: no host activity available |
488
506
  | `INVALID_ITEMS` | Cart items could not be parsed |
507
+ | `INVALID_ACCOUNT` | `accountId` was missing or empty (presentCheckout, presentCart) |
508
+ | `INVALID_OWNER` | Apple Pay / Google Pay `owner` was missing, malformed, or had an empty `id` |
509
+ | `INVALID_MERCHANT_ID` | Apple Pay `merchantId` was missing or empty |
510
+ | `INVALID_AMOUNT` | Google Pay `amountCents` was missing or non-positive |
489
511
  | `NO_RESULT` | Native activity returned OK but no payload |
490
512
  | `PARSE_ERROR` | Could not decode the native response |
491
- | `ENCODE_ERROR` | iOS: could not encode the charge intent |
513
+ | `APPLE_PAY_UNAVAILABLE` | iOS: device cannot make Apple Pay payments |
514
+ | `GOOGLE_PAY_UNAVAILABLE` | Android: Google Pay not ready on the device |
515
+ | `NOT_ATTESTED` | iOS: device attestation has not completed yet |
516
+ | `PAYMENT_METHOD_FAILED` | iOS: Apple Pay payment method creation failed |
517
+ | `PAYMENT_FAILED` | Wallet flow failed during Transfer creation |
492
518
  | `NETWORK_ERROR` | Network failure in the native SDK |
493
519
  | `API_ERROR` | Frame API returned an error |
494
520
 
@@ -498,7 +524,7 @@ You can also use the `isFrameError` and `normalizeToFrameError` utilities for ty
498
524
  import { isFrameError, normalizeToFrameError } from 'framepayments-react-native';
499
525
 
500
526
  try {
501
- await Frame.presentCheckout({ amount: 5000 });
527
+ await Frame.presentCheckout({ accountId: 'acct_xxx', amount: 5000 });
502
528
  } catch (e) {
503
529
  const err = normalizeToFrameError(e);
504
530
  // err.code, err.message, err.nativeError are all typed strings
@@ -562,10 +588,6 @@ Also ensure the **Frame-iOS** Swift package is added in Xcode (**File → Add Pa
562
588
 
563
589
  Ensure you are using SDK version 1.1.0+. Earlier versions had a bug where programmatic dismiss from the onboarding flow did not resolve the promise.
564
590
 
565
- ### `presentCart` returns `{}` on iOS
566
-
567
- This is a known limitation of `FrameCartView` on iOS — it does not expose the `ChargeIntent` from its nested checkout. On Android, the full object is returned. Guard with `intent?.id` before reading the result.
568
-
569
591
  ### `App ID verification failed` from `presentApplePay`
570
592
 
571
593
  The Frame backend computes `SHA256("<TeamID>.<BundleID>")` from the merchant's dashboard configuration and compares it to the hash signed by the device during attestation. A mismatch returns `App ID verification failed`. Fix: open your Frame dashboard → **Settings → Device Attestation** and confirm both the Apple Team ID and the Bundle ID match the iOS app you're running.
@@ -1 +1 @@
1
- #Fri May 01 16:00:34 PDT 2026
1
+ #Tue May 12 16:27:30 PDT 2026
@@ -31,9 +31,9 @@ android {
31
31
  dependencies {
32
32
  implementation 'com.facebook.react:react-native:+'
33
33
  implementation "org.jetbrains.kotlin:kotlin-stdlib:2.1.0"
34
- implementation 'com.framepayments:framesdk:2.0.4'
35
- implementation 'com.framepayments:framesdk_ui:2.0.4'
36
- implementation 'com.framepayments:framesdk_onboarding:2.0.4'
34
+ implementation 'com.framepayments:framesdk:2.0.7'
35
+ implementation 'com.framepayments:framesdk_ui:2.0.7'
36
+ implementation 'com.framepayments:framesdk_onboarding:2.0.7'
37
37
  // Required by FrameGooglePayButton (PaymentsClient, WalletConstants).
38
38
  // framesdk_ui declares this as `implementation`, so it is not exposed transitively.
39
39
  implementation 'com.google.android.gms:play-services-wallet:19.4.0'
@@ -7,9 +7,7 @@ import android.os.Looper
7
7
  import android.widget.FrameLayout
8
8
  import androidx.appcompat.app.AppCompatActivity
9
9
  import com.framepayments.framesdk.FrameNetworking
10
- import com.framepayments.framesdk.chargeintents.ChargeIntent
11
10
  import com.framepayments.framesdk_ui.FrameCheckoutView
12
- import com.google.gson.Gson
13
11
 
14
12
  class FrameCheckoutActivity : AppCompatActivity() {
15
13
 
@@ -25,17 +23,24 @@ class FrameCheckoutActivity : AppCompatActivity() {
25
23
  )
26
24
  }
27
25
  setContentView(container)
28
- val customerId = intent.getStringExtra(EXTRA_CUSTOMER_ID)
26
+ val accountId = intent.getStringExtra(EXTRA_ACCOUNT_ID)
29
27
  val amount = intent.getIntExtra(EXTRA_AMOUNT, 0)
30
28
 
29
+ // Bundled checkout always creates a Transfer, which requires an account.
30
+ if (accountId.isNullOrEmpty()) {
31
+ setResult(RESULT_CANCELED)
32
+ finish()
33
+ return
34
+ }
35
+
31
36
  // Evervault must be configured before FrameCheckoutView (EncryptedPaymentCardInput) can inflate.
32
37
  // configureEvervault() is async on first launch; direct checkout opens before it completes.
33
- tryShowCheckout(container, customerId, amount)
38
+ tryShowCheckout(container, accountId, amount)
34
39
  }
35
40
 
36
- private fun tryShowCheckout(container: FrameLayout, customerId: String?, amount: Int) {
41
+ private fun tryShowCheckout(container: FrameLayout, accountId: String, amount: Int) {
37
42
  if (FrameNetworking.isEvervaultConfigured) {
38
- addCheckoutView(container, customerId, amount)
43
+ addCheckoutView(container, accountId, amount)
39
44
  return
40
45
  }
41
46
  var attempts = 0
@@ -44,7 +49,7 @@ class FrameCheckoutActivity : AppCompatActivity() {
44
49
  override fun run() {
45
50
  if (isFinishing) return
46
51
  if (FrameNetworking.isEvervaultConfigured) {
47
- addCheckoutView(container, customerId, amount)
52
+ addCheckoutView(container, accountId, amount)
48
53
  pollRunnable = null
49
54
  return
50
55
  }
@@ -60,11 +65,10 @@ class FrameCheckoutActivity : AppCompatActivity() {
60
65
  handler.postDelayed(pollRunnable!!, 100)
61
66
  }
62
67
 
63
- private fun addCheckoutView(container: FrameLayout, customerId: String?, amount: Int) {
68
+ private fun addCheckoutView(container: FrameLayout, accountId: String, amount: Int) {
64
69
  val checkoutView = FrameCheckoutView(this)
65
- checkoutView.configure(customerId, amount) { chargeIntent ->
66
- val json = Gson().toJson(chargeIntent)
67
- setResult(RESULT_OK, Intent().putExtra(EXTRA_CHARGE_INTENT_JSON, json))
70
+ checkoutView.configure(accountId, amount) { transferId ->
71
+ setResult(RESULT_OK, Intent().putExtra(EXTRA_TRANSFER_ID, transferId))
68
72
  finish()
69
73
  }
70
74
  container.addView(checkoutView)
@@ -76,9 +80,9 @@ class FrameCheckoutActivity : AppCompatActivity() {
76
80
  }
77
81
 
78
82
  companion object {
79
- const val EXTRA_CUSTOMER_ID = "customer_id"
83
+ const val EXTRA_ACCOUNT_ID = "account_id"
80
84
  const val EXTRA_AMOUNT = "amount"
81
- const val EXTRA_CHARGE_INTENT_JSON = "charge_intent_json"
85
+ const val EXTRA_TRANSFER_ID = "transfer_id"
82
86
  const val REQUEST_CODE = 9001
83
87
  }
84
88
  }
@@ -27,11 +27,19 @@ class FrameFlowActivity : AppCompatActivity() {
27
27
  override fun onCreate(savedInstanceState: Bundle?) {
28
28
  super.onCreate(savedInstanceState)
29
29
  setContentView(container)
30
- val customerId = intent.getStringExtra(EXTRA_CUSTOMER_ID)
30
+ val accountId = intent.getStringExtra(EXTRA_ACCOUNT_ID)
31
31
  val itemsJson = intent.getStringExtra(EXTRA_ITEMS_JSON)
32
32
  val shippingCents = intent.getIntExtra(EXTRA_SHIPPING_CENTS, 0)
33
33
  val items: List<FrameCartItem> = parseCartItems(itemsJson) ?: emptyList()
34
- showCart(customerId, items, shippingCents)
34
+
35
+ // Bundled cart → checkout always creates a Transfer, which requires an account.
36
+ if (accountId.isNullOrEmpty()) {
37
+ setResult(RESULT_CANCELED)
38
+ finish()
39
+ return
40
+ }
41
+
42
+ showCart(accountId, items, shippingCents)
35
43
  }
36
44
 
37
45
  private fun parseCartItems(json: String?): List<FrameCartItem>? {
@@ -52,22 +60,21 @@ class FrameFlowActivity : AppCompatActivity() {
52
60
  val imageUrl: String
53
61
  )
54
62
 
55
- private fun showCart(customerId: String?, items: List<FrameCartItem>, shippingCents: Int) {
63
+ private fun showCart(accountId: String, items: List<FrameCartItem>, shippingCents: Int) {
56
64
  container.removeAllViews()
57
65
  cartView = FrameCartView(this).apply {
58
- configure(customerId, items, shippingCents, { totalCents ->
59
- showCheckout(customerId, totalCents)
66
+ configure(accountId, items, shippingCents, { totalCents ->
67
+ showCheckout(accountId, totalCents)
60
68
  }, null)
61
69
  }
62
70
  container.addView(cartView)
63
71
  }
64
72
 
65
- private fun showCheckout(customerId: String?, amount: Int) {
73
+ private fun showCheckout(accountId: String, amount: Int) {
66
74
  container.removeAllViews()
67
75
  checkoutView = FrameCheckoutView(this).apply {
68
- configure(customerId, amount) { chargeIntent ->
69
- val json = Gson().toJson(chargeIntent)
70
- setResult(RESULT_OK, Intent().putExtra(EXTRA_CHARGE_INTENT_JSON, json))
76
+ configure(accountId, amount) { transferId ->
77
+ setResult(RESULT_OK, Intent().putExtra(EXTRA_TRANSFER_ID, transferId))
71
78
  finish()
72
79
  }
73
80
  }
@@ -75,10 +82,10 @@ class FrameFlowActivity : AppCompatActivity() {
75
82
  }
76
83
 
77
84
  companion object {
78
- const val EXTRA_CUSTOMER_ID = "customer_id"
85
+ const val EXTRA_ACCOUNT_ID = "account_id"
79
86
  const val EXTRA_ITEMS_JSON = "items_json"
80
87
  const val EXTRA_SHIPPING_CENTS = "shipping_cents"
81
- const val EXTRA_CHARGE_INTENT_JSON = "charge_intent_json"
88
+ const val EXTRA_TRANSFER_ID = "transfer_id"
82
89
  const val REQUEST_CODE = 9002
83
90
  }
84
91
  }
@@ -4,11 +4,9 @@ import android.content.Intent
4
4
  import android.os.Bundle
5
5
  import android.os.Handler
6
6
  import android.os.Looper
7
- import android.view.View
8
7
  import android.widget.FrameLayout
9
8
  import androidx.appcompat.app.AppCompatActivity
10
9
  import com.framepayments.framesdk_ui.buttons.FrameGooglePayButton
11
- import com.google.gson.Gson
12
10
 
13
11
  /**
14
12
  * Hidden host activity for Frame.presentGooglePay(). The Frame Android SDK only
@@ -39,7 +37,8 @@ class FrameGooglePayActivity : AppCompatActivity() {
39
37
  setContentView(container)
40
38
 
41
39
  val amountCents = intent.getIntExtra(EXTRA_AMOUNT_CENTS, 0)
42
- val customerId = intent.getStringExtra(EXTRA_CUSTOMER_ID)
40
+ val ownerType = intent.getStringExtra(EXTRA_OWNER_TYPE)
41
+ val ownerId = intent.getStringExtra(EXTRA_OWNER_ID)
43
42
  val currencyCode = intent.getStringExtra(EXTRA_CURRENCY) ?: "USD"
44
43
  val googlePayMerchantId = intent.getStringExtra(EXTRA_MERCHANT_ID)
45
44
 
@@ -47,6 +46,18 @@ class FrameGooglePayActivity : AppCompatActivity() {
47
46
  deliverFailure("Invalid amountCents")
48
47
  return
49
48
  }
49
+ if (ownerId.isNullOrEmpty()) {
50
+ deliverFailure("owner.id is required")
51
+ return
52
+ }
53
+ val owner: FrameGooglePayButton.Owner = when (ownerType) {
54
+ "customer" -> FrameGooglePayButton.Owner.Customer(ownerId)
55
+ "account" -> FrameGooglePayButton.Owner.Account(ownerId)
56
+ else -> {
57
+ deliverFailure("owner.type must be 'customer' or 'account'")
58
+ return
59
+ }
60
+ }
50
61
 
51
62
  val button = FrameGooglePayButton(this)
52
63
  button.layoutParams = FrameLayout.LayoutParams(1, 1) // tiny but measurable so click can fire
@@ -55,7 +66,7 @@ class FrameGooglePayActivity : AppCompatActivity() {
55
66
 
56
67
  button.configure(
57
68
  amountCents = amountCents,
58
- customerId = customerId,
69
+ owner = owner,
59
70
  currencyCode = currencyCode,
60
71
  googlePayMerchantId = googlePayMerchantId,
61
72
  onResult = { result -> handleResult(result) },
@@ -94,8 +105,14 @@ class FrameGooglePayActivity : AppCompatActivity() {
94
105
  didDeliverResult = true
95
106
  when (result) {
96
107
  is FrameGooglePayButton.Result.Success -> {
97
- val json = Gson().toJson(result.chargeIntent)
98
- deliverViaCallback(android.app.Activity.RESULT_OK, Intent().putExtra(EXTRA_CHARGE_INTENT_JSON, json))
108
+ // `result.id` is a Transfer id (for Owner.Account) or a ChargeIntent id
109
+ // (for Owner.Customer). JS knows which it is because it passed the owner.
110
+ deliverViaCallback(android.app.Activity.RESULT_OK, Intent().putExtra(EXTRA_CHARGE_ID, result.id))
111
+ }
112
+ is FrameGooglePayButton.Result.PaymentMethodCreated -> {
113
+ // RN bridge does not currently expose AddToOwner mode, so this branch
114
+ // shouldn't fire in practice. Surface it as failure instead of silently dropping.
115
+ deliverViaCallback(RESULT_FAILURE, Intent().putExtra(EXTRA_FAILURE_MESSAGE, "Unsupported Google Pay result"))
99
116
  }
100
117
  is FrameGooglePayButton.Result.Failure -> {
101
118
  deliverViaCallback(RESULT_FAILURE, Intent().putExtra(EXTRA_FAILURE_MESSAGE, result.message))
@@ -133,10 +150,16 @@ class FrameGooglePayActivity : AppCompatActivity() {
133
150
 
134
151
  companion object {
135
152
  const val EXTRA_AMOUNT_CENTS = "amount_cents"
136
- const val EXTRA_CUSTOMER_ID = "customer_id"
153
+ const val EXTRA_OWNER_TYPE = "owner_type"
154
+ const val EXTRA_OWNER_ID = "owner_id"
137
155
  const val EXTRA_CURRENCY = "currency"
138
156
  const val EXTRA_MERCHANT_ID = "merchant_id"
139
- const val EXTRA_CHARGE_INTENT_JSON = "charge_intent_json"
157
+ /**
158
+ * The id of the resource created by the wallet flow. Holds a Transfer id when
159
+ * the owner was an account, or a ChargeIntent id when the owner was a customer.
160
+ * JS knows which by inspecting the owner it passed in.
161
+ */
162
+ const val EXTRA_CHARGE_ID = "charge_id"
140
163
  const val EXTRA_FAILURE_MESSAGE = "failure_message"
141
164
 
142
165
  const val REQUEST_CODE = 9003