1.  Specify URL Redirects for Application decision of Approve, Manual Review and Decline

  • KYC Plugin will redirect users the URLs based on application decision allowing you to present appropriate next steps to your users.

Callback URL (web hook)

  • Callback URL will allow clients to consume raw response of the KYC application processing and getting the user id back from IDM which will passed to the KYC plugin.

Note: The webhook response will need to contain the Access-Control-Allow-Origin header with the Form domain in order for the KYC plugin to correctly work.

2. Setup Webhook response (optional)

If you have configured the Callback URL setting, after a user completes the registration form, the plugin will generate an AJAX call to the specified Callback URL. For this functionality to work properly, your webhook response needs to contain the following requirements:

Response Headers
Access-Control-Allow-Origin: https://regtech.identitymind.store
Access-Control-Allow-Methods:  POST
Access-Control-Allow-Headers: Content-Type
Content-Type: application/json

Response Body

{"response":"OK"}

Please note that AJAX will perform a preflight request prior to the actual POST request, which needs to result in success, if not, POST request will be dropped. 

Webhook Redirect

You can also manage user redirection via the webhook response, this will give you more flexibility into supporting more specific use cases, to make use of this feature, the response will need to be like so:

Response Method
HTTP/1.1 302

Response Headers
Access-Control-Allow-Origin: https://regtech.identitymind.store
Access-Control-Allow-Methods:  POST
Access-Control-Allow-Headers: Content-Type
Content-Type: application/json

Response Body

{"redirect":"<REDIRECT_URL>"}

2.1. Validate Response (optional)

The request body format of the callback will be a JSON containing a JWT with the following structure of <header-in-base64-encoding>.<response-in-base64-encoding>.

The response data excepted is as follows:

The response data excepted is as follows:

Header:{
    "alg": "RS256",
    "typ": "JWT"
}
Payload:{
    {
  "form_data": {
    "full_name": "Daniel",
    "last_name": "Perez",
    "email": "example@mail.com",
    "phone_code": "+1",
    "phone": "555555555",
    "street": "Street",
    "country": "MX",
    "zip_code": "55555",
    "city": "Some City",
    "state": "FL",
    "ssn": "12345..",
    "btc": "10x4....",
    "btc_type": "BTC",
    "dob": "2003-03-02",
    "tid": "1c67949ac6e6e334b6b2b...",
    "dfp": "eyJJRHMiO...",
    "show_id_list": [
      ""
    ],
    "show_address_list": [
      ""
    ],
    "user_id": "",
    "gdpr_purpose": "Purpose of processing...",
    "version": "2"
  },
  "kyc_result": "ACCEPT",
  "tid": "1c67949ac6...",
  "step": 1
}
}
Verify Signature: ԑ>jkbW[Pt@.kf

If subscribed on ID DV plan, the response will also contain the following fields inside the form_data object:

And if you are subscribed to the 4D ID plan, the response will contain previous fields from ID IV, plus:

Response Validation (Server side ONLY)

It’s very important to validate the response coming back is indeed from Identitymind. For validating that the information received came from IDM, you’ll need the following public key depending on the environment:

Public Key for Free Tiers

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqPUvTUy2Pza92EGQGLpq
IvnqTrZxrXRaAY1ZKuAKYOAmk56c3lJJbkZOczzgtSIN6S5AyNtp3GCUgiAdfoCk
ngbaRvhdK92+ij2tCglgwZVYMNFDLF5HbhU7Vohxk2aR3NDUzD2ruHt9MbD5/2f7
cmyAHjDSvbH4x4dsgE7DHe/qdPjqhtXmSaWVIy2ProJqiaGgvOi+DtXnqddQvxmP
5KsYqlvN2ZGizl1CWHpoN1wCsZMrJPyBxQ1t/lGv+3HGu3p3cjFgM/j6OJZzQscc
3FLZ4f7rIMR2V31MeqbRpReReS3Ibw0xgdUxSumc8fISO8UBMdfhp3wL0MLCpUoy
GQIDAQAB
-----END PUBLIC KEY-----
Public Key for Paid/Subscription Tiers

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv53X2ZcsXPNrtpfJwS7x
GT3Q/YYSmlLyND4j917vgHLYA8iMfByMMXqXnakp7+xzOHuLdoc2BX3bjDWgB2yP
sX2wC17+PylWPWQkIIO6ZhkuckYgFlGhg38VV2r5mgiamYdv/jbPz6Fmmf3+kRc3
XiR74gMy15k1YgYDiEQOEaREOk0H8DmW78sRPetkdhgOy+f8z74aA7ihpk8BZNhN
FwB7iptSjDwR0RfUx6cyzOA77uMIACEnkh4kqfT2kJrhNd9kYw+WgRXiGcY7RUyx
QV7fa3nMMxsvusDRDfLM52wuuPmwB8w8wxXmr4i7KvHKs3n37Adaekme32+dX6nO
7QIDAQAB
-----END PUBLIC KEY-----

The following is an example of validating a JWT with the provided Public key:

############### Python ###############

# Using https://github.com/jpadilla/pyjwt
import jwt

jwt.decode(jwtresponse, <public_key>, algorithms=['RS256'])

############### JavaScript ###############

// Using https://www.npmjs.com/package/jsonwebtoken
var jwt = require('jsonwebtoken');

// verify a token asymmetric
var cert = fs.readFileSync('public_key.txt'); // get public key
jwt.verify(jwtresponse, cert, function(err, decoded) {
console.log(decoded.foo) // bar
});

############### PHP ###############

<?php
/*
 Using https://github.com/firebase/php-jwt
*/

use \Firebase\JWT\JWT;

/*
Replace $jwt with the post parameter
*/
$decoded = JWT::decode($jwt, $publicKey, array('RS256'));

/*
 NOTE: This will now be an object instead of an associative array. To get
 an associative array, you will need to cast it as such:
*/

$decoded_array = (array) $decoded;
echo "Decode:\n" . print_r($decoded_array, true) . "\n";
?>

############### Ruby ###############

# Using https://github.com/jwt/ruby-jwt

rsa_public = <public_key>

token = "JWT RESPONSE FROM PLUGIN"

puts token

decoded_token = JWT.decode token, rsa_public, true, { :algorithm => 'RS256' }

puts decoded_token

############### Go ###############

package main

import (
    "fmt"
    // Please check https://github.com/dgrijalva/jwt-go documentation
    jwt "github.com/dgrijalva/jwt-go"
    "io/ioutil"
    "log"
    "crypto/rsa"
)

var (
verifyKey *rsa.PublicKey
)

func init() {
//PUBLIC KEY PROVIDED ON PREVIOUS STEP
verifyBytes, err := ioutil.ReadFile("public.key")
fatal(err)

verifyKey, err = jwt.ParseRSAPublicKeyFromPEM(verifyBytes)
fatal(err)
}

func fatal(err error) {
if err != nil {
log.Fatal(err)
}
}

func main() {

// raw response from plugin in JWT format
tokenString := "JWT RESPONSE FROM PLUGIN"

    token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {

        return verifyKey, nil
    })

    //if not error and response is valid proceed
    if err == nil && token.Valid {
        fmt.Printf("Valid token: %v\n", token.Claims)
    } else {
        fmt.Printf("Token parse error: %v\n", err)
    }
}

3. Simulate KYC Results

If you wish to test certain results, you'll need to send specific values to the city in the complete address section:

4. Pass custom user ID

If you need to pass a custom user id, to map the TID, then you can check our Passing Custom User ID Guide

Did this answer your question?