framepayments-react-native 2.0.4 → 2.0.5
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 +1 -0
- package/ios/FrameSDKBridge.m +17 -0
- package/ios/FrameSDKBridge.swift +11 -2
- package/lib/native.d.ts +1 -0
- package/lib/native.d.ts.map +1 -1
- package/lib/native.js +4 -1
- package/package.json +1 -1
- package/src/__tests__/native.test.ts +24 -1
- package/src/native.ts +11 -1
package/README.md
CHANGED
|
@@ -191,6 +191,7 @@ if (result.status === 'completed') {
|
|
|
191
191
|
|---|---|---|---|
|
|
192
192
|
| `accountId` | `string` | No | The Frame account to onboard |
|
|
193
193
|
| `capabilities` | `OnboardingCapability[]` | No | Which onboarding steps to include (see below) |
|
|
194
|
+
| `applePayMerchantId` | `string` | No | Apple Pay merchant ID. When set, the onboarding flow includes an Apple Pay setup step. iOS only — ignored on Android. Same prerequisites as `presentApplePay`. |
|
|
194
195
|
|
|
195
196
|
**`capabilities` values:**
|
|
196
197
|
|
package/ios/FrameSDKBridge.m
CHANGED
|
@@ -47,6 +47,12 @@ RCT_EXTERN_METHOD(presentOnboarding:(id)accountId
|
|
|
47
47
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
48
48
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
49
49
|
|
|
50
|
+
RCT_EXTERN_METHOD(presentOnboardingWithApplePay:(id)accountId
|
|
51
|
+
capabilities:(NSArray *)capabilities
|
|
52
|
+
applePayMerchantId:(id)applePayMerchantId
|
|
53
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
54
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
55
|
+
|
|
50
56
|
RCT_EXTERN_METHOD(presentApplePay:(NSString *)ownerType
|
|
51
57
|
ownerId:(NSString *)ownerId
|
|
52
58
|
amount:(nonnull NSNumber *)amount
|
|
@@ -104,6 +110,17 @@ RCT_EXTERN_METHOD(presentApplePay:(NSString *)ownerType
|
|
|
104
110
|
});
|
|
105
111
|
}
|
|
106
112
|
|
|
113
|
+
- (void)presentOnboardingWithApplePay:(id)accountId capabilities:(NSArray *)capabilities applePayMerchantId:(id)applePayMerchantId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
114
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
115
|
+
UIViewController *topVC = FrameGetTopViewController();
|
|
116
|
+
if (!topVC) {
|
|
117
|
+
reject(@"NO_ROOT_VC", @"Could not find root view controller to present onboarding", nil);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
[[[ObjCFrameSDKBridge alloc] init] presentOnboardingWithApplePayFrom:topVC accountId:accountId capabilities:capabilities applePayMerchantId:applePayMerchantId resolver:resolve rejecter:reject];
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
107
124
|
- (void)presentApplePay:(NSString *)ownerType ownerId:(NSString *)ownerId amount:(NSNumber *)amount currency:(NSString *)currency merchantId:(NSString *)merchantId resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {
|
|
108
125
|
[[[ObjCFrameSDKBridge alloc] init] presentApplePay:ownerType ownerId:ownerId amount:amount.intValue currency:currency merchantId:merchantId resolver:resolve rejecter:reject];
|
|
109
126
|
}
|
package/ios/FrameSDKBridge.swift
CHANGED
|
@@ -45,7 +45,15 @@ public class FrameSDKBridge: NSObject {
|
|
|
45
45
|
func presentOnboarding(from viewController: UIViewController, accountId: NSObject?, capabilities: NSArray, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
46
46
|
let parsedCapabilities = parseCapabilities(capabilities)
|
|
47
47
|
let accountIdString = accountId as? String
|
|
48
|
-
presentOnboardingOnMain(from: viewController, accountId: accountIdString, capabilities: parsedCapabilities, resolve: resolve, reject: reject)
|
|
48
|
+
presentOnboardingOnMain(from: viewController, accountId: accountIdString, capabilities: parsedCapabilities, applePayMerchantId: nil, resolve: resolve, reject: reject)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@objc public
|
|
52
|
+
func presentOnboardingWithApplePay(from viewController: UIViewController, accountId: NSObject?, capabilities: NSArray, applePayMerchantId: NSObject?, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
|
|
53
|
+
let parsedCapabilities = parseCapabilities(capabilities)
|
|
54
|
+
let accountIdString = accountId as? String
|
|
55
|
+
let merchantIdString = applePayMerchantId as? String
|
|
56
|
+
presentOnboardingOnMain(from: viewController, accountId: accountIdString, capabilities: parsedCapabilities, applePayMerchantId: merchantIdString, resolve: resolve, reject: reject)
|
|
49
57
|
}
|
|
50
58
|
|
|
51
59
|
@objc public
|
|
@@ -179,13 +187,14 @@ public class FrameSDKBridge: NSObject {
|
|
|
179
187
|
}
|
|
180
188
|
}
|
|
181
189
|
|
|
182
|
-
private func presentOnboardingOnMain(from top: UIViewController, accountId: String?, capabilities: [FrameObjects.Capabilities], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
190
|
+
private func presentOnboardingOnMain(from top: UIViewController, accountId: String?, capabilities: [FrameObjects.Capabilities], applePayMerchantId: String?, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
183
191
|
var hosting: OnboardingHostingController<OnboardingContainerView>!
|
|
184
192
|
var delegate: OnboardingDismissDelegate!
|
|
185
193
|
hosting = OnboardingHostingController(
|
|
186
194
|
rootView: OnboardingContainerView(
|
|
187
195
|
accountId: accountId,
|
|
188
196
|
requiredCapabilities: capabilities,
|
|
197
|
+
applePayMerchantId: applePayMerchantId,
|
|
189
198
|
onComplete: { [weak hosting] in
|
|
190
199
|
delegate?.finish(completed: true)
|
|
191
200
|
hosting?.dismiss(animated: true)
|
package/lib/native.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ export declare function presentCart(options: {
|
|
|
19
19
|
export declare function presentOnboarding(options: {
|
|
20
20
|
accountId?: string | null;
|
|
21
21
|
capabilities?: OnboardingCapability[];
|
|
22
|
+
applePayMerchantId?: string | null;
|
|
22
23
|
}): Promise<OnboardingResult>;
|
|
23
24
|
export declare function presentApplePay(options: PresentApplePayOptions): Promise<ChargeIntent>;
|
|
24
25
|
export declare function presentGooglePay(options: PresentGooglePayOptions): Promise<ChargeIntent>;
|
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,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAmBjB,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhB;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;
|
|
1
|
+
{"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAmBjB,wBAAgB,UAAU,CAAC,OAAO,EAAE;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBhB;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;CACpC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAiB5B;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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Native module bridge. Uses NativeModules for classic React Native bridge.
|
|
3
3
|
*/
|
|
4
|
-
import { NativeModules } from 'react-native';
|
|
4
|
+
import { NativeModules, Platform } from 'react-native';
|
|
5
5
|
import { ErrorCodes } from './errors';
|
|
6
6
|
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
7
|
const FrameSDK = NativeModules.FrameSDK
|
|
@@ -53,6 +53,9 @@ export function presentCart(options) {
|
|
|
53
53
|
}
|
|
54
54
|
export function presentOnboarding(options) {
|
|
55
55
|
guardInitialized();
|
|
56
|
+
if (Platform.OS === 'ios' && options.applePayMerchantId) {
|
|
57
|
+
return wrapPromise(FrameSDK.presentOnboardingWithApplePay(options.accountId ?? null, options.capabilities ?? [], options.applePayMerchantId));
|
|
58
|
+
}
|
|
56
59
|
return wrapPromise(FrameSDK.presentOnboarding(options.accountId ?? null, options.capabilities ?? []));
|
|
57
60
|
}
|
|
58
61
|
export function presentApplePay(options) {
|
package/package.json
CHANGED
|
@@ -7,6 +7,9 @@ const mockInitialize = jest.fn((_secretKey: string, _publishableKey: string, _de
|
|
|
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
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' }));
|
|
11
|
+
|
|
12
|
+
const mockPlatform = { OS: 'ios' as 'ios' | 'android' };
|
|
10
13
|
|
|
11
14
|
jest.mock('react-native', () => ({
|
|
12
15
|
NativeModules: {
|
|
@@ -15,8 +18,10 @@ jest.mock('react-native', () => ({
|
|
|
15
18
|
presentCheckout: mockPresentCheckout,
|
|
16
19
|
presentCart: mockPresentCart,
|
|
17
20
|
presentOnboarding: mockPresentOnboarding,
|
|
21
|
+
presentOnboardingWithApplePay: mockPresentOnboardingWithApplePay,
|
|
18
22
|
},
|
|
19
23
|
},
|
|
24
|
+
Platform: mockPlatform,
|
|
20
25
|
}));
|
|
21
26
|
|
|
22
27
|
// Re-import after mock so we get the mocked NativeModules
|
|
@@ -27,7 +32,7 @@ let presentCart: (opts: {
|
|
|
27
32
|
items: Array<{ id: string; title: string; amountInCents: number; imageUrl: string }>;
|
|
28
33
|
shippingAmountInCents: number;
|
|
29
34
|
}) => Promise<unknown>;
|
|
30
|
-
let presentOnboarding: (opts: { accountId?: string | null; capabilities?: string[] }) => Promise<unknown>;
|
|
35
|
+
let presentOnboarding: (opts: { accountId?: string | null; capabilities?: string[]; applePayMerchantId?: string | null }) => Promise<unknown>;
|
|
31
36
|
|
|
32
37
|
beforeEach(() => {
|
|
33
38
|
jest.resetModules();
|
|
@@ -35,6 +40,8 @@ beforeEach(() => {
|
|
|
35
40
|
mockPresentCheckout.mockClear();
|
|
36
41
|
mockPresentCart.mockClear();
|
|
37
42
|
mockPresentOnboarding.mockClear();
|
|
43
|
+
mockPresentOnboardingWithApplePay.mockClear();
|
|
44
|
+
mockPlatform.OS = 'ios';
|
|
38
45
|
const native = require('../native');
|
|
39
46
|
initialize = native.initialize;
|
|
40
47
|
presentCheckout = native.presentCheckout;
|
|
@@ -150,4 +157,20 @@ describe('presentOnboarding', () => {
|
|
|
150
157
|
await presentOnboarding({});
|
|
151
158
|
expect(mockPresentOnboarding).toHaveBeenCalledWith(null, []);
|
|
152
159
|
});
|
|
160
|
+
|
|
161
|
+
it('routes to presentOnboardingWithApplePay on iOS when applePayMerchantId is set', async () => {
|
|
162
|
+
mockPlatform.OS = 'ios';
|
|
163
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
164
|
+
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'], applePayMerchantId: 'merchant.com.example' });
|
|
165
|
+
expect(mockPresentOnboardingWithApplePay).toHaveBeenCalledWith('acct_1', ['kyc'], 'merchant.com.example');
|
|
166
|
+
expect(mockPresentOnboarding).not.toHaveBeenCalled();
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('still routes to presentOnboarding on Android even when applePayMerchantId is set', async () => {
|
|
170
|
+
mockPlatform.OS = 'android';
|
|
171
|
+
await initialize({ secretKey: 'sk_xxx', publishableKey: 'pk_xxx' });
|
|
172
|
+
await presentOnboarding({ accountId: 'acct_1', capabilities: ['kyc'], applePayMerchantId: 'merchant.com.example' });
|
|
173
|
+
expect(mockPresentOnboarding).toHaveBeenCalledWith('acct_1', ['kyc']);
|
|
174
|
+
expect(mockPresentOnboardingWithApplePay).not.toHaveBeenCalled();
|
|
175
|
+
});
|
|
153
176
|
});
|
package/src/native.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Native module bridge. Uses NativeModules for classic React Native bridge.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { NativeModules } from 'react-native';
|
|
5
|
+
import { NativeModules, Platform } from 'react-native';
|
|
6
6
|
import type {
|
|
7
7
|
ChargeIntent,
|
|
8
8
|
FrameCartItem,
|
|
@@ -101,8 +101,18 @@ export function presentCart(options: {
|
|
|
101
101
|
export function presentOnboarding(options: {
|
|
102
102
|
accountId?: string | null;
|
|
103
103
|
capabilities?: OnboardingCapability[];
|
|
104
|
+
applePayMerchantId?: string | null;
|
|
104
105
|
}): Promise<OnboardingResult> {
|
|
105
106
|
guardInitialized();
|
|
107
|
+
if (Platform.OS === 'ios' && options.applePayMerchantId) {
|
|
108
|
+
return wrapPromise(
|
|
109
|
+
FrameSDK.presentOnboardingWithApplePay(
|
|
110
|
+
options.accountId ?? null,
|
|
111
|
+
options.capabilities ?? [],
|
|
112
|
+
options.applePayMerchantId
|
|
113
|
+
)
|
|
114
|
+
);
|
|
115
|
+
}
|
|
106
116
|
return wrapPromise(
|
|
107
117
|
FrameSDK.presentOnboarding(
|
|
108
118
|
options.accountId ?? null,
|