//------------------------------------------------------------------------------------ //npm install --save axios dotenv crypto-js const axios = require("axios"); const CryptoJS = require("crypto-js"); require('dotenv').config() //------------------------------------------------------------------------------------ /* This particular onboarding process is for illustration purposes only. It is possible to customize the ampliFi onboarding process to your (the client's) use case. For example, it is possible to require a passport instead of a driver's license, require additional information, create multiple accounts at once following onboarding, etc. Please speak to your support representative about customizing the onboarding process to your use case. BEFORE RUNNING THIS EXAMPLE: * Set AMPLIFI_BASE_URL, AMPLIFI_TEST_DEVICETAG, AMPLIFI_FACE_IMAGE_B64, AMPLIFI_DL_FRONT_B64, and AMPLIFI_DL_BACK_B64 in an .env file. (Speak to a support representative to be issued client credentials and URL after receiving access to the sandbox.) * Set UNIQUE_REFERENCE_ID to a unique identifier. * Note: The generation of secrets during the onboarding process and the method of secrets delivery is specific to the client use case. This is an example only. */ const AMPLIFI_BASE_URL = process.env.AMPLIFI_BASE_URL; const AMPLIFI_TEST_DEVICETAG = process.env.AMPLIFI_TEST_DEVICETAG; const AMPLIFI_FACE_IMAGE_B64 = process.env.AMPLIFI_FACE_IMAGE_B64; const AMPLIFI_DL_FRONT_B64 = process.env.AMPLIFI_DL_FRONT_B64; const AMPLIFI_DL_BACK_B64 = process.env.AMPLIFI_DL_BACK_B64; const UNIQUE_REFERENCE_ID = "exampleRef1017"; //Update this value so that it is a unique ID before running //Log in credentials for client tests must be configured //Speak to a support representative to be issued test credentials const credentialsTestChannel = { channel: "test", deviceTag: AMPLIFI_TEST_DEVICETAG, deviceData: { "platform": "test" } }; //Example prospect data const PROSPECT_DATA = { deviceTag: `my_deviceTag${(new Date() / 1000).toString().substring(0, 4)}`, dtsCollected: new Date(), payload: { referrerAFiUserId: "qweaurl4zdpfo2hu", referral: "BBQFCHQXN", client: { email: "test.email@abc.test", mobile: "5556667777", isIntroSeen: true, name: { firstName: "John", middleName: "Quincy", lastName: "Smith" }, dob: { day: "01", month: "01", year: "1975" }, address: { addressLine1: "123 Main Str.", addressLine2: undefined, city: "Harrisburg", postalCode: "12345", state: "PA", country: "USA" }, extra: { sex: "male", eyeColor: "BRO", hairColor: "BLK", heightMetric: "181", weightMetric: "85" }, ssn: "3" + (new Date() / 1000).toString().substring(0, 8), document: { type: "US driving license", number: "99999999", issued: "10052015", expires: "08042027", issuingState: "PA", raw: {}, }, languageCode: "en" } }, preSegment: "demo_uoiuqwehflkipahgoqq", linkinjected: "null", deepLink: "null", //if app was opened with a deepLink URL, it gets populated here deviceData: { "platform": "android", "build": "0.0.01" }, referral: "BBQFCHQXN" }; //------------------------------------------------------------------------------------ //Get Authorization Token /* The ampliFi system exposes a REST API and expects calls directly from the front-end. After onboarding, ampliFi authenticates each individual customer and performs transactions only explicitly allowed to that specific customer. Requests must have a valid authorization token in the request headers, so your first request in any workflow should be to /token in order to receive an authorization token. A valid token should be included in the headers of all subsequent requests. */ async function getAuthToken(credentials) { const data = credentials; const config = { method: 'PUT', url: `${AMPLIFI_BASE_URL}/token`, headers: { 'Content-Type': "application/json" }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Connect Web-Socket /* To enable efficient 2-way communication between the prospect and the server-side processes, we will first request authorization of a websocket connection. The halfRef value will be a long string used to establish the connection to the device specified by the deviceTag. */ async function connectSocket(deviceTag) { const data = { halfRef: `some1RANDOM2string${(new Date() / 1).toString()}`, deviceTag }; const config = { method: 'POST', url: `${AMPLIFI_BASE_URL}/prospect/connectsocket`, headers: { 'Content-Type': "application/json" }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Take Prospect Data /* We will send prospect data including both the payload (prospect details) and device data. The data will be saved and an attempt will be made to verify the prospect data according to the requirements of the included preSegment. */ async function takeProspectData(prospectData) { const data = prospectData; const config = { method: 'POST', url: `${AMPLIFI_BASE_URL}/prospect/data`, headers: { 'Content-Type': "application/json" }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Take Prospect Image /* We will call /prospect/image to post image data in base 64 encoded format for each image. Depending on the preSegment, there may be different image requirements and there may be different image set combinations that will meet the requirements. For example, for preSegment: demo_uoiuqwehflkipahgoqq, one possible valid image type combination is the following: ["Face image", "US driving license front document image", "US driving license back document image"] Therefore, we will take these three image types in this example walkthrough. Each time this endpoint is called, the image data will be saved and an attempt will be made to verify the prospect data and image data according to the requirements of the included preSegment. */ async function takeProspectImage(deviceTag, AFiImageId, imageBase64, type) { const data = { deviceTag, AFiImageId, type, imageBase64, preSegment: "demo_uoiuqwehflkipahgoqq", dtsCreated: new Date() }; const config = { method: 'POST', url: `${AMPLIFI_BASE_URL}/prospect/image`, headers: { 'Content-Type': "application/json" }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Register Prospect Device /* When a prospect device is registered, it could be a new device for an existing user or a device for a completely new user/prospect. If it is a new prospect, this endpoint will attempt to convert the prospect into a user as well as registering the device. If a valid referral code is included, then an attempt will be made to register a referral bonus task in order to pay a referral bonus if applicable. */ async function registerProspectDevice(deviceTag) { const data = { deviceData: { "platform": "android", "build": "0.0.01" }, deviceTag, linkinjected: "null", preSegment: "demo_uoiuqwehflkipahgoqq", referral: "BBQFCHQXN" }; const config = { method: 'POST', url: `${AMPLIFI_BASE_URL}/prospect/registration`, headers: { 'Content-Type': "application/json" }, data }; let result; try { result = await axios.request(config); if (result.status === 200) { return Promise.resolve(result.data); } } catch (err) { console.log({ errCode: err.code, responseStatus: err.response && err.response.status, data: err.response && JSON.stringify(err.response.data) }); } } //------------------------------------------------------------------------------------ //Run the walkthrough async function ampliFiOnboardingWalkthrough() { //Get Authorization Token credentialsTestChannel /* console.log(`Start /token example credentialsTestChannel.\n`); const authObjectTest = await getAuthToken(credentialsTestChannel); let authToken = undefined; if (authObjectTest) { console.log(`Successfully obtained test user authorization: ${JSON.stringify(authObjectTest)}\n`); authToken = authObjectTest.token; console.log(`Authorization token: ${authToken}\n`); } else { console.log(`Error getting Test authorization token\n`) } console.log(`End /token example credentialsTestChannel.\n`); */ //Connect Websocket console.log(`Start /prospect/connectsocket example.\n`); let webSocketResult; webSocketResult = await connectSocket(PROSPECT_DATA.deviceTag); if (webSocketResult) { console.log(`Successfully connected web-socket: ${JSON.stringify(webSocketResult)}\n`); } console.log(`End /prospect/connectsocket example.\n`); //Take Prospect Data console.log(`Start /prospect/data example.\n`); let prospectDataResult; prospectDataResult = await takeProspectData(PROSPECT_DATA); if (prospectDataResult) { console.log(`Successfully took prospect data: ${JSON.stringify(prospectDataResult)}\n`); console.log(`deviceTag: ${PROSPECT_DATA.deviceTag}\n`); } console.log(`End /prospect/data example.\n`); //Take Prospect Image (Face Image) console.log(`Start /prospect/image example. (Face Image)\n`); let prospectImageResult; prospectImageResult = await takeProspectImage(PROSPECT_DATA.deviceTag, `${UNIQUE_REFERENCE_ID}imageId1`, AMPLIFI_FACE_IMAGE_B64, "Face image"); if (prospectImageResult) { console.log(`Successfully uploaded prospect image: ${JSON.stringify(prospectImageResult)}\n`); } console.log(`End /prospect/image example. (Face Image)\n`); //Take Prospect Image (DL FRONT) console.log(`Start /prospect/image example. (DL FRONT)\n`); let prospectImageResult2; prospectImageResult2 = await takeProspectImage(PROSPECT_DATA.deviceTag, `${UNIQUE_REFERENCE_ID}imageId2`, AMPLIFI_DL_FRONT_B64, "US driving license front document image"); if (prospectImageResult2) { console.log(`Successfully uploaded prospect image: ${JSON.stringify(prospectImageResult2)}\n`); } console.log(`End /prospect/image example. (DL FRONT)\n`); //Take Prospect Image (DL BACK) console.log(`Start /prospect/image example. (DL BACK)\n`); let prospectImageResult3; prospectImageResult3 = await takeProspectImage(PROSPECT_DATA.deviceTag, `${UNIQUE_REFERENCE_ID}imageId3`, AMPLIFI_DL_BACK_B64, "US driving license back document image"); if (prospectImageResult3) { console.log(`Successfully uploaded prospect image: ${JSON.stringify(prospectImageResult3)}\n`); } console.log(`End /prospect/image example. (DL BACK)\n`); //Register Prospect Device console.log(`Start /prospect/registration example.\n`); let prospectRegistrationResult; let SERVER_SECRET; prospectRegistrationResult = await registerProspectDevice(PROSPECT_DATA.deviceTag); if (prospectRegistrationResult) { console.log(`Successfully registered prospect: ${JSON.stringify(prospectRegistrationResult)}\n`); SERVER_SECRET = prospectRegistrationResult.serverSecret; } console.log(`End /prospect/registration example.\n`); if (SERVER_SECRET) { //After registering successfully and obtaining a serverSecret, user can log in const mobileType = "android_v1"; const mobileType2 = "ios_v1"; const deviceTag = PROSPECT_DATA.deviceTag; const halfRef = `some1RANDOM2string${(new Date() / 1).toString()}`; const dtsValueString = (new Date()).valueOf().toString(); let cryptotext = CryptoJS.AES.encrypt(deviceTag + dtsValueString, SERVER_SECRET).toString(); const credentialsAndroidChannel = { "channel": mobileType, "dtsValueString": dtsValueString, "deviceTag": deviceTag, "socket": { halfRef: halfRef }, "cryptotext": cryptotext }; const credentialsIOSChannel = { "channel": mobileType2, "dtsValueString": dtsValueString, "deviceTag": deviceTag, "socket": { halfRef: halfRef }, "cryptotext": cryptotext }; //Get Authorization Token credentialsAndroidChannel console.log(`Start /token example credentialsAndroidChannel.\n`); const authObjectAndroid = await getAuthToken(credentialsAndroidChannel); let authTokenAndroid = undefined; if (authObjectAndroid) { console.log(`Successfully obtained android user authorization: ${JSON.stringify(authObjectAndroid)}\n`); authTokenAndroid = authObjectAndroid.token; console.log(`Authorization token: ${authTokenAndroid}\n`); } else { console.log(`Error getting Android authorization token\n`) } console.log(`End /token example credentialsAndroidChannel.\n`); //Get Authorization Token credentialsIOSChannel console.log(`Start /token example credentialsIOSChannel.\n`); const authObjectIOS = await getAuthToken(credentialsIOSChannel); let authTokenIOS = undefined; if (authObjectIOS) { console.log(`Successfully obtained iOS user authorization: ${JSON.stringify(authObjectIOS)}\n`); authTokenIOS = authObjectIOS.token; console.log(`Authorization token: ${authTokenIOS}\n`); } else { console.log(`Error getting iOS authorization token\n`) } console.log(`End /token example credentialsIOSChannel.\n`); } } if (process.env.AMPLIFI_TEST_DEVICETAG && process.env.AMPLIFI_FACE_IMAGE_B64 && process.env.AMPLIFI_DL_FRONT_B64 && process.env.AMPLIFI_DL_BACK_B64 && process.env.AMPLIFI_BASE_URL) { ampliFiOnboardingWalkthrough(); } else { console.log("Before running the walkthrough, set the required .env variables."); }