framepayments-react-native 3.0.0 → 3.0.1
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.swift +1 -1
- package/README.md +57 -16
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameCheckoutActivity.kt +18 -3
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameFlowActivity.kt +16 -3
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameGooglePayActivity.kt +0 -3
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameOnboardingActivity.kt +2 -5
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameSDKModule.kt +6 -5
- package/ios/ApplePayPresenter.swift +1 -4
- package/ios/FrameSDKBridge.m +8 -8
- package/ios/FrameSDKBridge.swift +68 -36
- package/lib/native.d.ts +12 -2
- package/lib/native.d.ts.map +1 -1
- package/lib/native.js +4 -10
- package/lib/types.d.ts +12 -6
- package/lib/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/native.test.ts +55 -74
- package/src/native.ts +17 -20
- package/src/types.ts +12 -6
package/Package.swift
CHANGED
|
@@ -27,7 +27,7 @@ let package = Package(
|
|
|
27
27
|
dependencies: [
|
|
28
28
|
.package(
|
|
29
29
|
url: "https://github.com/Frame-Payments/frame-ios",
|
|
30
|
-
from: "2.2.
|
|
30
|
+
from: "2.2.3" // Keep in sync with package.json:frameNativeVersions.ios
|
|
31
31
|
)
|
|
32
32
|
],
|
|
33
33
|
targets: [
|
package/README.md
CHANGED
|
@@ -91,6 +91,8 @@ Initializes the native SDK. Must be called before any `present*` method. Call on
|
|
|
91
91
|
await Frame.initialize({
|
|
92
92
|
secretKey: 'sk_sandbox_...', // your Frame secret key
|
|
93
93
|
publishableKey: 'pk_sandbox_...', // your Frame publishable key
|
|
94
|
+
applePayMerchantId: 'merchant.com.yourapp', // optional — see Apple Pay section
|
|
95
|
+
googlePayMerchantId: 'BCR2DN4T...', // optional — see Google Pay section
|
|
94
96
|
debugMode: false, // set true in development to enable native debug logging
|
|
95
97
|
});
|
|
96
98
|
```
|
|
@@ -99,6 +101,8 @@ await Frame.initialize({
|
|
|
99
101
|
|---|---|---|---|
|
|
100
102
|
| `secretKey` | `string` | Yes | Your Frame secret key (`sk_…`). Used for server-style operations. |
|
|
101
103
|
| `publishableKey` | `string` | Yes | Your Frame publishable key (`pk_…`). Used for client-side operations like wallet payments. |
|
|
104
|
+
| `applePayMerchantId` | `string` | No | Apple Pay merchant identifier (`merchant.com.…`). Single source of truth for every Apple Pay surface — `presentApplePay`, the bundled checkout's wallet row, the onboarding wallet attach button. iOS-only; ignored on Android. |
|
|
105
|
+
| `googlePayMerchantId` | `string` | No | Google Pay merchant identifier from the Google Pay & Wallet Console. Single source of truth for every Google Pay surface — `presentGooglePay`, the bundled checkout's wallet row, the onboarding wallet attach button. Android-only; ignored on iOS. |
|
|
102
106
|
| `debugMode` | `boolean` | No | Enables native debug logging and routes wallet flows through sandbox/test environments. Default: `false`. |
|
|
103
107
|
|
|
104
108
|
---
|
|
@@ -184,7 +188,8 @@ if (result.status === 'completed') {
|
|
|
184
188
|
|---|---|---|---|
|
|
185
189
|
| `accountId` | `string` | No | The Frame account to onboard |
|
|
186
190
|
| `capabilities` | `OnboardingCapability[]` | No | Which onboarding steps to include (see below) |
|
|
187
|
-
|
|
191
|
+
|
|
192
|
+
The Apple Pay / Google Pay wallet attach steps are rendered automatically when the corresponding merchant ID was passed to `Frame.initialize`. No per-call merchant params here.
|
|
188
193
|
|
|
189
194
|
**`capabilities` values:**
|
|
190
195
|
|
|
@@ -217,6 +222,8 @@ if (result.status === 'completed') {
|
|
|
217
222
|
|
|
218
223
|
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`.
|
|
219
224
|
|
|
225
|
+
The Apple Pay merchant ID is configured **once** at `Frame.initialize({ applePayMerchantId })`; there is no per-call merchant parameter.
|
|
226
|
+
|
|
220
227
|
The `owner` determines which downstream resource is created:
|
|
221
228
|
|
|
222
229
|
- `owner.type === 'customer'` → creates a `ChargeIntent` against the customer; resolves with the ChargeIntent's `id`.
|
|
@@ -232,7 +239,6 @@ const transferId = await Frame.presentApplePay({
|
|
|
232
239
|
amount: 15000,
|
|
233
240
|
currency: 'usd',
|
|
234
241
|
owner: { type: 'account', id: 'acct_xxx' },
|
|
235
|
-
merchantId: 'merchant.com.yourapp',
|
|
236
242
|
});
|
|
237
243
|
|
|
238
244
|
// Customer → ChargeIntent
|
|
@@ -240,7 +246,6 @@ const chargeIntentId = await Frame.presentApplePay({
|
|
|
240
246
|
amount: 15000,
|
|
241
247
|
currency: 'usd',
|
|
242
248
|
owner: { type: 'customer', id: 'cus_xxx' },
|
|
243
|
-
merchantId: 'merchant.com.yourapp',
|
|
244
249
|
});
|
|
245
250
|
```
|
|
246
251
|
|
|
@@ -249,23 +254,42 @@ const chargeIntentId = await Frame.presentApplePay({
|
|
|
249
254
|
| `amount` | `number` | Yes | Payment amount in cents |
|
|
250
255
|
| `currency` | `string` | No | ISO 4217 currency code. Default `'usd'` |
|
|
251
256
|
| `owner` | `{ type: 'customer' \| 'account', id: string }` | Yes | Customer or account that owns the resulting payment method and charge |
|
|
252
|
-
| `merchantId` | `string` | Yes | Apple Pay merchant ID configured in your Apple Developer account |
|
|
253
257
|
|
|
254
258
|
**Returns:** `Promise<string>` — the created `ChargeIntent`'s `id` (for customer owners) or the `Transfer`'s `id` (for account owners).
|
|
255
259
|
|
|
256
|
-
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.
|
|
260
|
+
The promise rejects with `code: 'USER_CANCELED'` when the user dismisses the sheet, `'INVALID_OWNER'` if the owner is missing or malformed, `'INVALID_MERCHANT_ID'` if `applePayMerchantId` was not configured at `Frame.initialize`, `'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.
|
|
257
261
|
|
|
258
|
-
|
|
262
|
+
#### Required iOS setup
|
|
259
263
|
|
|
260
|
-
|
|
261
|
-
|
|
264
|
+
Apple Pay setup is a four-part process: create a merchant ID with Apple, configure your Xcode project, pass the merchant ID to `Frame.initialize`, then **contact Frame** to enable the feature on your account.
|
|
265
|
+
|
|
266
|
+
1. **Create a merchant identifier.** Sign in to [developer.apple.com → Certificates, Identifiers & Profiles → Identifiers → Merchant IDs](https://developer.apple.com/account/resources/identifiers/list/merchant), click **+**, choose **Merchant IDs**, and create one in reverse-DNS form (e.g. `merchant.com.yourapp`).
|
|
267
|
+
2. **Add the Apple Pay capability in Xcode.** Open your project, select your **app target**, go to **Signing & Capabilities** → **+ Capability** → **Apple Pay**, and add the merchant ID you created in step 1. Xcode writes it into your entitlements file:
|
|
268
|
+
```xml
|
|
269
|
+
<key>com.apple.developer.in-app-payments</key>
|
|
270
|
+
<array>
|
|
271
|
+
<string>merchant.com.yourapp</string>
|
|
272
|
+
</array>
|
|
273
|
+
```
|
|
274
|
+
3. **App Attest entitlement.** Frame uses Apple's App Attest for device attestation on every Apple Pay payment. Add to your `.entitlements`:
|
|
262
275
|
```xml
|
|
263
276
|
<key>com.apple.developer.devicecheck.appattest-environment</key>
|
|
264
277
|
<string>development</string>
|
|
265
278
|
```
|
|
266
|
-
Use `production` for App Store builds.
|
|
267
|
-
|
|
268
|
-
|
|
279
|
+
Use `production` for App Store builds. App Attest does not work in the simulator — Apple Pay requires a real device.
|
|
280
|
+
4. **Frame dashboard — device attestation.** In your Frame dashboard, **Settings → Device Attestation**, set your Apple Team ID and the Bundle ID of your iOS app. These must exactly match the app you're running — the backend computes `SHA256("<TeamID>.<BundleID>")` and compares it to the hash signed by the device. If they don't match, payment-method creation fails with `App ID verification failed`.
|
|
281
|
+
5. **Pass the merchant ID to `Frame.initialize`.** This is the single source of truth — every Frame Apple Pay surface reads it from here.
|
|
282
|
+
```ts
|
|
283
|
+
await Frame.initialize({
|
|
284
|
+
secretKey: 'sk_...',
|
|
285
|
+
publishableKey: 'pk_...',
|
|
286
|
+
applePayMerchantId: 'merchant.com.yourapp',
|
|
287
|
+
});
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
#### Enabling Apple Pay on your account
|
|
291
|
+
|
|
292
|
+
Once the steps above are complete, contact Frame at [support@framepayments.com](mailto:support@framepayments.com) (or via your [Frame dashboard](https://framepayments.com)) and we'll enable Apple Pay on your account. Apple Pay charges won't succeed until this is done on our side.
|
|
269
293
|
|
|
270
294
|
On non-iOS platforms `Frame.presentApplePay` rejects synchronously with a not-supported error.
|
|
271
295
|
|
|
@@ -275,6 +299,8 @@ On non-iOS platforms `Frame.presentApplePay` rejects synchronously with a not-su
|
|
|
275
299
|
|
|
276
300
|
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`.
|
|
277
301
|
|
|
302
|
+
The Google Pay merchant ID is configured **once** at `Frame.initialize({ googlePayMerchantId })`; there is no per-call merchant parameter.
|
|
303
|
+
|
|
278
304
|
The `owner` mirrors `presentApplePay` and determines which downstream resource is created:
|
|
279
305
|
|
|
280
306
|
- `owner.type === 'customer'` → creates a `ChargeIntent` against the customer; resolves with the ChargeIntent's `id`.
|
|
@@ -302,21 +328,36 @@ const chargeIntentId = await Frame.presentGooglePay({
|
|
|
302
328
|
| `amountCents` | `number` | Yes | Payment amount in cents |
|
|
303
329
|
| `owner` | `{ type: 'customer' \| 'account', id: string }` | Yes | Customer or account that owns the resulting payment method and charge |
|
|
304
330
|
| `currencyCode` | `string` | No | ISO 4217 currency code. Default `'USD'` |
|
|
305
|
-
| `googlePayMerchantId` | `string` | No | Google Pay merchant ID override |
|
|
306
331
|
|
|
307
332
|
**Returns:** `Promise<string>` — the created `ChargeIntent`'s `id` (for customer owners) or the `Transfer`'s `id` (for account owners).
|
|
308
333
|
|
|
309
|
-
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.
|
|
334
|
+
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, no `googlePayMerchantId` configured at `Frame.initialize`, or Wallet API disabled in the manifest), and `'PAYMENT_FAILED'` for backend failures.
|
|
335
|
+
|
|
336
|
+
#### Required Android setup
|
|
310
337
|
|
|
311
|
-
**
|
|
338
|
+
Google Pay setup is a four-part process: get a merchant ID from Google, declare the wallet capability in your manifest, pass the merchant ID to `Frame.initialize`, then **contact Frame** to enable the feature on your account.
|
|
312
339
|
|
|
313
|
-
1. **Google Pay
|
|
340
|
+
1. **Obtain a Google Pay merchant ID.** Sign up for a [Google Pay & Wallet Console](https://pay.google.com/business/console/) account, complete the business profile, and accept the Google Pay API Terms of Service. Your **Merchant ID** (looks like `BCR2DN4T…`) appears on the Business Console home page once approved.
|
|
341
|
+
2. **Declare the wallet capability in `AndroidManifest.xml`.** Inside `<application>`:
|
|
314
342
|
```xml
|
|
315
343
|
<meta-data
|
|
316
344
|
android:name="com.google.android.gms.wallet.api.enabled"
|
|
317
345
|
android:value="true" />
|
|
318
346
|
```
|
|
319
|
-
|
|
347
|
+
Without this entry the Google Pay button stays hidden — the Wallet API is opted-out by default.
|
|
348
|
+
3. **Test environment.** When the SDK is initialized with `debugMode: true`, Google Pay runs in `ENVIRONMENT_TEST`; otherwise it uses `ENVIRONMENT_PRODUCTION`.
|
|
349
|
+
4. **Pass the merchant ID to `Frame.initialize`.** This is the single source of truth — every Frame Google Pay surface reads it from here.
|
|
350
|
+
```ts
|
|
351
|
+
await Frame.initialize({
|
|
352
|
+
secretKey: 'sk_...',
|
|
353
|
+
publishableKey: 'pk_...',
|
|
354
|
+
googlePayMerchantId: 'BCR2DN4T...',
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
#### Enabling Google Pay on your account
|
|
359
|
+
|
|
360
|
+
Once the steps above are complete, contact Frame at [support@framepayments.com](mailto:support@framepayments.com) (or via your [Frame dashboard](https://framepayments.com)) and we'll enable Google Pay on your account. Google Pay charges won't succeed until this is done on our side.
|
|
320
361
|
|
|
321
362
|
On non-Android platforms `Frame.presentGooglePay` rejects synchronously with a not-supported error.
|
|
322
363
|
|
|
@@ -7,6 +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.FrameResult
|
|
10
11
|
import com.framepayments.framesdk_ui.FrameCheckoutView
|
|
11
12
|
|
|
12
13
|
class FrameCheckoutActivity : AppCompatActivity() {
|
|
@@ -68,9 +69,23 @@ class FrameCheckoutActivity : AppCompatActivity() {
|
|
|
68
69
|
private fun addCheckoutView(container: FrameLayout, accountId: String, amount: Int) {
|
|
69
70
|
val checkoutView = FrameCheckoutView(this)
|
|
70
71
|
FrameRNTheme.current?.let { checkoutView.setTheme(it) }
|
|
71
|
-
checkoutView.configure(accountId, amount) {
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
checkoutView.configure(accountId, amount) { result ->
|
|
73
|
+
when (result) {
|
|
74
|
+
is FrameResult.Completed -> {
|
|
75
|
+
setResult(RESULT_OK, Intent().putExtra(EXTRA_TRANSFER_ID, result.id))
|
|
76
|
+
finish()
|
|
77
|
+
}
|
|
78
|
+
FrameResult.Cancelled -> {
|
|
79
|
+
setResult(RESULT_CANCELED)
|
|
80
|
+
finish()
|
|
81
|
+
}
|
|
82
|
+
is FrameResult.Failed -> {
|
|
83
|
+
// Surfaced as USER_CANCELED at the JS layer (RESULT_CANCELED maps to it in FrameSDKModule).
|
|
84
|
+
// Per-error toast UI is already shown by the native FrameCheckoutView before this fires.
|
|
85
|
+
setResult(RESULT_CANCELED)
|
|
86
|
+
finish()
|
|
87
|
+
}
|
|
88
|
+
}
|
|
74
89
|
}
|
|
75
90
|
container.addView(checkoutView)
|
|
76
91
|
}
|
|
@@ -4,6 +4,7 @@ import android.content.Intent
|
|
|
4
4
|
import android.os.Bundle
|
|
5
5
|
import android.widget.FrameLayout
|
|
6
6
|
import androidx.appcompat.app.AppCompatActivity
|
|
7
|
+
import com.framepayments.framesdk.FrameResult
|
|
7
8
|
import com.framepayments.framesdk_ui.FrameCartItem
|
|
8
9
|
import com.framepayments.framesdk_ui.FrameCartView
|
|
9
10
|
import com.framepayments.framesdk_ui.FrameCheckoutView
|
|
@@ -75,9 +76,21 @@ class FrameFlowActivity : AppCompatActivity() {
|
|
|
75
76
|
container.removeAllViews()
|
|
76
77
|
checkoutView = FrameCheckoutView(this).apply {
|
|
77
78
|
FrameRNTheme.current?.let { setTheme(it) }
|
|
78
|
-
configure(accountId, amount) {
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
configure(accountId, amount) { result ->
|
|
80
|
+
when (result) {
|
|
81
|
+
is FrameResult.Completed -> {
|
|
82
|
+
setResult(RESULT_OK, Intent().putExtra(EXTRA_TRANSFER_ID, result.id))
|
|
83
|
+
finish()
|
|
84
|
+
}
|
|
85
|
+
FrameResult.Cancelled -> {
|
|
86
|
+
setResult(RESULT_CANCELED)
|
|
87
|
+
finish()
|
|
88
|
+
}
|
|
89
|
+
is FrameResult.Failed -> {
|
|
90
|
+
setResult(RESULT_CANCELED)
|
|
91
|
+
finish()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
81
94
|
}
|
|
82
95
|
}
|
|
83
96
|
container.addView(checkoutView)
|
|
@@ -40,7 +40,6 @@ class FrameGooglePayActivity : AppCompatActivity() {
|
|
|
40
40
|
val ownerType = intent.getStringExtra(EXTRA_OWNER_TYPE)
|
|
41
41
|
val ownerId = intent.getStringExtra(EXTRA_OWNER_ID)
|
|
42
42
|
val currencyCode = intent.getStringExtra(EXTRA_CURRENCY) ?: "USD"
|
|
43
|
-
val googlePayMerchantId = intent.getStringExtra(EXTRA_MERCHANT_ID)
|
|
44
43
|
|
|
45
44
|
if (amountCents <= 0) {
|
|
46
45
|
deliverFailure("Invalid amountCents")
|
|
@@ -68,7 +67,6 @@ class FrameGooglePayActivity : AppCompatActivity() {
|
|
|
68
67
|
amountCents = amountCents,
|
|
69
68
|
owner = owner,
|
|
70
69
|
currencyCode = currencyCode,
|
|
71
|
-
googlePayMerchantId = googlePayMerchantId,
|
|
72
70
|
onResult = { result -> handleResult(result) },
|
|
73
71
|
onReadinessChanged = { isReady -> handleReadiness(isReady) }
|
|
74
72
|
)
|
|
@@ -153,7 +151,6 @@ class FrameGooglePayActivity : AppCompatActivity() {
|
|
|
153
151
|
const val EXTRA_OWNER_TYPE = "owner_type"
|
|
154
152
|
const val EXTRA_OWNER_ID = "owner_id"
|
|
155
153
|
const val EXTRA_CURRENCY = "currency"
|
|
156
|
-
const val EXTRA_MERCHANT_ID = "merchant_id"
|
|
157
154
|
/**
|
|
158
155
|
* The id of the resource created by the wallet flow. Holds a Transfer id when
|
|
159
156
|
* the owner was an account, or a ChargeIntent id when the owner was a customer.
|
|
@@ -19,12 +19,10 @@ class FrameOnboardingActivity : ComponentActivity() {
|
|
|
19
19
|
val accountId = intent.getStringExtra(EXTRA_ACCOUNT_ID)
|
|
20
20
|
val capabilitiesJson = intent.getStringExtra(EXTRA_CAPABILITIES_JSON) ?: "[]"
|
|
21
21
|
val capabilities = parseCapabilities(capabilitiesJson)
|
|
22
|
-
val googlePayMerchantId = intent.getStringExtra(EXTRA_GOOGLE_PAY_MERCHANT_ID)
|
|
23
22
|
|
|
24
23
|
val config = OnboardingConfig(
|
|
25
24
|
accountId = accountId,
|
|
26
|
-
requiredCapabilities = capabilities
|
|
27
|
-
googlePayMerchantId = googlePayMerchantId
|
|
25
|
+
requiredCapabilities = capabilities
|
|
28
26
|
)
|
|
29
27
|
|
|
30
28
|
val themeOverride = FrameRNTheme.current
|
|
@@ -44,7 +42,7 @@ class FrameOnboardingActivity : ComponentActivity() {
|
|
|
44
42
|
setResult(RESULT_CANCELED)
|
|
45
43
|
finish()
|
|
46
44
|
}
|
|
47
|
-
is OnboardingResult.
|
|
45
|
+
is OnboardingResult.Failed -> {
|
|
48
46
|
setResult(RESULT_CANCELED)
|
|
49
47
|
finish()
|
|
50
48
|
}
|
|
@@ -69,7 +67,6 @@ class FrameOnboardingActivity : ComponentActivity() {
|
|
|
69
67
|
companion object {
|
|
70
68
|
const val EXTRA_ACCOUNT_ID = "account_id"
|
|
71
69
|
const val EXTRA_CAPABILITIES_JSON = "capabilities_json"
|
|
72
|
-
const val EXTRA_GOOGLE_PAY_MERCHANT_ID = "google_pay_merchant_id"
|
|
73
70
|
const val EXTRA_PAYMENT_METHOD_ID = "payment_method_id"
|
|
74
71
|
const val REQUEST_CODE = 9003
|
|
75
72
|
}
|
|
@@ -36,12 +36,17 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
|
|
|
36
36
|
secretKey: String,
|
|
37
37
|
publishableKey: String,
|
|
38
38
|
debugMode: Boolean,
|
|
39
|
+
applePayMerchantId: String?,
|
|
40
|
+
googlePayMerchantId: String?,
|
|
39
41
|
theme: ReadableMap?,
|
|
40
42
|
promise: Promise
|
|
41
43
|
) {
|
|
42
44
|
try {
|
|
43
45
|
val ctx = reactApplicationContext.applicationContext
|
|
44
|
-
|
|
46
|
+
// applePayMerchantId is iOS-only; accepted in the bridge signature so the JS Frame.initialize()
|
|
47
|
+
// API stays cross-platform, but ignored here. frame-android has no Apple Pay surface.
|
|
48
|
+
@Suppress("UNUSED_PARAMETER") val ignoredApplePayMerchantId = applePayMerchantId
|
|
49
|
+
FrameNetworking.initializeWithAPIKey(ctx, secretKey, publishableKey, googlePayMerchantId, debugMode)
|
|
45
50
|
FrameRNTheme.current = theme?.takeIf { it.keySetIterator().hasNextKey() }?.let {
|
|
46
51
|
FrameRNTheme.parse(ctx, it)
|
|
47
52
|
}
|
|
@@ -99,7 +104,6 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
|
|
|
99
104
|
ownerType: String?,
|
|
100
105
|
ownerId: String?,
|
|
101
106
|
currencyCode: String?,
|
|
102
|
-
googlePayMerchantId: String?,
|
|
103
107
|
promise: Promise
|
|
104
108
|
) {
|
|
105
109
|
val activity = reactApplicationContext.currentActivity ?: run {
|
|
@@ -129,7 +133,6 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
|
|
|
129
133
|
putExtra(FrameGooglePayActivity.EXTRA_OWNER_TYPE, ownerType)
|
|
130
134
|
putExtra(FrameGooglePayActivity.EXTRA_OWNER_ID, ownerId)
|
|
131
135
|
putExtra(FrameGooglePayActivity.EXTRA_CURRENCY, currencyCode ?: "USD")
|
|
132
|
-
putExtra(FrameGooglePayActivity.EXTRA_MERCHANT_ID, googlePayMerchantId)
|
|
133
136
|
}
|
|
134
137
|
activity.startActivity(intent)
|
|
135
138
|
}
|
|
@@ -139,7 +142,6 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
|
|
|
139
142
|
fun presentOnboarding(
|
|
140
143
|
accountId: String?,
|
|
141
144
|
capabilities: ReadableArray,
|
|
142
|
-
googlePayMerchantId: String?,
|
|
143
145
|
promise: Promise
|
|
144
146
|
) {
|
|
145
147
|
val activity = reactApplicationContext.currentActivity ?: run {
|
|
@@ -152,7 +154,6 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
|
|
|
152
154
|
val intent = Intent(activity, FrameOnboardingActivity::class.java).apply {
|
|
153
155
|
putExtra(FrameOnboardingActivity.EXTRA_ACCOUNT_ID, accountId)
|
|
154
156
|
putExtra(FrameOnboardingActivity.EXTRA_CAPABILITIES_JSON, capabilitiesJson)
|
|
155
|
-
putExtra(FrameOnboardingActivity.EXTRA_GOOGLE_PAY_MERCHANT_ID, googlePayMerchantId)
|
|
156
157
|
}
|
|
157
158
|
activity.startActivityForResult(intent, FrameOnboardingActivity.REQUEST_CODE)
|
|
158
159
|
}
|
|
@@ -28,7 +28,6 @@ final class ApplePayPresenter: NSObject, PKPaymentAuthorizationControllerDelegat
|
|
|
28
28
|
private let amount: Int
|
|
29
29
|
private let currency: String
|
|
30
30
|
private let owner: Owner
|
|
31
|
-
private let merchantId: String
|
|
32
31
|
private let resolve: (Any?) -> Void
|
|
33
32
|
private let reject: (String, String, Error?) -> Void
|
|
34
33
|
|
|
@@ -46,13 +45,11 @@ final class ApplePayPresenter: NSObject, PKPaymentAuthorizationControllerDelegat
|
|
|
46
45
|
init(amount: Int,
|
|
47
46
|
currency: String,
|
|
48
47
|
owner: Owner,
|
|
49
|
-
merchantId: String,
|
|
50
48
|
resolve: @escaping (Any?) -> Void,
|
|
51
49
|
reject: @escaping (String, String, Error?) -> Void) {
|
|
52
50
|
self.amount = amount
|
|
53
51
|
self.currency = currency
|
|
54
52
|
self.owner = owner
|
|
55
|
-
self.merchantId = merchantId
|
|
56
53
|
self.resolve = resolve
|
|
57
54
|
self.reject = reject
|
|
58
55
|
}
|
|
@@ -63,7 +60,7 @@ final class ApplePayPresenter: NSObject, PKPaymentAuthorizationControllerDelegat
|
|
|
63
60
|
|
|
64
61
|
func present() {
|
|
65
62
|
let request = PKPaymentRequest()
|
|
66
|
-
request.merchantIdentifier =
|
|
63
|
+
request.merchantIdentifier = FrameNetworking.shared.applePayMerchantId ?? ""
|
|
67
64
|
request.supportedNetworks = Self.supportedNetworks
|
|
68
65
|
request.merchantCapabilities = .threeDSecure
|
|
69
66
|
request.countryCode = "US"
|
package/ios/FrameSDKBridge.m
CHANGED
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
RCT_EXTERN_METHOD(initialize:(NSString *)secretKey
|
|
29
29
|
publishableKey:(NSString *)publishableKey
|
|
30
30
|
debugMode:(BOOL)debugMode
|
|
31
|
+
applePayMerchantId:(id)applePayMerchantId
|
|
32
|
+
googlePayMerchantId:(id)googlePayMerchantId
|
|
31
33
|
theme:(NSDictionary *)theme
|
|
32
34
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
33
35
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
@@ -45,7 +47,6 @@ RCT_EXTERN_METHOD(presentCart:(id)accountId
|
|
|
45
47
|
|
|
46
48
|
RCT_EXTERN_METHOD(presentOnboarding:(id)accountId
|
|
47
49
|
capabilities:(NSArray *)capabilities
|
|
48
|
-
applePayMerchantId:(id)applePayMerchantId
|
|
49
50
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
50
51
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
51
52
|
|
|
@@ -53,7 +54,6 @@ RCT_EXTERN_METHOD(presentApplePay:(NSString *)ownerType
|
|
|
53
54
|
ownerId:(NSString *)ownerId
|
|
54
55
|
amount:(nonnull NSNumber *)amount
|
|
55
56
|
currency:(NSString *)currency
|
|
56
|
-
merchantId:(NSString *)merchantId
|
|
57
57
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
58
58
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
59
59
|
|
|
@@ -68,8 +68,8 @@ RCT_EXTERN_METHOD(presentApplePay:(NSString *)ownerType
|
|
|
68
68
|
return YES;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
- (void)initialize:(NSString *)secretKey publishableKey:(NSString *)publishableKey debugMode:(BOOL)debugMode theme:(NSDictionary *)theme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
72
|
-
[[[ObjCFrameSDKBridge alloc] init] initialize:secretKey publishableKey:publishableKey debugMode:debugMode theme:theme resolver:resolve rejecter:reject];
|
|
71
|
+
- (void)initialize:(NSString *)secretKey publishableKey:(NSString *)publishableKey debugMode:(BOOL)debugMode applePayMerchantId:(id)applePayMerchantId googlePayMerchantId:(id)googlePayMerchantId theme:(NSDictionary *)theme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
72
|
+
[[[ObjCFrameSDKBridge alloc] init] initialize:secretKey publishableKey:publishableKey debugMode:debugMode applePayMerchantId:applePayMerchantId googlePayMerchantId:googlePayMerchantId theme:theme resolver:resolve rejecter:reject];
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
- (void)presentCheckout:(id)accountId amount:(NSNumber *)amount resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
@@ -95,19 +95,19 @@ RCT_EXTERN_METHOD(presentApplePay:(NSString *)ownerType
|
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
- (void)presentOnboarding:(id)accountId capabilities:(NSArray *)capabilities
|
|
98
|
+
- (void)presentOnboarding:(id)accountId capabilities:(NSArray *)capabilities resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
99
99
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
100
100
|
UIViewController *topVC = FrameGetTopViewController();
|
|
101
101
|
if (!topVC) {
|
|
102
102
|
reject(@"NO_ROOT_VC", @"Could not find root view controller to present onboarding", nil);
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
|
-
[[[ObjCFrameSDKBridge alloc] init] presentOnboardingFrom:topVC accountId:accountId capabilities:capabilities
|
|
105
|
+
[[[ObjCFrameSDKBridge alloc] init] presentOnboardingFrom:topVC accountId:accountId capabilities:capabilities resolver:resolve rejecter:reject];
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
- (void)presentApplePay:(NSString *)ownerType ownerId:(NSString *)ownerId amount:(NSNumber *)amount currency:(NSString *)currency
|
|
110
|
-
[[[ObjCFrameSDKBridge alloc] init] presentApplePay:ownerType ownerId:ownerId amount:amount.intValue currency:currency
|
|
109
|
+
- (void)presentApplePay:(NSString *)ownerType ownerId:(NSString *)ownerId amount:(NSNumber *)amount currency:(NSString *)currency resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
110
|
+
[[[ObjCFrameSDKBridge alloc] init] presentApplePay:ownerType ownerId:ownerId amount:amount.intValue currency:currency resolver:resolve rejecter:reject];
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
@end
|
package/ios/FrameSDKBridge.swift
CHANGED
|
@@ -20,11 +20,21 @@ public class FrameSDKBridge: NSObject {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
@objc public
|
|
23
|
-
func initialize(_ secretKey: String, publishableKey: String, debugMode: Bool, theme: NSDictionary?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
23
|
+
func initialize(_ secretKey: String, publishableKey: String, debugMode: Bool, applePayMerchantId: NSObject?, googlePayMerchantId: NSObject?, theme: NSDictionary?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
24
24
|
DispatchQueue.main.async {
|
|
25
25
|
let themeDict = theme as? [String: Any] ?? [:]
|
|
26
26
|
let resolvedTheme = themeDict.isEmpty ? FrameTheme.default : FrameRNTheme.parse(themeDict)
|
|
27
|
-
|
|
27
|
+
// googlePayMerchantId is iOS-side ignored — frame-iOS has no Google Pay surface today.
|
|
28
|
+
// Accepted in the bridge signature so the JS Frame.initialize() API stays cross-platform.
|
|
29
|
+
_ = googlePayMerchantId
|
|
30
|
+
let applePayMerchantIdString = applePayMerchantId as? String
|
|
31
|
+
FrameNetworking.shared.initializeWithAPIKey(
|
|
32
|
+
secretKey,
|
|
33
|
+
publishableKey: publishableKey,
|
|
34
|
+
applePayMerchantId: applePayMerchantIdString,
|
|
35
|
+
theme: resolvedTheme,
|
|
36
|
+
debugMode: debugMode
|
|
37
|
+
)
|
|
28
38
|
resolve(nil)
|
|
29
39
|
}
|
|
30
40
|
}
|
|
@@ -52,15 +62,14 @@ public class FrameSDKBridge: NSObject {
|
|
|
52
62
|
}
|
|
53
63
|
|
|
54
64
|
@objc public
|
|
55
|
-
func presentOnboarding(from viewController: UIViewController, accountId: NSObject?, capabilities: NSArray,
|
|
65
|
+
func presentOnboarding(from viewController: UIViewController, accountId: NSObject?, capabilities: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
56
66
|
let parsedCapabilities = parseCapabilities(capabilities)
|
|
57
67
|
let accountIdString = accountId as? String
|
|
58
|
-
|
|
59
|
-
presentOnboardingOnMain(from: viewController, accountId: accountIdString, capabilities: parsedCapabilities, applePayMerchantId: merchantIdString, resolve: resolve, reject: reject)
|
|
68
|
+
presentOnboardingOnMain(from: viewController, accountId: accountIdString, capabilities: parsedCapabilities, resolve: resolve, reject: reject)
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
@objc public
|
|
63
|
-
func presentApplePay(_ ownerType: String, ownerId: String, amount: Int, currency: String,
|
|
72
|
+
func presentApplePay(_ ownerType: String, ownerId: String, amount: Int, currency: String, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
64
73
|
DispatchQueue.main.async {
|
|
65
74
|
Task { @MainActor in
|
|
66
75
|
let owner: ApplePayPresenter.Owner
|
|
@@ -75,8 +84,9 @@ public class FrameSDKBridge: NSObject {
|
|
|
75
84
|
reject("INVALID_OWNER", "owner.id must be non-empty", nil)
|
|
76
85
|
return
|
|
77
86
|
}
|
|
78
|
-
|
|
79
|
-
|
|
87
|
+
let configuredMerchantId = FrameNetworking.shared.applePayMerchantId ?? ""
|
|
88
|
+
guard !configuredMerchantId.isEmpty else {
|
|
89
|
+
reject("INVALID_MERCHANT_ID", "Apple Pay merchant ID is not configured. Pass `applePayMerchantId` to Frame.initialize().", nil)
|
|
80
90
|
return
|
|
81
91
|
}
|
|
82
92
|
guard ApplePayPresenter.canMakePayments() else {
|
|
@@ -94,7 +104,6 @@ public class FrameSDKBridge: NSObject {
|
|
|
94
104
|
amount: amount,
|
|
95
105
|
currency: currency,
|
|
96
106
|
owner: owner,
|
|
97
|
-
merchantId: merchantId,
|
|
98
107
|
resolve: { resolve($0) },
|
|
99
108
|
reject: { code, message, error in reject(code, message, error) }
|
|
100
109
|
)
|
|
@@ -106,17 +115,21 @@ public class FrameSDKBridge: NSObject {
|
|
|
106
115
|
// MARK: - Private helpers
|
|
107
116
|
|
|
108
117
|
private func presentCheckoutOnMain(from top: UIViewController, accountId: String, amount: Int, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
109
|
-
// Single dismiss delegate guards against double-resolve
|
|
110
|
-
//
|
|
111
|
-
//
|
|
118
|
+
// Single dismiss delegate guards against double-resolve. The native FrameCheckoutView now
|
|
119
|
+
// emits `.cancelled` on its own .onDisappear and the bridge's
|
|
120
|
+
// `presentationControllerDidDismiss` ALSO fires on swipe-down — the delegate's `didFinish`
|
|
121
|
+
// guard prevents the double-resolve.
|
|
112
122
|
let delegate = CheckoutDismissDelegate(resolve: resolve, reject: reject)
|
|
113
123
|
let checkoutView = FrameCheckoutView(
|
|
114
124
|
accountId: accountId,
|
|
115
125
|
paymentAmount: amount,
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
onResult: { [weak top, delegate] result in
|
|
127
|
+
switch result {
|
|
128
|
+
case .completed(let id):
|
|
129
|
+
delegate.finish(.success(id))
|
|
130
|
+
case .cancelled:
|
|
131
|
+
delegate.finish(.cancel)
|
|
132
|
+
case .failed:
|
|
120
133
|
delegate.finish(.failure)
|
|
121
134
|
}
|
|
122
135
|
top?.dismiss(animated: true)
|
|
@@ -164,19 +177,22 @@ public class FrameSDKBridge: NSObject {
|
|
|
164
177
|
}
|
|
165
178
|
|
|
166
179
|
private func presentCartOnMain(from top: UIViewController, accountId: String, cartItems: [RNFrameCartItem], shippingAmountInCents: Int, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
167
|
-
// Single dismiss delegate guards against double-resolve
|
|
168
|
-
//
|
|
169
|
-
//
|
|
180
|
+
// Single dismiss delegate guards against double-resolve. The native FrameCartView's own
|
|
181
|
+
// .onDisappear emits `.cancelled`, and the bridge's `presentationControllerDidDismiss`
|
|
182
|
+
// also fires on swipe-down — the delegate's `didFinish` guard prevents re-resolve.
|
|
170
183
|
let delegate = CartDismissDelegate(resolve: resolve, reject: reject)
|
|
171
184
|
let cartView = FrameCartView(
|
|
172
185
|
accountId: accountId,
|
|
173
186
|
cartItems: cartItems,
|
|
174
187
|
shippingAmountInCents: shippingAmountInCents,
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
188
|
+
onResult: { [weak top, delegate] result in
|
|
189
|
+
switch result {
|
|
190
|
+
case .completed(let id):
|
|
191
|
+
delegate.finish(.success(id))
|
|
192
|
+
case .cancelled:
|
|
179
193
|
delegate.finish(.cancel)
|
|
194
|
+
case .failed:
|
|
195
|
+
delegate.finish(.failure)
|
|
180
196
|
}
|
|
181
197
|
top?.dismiss(animated: true)
|
|
182
198
|
}
|
|
@@ -192,21 +208,23 @@ public class FrameSDKBridge: NSObject {
|
|
|
192
208
|
}
|
|
193
209
|
}
|
|
194
210
|
|
|
195
|
-
private func presentOnboardingOnMain(from top: UIViewController, accountId: String?, capabilities: [FrameObjects.Capabilities],
|
|
196
|
-
// Build the dismiss delegate up-front so
|
|
197
|
-
// instance directly. Earlier shape declared `var delegate: …!` and assigned
|
|
198
|
-
// it AFTER constructing OnboardingContainerView; the onComplete closure
|
|
199
|
-
// captured the local by reference, so any path that fired the callback
|
|
200
|
-
// before assignment landed on a nil delegate and silently no-op'd via `?.`.
|
|
211
|
+
private func presentOnboardingOnMain(from top: UIViewController, accountId: String?, capabilities: [FrameObjects.Capabilities], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
212
|
+
// Build the dismiss delegate up-front so onResult captures a non-nil instance directly.
|
|
201
213
|
let delegate = OnboardingDismissDelegate(resolve: resolve)
|
|
202
214
|
|
|
203
215
|
let hosting = OnboardingHostingController(
|
|
204
216
|
rootView: OnboardingContainerView(
|
|
205
217
|
accountId: accountId,
|
|
206
218
|
requiredCapabilities: capabilities,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
219
|
+
onResult: { [delegate, weak top] result in
|
|
220
|
+
switch result {
|
|
221
|
+
case .completed(let id):
|
|
222
|
+
delegate.finish(.completed(paymentMethodId: id.isEmpty ? nil : id))
|
|
223
|
+
case .cancelled:
|
|
224
|
+
delegate.finish(.cancelled)
|
|
225
|
+
case .failed:
|
|
226
|
+
delegate.finish(.cancelled)
|
|
227
|
+
}
|
|
210
228
|
top?.dismiss(animated: true)
|
|
211
229
|
}
|
|
212
230
|
)
|
|
@@ -276,6 +294,7 @@ private final class CheckoutDismissDelegate: NSObject, UIAdaptivePresentationCon
|
|
|
276
294
|
private final class CartDismissDelegate: NSObject, UIAdaptivePresentationControllerDelegate {
|
|
277
295
|
enum Outcome {
|
|
278
296
|
case success(String)
|
|
297
|
+
case failure
|
|
279
298
|
case cancel
|
|
280
299
|
}
|
|
281
300
|
|
|
@@ -294,6 +313,7 @@ private final class CartDismissDelegate: NSObject, UIAdaptivePresentationControl
|
|
|
294
313
|
DispatchQueue.main.async { [resolve, reject] in
|
|
295
314
|
switch outcome {
|
|
296
315
|
case .success(let transferId): resolve(transferId)
|
|
316
|
+
case .failure: reject("PAYMENT_FAILED", "Cart checkout did not produce a transfer id", nil)
|
|
297
317
|
case .cancel: reject("USER_CANCELED", "User dismissed cart without completing checkout", nil)
|
|
298
318
|
}
|
|
299
319
|
}
|
|
@@ -305,6 +325,11 @@ private final class CartDismissDelegate: NSObject, UIAdaptivePresentationControl
|
|
|
305
325
|
}
|
|
306
326
|
|
|
307
327
|
private final class OnboardingDismissDelegate: NSObject, UIAdaptivePresentationControllerDelegate {
|
|
328
|
+
enum Outcome {
|
|
329
|
+
case completed(paymentMethodId: String?)
|
|
330
|
+
case cancelled
|
|
331
|
+
}
|
|
332
|
+
|
|
308
333
|
let resolve: RCTPromiseResolveBlock
|
|
309
334
|
weak var hostingController: UIViewController?
|
|
310
335
|
var didFinish = false
|
|
@@ -313,11 +338,18 @@ private final class OnboardingDismissDelegate: NSObject, UIAdaptivePresentationC
|
|
|
313
338
|
self.resolve = resolve
|
|
314
339
|
}
|
|
315
340
|
|
|
316
|
-
func finish(
|
|
341
|
+
func finish(_ outcome: Outcome) {
|
|
317
342
|
guard !didFinish else { return }
|
|
318
343
|
didFinish = true
|
|
319
|
-
DispatchQueue.main.async { [resolve
|
|
320
|
-
|
|
344
|
+
DispatchQueue.main.async { [resolve] in
|
|
345
|
+
switch outcome {
|
|
346
|
+
case .completed(let paymentMethodId):
|
|
347
|
+
var payload: [String: Any] = ["status": "completed"]
|
|
348
|
+
if let paymentMethodId { payload["paymentMethodId"] = paymentMethodId }
|
|
349
|
+
resolve(payload)
|
|
350
|
+
case .cancelled:
|
|
351
|
+
resolve(["status": "cancelled"])
|
|
352
|
+
}
|
|
321
353
|
}
|
|
322
354
|
}
|
|
323
355
|
|
|
@@ -326,7 +358,7 @@ private final class OnboardingDismissDelegate: NSObject, UIAdaptivePresentationC
|
|
|
326
358
|
// callback to the Onboarding host's delegate. Only treat dismissal of the
|
|
327
359
|
// Onboarding hosting controller itself as a cancellation.
|
|
328
360
|
guard presentationController.presentedViewController === hostingController else { return }
|
|
329
|
-
finish(
|
|
361
|
+
finish(.cancelled)
|
|
330
362
|
}
|
|
331
363
|
}
|
|
332
364
|
|
package/lib/native.d.ts
CHANGED
|
@@ -6,6 +6,18 @@ export declare function initialize(options: {
|
|
|
6
6
|
secretKey: string;
|
|
7
7
|
publishableKey: string;
|
|
8
8
|
debugMode?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Apple Pay merchant ID configured in your Apple Developer account. Applied to every
|
|
11
|
+
* Apple Pay surface (presentApplePay, the bundled checkout's wallet row, the
|
|
12
|
+
* onboarding wallet attach button). iOS-only — ignored on Android.
|
|
13
|
+
*/
|
|
14
|
+
applePayMerchantId?: string;
|
|
15
|
+
/**
|
|
16
|
+
* Google Pay merchant ID from the Google Pay & Wallet Console. Applied to every
|
|
17
|
+
* Google Pay surface (presentGooglePay, the bundled checkout's wallet row, the
|
|
18
|
+
* onboarding wallet attach button). Android-only — ignored on iOS.
|
|
19
|
+
*/
|
|
20
|
+
googlePayMerchantId?: string;
|
|
9
21
|
/**
|
|
10
22
|
* Optional theme applied SDK-wide to Frame's reusable iOS components
|
|
11
23
|
* (checkout, cart, onboarding). Pass any subset — unspecified tokens fall
|
|
@@ -41,8 +53,6 @@ export declare function presentCart(options: {
|
|
|
41
53
|
export declare function presentOnboarding(options: {
|
|
42
54
|
accountId?: string | null;
|
|
43
55
|
capabilities?: OnboardingCapability[];
|
|
44
|
-
applePayMerchantId?: string | null;
|
|
45
|
-
googlePayMerchantId?: string | null;
|
|
46
56
|
}): Promise<OnboardingResult>;
|
|
47
57
|
/**
|
|
48
58
|
* Presents the Apple Pay sheet and creates a charge from the resulting wallet
|
package/lib/native.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAiCjB,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAiCjB,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhB;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAQlB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;CAC/B,GAAG,OAAO,CAAC,MAAM,CAAC,CAYlB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;CACvC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAQ5B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBhF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBlF"}
|
package/lib/native.js
CHANGED
|
@@ -34,7 +34,7 @@ export function initialize(options) {
|
|
|
34
34
|
if (options.theme !== undefined && (typeof options.theme !== 'object' || Array.isArray(options.theme))) {
|
|
35
35
|
throwCoded(ErrorCodes.INIT_FAILED, 'Frame.initialize: theme must be an object');
|
|
36
36
|
}
|
|
37
|
-
return wrapPromise(FrameSDK.initialize(options.secretKey, options.publishableKey, options.debugMode ?? false, options.theme ?? null)).then(() => {
|
|
37
|
+
return wrapPromise(FrameSDK.initialize(options.secretKey, options.publishableKey, options.debugMode ?? false, options.applePayMerchantId ?? null, options.googlePayMerchantId ?? null, options.theme ?? null)).then(() => {
|
|
38
38
|
isInitialized = true;
|
|
39
39
|
});
|
|
40
40
|
}
|
|
@@ -89,10 +89,7 @@ export function presentCart(options) {
|
|
|
89
89
|
}
|
|
90
90
|
export function presentOnboarding(options) {
|
|
91
91
|
guardInitialized();
|
|
92
|
-
|
|
93
|
-
return wrapPromise(FrameSDK.presentOnboarding(options.accountId ?? null, options.capabilities ?? [], options.applePayMerchantId ?? null));
|
|
94
|
-
}
|
|
95
|
-
return wrapPromise(FrameSDK.presentOnboarding(options.accountId ?? null, options.capabilities ?? [], options.googlePayMerchantId ?? null));
|
|
92
|
+
return wrapPromise(FrameSDK.presentOnboarding(options.accountId ?? null, options.capabilities ?? []));
|
|
96
93
|
}
|
|
97
94
|
/**
|
|
98
95
|
* Presents the Apple Pay sheet and creates a charge from the resulting wallet
|
|
@@ -113,10 +110,7 @@ export function presentApplePay(options) {
|
|
|
113
110
|
if (!options.owner.id) {
|
|
114
111
|
throwCoded(ErrorCodes.INVALID_OWNER, 'Frame.presentApplePay requires owner.id');
|
|
115
112
|
}
|
|
116
|
-
|
|
117
|
-
throwCoded(ErrorCodes.INVALID_MERCHANT_ID, 'Frame.presentApplePay requires merchantId');
|
|
118
|
-
}
|
|
119
|
-
return wrapPromise(FrameSDK.presentApplePay(options.owner.type, options.owner.id, options.amount, options.currency ?? 'usd', options.merchantId));
|
|
113
|
+
return wrapPromise(FrameSDK.presentApplePay(options.owner.type, options.owner.id, options.amount, options.currency ?? 'usd'));
|
|
120
114
|
}
|
|
121
115
|
/**
|
|
122
116
|
* Presents Google Pay and creates a charge from the resulting wallet payment method.
|
|
@@ -136,5 +130,5 @@ export function presentGooglePay(options) {
|
|
|
136
130
|
if (!options.owner.id) {
|
|
137
131
|
throwCoded(ErrorCodes.INVALID_OWNER, 'Frame.presentGooglePay requires owner.id');
|
|
138
132
|
}
|
|
139
|
-
return wrapPromise(FrameSDK.presentGooglePay(options.amountCents, options.owner.type, options.owner.id, options.currencyCode ?? 'USD'
|
|
133
|
+
return wrapPromise(FrameSDK.presentGooglePay(options.amountCents, options.owner.type, options.owner.id, options.currencyCode ?? 'USD'));
|
|
140
134
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -79,7 +79,12 @@ export type WalletOwner = {
|
|
|
79
79
|
};
|
|
80
80
|
/** @deprecated Use {@link WalletOwner}. Retained as an alias for source compatibility. */
|
|
81
81
|
export type ApplePayOwner = WalletOwner;
|
|
82
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* Options for Frame.presentApplePay.
|
|
84
|
+
*
|
|
85
|
+
* The Apple Pay merchant ID is set once at `Frame.initialize({ applePayMerchantId })`. There is
|
|
86
|
+
* no per-call merchant ID parameter — the SDK reads it from the singleton at present time.
|
|
87
|
+
*/
|
|
83
88
|
export interface PresentApplePayOptions {
|
|
84
89
|
/** Payment amount in cents. */
|
|
85
90
|
amount: number;
|
|
@@ -87,10 +92,13 @@ export interface PresentApplePayOptions {
|
|
|
87
92
|
currency?: string;
|
|
88
93
|
/** Customer or account that owns the resulting payment method and charge. */
|
|
89
94
|
owner: WalletOwner;
|
|
90
|
-
/** Apple Pay merchant ID configured in your Apple Developer account. */
|
|
91
|
-
merchantId: string;
|
|
92
95
|
}
|
|
93
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Options for Frame.presentGooglePay.
|
|
98
|
+
*
|
|
99
|
+
* The Google Pay merchant ID is set once at `Frame.initialize({ googlePayMerchantId })`. There
|
|
100
|
+
* is no per-call merchant ID parameter — the SDK reads it from the singleton at present time.
|
|
101
|
+
*/
|
|
94
102
|
export interface PresentGooglePayOptions {
|
|
95
103
|
/** Payment amount in cents. */
|
|
96
104
|
amountCents: number;
|
|
@@ -98,8 +106,6 @@ export interface PresentGooglePayOptions {
|
|
|
98
106
|
owner: WalletOwner;
|
|
99
107
|
/** ISO 4217 currency code. Defaults to 'USD'. */
|
|
100
108
|
currencyCode?: string;
|
|
101
|
-
/** Optional override for the Google Pay merchant ID. */
|
|
102
|
-
googlePayMerchantId?: string;
|
|
103
109
|
}
|
|
104
110
|
/**
|
|
105
111
|
* Theming for Frame's reusable iOS components (checkout, cart, onboarding).
|
package/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,sFAAsF;AACtF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,+DAA+D;AAC/D,MAAM,MAAM,oBAAoB,GAC5B,KAAK,GACL,aAAa,GACb,oBAAoB,GACpB,gBAAgB,GAChB,mBAAmB,GACnB,WAAW,GACX,cAAc,GACd,sBAAsB,GACtB,2BAA2B,GAC3B,mBAAmB,GACnB,sBAAsB,GACtB,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,MAAM,MAAM,sBAAsB,GAAG,WAAW,GAAG,WAAW,CAAC;AAE/D,6CAA6C;AAC7C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,oFAAoF;IACpF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpC,0FAA0F;AAC1F,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC;AAExC
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "framepayments-react-native",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "React Native SDK for Frame Payments - modal checkout and cart, with API usage via frame-node.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
"react-native": ">=0.81.0"
|
|
35
35
|
},
|
|
36
36
|
"frameNativeVersions": {
|
|
37
|
-
"ios": "2.2.
|
|
38
|
-
"android": "2.0.
|
|
37
|
+
"ios": "2.2.3",
|
|
38
|
+
"android": "2.0.9"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/jest": "^29.5.0",
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* presentApplePay, presentGooglePay, presentOnboarding). NativeModules.FrameSDK is mocked.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const mockInitialize = jest.fn((_secretKey: string, _publishableKey: string, _debugMode: boolean) => Promise.resolve());
|
|
6
|
+
const mockInitialize = jest.fn((_secretKey: string, _publishableKey: string, _debugMode: boolean, _applePayMerchantId: string | null, _googlePayMerchantId: string | null, _theme: unknown) => Promise.resolve());
|
|
7
7
|
const mockPresentCheckout = jest.fn((_accountId: unknown, _amount: number) => Promise.resolve('tr_1'));
|
|
8
8
|
const mockPresentCart = jest.fn((_accountId: unknown, _items: unknown[], _shipping: number) => Promise.resolve('tr_2'));
|
|
9
|
-
const mockPresentApplePay = jest.fn((_ownerType: string, _ownerId: string, _amount: number, _currency: string
|
|
10
|
-
const mockPresentGooglePay = jest.fn((_amountCents: number, _ownerType: string, _ownerId: string, _currencyCode: string
|
|
11
|
-
const mockPresentOnboarding = jest.fn((_accountId: unknown, _capabilities: unknown[]
|
|
9
|
+
const mockPresentApplePay = jest.fn((_ownerType: string, _ownerId: string, _amount: number, _currency: string) => Promise.resolve('tr_3'));
|
|
10
|
+
const mockPresentGooglePay = jest.fn((_amountCents: number, _ownerType: string, _ownerId: string, _currencyCode: string) => Promise.resolve('tr_4'));
|
|
11
|
+
const mockPresentOnboarding = jest.fn((_accountId: unknown, _capabilities: unknown[]) => Promise.resolve({ status: 'completed', paymentMethodId: 'pm_1' }));
|
|
12
12
|
|
|
13
13
|
const mockPlatform = { OS: 'ios' as 'ios' | 'android' };
|
|
14
14
|
|
|
@@ -27,16 +27,16 @@ jest.mock('react-native', () => ({
|
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
29
|
// Re-import after mock so we get the mocked NativeModules
|
|
30
|
-
let initialize: (opts: { secretKey: string; publishableKey: string; debugMode?: boolean }) => Promise<void>;
|
|
30
|
+
let initialize: (opts: { secretKey: string; publishableKey: string; debugMode?: boolean; applePayMerchantId?: string; googlePayMerchantId?: string }) => Promise<void>;
|
|
31
31
|
let presentCheckout: (opts: { accountId: string; amount: number }) => Promise<string>;
|
|
32
32
|
let presentCart: (opts: {
|
|
33
33
|
accountId: string;
|
|
34
34
|
items: Array<{ id: string; title: string; amountInCents: number; imageUrl: string }>;
|
|
35
35
|
shippingAmountInCents: number;
|
|
36
36
|
}) => Promise<string>;
|
|
37
|
-
let presentApplePay: (opts: { amount: number; currency?: string; owner: { type: 'customer' | 'account'; id: string }
|
|
38
|
-
let presentGooglePay: (opts: { amountCents: number; owner: { type: 'customer' | 'account'; id: string }; currencyCode?: string
|
|
39
|
-
let presentOnboarding: (opts: { accountId?: string | null; capabilities?: string[]
|
|
37
|
+
let presentApplePay: (opts: { amount: number; currency?: string; owner: { type: 'customer' | 'account'; id: string } }) => Promise<string>;
|
|
38
|
+
let presentGooglePay: (opts: { amountCents: number; owner: { type: 'customer' | 'account'; id: string }; currencyCode?: string }) => Promise<string>;
|
|
39
|
+
let presentOnboarding: (opts: { accountId?: string | null; capabilities?: string[] }) => Promise<unknown>;
|
|
40
40
|
|
|
41
41
|
beforeEach(() => {
|
|
42
42
|
jest.resetModules();
|
|
@@ -57,15 +57,33 @@ beforeEach(() => {
|
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
describe('initialize', () => {
|
|
60
|
-
it('calls native FrameSDK.initialize with
|
|
60
|
+
it('calls native FrameSDK.initialize with all six positional args', () => {
|
|
61
61
|
initialize({ secretKey: 'sk_test_xxx', publishableKey: 'pk_test_xxx', debugMode: true });
|
|
62
62
|
expect(mockInitialize).toHaveBeenCalledTimes(1);
|
|
63
|
-
expect(mockInitialize).toHaveBeenCalledWith('sk_test_xxx', 'pk_test_xxx', true, null);
|
|
63
|
+
expect(mockInitialize).toHaveBeenCalledWith('sk_test_xxx', 'pk_test_xxx', true, null, null, null);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
-
it('defaults debugMode to false', () => {
|
|
66
|
+
it('defaults debugMode to false and both merchant IDs to null', () => {
|
|
67
67
|
initialize({ secretKey: 'sk_test_yyy', publishableKey: 'pk_test_yyy' });
|
|
68
|
-
expect(mockInitialize).toHaveBeenCalledWith('sk_test_yyy', 'pk_test_yyy', false, null);
|
|
68
|
+
expect(mockInitialize).toHaveBeenCalledWith('sk_test_yyy', 'pk_test_yyy', false, null, null, null);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('forwards applePayMerchantId to native init', () => {
|
|
72
|
+
initialize({
|
|
73
|
+
secretKey: 'sk_test',
|
|
74
|
+
publishableKey: 'pk_test',
|
|
75
|
+
applePayMerchantId: 'merchant.com.example',
|
|
76
|
+
});
|
|
77
|
+
expect(mockInitialize).toHaveBeenCalledWith('sk_test', 'pk_test', false, 'merchant.com.example', null, null);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('forwards googlePayMerchantId to native init', () => {
|
|
81
|
+
initialize({
|
|
82
|
+
secretKey: 'sk_test',
|
|
83
|
+
publishableKey: 'pk_test',
|
|
84
|
+
googlePayMerchantId: 'BCR2DN4T...',
|
|
85
|
+
});
|
|
86
|
+
expect(mockInitialize).toHaveBeenCalledWith('sk_test', 'pk_test', false, null, 'BCR2DN4T...', null);
|
|
69
87
|
});
|
|
70
88
|
|
|
71
89
|
it('throws if secretKey is missing', () => {
|
|
@@ -153,7 +171,7 @@ describe('presentCart', () => {
|
|
|
153
171
|
describe('presentApplePay', () => {
|
|
154
172
|
it('throws NOT_INITIALIZED if initialize was not called', async () => {
|
|
155
173
|
try {
|
|
156
|
-
await presentApplePay({ amount: 100, owner: { type: 'account', id: 'acct_1' }
|
|
174
|
+
await presentApplePay({ amount: 100, owner: { type: 'account', id: 'acct_1' } });
|
|
157
175
|
expect(true).toBe(false);
|
|
158
176
|
} catch (e: any) {
|
|
159
177
|
expect(e.code).toBe('NOT_INITIALIZED');
|
|
@@ -164,7 +182,7 @@ describe('presentApplePay', () => {
|
|
|
164
182
|
it('throws INVALID_OWNER when owner is missing', async () => {
|
|
165
183
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
166
184
|
try {
|
|
167
|
-
await presentApplePay({ amount: 100
|
|
185
|
+
await presentApplePay({ amount: 100 } as any);
|
|
168
186
|
expect(true).toBe(false);
|
|
169
187
|
} catch (e: any) {
|
|
170
188
|
expect(e.code).toBe('INVALID_OWNER');
|
|
@@ -175,7 +193,7 @@ describe('presentApplePay', () => {
|
|
|
175
193
|
it('throws INVALID_OWNER when owner.id is empty', async () => {
|
|
176
194
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
177
195
|
try {
|
|
178
|
-
await presentApplePay({ amount: 100, owner: { type: 'account', id: '' }
|
|
196
|
+
await presentApplePay({ amount: 100, owner: { type: 'account', id: '' } });
|
|
179
197
|
expect(true).toBe(false);
|
|
180
198
|
} catch (e: any) {
|
|
181
199
|
expect(e.code).toBe('INVALID_OWNER');
|
|
@@ -183,43 +201,30 @@ describe('presentApplePay', () => {
|
|
|
183
201
|
expect(mockPresentApplePay).not.toHaveBeenCalled();
|
|
184
202
|
});
|
|
185
203
|
|
|
186
|
-
it('throws INVALID_MERCHANT_ID when merchantId is missing', async () => {
|
|
187
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
188
|
-
try {
|
|
189
|
-
await presentApplePay({ amount: 100, owner: { type: 'account', id: 'acct_1' } } as any);
|
|
190
|
-
expect(true).toBe(false);
|
|
191
|
-
} catch (e: any) {
|
|
192
|
-
expect(e.code).toBe('INVALID_MERCHANT_ID');
|
|
193
|
-
}
|
|
194
|
-
expect(mockPresentApplePay).not.toHaveBeenCalled();
|
|
195
|
-
});
|
|
196
|
-
|
|
197
204
|
it('forwards account owner; resolves with transfer id string', async () => {
|
|
198
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
205
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx', applePayMerchantId: 'merchant.test' });
|
|
199
206
|
const result = await presentApplePay({
|
|
200
207
|
amount: 12345,
|
|
201
208
|
currency: 'usd',
|
|
202
209
|
owner: { type: 'account', id: 'acct_1' },
|
|
203
|
-
merchantId: 'merchant.test',
|
|
204
210
|
});
|
|
205
|
-
expect(mockPresentApplePay).toHaveBeenCalledWith('account', 'acct_1', 12345, 'usd'
|
|
211
|
+
expect(mockPresentApplePay).toHaveBeenCalledWith('account', 'acct_1', 12345, 'usd');
|
|
206
212
|
expect(result).toBe('tr_3');
|
|
207
213
|
});
|
|
208
214
|
|
|
209
215
|
it('forwards customer owner; resolves with charge intent id string', async () => {
|
|
210
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
216
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx', applePayMerchantId: 'merchant.test' });
|
|
211
217
|
await presentApplePay({
|
|
212
218
|
amount: 9999,
|
|
213
219
|
owner: { type: 'customer', id: 'cus_1' },
|
|
214
|
-
merchantId: 'merchant.test',
|
|
215
220
|
});
|
|
216
|
-
expect(mockPresentApplePay).toHaveBeenCalledWith('customer', 'cus_1', 9999, 'usd'
|
|
221
|
+
expect(mockPresentApplePay).toHaveBeenCalledWith('customer', 'cus_1', 9999, 'usd');
|
|
217
222
|
});
|
|
218
223
|
|
|
219
224
|
it('defaults currency to usd', async () => {
|
|
220
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
221
|
-
await presentApplePay({ amount: 100, owner: { type: 'account', id: 'acct_1' }
|
|
222
|
-
expect(mockPresentApplePay).toHaveBeenCalledWith('account', 'acct_1', 100, 'usd'
|
|
225
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx', applePayMerchantId: 'merchant.test' });
|
|
226
|
+
await presentApplePay({ amount: 100, owner: { type: 'account', id: 'acct_1' } });
|
|
227
|
+
expect(mockPresentApplePay).toHaveBeenCalledWith('account', 'acct_1', 100, 'usd');
|
|
223
228
|
});
|
|
224
229
|
});
|
|
225
230
|
|
|
@@ -262,30 +267,29 @@ describe('presentGooglePay', () => {
|
|
|
262
267
|
});
|
|
263
268
|
|
|
264
269
|
it('forwards account owner; resolves with transfer id string', async () => {
|
|
265
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
270
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx', googlePayMerchantId: 'BCR2DN4T...' });
|
|
266
271
|
const result = await presentGooglePay({
|
|
267
272
|
amountCents: 9999,
|
|
268
273
|
owner: { type: 'account', id: 'acct_1' },
|
|
269
274
|
currencyCode: 'EUR',
|
|
270
|
-
googlePayMerchantId: 'BCR2DN4T...',
|
|
271
275
|
});
|
|
272
|
-
expect(mockPresentGooglePay).toHaveBeenCalledWith(9999, 'account', 'acct_1', 'EUR'
|
|
276
|
+
expect(mockPresentGooglePay).toHaveBeenCalledWith(9999, 'account', 'acct_1', 'EUR');
|
|
273
277
|
expect(result).toBe('tr_4');
|
|
274
278
|
});
|
|
275
279
|
|
|
276
280
|
it('forwards customer owner; resolves with charge intent id string', async () => {
|
|
277
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
281
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx', googlePayMerchantId: 'BCR2DN4T...' });
|
|
278
282
|
await presentGooglePay({
|
|
279
283
|
amountCents: 4242,
|
|
280
284
|
owner: { type: 'customer', id: 'cus_1' },
|
|
281
285
|
});
|
|
282
|
-
expect(mockPresentGooglePay).toHaveBeenCalledWith(4242, 'customer', 'cus_1', 'USD'
|
|
286
|
+
expect(mockPresentGooglePay).toHaveBeenCalledWith(4242, 'customer', 'cus_1', 'USD');
|
|
283
287
|
});
|
|
284
288
|
|
|
285
|
-
it('defaults currencyCode to USD
|
|
286
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
289
|
+
it('defaults currencyCode to USD', async () => {
|
|
290
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx', googlePayMerchantId: 'BCR2DN4T...' });
|
|
287
291
|
await presentGooglePay({ amountCents: 100, owner: { type: 'account', id: 'acct_1' } });
|
|
288
|
-
expect(mockPresentGooglePay).toHaveBeenCalledWith(100, 'account', 'acct_1', 'USD'
|
|
292
|
+
expect(mockPresentGooglePay).toHaveBeenCalledWith(100, 'account', 'acct_1', 'USD');
|
|
289
293
|
});
|
|
290
294
|
});
|
|
291
295
|
|
|
@@ -301,46 +305,23 @@ describe('presentOnboarding', () => {
|
|
|
301
305
|
expect(mockPresentOnboarding).not.toHaveBeenCalled();
|
|
302
306
|
});
|
|
303
307
|
|
|
304
|
-
it('calls native presentOnboarding with accountId
|
|
305
|
-
mockPlatform.OS = 'ios';
|
|
308
|
+
it('calls native presentOnboarding with accountId and capabilities only — no merchant params', async () => {
|
|
306
309
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
307
310
|
const result = await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc', 'bank_account_verification'] });
|
|
308
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc', 'bank_account_verification']
|
|
311
|
+
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc', 'bank_account_verification']);
|
|
309
312
|
expect(result).toEqual({ status: 'completed', paymentMethodId: 'pm_1' });
|
|
310
313
|
});
|
|
311
314
|
|
|
312
|
-
it('passes null
|
|
313
|
-
mockPlatform.OS = 'ios';
|
|
315
|
+
it('passes null accountId and empty array for capabilities when not provided', async () => {
|
|
314
316
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
315
317
|
await presentOnboarding({});
|
|
316
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith(null, []
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
it('forwards applePayMerchantId on iOS', async () => {
|
|
320
|
-
mockPlatform.OS = 'ios';
|
|
321
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
322
|
-
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'], applePayMerchantId: 'merchant.com.example' });
|
|
323
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc'], 'merchant.com.example');
|
|
318
|
+
expect(mockPresentOnboarding).toHaveBeenCalledWith(null, []);
|
|
324
319
|
});
|
|
325
320
|
|
|
326
|
-
it('
|
|
321
|
+
it('behaves the same on Android — merchant IDs are init-only across both platforms', async () => {
|
|
327
322
|
mockPlatform.OS = 'android';
|
|
328
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
329
|
-
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc']
|
|
330
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc']
|
|
331
|
-
});
|
|
332
|
-
|
|
333
|
-
it('forwards googlePayMerchantId to native presentOnboarding on Android', async () => {
|
|
334
|
-
mockPlatform.OS = 'android';
|
|
335
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
336
|
-
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'], googlePayMerchantId: 'BCR2DN4T...' });
|
|
337
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc'], 'BCR2DN4T...');
|
|
338
|
-
});
|
|
339
|
-
|
|
340
|
-
it('ignores googlePayMerchantId on iOS', async () => {
|
|
341
|
-
mockPlatform.OS = 'ios';
|
|
342
|
-
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
343
|
-
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'], googlePayMerchantId: 'BCR2DN4T...' });
|
|
344
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc'], null);
|
|
323
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx', googlePayMerchantId: 'BCR2DN4T...' });
|
|
324
|
+
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'] });
|
|
325
|
+
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc']);
|
|
345
326
|
});
|
|
346
327
|
});
|
package/src/native.ts
CHANGED
|
@@ -47,6 +47,18 @@ export function initialize(options: {
|
|
|
47
47
|
secretKey: string;
|
|
48
48
|
publishableKey: string;
|
|
49
49
|
debugMode?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Apple Pay merchant ID configured in your Apple Developer account. Applied to every
|
|
52
|
+
* Apple Pay surface (presentApplePay, the bundled checkout's wallet row, the
|
|
53
|
+
* onboarding wallet attach button). iOS-only — ignored on Android.
|
|
54
|
+
*/
|
|
55
|
+
applePayMerchantId?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Google Pay merchant ID from the Google Pay & Wallet Console. Applied to every
|
|
58
|
+
* Google Pay surface (presentGooglePay, the bundled checkout's wallet row, the
|
|
59
|
+
* onboarding wallet attach button). Android-only — ignored on iOS.
|
|
60
|
+
*/
|
|
61
|
+
googlePayMerchantId?: string;
|
|
50
62
|
/**
|
|
51
63
|
* Optional theme applied SDK-wide to Frame's reusable iOS components
|
|
52
64
|
* (checkout, cart, onboarding). Pass any subset — unspecified tokens fall
|
|
@@ -69,6 +81,8 @@ export function initialize(options: {
|
|
|
69
81
|
options.secretKey,
|
|
70
82
|
options.publishableKey,
|
|
71
83
|
options.debugMode ?? false,
|
|
84
|
+
options.applePayMerchantId ?? null,
|
|
85
|
+
options.googlePayMerchantId ?? null,
|
|
72
86
|
options.theme ?? null
|
|
73
87
|
)
|
|
74
88
|
).then(() => {
|
|
@@ -147,24 +161,12 @@ export function presentCart(options: {
|
|
|
147
161
|
export function presentOnboarding(options: {
|
|
148
162
|
accountId?: string | null;
|
|
149
163
|
capabilities?: OnboardingCapability[];
|
|
150
|
-
applePayMerchantId?: string | null;
|
|
151
|
-
googlePayMerchantId?: string | null;
|
|
152
164
|
}): Promise<OnboardingResult> {
|
|
153
165
|
guardInitialized();
|
|
154
|
-
if (Platform.OS === 'ios') {
|
|
155
|
-
return wrapPromise(
|
|
156
|
-
FrameSDK.presentOnboarding(
|
|
157
|
-
options.accountId ?? null,
|
|
158
|
-
options.capabilities ?? [],
|
|
159
|
-
options.applePayMerchantId ?? null
|
|
160
|
-
)
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
166
|
return wrapPromise(
|
|
164
167
|
FrameSDK.presentOnboarding(
|
|
165
168
|
options.accountId ?? null,
|
|
166
|
-
options.capabilities ?? []
|
|
167
|
-
options.googlePayMerchantId ?? null
|
|
169
|
+
options.capabilities ?? []
|
|
168
170
|
)
|
|
169
171
|
);
|
|
170
172
|
}
|
|
@@ -188,16 +190,12 @@ export function presentApplePay(options: PresentApplePayOptions): Promise<string
|
|
|
188
190
|
if (!options.owner.id) {
|
|
189
191
|
throwCoded(ErrorCodes.INVALID_OWNER, 'Frame.presentApplePay requires owner.id');
|
|
190
192
|
}
|
|
191
|
-
if (!options.merchantId) {
|
|
192
|
-
throwCoded(ErrorCodes.INVALID_MERCHANT_ID, 'Frame.presentApplePay requires merchantId');
|
|
193
|
-
}
|
|
194
193
|
return wrapPromise(
|
|
195
194
|
FrameSDK.presentApplePay(
|
|
196
195
|
options.owner.type,
|
|
197
196
|
options.owner.id,
|
|
198
197
|
options.amount,
|
|
199
|
-
options.currency ?? 'usd'
|
|
200
|
-
options.merchantId
|
|
198
|
+
options.currency ?? 'usd'
|
|
201
199
|
)
|
|
202
200
|
);
|
|
203
201
|
}
|
|
@@ -225,8 +223,7 @@ export function presentGooglePay(options: PresentGooglePayOptions): Promise<stri
|
|
|
225
223
|
options.amountCents,
|
|
226
224
|
options.owner.type,
|
|
227
225
|
options.owner.id,
|
|
228
|
-
options.currencyCode ?? 'USD'
|
|
229
|
-
options.googlePayMerchantId ?? null
|
|
226
|
+
options.currencyCode ?? 'USD'
|
|
230
227
|
)
|
|
231
228
|
);
|
|
232
229
|
}
|
package/src/types.ts
CHANGED
|
@@ -100,7 +100,12 @@ export type WalletOwner =
|
|
|
100
100
|
/** @deprecated Use {@link WalletOwner}. Retained as an alias for source compatibility. */
|
|
101
101
|
export type ApplePayOwner = WalletOwner;
|
|
102
102
|
|
|
103
|
-
/**
|
|
103
|
+
/**
|
|
104
|
+
* Options for Frame.presentApplePay.
|
|
105
|
+
*
|
|
106
|
+
* The Apple Pay merchant ID is set once at `Frame.initialize({ applePayMerchantId })`. There is
|
|
107
|
+
* no per-call merchant ID parameter — the SDK reads it from the singleton at present time.
|
|
108
|
+
*/
|
|
104
109
|
export interface PresentApplePayOptions {
|
|
105
110
|
/** Payment amount in cents. */
|
|
106
111
|
amount: number;
|
|
@@ -108,11 +113,14 @@ export interface PresentApplePayOptions {
|
|
|
108
113
|
currency?: string;
|
|
109
114
|
/** Customer or account that owns the resulting payment method and charge. */
|
|
110
115
|
owner: WalletOwner;
|
|
111
|
-
/** Apple Pay merchant ID configured in your Apple Developer account. */
|
|
112
|
-
merchantId: string;
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* Options for Frame.presentGooglePay.
|
|
120
|
+
*
|
|
121
|
+
* The Google Pay merchant ID is set once at `Frame.initialize({ googlePayMerchantId })`. There
|
|
122
|
+
* is no per-call merchant ID parameter — the SDK reads it from the singleton at present time.
|
|
123
|
+
*/
|
|
116
124
|
export interface PresentGooglePayOptions {
|
|
117
125
|
/** Payment amount in cents. */
|
|
118
126
|
amountCents: number;
|
|
@@ -120,8 +128,6 @@ export interface PresentGooglePayOptions {
|
|
|
120
128
|
owner: WalletOwner;
|
|
121
129
|
/** ISO 4217 currency code. Defaults to 'USD'. */
|
|
122
130
|
currencyCode?: string;
|
|
123
|
-
/** Optional override for the Google Pay merchant ID. */
|
|
124
|
-
googlePayMerchantId?: string;
|
|
125
131
|
}
|
|
126
132
|
|
|
127
133
|
/**
|