framepayments-react-native 2.1.1 → 2.1.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/README.md +81 -59
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameCheckoutActivity$Companion.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameCheckoutActivity$tryShowCheckout$1.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameCheckoutActivity.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameFlowActivity$CartItemDto.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameFlowActivity$Companion.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameFlowActivity$parseCartItems$type$1.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameFlowActivity.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameGooglePayActivity$Companion.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameGooglePayActivity.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameOnboardingActivity$Companion.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameOnboardingActivity$parseCapabilities$type$1.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameOnboardingActivity.dex +0 -0
- package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/framepayments/reactnativeframe/FrameSDKModule.dex +0 -0
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameCheckoutActivity$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameCheckoutActivity$tryShowCheckout$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameCheckoutActivity.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameFlowActivity$CartItemDto.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameFlowActivity$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameFlowActivity$parseCartItems$type$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameFlowActivity.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameGooglePayActivity$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameGooglePayActivity.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameOnboardingActivity$Companion.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameOnboardingActivity$parseCapabilities$type$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameOnboardingActivity.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/framepayments/reactnativeframe/FrameSDKModule.class +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab_i +0 -0
- package/android/build/kotlin/compileDebugKotlin/cacheable/last-build.bin +0 -0
- package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameCheckoutActivity$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameCheckoutActivity$tryShowCheckout$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameCheckoutActivity.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameFlowActivity$CartItemDto.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameFlowActivity$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameFlowActivity$parseCartItems$type$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameFlowActivity.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameGooglePayActivity$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameGooglePayActivity.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameOnboardingActivity$Companion.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameOnboardingActivity$parseCapabilities$type$1.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameOnboardingActivity.class +0 -0
- package/android/build/tmp/kotlin-classes/debug/com/framepayments/reactnativeframe/FrameSDKModule.class +0 -0
- package/android/build.gradle +3 -3
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameCheckoutActivity.kt +17 -13
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameFlowActivity.kt +18 -11
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameGooglePayActivity.kt +31 -8
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameSDKModule.kt +28 -35
- package/ios/ApplePayPresenter.swift +53 -28
- package/ios/FrameSDKBridge.m +7 -7
- package/ios/FrameSDKBridge.swift +61 -27
- package/lib/errors.d.ts +9 -1
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +9 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/native.d.ts +37 -7
- package/lib/native.d.ts.map +1 -1
- package/lib/native.js +61 -9
- package/lib/types.d.ts +18 -45
- package/lib/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/native.test.ts +179 -25
- package/src/errors.ts +9 -1
- package/src/index.ts +1 -3
- package/src/native.ts +69 -17
- package/src/types.ts +19 -58
- /package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/{FrameSDKModule$$InternalSyntheticLambda$2$984ab30558bc904ed37602fa6e3ebf28f1ed69df6712b31b00c4f26fc26d3b70$0.globals → FrameSDKModule$$InternalSyntheticLambda$2$7347ff5b95d03cf5be9ee5177309c1bf4be5faabda2bbedb79f5f4c91917c2b1$0.globals} +0 -0
- /package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/{FrameSDKModule$$InternalSyntheticLambda$2$f8d46f7169c404d37a1d505f19439b83090fbed62b5bdaf1e86717fdddebf622$0.globals → FrameSDKModule$$InternalSyntheticLambda$2$7347ff5b95d03cf5be9ee5177309c1bf4be5faabda2bbedb79f5f4c91917c2b1$1.globals} +0 -0
- /package/android/build/.transforms/5a2061641b1fc5518a336681809507bc/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_global-synthetics/com/framepayments/reactnativeframe/{FrameSDKModule$$InternalSyntheticLambda$2$f8d46f7169c404d37a1d505f19439b83090fbed62b5bdaf1e86717fdddebf622$1.globals → FrameSDKModule$$InternalSyntheticLambda$2$9816d2cb3db63bf5efb3411b62dbb57847dd7ef82f88bae5f375baced7880f11$0.globals} +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
|
|
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
|
|
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
|
|
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
|
|
121
|
-
|
|
122
|
-
|
|
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:**
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 |
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
296
|
+
// Account → Transfer
|
|
297
|
+
const transferId = await Frame.presentGooglePay({
|
|
272
298
|
amountCents: 15000,
|
|
273
299
|
currencyCode: 'USD',
|
|
274
|
-
|
|
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
|
-
| `
|
|
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
|
-
|
|
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,
|
|
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: '
|
|
438
|
+
owner: { type: 'account', id: accountId },
|
|
406
439
|
merchantId,
|
|
407
440
|
});
|
|
408
441
|
} else {
|
|
409
|
-
await Frame.presentGooglePay({
|
|
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
|
-
###
|
|
473
|
+
### Inspecting the full resource
|
|
438
474
|
|
|
439
|
-
|
|
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
|
|
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
|
-
| `
|
|
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.
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
#
|
|
1
|
+
#Mon May 11 22:24:08 PDT 2026
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/constants.tab
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/jvm/kotlin/proto.tab.values.at
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.keystream
CHANGED
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.len
CHANGED
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/cacheable/caches-jvm/lookups/lookups.tab.values.at
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build/kotlin/compileDebugKotlin/classpath-snapshot/shrunk-classpath-snapshot.bin
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build.gradle
CHANGED
|
@@ -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.
|
|
35
|
-
implementation 'com.framepayments:framesdk_ui:2.0.
|
|
36
|
-
implementation 'com.framepayments:framesdk_onboarding:2.0.
|
|
34
|
+
implementation 'com.framepayments:framesdk:2.0.6'
|
|
35
|
+
implementation 'com.framepayments:framesdk_ui:2.0.6'
|
|
36
|
+
implementation 'com.framepayments:framesdk_onboarding:2.0.6'
|
|
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
|
|
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,
|
|
38
|
+
tryShowCheckout(container, accountId, amount)
|
|
34
39
|
}
|
|
35
40
|
|
|
36
|
-
private fun tryShowCheckout(container: FrameLayout,
|
|
41
|
+
private fun tryShowCheckout(container: FrameLayout, accountId: String, amount: Int) {
|
|
37
42
|
if (FrameNetworking.isEvervaultConfigured) {
|
|
38
|
-
addCheckoutView(container,
|
|
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,
|
|
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,
|
|
68
|
+
private fun addCheckoutView(container: FrameLayout, accountId: String, amount: Int) {
|
|
64
69
|
val checkoutView = FrameCheckoutView(this)
|
|
65
|
-
checkoutView.configure(
|
|
66
|
-
|
|
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
|
|
83
|
+
const val EXTRA_ACCOUNT_ID = "account_id"
|
|
80
84
|
const val EXTRA_AMOUNT = "amount"
|
|
81
|
-
const val
|
|
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
|
|
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
|
-
|
|
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(
|
|
63
|
+
private fun showCart(accountId: String, items: List<FrameCartItem>, shippingCents: Int) {
|
|
56
64
|
container.removeAllViews()
|
|
57
65
|
cartView = FrameCartView(this).apply {
|
|
58
|
-
configure(
|
|
59
|
-
showCheckout(
|
|
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(
|
|
73
|
+
private fun showCheckout(accountId: String, amount: Int) {
|
|
66
74
|
container.removeAllViews()
|
|
67
75
|
checkoutView = FrameCheckoutView(this).apply {
|
|
68
|
-
configure(
|
|
69
|
-
|
|
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
|
|
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
|
|
88
|
+
const val EXTRA_TRANSFER_ID = "transfer_id"
|
|
82
89
|
const val REQUEST_CODE = 9002
|
|
83
90
|
}
|
|
84
91
|
}
|