Skip to content

Commit 33d4aa7

Browse files
committed
SumSub: Enhancement - Prefill KYC applicant with the account email and phone
1 parent 9daea2e commit 33d4aa7

6 files changed

Lines changed: 82 additions & 7 deletions

File tree

declarations.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,22 @@ declare module '@sumsub/react-native-mobilesdk-module' {
6464
onEvent?: (event: SumSubEventPayload) => void;
6565
}
6666

67+
interface SumSubDocumentDefinition {
68+
idDocType?: string;
69+
country?: string;
70+
}
71+
6772
interface SumSubSdkBuilder {
6873
withHandlers(handlers: SumSubHandlers): SumSubSdkBuilder;
6974
withLocale(locale: string): SumSubSdkBuilder;
7075
withDebug(debug: boolean): SumSubSdkBuilder;
76+
withTheme(theme: object): SumSubSdkBuilder;
7177
withAutoCloseOnApprove(delayMs: number): SumSubSdkBuilder;
7278
withAnalyticsEnabled(enabled: boolean): SumSubSdkBuilder;
7379
withApplicantConf(conf: {email?: string; phone?: string}): SumSubSdkBuilder;
80+
withPreferredDocumentDefinitions(
81+
definitions: Record<string, SumSubDocumentDefinition>,
82+
): SumSubSdkBuilder;
7483
build(): {
7584
launch(): Promise<SumSubSdkResult>;
7685
dismiss(): void;

src/lib/sumsub.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,44 @@ describe('launchSumSubSdk', () => {
3636
expect(defaultBuilder.withLocale).toHaveBeenCalledWith('en');
3737
});
3838

39+
it('seeds the applicant with the account email and phone', async () => {
40+
await launchSumSubSdk(ACCESS_TOKEN, jest.fn(), 'en', {
41+
email: 'user@bitpay.com',
42+
phone: '+15550001111',
43+
});
44+
45+
const builder = (SNSMobileSDK.init as jest.Mock).mock.results[0].value;
46+
expect(builder.withApplicantConf).toHaveBeenCalledWith({
47+
email: 'user@bitpay.com',
48+
phone: '+15550001111',
49+
});
50+
});
51+
52+
it('omits applicant fields the account does not have', async () => {
53+
await launchSumSubSdk(ACCESS_TOKEN, jest.fn(), 'en', {
54+
email: 'user@bitpay.com',
55+
});
56+
57+
const builder = (SNSMobileSDK.init as jest.Mock).mock.results[0].value;
58+
expect(builder.withApplicantConf).toHaveBeenCalledWith({
59+
email: 'user@bitpay.com',
60+
});
61+
});
62+
63+
it('does not set an applicant conf when no account data is available', async () => {
64+
await launchSumSubSdk(ACCESS_TOKEN, jest.fn(), 'en', {});
65+
66+
const builder = (SNSMobileSDK.init as jest.Mock).mock.results[0].value;
67+
expect(builder.withApplicantConf).not.toHaveBeenCalled();
68+
});
69+
70+
it('never sets a document country — the SDK cannot fix it client-side (RN-2904)', async () => {
71+
await launchSumSubSdk(ACCESS_TOKEN, jest.fn());
72+
73+
const builder = (SNSMobileSDK.init as jest.Mock).mock.results[0].value;
74+
expect(builder.withPreferredDocumentDefinitions).not.toHaveBeenCalled();
75+
});
76+
3977
it('resolves with the result returned by sdk.launch()', async () => {
4078
const result = await launchSumSubSdk(ACCESS_TOKEN, jest.fn());
4179

src/lib/sumsub.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,18 @@ export interface SumSubSdkResult {
88
errorMsg?: string;
99
}
1010

11+
export interface SumSubApplicantConf {
12+
email?: string;
13+
phone?: string;
14+
}
15+
1116
export const launchSumSubSdk = (
1217
accessToken: string,
1318
onTokenExpired: () => Promise<string>,
1419
locale: string = 'en',
20+
applicantConf?: SumSubApplicantConf,
1521
): Promise<SumSubSdkResult> => {
16-
const sdk = SNSMobileSDK.init(accessToken, onTokenExpired)
22+
const builder = SNSMobileSDK.init(accessToken, onTokenExpired)
1723
.withHandlers({
1824
onStatusChanged: (event: {prevStatus: string; newStatus: string}) => {
1925
console.log(
@@ -26,8 +32,17 @@ export const launchSumSubSdk = (
2632
})
2733
.withLocale(locale)
2834
.withTheme(sumSubTheme)
29-
.withDebug(__DEV__)
30-
.build();
35+
.withDebug(__DEV__);
36+
37+
// Seed the applicant from the authenticated BitPay account instead of letting
38+
// the flow start from blank, user-typed values.
39+
const conf: SumSubApplicantConf = {
40+
...(applicantConf?.email ? {email: applicantConf.email} : {}),
41+
...(applicantConf?.phone ? {phone: applicantConf.phone} : {}),
42+
};
43+
if (Object.keys(conf).length) {
44+
builder.withApplicantConf(conf);
45+
}
3146

32-
return sdk.launch();
47+
return builder.build().launch();
3348
};

src/store/sumsub/sumsub.effects.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ const mockLaunchSumSubSdk = launchSumSubSdk as jest.Mock;
4242
const EID = 'user-eid-123';
4343
const API_TOKEN = 'api-token-xyz';
4444
const ACCESS_TOKEN = 'sumsub-access-token';
45+
const EMAIL = 'user@bitpay.com';
46+
const PHONE = '+15550001111';
4547

4648
const NOT_STARTED = {
4749
path: 'sumsub',
@@ -55,7 +57,7 @@ const makeLoggedInStore = () =>
5557
configureTestStore({
5658
APP: {network: Network.mainnet},
5759
BITPAY_ID: {
58-
user: {[Network.mainnet]: {eid: EID}},
60+
user: {[Network.mainnet]: {eid: EID, email: EMAIL, phone: PHONE}},
5961
apiToken: {[Network.mainnet]: API_TOKEN},
6062
},
6163
});
@@ -111,6 +113,7 @@ describe('startKycVerification — happy path', () => {
111113
ACCESS_TOKEN,
112114
expect.any(Function),
113115
'en',
116+
{email: EMAIL, phone: PHONE},
114117
);
115118
});
116119

@@ -129,6 +132,7 @@ describe('startKycVerification — happy path', () => {
129132
ACCESS_TOKEN,
130133
expect.any(Function),
131134
'es',
135+
{email: undefined, phone: undefined},
132136
);
133137
});
134138

src/store/sumsub/sumsub.effects.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,15 @@ export const startKycVerification =
8282

8383
const locale = (APP.defaultLanguage || 'en').split('-')[0];
8484

85-
const result = await launchSumSubSdk(accessToken, onTokenExpired, locale);
85+
const result = await launchSumSubSdk(
86+
accessToken,
87+
onTokenExpired,
88+
locale,
89+
{
90+
email: user.email,
91+
phone: user.phone,
92+
},
93+
);
8694

8795
dispatch(
8896
LogActions.debug(`[SumSub] SDK closed — status: ${result.status}`),

test/mocks/sumsubSdkMock.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const builder = {
88
withDebug: () => builder,
99
withAutoCloseOnApprove: () => builder,
1010
withAnalyticsEnabled: () => builder,
11-
withApplicantConf: () => builder,
11+
withApplicantConf: jest.fn(() => builder),
12+
withPreferredDocumentDefinitions: jest.fn(() => builder),
1213
build: () => ({
1314
launch: jest.fn().mockResolvedValue({
1415
success: true,

0 commit comments

Comments
 (0)