Callback - PII Verification
When your counterparty initiated a Pre-transaction Travel Rule or a Post-transaction Travel Rule request, and they designate your VASP as the Travel Rule Receiver VASP, you will receive this callback with callbackType=4 to validate the PII correctness based on your in-house KYC data.
For further details of the request structure, see: RegularizeCallbackVerifyAddressRequest.
| Type | Pre-transaction Travel Rule | Post-transaction Travel Rule |
|---|---|---|
| Your Role in Travel Rule | Travel Rule Receiver VASP | Travel Rule Receiver VASP |
| Your Counterparty in Travel Rule | Travel Rule Initiator VASP | Travel Rule Initiator VASP |
| Your Role in Transfer | Beneficiary VASP | Originator VASP |
| Your Counterparty Role in Transfer | Originator VASP | Beneficiary VASP |
| Your Responsibility | Confirm correctness of Beneficiary Person | Confirm correctness of Originator Person |
Request
You can expect to receive below request From GTR:
{
"requestId": "IGicRINHYF4N",
"invokeVaspCode": "[Invoker VASP Code]",
"originatorVasp": "[Originator VASP Code]",
"beneficiaryVasp": "[Beneficiary VASP Code]",
"callbackType": 4,
"callbackData": {
"requestId": "IGicRINHYF4N",
"txId": "1fcd10006f252d2cca3a4803d0dcb84b0ee10ef73d1055f0fe23ce4ead0f6e75", // In pre-transaction travel rule, txId will be null
"amount": "1000",
"fiatPrice": "6.66",
"fiatName": "USDT",
"network": "ETH",
"ticker": "USDT",
"tag": "",
"address": "1GURHee2JsCkdpxVisjbjAeNhbDbGub8R4",
"secretType": 1,
"originatorVasp": "[Originator VASP Code]", // save it, don't use it
"beneficiaryVasp": "[Beneficiary VASP Code]", // save it, don't use it
"initiatorVasp": "[Initiator VASP Code]",
"receiverVasp": "[Receiver VASP Code / Your VASP Code]",
"verificationDirection": 1, // 1: RECEIVER TO SENDER (Post-transaction Travel Rule, YOU are Originator), 2: SENDER TO RECEIVER (Pre-transaction Travel Rule, You are Beneficiary)
"piiSecuredInfo": {
"initiatorKeyInfo": {
"publicKey": "[COUNTER_PARTY_VASP_PUBLIC_KEY]"
},
"receiverKeyInfo": {
"publicKey": "[YOUR_PUBLIC_KEY]"
},
"piiSecretFormatType": "FULL_JSON_OBJECT_ENCRYPT",
"piiSpecVersion": "ivms101-2020",
"secretAlgorithm": "ed25519_curve25519",
"securedPayload": "[Encrypted PII, clear-text is forbidden]"
}
}
}
PII Matching Process
Once you receive above request, you can start your PII matching process by following below steps.
1. Identify the algorithm and decrypt
- Decrypt the PII payload from
piiSecuredInfo.securedPayloadby usingpiiSecuredInfo.initiatorPublicKeyand your Self-hosted Private Key. piiSecuredInfo.secretAlgorithmtells the exact encryption algorithm, if your VASP supports multiple algorithms.- Decrypted PII is usually in JSON format.
- All encryption algorithms are listing in Secret Algorithm in GTR.
✍️ If you operate as a Travel Rule Service Provider(TRSP) just as GTR, you shouldn't and you can't decrypt PII payload on behalf of your VASP clients.
Your VASP client should always self-custody their Private Key and do the decryption by themselves.
2. Identify the PII Version and deserialize it to structure
- Parse decrypted PII into PII Data Structure
piiSecuredInfo.piiSpecVersiontells the exact PII specification version , if your system supports multiple PII specifications.- All PII specification version are listing in List of PII Spec Version.
3. Compare the Required PII / Supported PII Fields
- Compare all the required PII and supported PII fields to the decrypted payload.
- Add PII field matching result to the
verifyFieldsof response body. - the
typeshould refer to the PII Verify Fields, and using the VerifyFields ID as the value oftype, and thestatus: 1: matched, 2: mismatch, 3: not support. - In the pre-transaction travel rule: beneficiary VASP perspective, it could be possible that you need to collect the originator info as required, but you cannot verify it. Fields in this kind of situation should use: 4: INFO_INSUFFICIENT or 5: INFO_EXISTS to reply.
- Just to verify all the fields that you can verify, DO NOT use
initiatorExpectedVerifyFields. - For the matching method, please refer to the: PII Verify Fields and PII Verify Methods
| Field Name | VerifyFields ID | Required | Supported Verify |
|---|---|---|---|
| Beneficiary Legal Person Name | 111001 | Yes | Yes |
| Beneficiary Country of Registration | 111022 | No | Yes |
| Beneficiary Natural Person National ID | 110045 | No | No |
| Originator Country of Registration | 101022 | Yes | No |
| Originator Natural Person Address - Address Lines | 100031 | Yes | No |
"verifyFields": [
{
"message": "matched (success)",
"status": 1, // (SUCCESS)
"type": "111001" // Beneficiary Legal Person Name
},
{
"message": "mismatch (failed)",
"status": 2, // (FAILED)
"type": "111022" // Beneficiary Country of Registration
},
{
"message": "not support",
"status": 3, // (NOT SUPPORT)
"type": "110045" // Beneficiary Natural Person National ID
},
{
"message": "info missing",
"status": 4, // <-- you need originator info but insufficient (FAILED)
"type": "100031" // Originator Natural Person Address - Address Lines
},
{
"message": "info exists (success)",
"status": 5, // <-- you need originator info and it provided (SUCCESS)
"type": "101022" // Originator Country of Registration
}
]
4. Decide the final result
Final result of PII Verification is decided by you based on your compliance requirement.
For example:
| Field Name | VerifyFields ID | Your Compliance Required | You Support Validation |
|---|---|---|---|
| Beneficiary Legal Person Name | 111001 | Yes | Yes |
| Beneficiary Country of Registration | 111022 | Yes | Yes |
| Beneficiary Natural Person National ID | 110045 | No | No |
| Originator Country of Registration | 101022 | Yes | No |
| Originator Natural Person Address - Address Lines | 100031 | Yes | No |
✍️ You should focus on the
Your Compliance Requiredfields so you can give the final result based on the matching status of these fields.
5. Understand the direction
IVMS Payload contains the PII info of both Originator Person and Beneficiary Person. To decide which person's PII is the one you should validate, you can use the verificationDirection in the request body:
- if
verificationDirection = 2: this is a Pre-transaction Travel Rule situation. So, you, as the Travel Rule Receiver VASP, also serves as a Beneficiary VASP. You should validate the Beneficiary person in the IVMS payload with your in-house KYC data of your customers. - if
verificationDirection = 1: this is a Post-transaction Travel Rule situation. So, you, as the Travel Rule Receiver VASP, also serves as an Originator VASP. You should validate the Originator person in the IVMS payload with your in-house KYC data of your customers.
6. Put your company info into PII and encrypt again
- You're required to fill in your company info into
OriginatorVASPorBeneficiaryVASPof IVMS payload and encrypt again. - Encrypt PII payload data by your self-hosted Private Key and the
piiSecuredInfo.initiatorPublicKey. - Put the encrypted data into
securedPayloadof the response. - You should also fill in the
secretAlgorithmandpiiSpecVersionwhich is same as the request body.
If verificationDirection=1, it means you should fill your VASP's entity info to OriginatorVASP structure.
{
"ivms101": {
... keep original data ...
"OriginatingVASP": {
"originatingVASP": {
// required
"legalPerson": {
// required, nameIdentifier*, localNameIdentifier, phoneticNameIdentifier
"name": {
"nameIdentifier": [
{
"legalPersonName": "Originator VASP Company Name - VVVV Inc.",
"legalPersonNameIdentifierType": "LEGL" // Usually Fixed as LEGL // for legal person: LEGL, SHRT, TRAD
}
]
},
// required, For Company Legal Person use RAID and fill your company ID in nationalIdentifier
"nationalIdentification": {
// nationalIdentifierType: ISO20022, ARNU, CCPT, RAID, DRLC, FIIN, TXID, SOCS, IDCD, LEIX, MISC,
"nationalIdentifierType": "RAID",
// registrationAuthority: GLEIF code (i.e: 香港公司註冊處核發 Hong Kong Company Registry Approved, For more please check: https://www.gleif.org/en/about-lei/code-lists/gleif-registration-authorities-list)
"registrationAuthority": "RA000388",
// countryOfIssue: ISO 3166-1 alpha-2 codes
"countryOfIssue": "HK",
// nationalIdentifier: (i.e: Your Company ID from authority)
"nationalIdentifier": "38429049028390482"
},
// required
"geographicAddress": [
{
// required
"country": "HK", // ISO 3166-1 alpha-2 codes
"townName": "Hong Kong",
"addressType": "GEOG", // HOME, BIZZ, GEOG
"addressLine": ["Please fill your address here"],
// optional:
"department": "OfficeOfTheCEO",
"subDepartment": "InternalAudit8562",
"streetName": "SiliconAlley65",
"buildingNumber": "J4H6",
"buildingName": "VirtualTower200",
"floor": "Floor94",
"postBox": "CB842",
"room": "BionicRoom38",
"postCode": "TT7643",
"townLocationName": "E-Sector",
"districtName": "BlockchainDistrict",
"countrySubDivision": "E-Province"
}
],
// required
"countryOfRegistration": "HK"
}
}
},
If verificationDirection=2, it means you should fill your VASP's entity info into BeneficiaryVASP part.
{
"ivms101": {
... keep original data ...
"BeneficiaryVASP": {
"beneficiaryVASP": {
// required
"legalPerson": {
// required, nameIdentifier*, localNameIdentifier, phoneticNameIdentifier
"name": {
"nameIdentifier": [
{
"legalPersonName": "Beneficiary VASP Company Name - VVVV Inc.",
"legalPersonNameIdentifierType": "LEGL" // Usually Fixed as LEGL // for legal person: LEGL, SHRT, TRAD
}
]
},
// required, For Company Legal Person use RAID and fill your company ID in nationalIdentifier
"nationalIdentification": {
// nationalIdentifierType: ISO20022, ARNU, CCPT, RAID, DRLC, FIIN, TXID, SOCS, IDCD, LEIX, MISC,
"nationalIdentifierType": "RAID",
// registrationAuthority: GLEIF code (i.e: 香港公司註冊處核發 Hong Kong Company Registry Approved, For more please check: https://www.gleif.org/en/about-lei/code-lists/gleif-registration-authorities-list)
"registrationAuthority": "RA000388",
// countryOfIssue: ISO 3166-1 alpha-2 codes
"countryOfIssue": "HK",
// nationalIdentifier: (i.e: Your Company ID from authority)
"nationalIdentifier": "38429049028390482"
},
// required
"geographicAddress": [
{
// required
"country": "HK", // ISO 3166-1 alpha-2 codes
"townName": "Hong Kong",
"addressType": "GEOG", // HOME, BIZZ, GEOG
"addressLine": ["Please fill your address here"],
// optional:
"department": "OfficeOfTheCEO",
"subDepartment": "InternalAudit8562",
"streetName": "SiliconAlley65",
"buildingNumber": "J4H6",
"buildingName": "VirtualTower200",
"floor": "Floor94",
"postBox": "CB842",
"room": "BionicRoom38",
"postCode": "TT7643",
"townLocationName": "E-Sector",
"districtName": "BlockchainDistrict",
"countrySubDivision": "E-Province"
}
],
// required
"countryOfRegistration": "HK"
}
}
},
7. Preflight Check Status
- Only when your VASP serves as the
Beneficiary VASP, you can tell the originator whether you will decide to receive the funds by filling the fieldpreflightCheckStatus. - If you are the Originator VASP, you could just simply reply
preflightCheckStatusasNONE. - For
preflightCheckStatus, it can be one of:- NONE
- NOT_SUPPORT
- SKIPPED
- ACCEPTED
- PENDING
- REJECTED
{
...
"preflightCheckStatus": "ACCEPTED",
"preflightCheckMessage": "will accept",
}
Response
Once you go through above PII Matching steps, GTR expect to receive your response as below. GTR will treat this callback request as Timeout if no response from your server in 2 seconds.
{
"data": {
"verifyFields": [
{
"message": "matched (success)",
"status": 1,
"type": "111001"
},
{
"message": "mismatch (failed)",
"status": 2,
"type": "111022"
},
{
"message": "not support",
"status": 3,
"type": "110045"
},
{
"message": "info missing",
"status": 4, // <-- you need originator info but insufficient (FAILED)
"type": "100031" // Originator Natural Person Address - Address Lines
},
{
"message": "info exists (success)",
"status": 5,
"type": "101022"
}
],
"piiSecuredInfo": {
"initiatorKeyInfo": {
"publicKey": "[COUNTER_PARTY_VASP_PUBLIC_KEY]"
},
"receiverKeyInfo": {
"publicKey": "[YOUR_PUBLIC_KEY]"
},
"piiSecretFormatType": "FULL_JSON_OBJECT_ENCRYPT",
"piiSpecVersion": "ivms101-2020",
"secretAlgorithm": "ed25519_curve25519",
"securedPayload": "[Encrypted PII, clear-text is forbidden]"
}
},
"preflightCheckStatus": "ACCEPTED",
"preflightCheckMessage": "will accept",
"verifyMessage": "Verification Success" or "Verification Failed",
"verifyStatus": 100000 or 200003
}
Response A: Pass
{
"data": {
// ...same as above
},
"verifyMessage": "Verification Success",
"verifyStatus": 100000
}
Response B: Fail
If one of required field failed, mismatch or info missing, then result as:
{
"data": {
// ...same as above
},
"verifyMessage": "Verification Failed",
"verifyStatus": 200003
}