{"_id":"5bc31451d61edd0012bcd95d","project":"59f79e3c584eb200345ceafc","version":{"_id":"5ba178b00a916500030c6a21","project":"59f79e3c584eb200345ceafc","__v":24,"forked_from":"59f79e3c584eb200345ceaff","createdAt":"2015-09-17T03:47:20.956Z","releaseDate":"2015-09-17T03:47:20.956Z","categories":["5ba178b00a916500030c69a2","5ba178b00a916500030c69a3","5ba178b00a916500030c69a4","5ba178b00a916500030c69a5","5ba178b00a916500030c69a6","5ba178b00a916500030c69a7","5ba178b00a916500030c69a8","5ba178b00a916500030c69a9","5ba178b00a916500030c69aa","5ba178b00a916500030c69ab","5ba178b00a916500030c69ac","5afb6888212c690003ae3d3b","5ba178b00a916500030c69ad","5ba178b00a916500030c69ae","5ba2dcbc99f53f0003b97e2c","5babd73fa0ab3e0003ead030","5bb4038be7222e000334dd97","5bb55954478c1300031a44c2","5bb665a1607307000327c81e","5bb6f90229a7fb0003a0650d","5bb7f9bc29a7fb0003a07ac1","5bba58bd7ba7710003bd901d","5bba6dac7ba7710003bd908d","5bba6e257ba7710003bd9090","5bbac87810189c0003e619ea","5bbb9d02b5862c00036266b2","5bbbadb6219c3e000376c2de","5bc417751d1b0000182bf7f6","5bc59e3b2a5b4f0044db5b97","5bc7bbce2262cc0041f6eff2","5bce6a3580a7250031199f34","5bcfac2c4082510019f2d91b","5bcfac3757bed90030e45d68","5bcfac45d305bc0049941539","5bd2a43548bb6f00289c8fad","5bd3a42a026ebe001f66259e","5bd9d5afffe003005b02f97b","5becb7ee85c6b300557662b6"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":false,"codename":"","version_clean":"3.2.0","version":"3.2"},"category":{"_id":"5babd73fa0ab3e0003ead030","project":"59f79e3c584eb200345ceafc","version":"5ba178b00a916500030c6a21","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2018-09-26T19:00:15.801Z","from_sync":false,"order":2,"slug":"userskyc","title":"Users/KYC"},"user":"5557e76e512c300d007730d1","__v":0,"parentDoc":null,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2018-10-14T10:02:57.791Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":3,"body":"Along with [OAuth](https://docs.synapsefi.com/v3.2/docs/oauth-the-user), we also use device fingerprints for authentication. Fingerprints are used to identify the device that is trying to access a user's information. You need to supply fingerprints when you create a user. Additionally, you can incorporate two factor authentication (\"2FA\") into your user login process when your user connects with a different device. To do so, just supply the new, non-verified fingerprint.\n\nIf the user supplies a non-verified fingerprint during login, the user will be directed to the 2FA flow. We return the linked phone numbers in the API call response with key phone_numbers. You can let the user select the phone number from that list and then make the API call again by specifying the phone_number you want the 2FA to be sent. This will trigger the 2FA protocol and a PIN will be sent to the selected phone number. The user will be able to verify the device via this API call itself. You can supply validation_pin under the user object and the verification will be triggered.\n\nIf you wish to register a new device fingerprint to the user account and use our two factor authentication (2FA) security protocols, complete the following steps:\n\n##Step 1: Supply the new fingerprint.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"POST /v3.1/oauth/594e0fa2838454002ea317a0 HTTP/1.1\\nHost: uat-api.synapsefi.com\\nX-SP-GATEWAY: client_id_2bb1e412edd311e6bd04e285d6015267|client_secret_2bb1e714edd311e6bd04e285d6015267\\nX-SP-USER-IP: 127.0.0.1\\nX-SP-USER: |e83cf6ddcf778e37bfe3d48fc78a6502062fcxx\\nContent-Type: application/json\\n\\n{\\n    \\\"refresh_token\\\":\\\"refresh_ehG7YBS8ZiD0sLa6PQHMUxryovVkJzElC5gWROXq\\\"\\n}\",\n      \"language\": \"http\",\n      \"name\": \"Request\"\n    },\n    {\n      \"code\": \"{\\n    \\\"error\\\": {\\n        \\\"en\\\": \\\"Fingerprint not registered. Please perform the MFA flow.\\\"\\n    },\\n    \\\"error_code\\\": \\\"10\\\",\\n    \\\"http_code\\\": \\\"202\\\",\\n    \\\"phone_numbers\\\": [\\n        \\\"test:::at:::synapsefi.com\\\",\\n        \\\"901-111-2222\\\"\\n    ],\\n    \\\"success\\\": false\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Response\"\n    }\n  ]\n}\n[/block]\n##Step 2: Supply 2FA device from the list.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"POST /v3.1/oauth/594e0fa2838454002ea317a0 HTTP/1.1\\nHost: uat-api.synapsefi.com\\nX-SP-GATEWAY: client_id_2bb1e412edd311e6bd04e285d6015267|client_secret_2bb1e714edd311e6bd04e285d6015267\\nX-SP-USER-IP: 127.0.0.1\\nX-SP-USER: |e83cf6ddcf778e37bfe3d48fc78a6502062fcxx\\nContent-Type: application/json\\n\\n{\\n    \\\"refresh_token\\\":\\\"refresh_ehG7YBS8ZiD0sLa6PQHMUxryovVkJzElC5gWROXq\\\",\\n    \\\"phone_number\\\":\\\"[email protected]\\\"\\n}\",\n      \"language\": \"http\",\n      \"name\": \"Request\"\n    },\n    {\n      \"code\": \"{\\n    \\\"error_code\\\": \\\"10\\\",\\n    \\\"http_code\\\": \\\"202\\\",\\n    \\\"message\\\": {\\n        \\\"en\\\": \\\"MFA sent to [email protected]\\\"\\n    },\\n    \\\"success\\\": true\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Response\"\n    }\n  ]\n}\n[/block]\n##Step 3: Verify the PIN sent to the 2FA device.\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"POST /v3.1/oauth/594e0fa2838454002ea317a0 HTTP/1.1\\nHost: uat-api.synapsefi.com\\nX-SP-GATEWAY: client_id_2bb1e412edd311e6bd04e285d6015267|client_secret_2bb1e714edd311e6bd04e285d6015267\\nX-SP-USER-IP: 127.0.0.1\\nX-SP-USER: |e83cf6ddcf778e37bfe3d48fc78a6502062fcxx\\nContent-Type: application/json\\n\\n{\\n    \\\"refresh_token\\\":\\\"refresh_ehG7YBS8ZiD0sLa6PQHMUxryovVkJzElC5gWROXq\\\",\\n    \\\"validation_pin\\\":\\\"594230\\\"\\n}\",\n      \"language\": \"http\",\n      \"name\": \"Request\"\n    },\n    {\n      \"code\": \"{\\n    \\\"client_id\\\": \\\"589acd9ecb3cd400fa75ac06\\\",\\n    \\\"client_name\\\": \\\"SynapseFI\\\",\\n    \\\"expires_at\\\": \\\"1498297791\\\",\\n    \\\"expires_in\\\": \\\"7200\\\",\\n    \\\"oauth_key\\\": \\\"oauth_vxGS10t7OQzBoVJIM4Z0rbnjyXsc8lCigaH6ewRp\\\",\\n    \\\"refresh_expires_in\\\": 6,\\n    \\\"refresh_token\\\": \\\"refresh_ehG7YBS8ZiD0sLa6PQHMUxryovVkJzElC5gWROXq\\\",\\n    \\\"scope\\\": [\\n        \\\"USER|PATCH\\\",\\n        \\\"USER|GET\\\",\\n        \\\"NODES|POST\\\",\\n        \\\"NODES|GET\\\",\\n        \\\"NODE|GET\\\",\\n        \\\"NODE|PATCH\\\",\\n        \\\"NODE|DELETE\\\",\\n        \\\"TRANS|POST\\\",\\n        \\\"TRANS|GET\\\",\\n        \\\"TRAN|GET\\\",\\n        \\\"TRAN|PATCH\\\",\\n        \\\"TRAN|DELETE\\\"\\n    ],\\n    \\\"user_id\\\": \\\"594e0fa2838454002ea317a0\\\"\\n}\",\n      \"language\": \"json\",\n      \"name\": \"Response\"\n    }\n  ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"We strongly recommend using 2FA or some form of MFA within your authentication process.\\n\\nIf you do not want to use our 2FA, store the fingerprint used when creating the user and supply the fingerprint when performing actions with the user. This way the system will not detect a new device and no 2FAs will be triggered.\\n\\nAlternatively, you can also pass a hashed version of your user_pk+client_id+client_secret. That way the value is still somewhat secret, but you won't need to store it for each unique user.\",\n  \"title\": \"Don't want to trigger 2FA? (NOT RECOMMENDED)\"\n}\n[/block]\n## Testing in Sandbox: Registering a new user fingerprint\n\nNormally when registering a new fingerprint, a random PIN is sent to the specified 2FA device. For testing purposes, it is convenient to know the PIN without checking the 2FA device. If you use this fingerprint the API will always accept the pre-programmed validation PIN.\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"static_pin\",\n    \"h-0\": \"fingerprint\",\n    \"h-1\": \"validation_pin\",\n    \"0-1\": \"\\\"123456\\\"\"\n  },\n  \"cols\": 2,\n  \"rows\": 1\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Collecting Fingerprints on Different Devices\"\n}\n[/block]\n##Web Browsers\nTo collect fingerprints on the web, our suggestion is to use Valve's [Fingerprint.js2144](https://github.com/Valve/fingerprintjs2). Just import the JS file and do the following:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"new Fingerprint2().get(function(result){\\n  // this will use all available fingerprinting sources\\n  console.log('This is the fingerprint '+result);\\n});\",\n      \"language\": \"text\",\n      \"name\": \"Collect Fingerprint\"\n    }\n  ]\n}\n[/block]\n##iOS\nFor iOS we suggest using UIDevice currentDevice method. It is relatively straightforward. Here is an example:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"#pragma mark - get device ID\\n- (NSString *)deviceID{\\n    return [NSString stringWithFormat:@\\\"%@-AAPL\\\",[UIDevice currentDevice].identifierForVendor.UUIDString];\\n}\",\n      \"language\": \"text\",\n      \"name\": \"Collect Fingerprint for iOS\"\n    }\n  ]\n}\n[/block]\n##Android\nFor android we suggest using a logic like the following:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"public static String getDeviceID(Context activity) {\\n        String androidID = Settings.Secure.getString(activity.getContentResolver(),Settings.Secure.ANDROID_ID);\\n        StringBuilder stringBuilder = new StringBuilder();\\n        stringBuilder.append(Build.MANUFACTURER.toUpperCase()+\\\"-\\\");\\n        stringBuilder.append(Build.MODEL+\\\"-\\\");\\n        stringBuilder.append(androidID);\\n        stringBuilder.append(\\\"-GOOG\\\");\\n        androidID = stringBuilder.toString();\\n        return androidID;\\n    }\",\n      \"language\": \"text\",\n      \"name\": \"Collect Fingerprint for Android\"\n    }\n  ]\n}\n[/block]","excerpt":"Verifying a new fingerprint","slug":"register-new-fingerprint","type":"basic","title":"Register New Fingerprint"}

Register New Fingerprint

Verifying a new fingerprint

Along with [OAuth](https://docs.synapsefi.com/v3.2/docs/oauth-the-user), we also use device fingerprints for authentication. Fingerprints are used to identify the device that is trying to access a user's information. You need to supply fingerprints when you create a user. Additionally, you can incorporate two factor authentication ("2FA") into your user login process when your user connects with a different device. To do so, just supply the new, non-verified fingerprint. If the user supplies a non-verified fingerprint during login, the user will be directed to the 2FA flow. We return the linked phone numbers in the API call response with key phone_numbers. You can let the user select the phone number from that list and then make the API call again by specifying the phone_number you want the 2FA to be sent. This will trigger the 2FA protocol and a PIN will be sent to the selected phone number. The user will be able to verify the device via this API call itself. You can supply validation_pin under the user object and the verification will be triggered. If you wish to register a new device fingerprint to the user account and use our two factor authentication (2FA) security protocols, complete the following steps: ##Step 1: Supply the new fingerprint. [block:code] { "codes": [ { "code": "POST /v3.1/oauth/594e0fa2838454002ea317a0 HTTP/1.1\nHost: uat-api.synapsefi.com\nX-SP-GATEWAY: client_id_2bb1e412edd311e6bd04e285d6015267|client_secret_2bb1e714edd311e6bd04e285d6015267\nX-SP-USER-IP: 127.0.0.1\nX-SP-USER: |e83cf6ddcf778e37bfe3d48fc78a6502062fcxx\nContent-Type: application/json\n\n{\n \"refresh_token\":\"refresh_ehG7YBS8ZiD0sLa6PQHMUxryovVkJzElC5gWROXq\"\n}", "language": "http", "name": "Request" }, { "code": "{\n \"error\": {\n \"en\": \"Fingerprint not registered. Please perform the MFA flow.\"\n },\n \"error_code\": \"10\",\n \"http_code\": \"202\",\n \"phone_numbers\": [\n \"[email protected]\",\n \"901-111-2222\"\n ],\n \"success\": false\n}", "language": "json", "name": "Response" } ] } [/block] ##Step 2: Supply 2FA device from the list. [block:code] { "codes": [ { "code": "POST /v3.1/oauth/594e0fa2838454002ea317a0 HTTP/1.1\nHost: uat-api.synapsefi.com\nX-SP-GATEWAY: client_id_2bb1e412edd311e6bd04e285d6015267|client_secret_2bb1e714edd311e6bd04e285d6015267\nX-SP-USER-IP: 127.0.0.1\nX-SP-USER: |e83cf6ddcf778e37bfe3d48fc78a6502062fcxx\nContent-Type: application/json\n\n{\n \"refresh_token\":\"refresh_ehG7YBS8ZiD0sLa6PQHMUxryovVkJzElC5gWROXq\",\n \"phone_number\":\"[email protected]\"\n}", "language": "http", "name": "Request" }, { "code": "{\n \"error_code\": \"10\",\n \"http_code\": \"202\",\n \"message\": {\n \"en\": \"MFA sent to [email protected]\"\n },\n \"success\": true\n}", "language": "json", "name": "Response" } ] } [/block] ##Step 3: Verify the PIN sent to the 2FA device. [block:code] { "codes": [ { "code": "POST /v3.1/oauth/594e0fa2838454002ea317a0 HTTP/1.1\nHost: uat-api.synapsefi.com\nX-SP-GATEWAY: client_id_2bb1e412edd311e6bd04e285d6015267|client_secret_2bb1e714edd311e6bd04e285d6015267\nX-SP-USER-IP: 127.0.0.1\nX-SP-USER: |e83cf6ddcf778e37bfe3d48fc78a6502062fcxx\nContent-Type: application/json\n\n{\n \"refresh_token\":\"refresh_ehG7YBS8ZiD0sLa6PQHMUxryovVkJzElC5gWROXq\",\n \"validation_pin\":\"594230\"\n}", "language": "http", "name": "Request" }, { "code": "{\n \"client_id\": \"589acd9ecb3cd400fa75ac06\",\n \"client_name\": \"SynapseFI\",\n \"expires_at\": \"1498297791\",\n \"expires_in\": \"7200\",\n \"oauth_key\": \"oauth_vxGS10t7OQzBoVJIM4Z0rbnjyXsc8lCigaH6ewRp\",\n \"refresh_expires_in\": 6,\n \"refresh_token\": \"refresh_ehG7YBS8ZiD0sLa6PQHMUxryovVkJzElC5gWROXq\",\n \"scope\": [\n \"USER|PATCH\",\n \"USER|GET\",\n \"NODES|POST\",\n \"NODES|GET\",\n \"NODE|GET\",\n \"NODE|PATCH\",\n \"NODE|DELETE\",\n \"TRANS|POST\",\n \"TRANS|GET\",\n \"TRAN|GET\",\n \"TRAN|PATCH\",\n \"TRAN|DELETE\"\n ],\n \"user_id\": \"594e0fa2838454002ea317a0\"\n}", "language": "json", "name": "Response" } ] } [/block] [block:callout] { "type": "info", "body": "We strongly recommend using 2FA or some form of MFA within your authentication process.\n\nIf you do not want to use our 2FA, store the fingerprint used when creating the user and supply the fingerprint when performing actions with the user. This way the system will not detect a new device and no 2FAs will be triggered.\n\nAlternatively, you can also pass a hashed version of your user_pk+client_id+client_secret. That way the value is still somewhat secret, but you won't need to store it for each unique user.", "title": "Don't want to trigger 2FA? (NOT RECOMMENDED)" } [/block] ## Testing in Sandbox: Registering a new user fingerprint Normally when registering a new fingerprint, a random PIN is sent to the specified 2FA device. For testing purposes, it is convenient to know the PIN without checking the 2FA device. If you use this fingerprint the API will always accept the pre-programmed validation PIN. [block:parameters] { "data": { "0-0": "static_pin", "h-0": "fingerprint", "h-1": "validation_pin", "0-1": "\"123456\"" }, "cols": 2, "rows": 1 } [/block] [block:api-header] { "title": "Collecting Fingerprints on Different Devices" } [/block] ##Web Browsers To collect fingerprints on the web, our suggestion is to use Valve's [Fingerprint.js2144](https://github.com/Valve/fingerprintjs2). Just import the JS file and do the following: [block:code] { "codes": [ { "code": "new Fingerprint2().get(function(result){\n // this will use all available fingerprinting sources\n console.log('This is the fingerprint '+result);\n});", "language": "text", "name": "Collect Fingerprint" } ] } [/block] ##iOS For iOS we suggest using UIDevice currentDevice method. It is relatively straightforward. Here is an example: [block:code] { "codes": [ { "code": "#pragma mark - get device ID\n- (NSString *)deviceID{\n return [NSString stringWithFormat:@\"%@-AAPL\",[UIDevice currentDevice].identifierForVendor.UUIDString];\n}", "language": "text", "name": "Collect Fingerprint for iOS" } ] } [/block] ##Android For android we suggest using a logic like the following: [block:code] { "codes": [ { "code": "public static String getDeviceID(Context activity) {\n String androidID = Settings.Secure.getString(activity.getContentResolver(),Settings.Secure.ANDROID_ID);\n StringBuilder stringBuilder = new StringBuilder();\n stringBuilder.append(Build.MANUFACTURER.toUpperCase()+\"-\");\n stringBuilder.append(Build.MODEL+\"-\");\n stringBuilder.append(androidID);\n stringBuilder.append(\"-GOOG\");\n androidID = stringBuilder.toString();\n return androidID;\n }", "language": "text", "name": "Collect Fingerprint for Android" } ] } [/block]