framepayments-react-native 2.0.9 → 2.1.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/README.md +20 -15
- package/android/src/main/java/com/framepayments/reactnativeframe/FrameSDKModule.kt +9 -1
- package/ios/FrameRNTheme.swift +3 -24
- package/ios/FrameSDKBridge.m +5 -28
- package/ios/FrameSDKBridge.swift +35 -51
- package/lib/index.d.ts +3 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -4
- package/lib/native.d.ts +7 -9
- package/lib/native.d.ts.map +1 -1
- package/lib/native.js +7 -21
- package/package.json +3 -1
- package/src/__tests__/native.test.ts +12 -15
- package/src/index.ts +1 -4
- package/src/native.ts +17 -26
package/README.md
CHANGED
|
@@ -299,32 +299,37 @@ On non-Android platforms `Frame.presentGooglePay` rejects synchronously with a n
|
|
|
299
299
|
|
|
300
300
|
---
|
|
301
301
|
|
|
302
|
-
###
|
|
302
|
+
### Theming (iOS)
|
|
303
303
|
|
|
304
304
|
Customizes colors, fonts, and corner radii on Frame's reusable components — checkout, cart, and the onboarding flow. Backed by `FrameTheme` introduced in Frame-iOS 2.1.2.
|
|
305
305
|
|
|
306
|
-
|
|
306
|
+
Pass an optional `theme` to `Frame.initialize`. It's stored on `FrameNetworking.shared` and read by every Frame view at present time, so all subsequent `present*` calls render with it. Modals already on screen are not re-themed if the theme is changed mid-flow. Omit the field, or pass `{}`, to use SDK defaults; pass a partial dict to override only specific tokens.
|
|
307
307
|
|
|
308
308
|
```ts
|
|
309
309
|
import Frame from 'framepayments-react-native';
|
|
310
310
|
|
|
311
|
-
await Frame.
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
311
|
+
await Frame.initialize({
|
|
312
|
+
secretKey: 'sk_sandbox_...',
|
|
313
|
+
publishableKey: 'pk_sandbox_...',
|
|
314
|
+
debugMode: __DEV__,
|
|
315
|
+
theme: {
|
|
316
|
+
colors: {
|
|
317
|
+
primaryButton: '#5B2DFF',
|
|
318
|
+
primaryButtonText: '#FFFFFF',
|
|
319
|
+
surface: '#0A0A0A',
|
|
320
|
+
textPrimary: '#FFFFFF',
|
|
321
|
+
error: '#E53935',
|
|
322
|
+
},
|
|
323
|
+
fonts: {
|
|
324
|
+
title: { name: 'Inter-Bold', size: 24 },
|
|
325
|
+
button: { name: 'Inter-SemiBold', size: 16 },
|
|
326
|
+
},
|
|
327
|
+
radii: { medium: 16 },
|
|
322
328
|
},
|
|
323
|
-
radii: { medium: 16 },
|
|
324
329
|
});
|
|
325
330
|
```
|
|
326
331
|
|
|
327
|
-
**Android**: `
|
|
332
|
+
**Android**: the `theme` field is accepted for cross-platform parity but currently has no effect — `frame-android` does not yet have a matching theme API.
|
|
328
333
|
|
|
329
334
|
#### Tokens
|
|
330
335
|
|
|
@@ -31,7 +31,15 @@ class FrameSDKModule(reactContext: ReactApplicationContext) :
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
@ReactMethod
|
|
34
|
-
fun initialize(
|
|
34
|
+
fun initialize(
|
|
35
|
+
secretKey: String,
|
|
36
|
+
publishableKey: String,
|
|
37
|
+
debugMode: Boolean,
|
|
38
|
+
@Suppress("UNUSED_PARAMETER") theme: com.facebook.react.bridge.ReadableMap?,
|
|
39
|
+
promise: Promise
|
|
40
|
+
) {
|
|
41
|
+
// theme is accepted for cross-platform parity with iOS but is currently a
|
|
42
|
+
// no-op on Android — frame-android does not yet have a matching theme API.
|
|
35
43
|
try {
|
|
36
44
|
val ctx = reactApplicationContext.applicationContext
|
|
37
45
|
FrameNetworking.initializeWithAPIKey(ctx, secretKey, publishableKey, debugMode)
|
package/ios/FrameRNTheme.swift
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
// FrameRNTheme.swift
|
|
3
3
|
// FrameReactNative
|
|
4
4
|
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
5
|
+
// Parses JS theme dictionaries into Frame-iOS's FrameTheme. The parsed
|
|
6
|
+
// theme is handed to FrameNetworking.shared.configureTheme(_:); the SDK
|
|
7
|
+
// owns storage and applies it via its FrameThemeKey environment default.
|
|
7
8
|
//
|
|
8
9
|
|
|
9
10
|
import Foundation
|
|
@@ -11,12 +12,6 @@ import SwiftUI
|
|
|
11
12
|
import Frame
|
|
12
13
|
|
|
13
14
|
enum FrameRNTheme {
|
|
14
|
-
// Main-thread only: written by FrameSDKBridge.setTheme (dispatched to main),
|
|
15
|
-
// read by present* methods (already on main).
|
|
16
|
-
static var current: FrameTheme? = nil
|
|
17
|
-
|
|
18
|
-
static func resolved() -> FrameTheme { current ?? .default }
|
|
19
|
-
|
|
20
15
|
static func parse(_ dict: [String: Any]) -> FrameTheme {
|
|
21
16
|
var theme = FrameTheme.default
|
|
22
17
|
|
|
@@ -75,22 +70,6 @@ enum FrameRNTheme {
|
|
|
75
70
|
}
|
|
76
71
|
}
|
|
77
72
|
|
|
78
|
-
// Applies the supplied FrameTheme to a single root view. Captured at present
|
|
79
|
-
// time so each UIHostingController has a stable, concrete rootView type.
|
|
80
|
-
struct ThemedRoot<Content: View>: View {
|
|
81
|
-
let theme: FrameTheme
|
|
82
|
-
let content: Content
|
|
83
|
-
|
|
84
|
-
init(_ content: Content, theme: FrameTheme) {
|
|
85
|
-
self.content = content
|
|
86
|
-
self.theme = theme
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
var body: some View {
|
|
90
|
-
content.frameTheme(theme)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
73
|
extension Color {
|
|
95
74
|
// Accepts "#RGB", "#RRGGBB", "#RRGGBBAA" with or without the leading '#'.
|
|
96
75
|
init?(rnHex hex: String) {
|
package/ios/FrameSDKBridge.m
CHANGED
|
@@ -28,10 +28,7 @@
|
|
|
28
28
|
RCT_EXTERN_METHOD(initialize:(NSString *)secretKey
|
|
29
29
|
publishableKey:(NSString *)publishableKey
|
|
30
30
|
debugMode:(BOOL)debugMode
|
|
31
|
-
|
|
32
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
33
|
-
|
|
34
|
-
RCT_EXTERN_METHOD(setTheme:(NSDictionary *)theme
|
|
31
|
+
theme:(NSDictionary *)theme
|
|
35
32
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
36
33
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
37
34
|
|
|
@@ -47,11 +44,6 @@ RCT_EXTERN_METHOD(presentCart:(id)customerId
|
|
|
47
44
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
48
45
|
|
|
49
46
|
RCT_EXTERN_METHOD(presentOnboarding:(id)accountId
|
|
50
|
-
capabilities:(NSArray *)capabilities
|
|
51
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
52
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
53
|
-
|
|
54
|
-
RCT_EXTERN_METHOD(presentOnboardingWithApplePay:(id)accountId
|
|
55
47
|
capabilities:(NSArray *)capabilities
|
|
56
48
|
applePayMerchantId:(id)applePayMerchantId
|
|
57
49
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
@@ -76,12 +68,8 @@ RCT_EXTERN_METHOD(presentApplePay:(NSString *)ownerType
|
|
|
76
68
|
return YES;
|
|
77
69
|
}
|
|
78
70
|
|
|
79
|
-
- (void)initialize:(NSString *)secretKey publishableKey:(NSString *)publishableKey debugMode:(BOOL)debugMode resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
80
|
-
[[[ObjCFrameSDKBridge alloc] init] initialize:secretKey publishableKey:publishableKey debugMode:debugMode resolver:resolve rejecter:reject];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
- (void)setTheme:(NSDictionary *)theme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
84
|
-
[[[ObjCFrameSDKBridge alloc] init] setTheme:theme resolver:resolve rejecter:reject];
|
|
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];
|
|
85
73
|
}
|
|
86
74
|
|
|
87
75
|
- (void)presentCheckout:(id)customerId amount:(NSNumber *)amount resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
@@ -107,25 +95,14 @@ RCT_EXTERN_METHOD(presentApplePay:(NSString *)ownerType
|
|
|
107
95
|
});
|
|
108
96
|
}
|
|
109
97
|
|
|
110
|
-
- (void)presentOnboarding:(id)accountId capabilities:(NSArray *)capabilities resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
111
|
-
dispatch_async(dispatch_get_main_queue(), ^{
|
|
112
|
-
UIViewController *topVC = FrameGetTopViewController();
|
|
113
|
-
if (!topVC) {
|
|
114
|
-
reject(@"NO_ROOT_VC", @"Could not find root view controller to present onboarding", nil);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
[[[ObjCFrameSDKBridge alloc] init] presentOnboardingFrom:topVC accountId:accountId capabilities:capabilities resolver:resolve rejecter:reject];
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
- (void)presentOnboardingWithApplePay:(id)accountId capabilities:(NSArray *)capabilities applePayMerchantId:(id)applePayMerchantId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
98
|
+
- (void)presentOnboarding:(id)accountId capabilities:(NSArray *)capabilities applePayMerchantId:(id)applePayMerchantId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
122
99
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
123
100
|
UIViewController *topVC = FrameGetTopViewController();
|
|
124
101
|
if (!topVC) {
|
|
125
102
|
reject(@"NO_ROOT_VC", @"Could not find root view controller to present onboarding", nil);
|
|
126
103
|
return;
|
|
127
104
|
}
|
|
128
|
-
[[[ObjCFrameSDKBridge alloc] init]
|
|
105
|
+
[[[ObjCFrameSDKBridge alloc] init] presentOnboardingFrom:topVC accountId:accountId capabilities:capabilities applePayMerchantId:applePayMerchantId resolver:resolve rejecter:reject];
|
|
129
106
|
});
|
|
130
107
|
}
|
|
131
108
|
|
package/ios/FrameSDKBridge.swift
CHANGED
|
@@ -20,18 +20,11 @@ public class FrameSDKBridge: NSObject {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
@objc public
|
|
23
|
-
func initialize(_ secretKey: String, publishableKey: String, debugMode: Bool, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
23
|
+
func initialize(_ secretKey: String, publishableKey: String, debugMode: Bool, theme: NSDictionary?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
24
24
|
DispatchQueue.main.async {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
@objc public
|
|
31
|
-
func setTheme(_ theme: NSDictionary, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
32
|
-
DispatchQueue.main.async {
|
|
33
|
-
let dict = theme as? [String: Any] ?? [:]
|
|
34
|
-
FrameRNTheme.current = dict.isEmpty ? nil : FrameRNTheme.parse(dict)
|
|
25
|
+
let themeDict = theme as? [String: Any] ?? [:]
|
|
26
|
+
let resolvedTheme = themeDict.isEmpty ? FrameTheme.default : FrameRNTheme.parse(themeDict)
|
|
27
|
+
FrameNetworking.shared.initializeWithAPIKey(secretKey, publishableKey: publishableKey, theme: resolvedTheme, debugMode: debugMode)
|
|
35
28
|
resolve(nil)
|
|
36
29
|
}
|
|
37
30
|
}
|
|
@@ -51,14 +44,7 @@ public class FrameSDKBridge: NSObject {
|
|
|
51
44
|
}
|
|
52
45
|
|
|
53
46
|
@objc public
|
|
54
|
-
func presentOnboarding(from viewController: UIViewController, accountId: NSObject?, capabilities: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
55
|
-
let parsedCapabilities = parseCapabilities(capabilities)
|
|
56
|
-
let accountIdString = accountId as? String
|
|
57
|
-
presentOnboardingOnMain(from: viewController, accountId: accountIdString, capabilities: parsedCapabilities, applePayMerchantId: nil, resolve: resolve, reject: reject)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@objc public
|
|
61
|
-
func presentOnboardingWithApplePay(from viewController: UIViewController, accountId: NSObject?, capabilities: NSArray, applePayMerchantId: NSObject?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
47
|
+
func presentOnboarding(from viewController: UIViewController, accountId: NSObject?, capabilities: NSArray, applePayMerchantId: NSObject?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
62
48
|
let parsedCapabilities = parseCapabilities(capabilities)
|
|
63
49
|
let accountIdString = accountId as? String
|
|
64
50
|
let merchantIdString = applePayMerchantId as? String
|
|
@@ -113,23 +99,20 @@ public class FrameSDKBridge: NSObject {
|
|
|
113
99
|
|
|
114
100
|
private func presentCheckoutOnMain(from top: UIViewController, customerId: String?, amount: Int, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
115
101
|
var hosting: CheckoutHostingController!
|
|
116
|
-
hosting = CheckoutHostingController(rootView:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
reject("ENCODE_ERROR", "Failed to encode charge intent", nil)
|
|
128
|
-
}
|
|
102
|
+
hosting = CheckoutHostingController(rootView: FrameCheckoutView(
|
|
103
|
+
customerId: customerId,
|
|
104
|
+
paymentAmount: amount,
|
|
105
|
+
checkoutCallback: { [weak hosting] chargeIntent in
|
|
106
|
+
hosting?.didComplete = true
|
|
107
|
+
top.dismiss(animated: true)
|
|
108
|
+
DispatchQueue.main.async {
|
|
109
|
+
if let dict = Self.encodeChargeIntent(chargeIntent) {
|
|
110
|
+
resolve(dict)
|
|
111
|
+
} else {
|
|
112
|
+
reject("ENCODE_ERROR", "Failed to encode charge intent", nil)
|
|
129
113
|
}
|
|
130
114
|
}
|
|
131
|
-
|
|
132
|
-
theme: FrameRNTheme.resolved()
|
|
115
|
+
}
|
|
133
116
|
))
|
|
134
117
|
hosting.onCancel = {
|
|
135
118
|
DispatchQueue.main.async {
|
|
@@ -186,7 +169,7 @@ public class FrameSDKBridge: NSObject {
|
|
|
186
169
|
cartItems: cartItems,
|
|
187
170
|
shippingAmountInCents: shippingAmountInCents
|
|
188
171
|
)
|
|
189
|
-
let hosting = UIHostingController(rootView:
|
|
172
|
+
let hosting = UIHostingController(rootView: cartView)
|
|
190
173
|
hosting.modalPresentationStyle = UIModalPresentationStyle.pageSheet
|
|
191
174
|
if let sheet = hosting.sheetPresentationController {
|
|
192
175
|
sheet.detents = [UISheetPresentationController.Detent.large()]
|
|
@@ -200,20 +183,22 @@ public class FrameSDKBridge: NSObject {
|
|
|
200
183
|
}
|
|
201
184
|
|
|
202
185
|
private func presentOnboardingOnMain(from top: UIViewController, accountId: String?, capabilities: [FrameObjects.Capabilities], applePayMerchantId: String?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
203
|
-
|
|
204
|
-
var delegate:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
186
|
+
// Build the dismiss delegate up-front so onComplete captures a non-nil
|
|
187
|
+
// instance directly. Earlier shape declared `var delegate: …!` and assigned
|
|
188
|
+
// it AFTER constructing OnboardingContainerView; the onComplete closure
|
|
189
|
+
// captured the local by reference, so any path that fired the callback
|
|
190
|
+
// before assignment landed on a nil delegate and silently no-op'd via `?.`.
|
|
191
|
+
let delegate = OnboardingDismissDelegate(resolve: resolve)
|
|
192
|
+
|
|
193
|
+
let hosting = OnboardingHostingController(
|
|
194
|
+
rootView: OnboardingContainerView(
|
|
195
|
+
accountId: accountId,
|
|
196
|
+
requiredCapabilities: capabilities,
|
|
197
|
+
applePayMerchantId: applePayMerchantId,
|
|
198
|
+
onComplete: { [delegate, weak top] in
|
|
199
|
+
delegate.finish(completed: true)
|
|
200
|
+
top?.dismiss(animated: true)
|
|
201
|
+
}
|
|
217
202
|
)
|
|
218
203
|
)
|
|
219
204
|
// Embed in a UINavigationController so the outer sheet is a UIKit container,
|
|
@@ -229,7 +214,6 @@ public class FrameSDKBridge: NSObject {
|
|
|
229
214
|
if let sheet = nav.sheetPresentationController {
|
|
230
215
|
sheet.detents = [UISheetPresentationController.Detent.large()]
|
|
231
216
|
}
|
|
232
|
-
delegate = OnboardingDismissDelegate(resolve: resolve)
|
|
233
217
|
delegate.hostingController = nav
|
|
234
218
|
objc_setAssociatedObject(nav, &onboardingDismissKey, delegate, .OBJC_ASSOCIATION_RETAIN)
|
|
235
219
|
NSLog("[FrameRN][onb] presenting OnboardingHostingController (wrapped in UINavigationController) from \(type(of: top))")
|
|
@@ -242,7 +226,7 @@ public class FrameSDKBridge: NSObject {
|
|
|
242
226
|
|
|
243
227
|
// MARK: - CheckoutHostingController
|
|
244
228
|
|
|
245
|
-
private final class CheckoutHostingController: UIHostingController<
|
|
229
|
+
private final class CheckoutHostingController: UIHostingController<FrameCheckoutView>, UIAdaptivePresentationControllerDelegate {
|
|
246
230
|
var didComplete = false
|
|
247
231
|
var onCancel: (() -> Void)?
|
|
248
232
|
private var cancelled = false
|
package/lib/index.d.ts
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* - Use presentApplePay / presentGooglePay to launch the platform wallet sheet from your own button UI.
|
|
8
8
|
* - For API calls (customers, charge intents, refunds), use the framepayments (frame-node) package from JS.
|
|
9
9
|
*/
|
|
10
|
-
import { initialize, presentCheckout, presentCart, presentOnboarding, presentApplePay, presentGooglePay
|
|
11
|
-
export { initialize, presentCheckout, presentCart, presentOnboarding, presentApplePay, presentGooglePay,
|
|
10
|
+
import { initialize, presentCheckout, presentCart, presentOnboarding, presentApplePay, presentGooglePay } from './native';
|
|
11
|
+
export { initialize, presentCheckout, presentCart, presentOnboarding, presentApplePay, presentGooglePay, } from './native';
|
|
12
12
|
export type { FrameCartItem, ChargeIntent, ChargeIntentStatus, AuthorizationMode, FrameError, BillingAddress, PaymentCard, BankAccount, PaymentMethod, OnboardingCapability, OnboardingResult, OnboardingResultStatus, ApplePayOwner, PresentApplePayOptions, PresentGooglePayOptions, FrameTheme, FrameThemeColor, FrameThemeFont, FrameThemeColors, FrameThemeFonts, FrameThemeRadii, } from './types';
|
|
13
13
|
export { ErrorCodes } from './errors';
|
|
14
14
|
export type { FrameErrorShape, FrameErrorCode } from './errors';
|
|
15
|
-
/** Default export for Frame.initialize(), Frame.presentCheckout(), Frame.presentCart(), Frame.presentOnboarding(), Frame.presentApplePay(), Frame.presentGooglePay()
|
|
15
|
+
/** Default export for Frame.initialize(), Frame.presentCheckout(), Frame.presentCart(), Frame.presentOnboarding(), Frame.presentApplePay(), Frame.presentGooglePay() */
|
|
16
16
|
declare const _default: {
|
|
17
17
|
initialize: typeof initialize;
|
|
18
18
|
presentCheckout: typeof presentCheckout;
|
|
@@ -20,7 +20,6 @@ declare const _default: {
|
|
|
20
20
|
presentOnboarding: typeof presentOnboarding;
|
|
21
21
|
presentApplePay: typeof presentApplePay;
|
|
22
22
|
presentGooglePay: typeof presentGooglePay;
|
|
23
|
-
setTheme: typeof setTheme;
|
|
24
23
|
};
|
|
25
24
|
export default _default;
|
|
26
25
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,UAAU,EACV,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,UAAU,EACV,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,UAAU,EACV,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,cAAc,EACd,WAAW,EACX,WAAW,EACX,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,aAAa,EACb,sBAAsB,EACtB,uBAAuB,EACvB,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEhE,wKAAwK;;;;;;;;;AACxK,wBAOE"}
|
package/lib/index.js
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
* - Use presentApplePay / presentGooglePay to launch the platform wallet sheet from your own button UI.
|
|
8
8
|
* - For API calls (customers, charge intents, refunds), use the framepayments (frame-node) package from JS.
|
|
9
9
|
*/
|
|
10
|
-
import { initialize, presentCheckout, presentCart, presentOnboarding, presentApplePay, presentGooglePay,
|
|
11
|
-
export { initialize, presentCheckout, presentCart, presentOnboarding, presentApplePay, presentGooglePay,
|
|
10
|
+
import { initialize, presentCheckout, presentCart, presentOnboarding, presentApplePay, presentGooglePay, } from './native';
|
|
11
|
+
export { initialize, presentCheckout, presentCart, presentOnboarding, presentApplePay, presentGooglePay, } from './native';
|
|
12
12
|
export { ErrorCodes } from './errors';
|
|
13
|
-
/** Default export for Frame.initialize(), Frame.presentCheckout(), Frame.presentCart(), Frame.presentOnboarding(), Frame.presentApplePay(), Frame.presentGooglePay()
|
|
13
|
+
/** Default export for Frame.initialize(), Frame.presentCheckout(), Frame.presentCart(), Frame.presentOnboarding(), Frame.presentApplePay(), Frame.presentGooglePay() */
|
|
14
14
|
export default {
|
|
15
15
|
initialize,
|
|
16
16
|
presentCheckout,
|
|
@@ -18,5 +18,4 @@ export default {
|
|
|
18
18
|
presentOnboarding,
|
|
19
19
|
presentApplePay,
|
|
20
20
|
presentGooglePay,
|
|
21
|
-
setTheme,
|
|
22
21
|
};
|
package/lib/native.d.ts
CHANGED
|
@@ -6,6 +6,13 @@ export declare function initialize(options: {
|
|
|
6
6
|
secretKey: string;
|
|
7
7
|
publishableKey: string;
|
|
8
8
|
debugMode?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Optional theme applied SDK-wide to Frame's reusable iOS components
|
|
11
|
+
* (checkout, cart, onboarding). Pass any subset — unspecified tokens fall
|
|
12
|
+
* back to SDK defaults. No-op on Android until frame-android ships a
|
|
13
|
+
* matching theme API.
|
|
14
|
+
*/
|
|
15
|
+
theme?: FrameTheme;
|
|
9
16
|
}): Promise<void>;
|
|
10
17
|
export declare function presentCheckout(options: {
|
|
11
18
|
customerId?: string | null;
|
|
@@ -24,13 +31,4 @@ export declare function presentOnboarding(options: {
|
|
|
24
31
|
}): Promise<OnboardingResult>;
|
|
25
32
|
export declare function presentApplePay(options: PresentApplePayOptions): Promise<ChargeIntent>;
|
|
26
33
|
export declare function presentGooglePay(options: PresentGooglePayOptions): Promise<ChargeIntent>;
|
|
27
|
-
/**
|
|
28
|
-
* Configure colors, fonts, and corner radii for Frame's reusable iOS
|
|
29
|
-
* components. Applied to every subsequent `present*` call; an in-flight modal
|
|
30
|
-
* is not re-themed mid-flow.
|
|
31
|
-
*
|
|
32
|
-
* Pass `null` or `{}` to reset to SDK defaults. Android is a no-op until
|
|
33
|
-
* frame-android ships a matching theme API.
|
|
34
|
-
*/
|
|
35
|
-
export declare function setTheme(theme: FrameTheme | null): Promise<void>;
|
|
36
34
|
//# sourceMappingURL=native.d.ts.map
|
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,YAAY,EACZ,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAsBjB,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,CAoBhB;AAwBD,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,YAAY,CAAC,CAKxB;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;CAC/B,GAAG,OAAO,CAAC,YAAY,CAAC,CASxB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACzC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACtC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkB5B;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,YAAY,CAAC,CAoBtF;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC,CAUxF"}
|
package/lib/native.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { NativeModules, Platform } from 'react-native';
|
|
5
5
|
import { ErrorCodes } from './errors';
|
|
6
|
+
// theme is iOS-only today: frame-android does not yet have a matching theme API,
|
|
7
|
+
// so the field is accepted on both platforms but ignored on Android until it does.
|
|
6
8
|
const LINKING_ERROR = `The package 'framepayments-react-native' doesn't seem to be linked. Make sure you have run 'pod install' (iOS) or rebuilt the app (Android).`;
|
|
7
9
|
const FrameSDK = NativeModules.FrameSDK
|
|
8
10
|
? NativeModules.FrameSDK
|
|
@@ -19,7 +21,10 @@ export function initialize(options) {
|
|
|
19
21
|
if (!options?.publishableKey) {
|
|
20
22
|
throw new Error('Frame.initialize requires publishableKey');
|
|
21
23
|
}
|
|
22
|
-
|
|
24
|
+
if (options.theme !== undefined && (typeof options.theme !== 'object' || Array.isArray(options.theme))) {
|
|
25
|
+
throw new Error('Frame.initialize: theme must be an object');
|
|
26
|
+
}
|
|
27
|
+
return wrapPromise(FrameSDK.initialize(options.secretKey, options.publishableKey, options.debugMode ?? false, options.theme ?? null)).then(() => {
|
|
23
28
|
isInitialized = true;
|
|
24
29
|
});
|
|
25
30
|
}
|
|
@@ -53,11 +58,8 @@ export function presentCart(options) {
|
|
|
53
58
|
}
|
|
54
59
|
export function presentOnboarding(options) {
|
|
55
60
|
guardInitialized();
|
|
56
|
-
if (Platform.OS === 'ios' && options.applePayMerchantId) {
|
|
57
|
-
return wrapPromise(FrameSDK.presentOnboardingWithApplePay(options.accountId ?? null, options.capabilities ?? [], options.applePayMerchantId));
|
|
58
|
-
}
|
|
59
61
|
if (Platform.OS === 'ios') {
|
|
60
|
-
return wrapPromise(FrameSDK.presentOnboarding(options.accountId ?? null, options.capabilities ?? []));
|
|
62
|
+
return wrapPromise(FrameSDK.presentOnboarding(options.accountId ?? null, options.capabilities ?? [], options.applePayMerchantId ?? null));
|
|
61
63
|
}
|
|
62
64
|
return wrapPromise(FrameSDK.presentOnboarding(options.accountId ?? null, options.capabilities ?? [], options.googlePayMerchantId ?? null));
|
|
63
65
|
}
|
|
@@ -78,19 +80,3 @@ export function presentGooglePay(options) {
|
|
|
78
80
|
guardInitialized();
|
|
79
81
|
return wrapPromise(FrameSDK.presentGooglePay(options.amountCents, options.customerId ?? null, options.currencyCode ?? 'USD', options.googlePayMerchantId ?? null));
|
|
80
82
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Configure colors, fonts, and corner radii for Frame's reusable iOS
|
|
83
|
-
* components. Applied to every subsequent `present*` call; an in-flight modal
|
|
84
|
-
* is not re-themed mid-flow.
|
|
85
|
-
*
|
|
86
|
-
* Pass `null` or `{}` to reset to SDK defaults. Android is a no-op until
|
|
87
|
-
* frame-android ships a matching theme API.
|
|
88
|
-
*/
|
|
89
|
-
export function setTheme(theme) {
|
|
90
|
-
if (theme !== null && (typeof theme !== 'object' || Array.isArray(theme))) {
|
|
91
|
-
throw new Error('Frame.setTheme requires a theme object or null');
|
|
92
|
-
}
|
|
93
|
-
if (Platform.OS !== 'ios')
|
|
94
|
-
return Promise.resolve();
|
|
95
|
-
return wrapPromise(FrameSDK.setTheme(theme ?? {}));
|
|
96
|
-
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "framepayments-react-native",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.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",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "tsc",
|
|
9
|
+
"watch": "tsc --watch",
|
|
9
10
|
"typecheck": "tsc --noEmit",
|
|
10
11
|
"lint": "eslint src --ext .ts,.tsx",
|
|
11
12
|
"test": "jest",
|
|
13
|
+
"prepare": "npm run build",
|
|
12
14
|
"prepublishOnly": "npm run build"
|
|
13
15
|
},
|
|
14
16
|
"keywords": [
|
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
const mockInitialize = jest.fn((_secretKey: string, _publishableKey: string, _debugMode: boolean) => Promise.resolve());
|
|
7
7
|
const mockPresentCheckout = jest.fn((_customerId: unknown, _amount: number) => Promise.resolve({ id: 'ci_1', amount: 10000 }));
|
|
8
8
|
const mockPresentCart = jest.fn((_customerId: unknown, _items: unknown[], _shipping: number) => Promise.resolve({ id: 'ci_2', amount: 15000 }));
|
|
9
|
-
const mockPresentOnboarding = jest.fn((_accountId: unknown, _capabilities: unknown[]) => Promise.resolve({ status: 'completed', paymentMethodId: 'pm_1' }));
|
|
10
|
-
const mockPresentOnboardingWithApplePay = jest.fn((_accountId: unknown, _capabilities: unknown[], _merchantId: string) => Promise.resolve({ status: 'completed', paymentMethodId: 'pm_2' }));
|
|
9
|
+
const mockPresentOnboarding = jest.fn((_accountId: unknown, _capabilities: unknown[], _merchantId: string | null) => Promise.resolve({ status: 'completed', paymentMethodId: 'pm_1' }));
|
|
11
10
|
|
|
12
11
|
const mockPlatform = { OS: 'ios' as 'ios' | 'android' };
|
|
13
12
|
|
|
@@ -18,7 +17,6 @@ jest.mock('react-native', () => ({
|
|
|
18
17
|
presentCheckout: mockPresentCheckout,
|
|
19
18
|
presentCart: mockPresentCart,
|
|
20
19
|
presentOnboarding: mockPresentOnboarding,
|
|
21
|
-
presentOnboardingWithApplePay: mockPresentOnboardingWithApplePay,
|
|
22
20
|
},
|
|
23
21
|
},
|
|
24
22
|
Platform: mockPlatform,
|
|
@@ -40,7 +38,6 @@ beforeEach(() => {
|
|
|
40
38
|
mockPresentCheckout.mockClear();
|
|
41
39
|
mockPresentCart.mockClear();
|
|
42
40
|
mockPresentOnboarding.mockClear();
|
|
43
|
-
mockPresentOnboardingWithApplePay.mockClear();
|
|
44
41
|
mockPlatform.OS = 'ios';
|
|
45
42
|
const native = require('../native');
|
|
46
43
|
initialize = native.initialize;
|
|
@@ -145,33 +142,33 @@ describe('presentOnboarding', () => {
|
|
|
145
142
|
expect(mockPresentOnboarding).not.toHaveBeenCalled();
|
|
146
143
|
});
|
|
147
144
|
|
|
148
|
-
it('calls native presentOnboarding with accountId and
|
|
145
|
+
it('calls native presentOnboarding with accountId, capabilities, and null merchantId after initialize on iOS', async () => {
|
|
146
|
+
mockPlatform.OS = 'ios';
|
|
149
147
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
150
148
|
const result = await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc', 'bank_account_verification'] });
|
|
151
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc', 'bank_account_verification']);
|
|
149
|
+
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc', 'bank_account_verification'], null);
|
|
152
150
|
expect(result).toEqual({ status: 'completed', paymentMethodId: 'pm_1' });
|
|
153
151
|
});
|
|
154
152
|
|
|
155
|
-
it('passes null for accountId and empty array for capabilities when not provided', async () => {
|
|
153
|
+
it('passes null for accountId and empty array for capabilities when not provided on iOS', async () => {
|
|
154
|
+
mockPlatform.OS = 'ios';
|
|
156
155
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
157
156
|
await presentOnboarding({});
|
|
158
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith(null, []);
|
|
157
|
+
expect(mockPresentOnboarding).toHaveBeenCalledWith(null, [], null);
|
|
159
158
|
});
|
|
160
159
|
|
|
161
|
-
it('
|
|
160
|
+
it('forwards applePayMerchantId on iOS', async () => {
|
|
162
161
|
mockPlatform.OS = 'ios';
|
|
163
162
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
164
163
|
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'], applePayMerchantId: 'merchant.com.example' });
|
|
165
|
-
expect(
|
|
166
|
-
expect(mockPresentOnboarding).not.toHaveBeenCalled();
|
|
164
|
+
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc'], 'merchant.com.example');
|
|
167
165
|
});
|
|
168
166
|
|
|
169
|
-
it('
|
|
167
|
+
it('ignores applePayMerchantId on Android', async () => {
|
|
170
168
|
mockPlatform.OS = 'android';
|
|
171
169
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
172
170
|
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'], applePayMerchantId: 'merchant.com.example' });
|
|
173
171
|
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc'], null);
|
|
174
|
-
expect(mockPresentOnboardingWithApplePay).not.toHaveBeenCalled();
|
|
175
172
|
});
|
|
176
173
|
|
|
177
174
|
it('forwards googlePayMerchantId to native presentOnboarding on Android', async () => {
|
|
@@ -181,10 +178,10 @@ describe('presentOnboarding', () => {
|
|
|
181
178
|
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc'], 'BCR2DN4T...');
|
|
182
179
|
});
|
|
183
180
|
|
|
184
|
-
it('
|
|
181
|
+
it('ignores googlePayMerchantId on iOS', async () => {
|
|
185
182
|
mockPlatform.OS = 'ios';
|
|
186
183
|
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
187
184
|
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'], googlePayMerchantId: 'BCR2DN4T...' });
|
|
188
|
-
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc']);
|
|
185
|
+
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc'], null);
|
|
189
186
|
});
|
|
190
187
|
});
|
package/src/index.ts
CHANGED
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
presentOnboarding,
|
|
16
16
|
presentApplePay,
|
|
17
17
|
presentGooglePay,
|
|
18
|
-
setTheme,
|
|
19
18
|
} from './native';
|
|
20
19
|
|
|
21
20
|
export {
|
|
@@ -25,7 +24,6 @@ export {
|
|
|
25
24
|
presentOnboarding,
|
|
26
25
|
presentApplePay,
|
|
27
26
|
presentGooglePay,
|
|
28
|
-
setTheme,
|
|
29
27
|
} from './native';
|
|
30
28
|
export type {
|
|
31
29
|
FrameCartItem,
|
|
@@ -53,7 +51,7 @@ export type {
|
|
|
53
51
|
export { ErrorCodes } from './errors';
|
|
54
52
|
export type { FrameErrorShape, FrameErrorCode } from './errors';
|
|
55
53
|
|
|
56
|
-
/** Default export for Frame.initialize(), Frame.presentCheckout(), Frame.presentCart(), Frame.presentOnboarding(), Frame.presentApplePay(), Frame.presentGooglePay()
|
|
54
|
+
/** Default export for Frame.initialize(), Frame.presentCheckout(), Frame.presentCart(), Frame.presentOnboarding(), Frame.presentApplePay(), Frame.presentGooglePay() */
|
|
57
55
|
export default {
|
|
58
56
|
initialize,
|
|
59
57
|
presentCheckout,
|
|
@@ -61,5 +59,4 @@ export default {
|
|
|
61
59
|
presentOnboarding,
|
|
62
60
|
presentApplePay,
|
|
63
61
|
presentGooglePay,
|
|
64
|
-
setTheme,
|
|
65
62
|
};
|
package/src/native.ts
CHANGED
|
@@ -14,6 +14,9 @@ import type {
|
|
|
14
14
|
} from './types';
|
|
15
15
|
import { ErrorCodes } from './errors';
|
|
16
16
|
|
|
17
|
+
// theme is iOS-only today: frame-android does not yet have a matching theme API,
|
|
18
|
+
// so the field is accepted on both platforms but ignored on Android until it does.
|
|
19
|
+
|
|
17
20
|
const LINKING_ERROR =
|
|
18
21
|
`The package 'framepayments-react-native' doesn't seem to be linked. Make sure you have run 'pod install' (iOS) or rebuilt the app (Android).`;
|
|
19
22
|
|
|
@@ -34,6 +37,13 @@ export function initialize(options: {
|
|
|
34
37
|
secretKey: string;
|
|
35
38
|
publishableKey: string;
|
|
36
39
|
debugMode?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Optional theme applied SDK-wide to Frame's reusable iOS components
|
|
42
|
+
* (checkout, cart, onboarding). Pass any subset — unspecified tokens fall
|
|
43
|
+
* back to SDK defaults. No-op on Android until frame-android ships a
|
|
44
|
+
* matching theme API.
|
|
45
|
+
*/
|
|
46
|
+
theme?: FrameTheme;
|
|
37
47
|
}): Promise<void> {
|
|
38
48
|
if (!options?.secretKey) {
|
|
39
49
|
throw new Error('Frame.initialize requires secretKey');
|
|
@@ -41,11 +51,15 @@ export function initialize(options: {
|
|
|
41
51
|
if (!options?.publishableKey) {
|
|
42
52
|
throw new Error('Frame.initialize requires publishableKey');
|
|
43
53
|
}
|
|
54
|
+
if (options.theme !== undefined && (typeof options.theme !== 'object' || Array.isArray(options.theme))) {
|
|
55
|
+
throw new Error('Frame.initialize: theme must be an object');
|
|
56
|
+
}
|
|
44
57
|
return wrapPromise(
|
|
45
58
|
FrameSDK.initialize(
|
|
46
59
|
options.secretKey,
|
|
47
60
|
options.publishableKey,
|
|
48
|
-
options.debugMode ?? false
|
|
61
|
+
options.debugMode ?? false,
|
|
62
|
+
options.theme ?? null
|
|
49
63
|
)
|
|
50
64
|
).then(() => {
|
|
51
65
|
isInitialized = true;
|
|
@@ -106,20 +120,12 @@ export function presentOnboarding(options: {
|
|
|
106
120
|
googlePayMerchantId?: string | null;
|
|
107
121
|
}): Promise<OnboardingResult> {
|
|
108
122
|
guardInitialized();
|
|
109
|
-
if (Platform.OS === 'ios' && options.applePayMerchantId) {
|
|
110
|
-
return wrapPromise(
|
|
111
|
-
FrameSDK.presentOnboardingWithApplePay(
|
|
112
|
-
options.accountId ?? null,
|
|
113
|
-
options.capabilities ?? [],
|
|
114
|
-
options.applePayMerchantId
|
|
115
|
-
)
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
123
|
if (Platform.OS === 'ios') {
|
|
119
124
|
return wrapPromise(
|
|
120
125
|
FrameSDK.presentOnboarding(
|
|
121
126
|
options.accountId ?? null,
|
|
122
|
-
options.capabilities ?? []
|
|
127
|
+
options.capabilities ?? [],
|
|
128
|
+
options.applePayMerchantId ?? null
|
|
123
129
|
)
|
|
124
130
|
);
|
|
125
131
|
}
|
|
@@ -166,18 +172,3 @@ export function presentGooglePay(options: PresentGooglePayOptions): Promise<Char
|
|
|
166
172
|
);
|
|
167
173
|
}
|
|
168
174
|
|
|
169
|
-
/**
|
|
170
|
-
* Configure colors, fonts, and corner radii for Frame's reusable iOS
|
|
171
|
-
* components. Applied to every subsequent `present*` call; an in-flight modal
|
|
172
|
-
* is not re-themed mid-flow.
|
|
173
|
-
*
|
|
174
|
-
* Pass `null` or `{}` to reset to SDK defaults. Android is a no-op until
|
|
175
|
-
* frame-android ships a matching theme API.
|
|
176
|
-
*/
|
|
177
|
-
export function setTheme(theme: FrameTheme | null): Promise<void> {
|
|
178
|
-
if (theme !== null && (typeof theme !== 'object' || Array.isArray(theme))) {
|
|
179
|
-
throw new Error('Frame.setTheme requires a theme object or null');
|
|
180
|
-
}
|
|
181
|
-
if (Platform.OS !== 'ios') return Promise.resolve();
|
|
182
|
-
return wrapPromise(FrameSDK.setTheme(theme ?? {}));
|
|
183
|
-
}
|