Verify beneficiary details

Confirming that beneficiary details match your customer

According to FATF, you should verify the accuracy of the beneficiary information you receive in the travel rule message:

This means that in addition to verifying that the address belongs to you, you should also compare the name of the beneficiary (and additional information, if applicable) in the travel rule message against the KYC details of your customer that you have collected and confirmed during the onboarding stage.


When to verify

Usually the beneficiary name matching would happen at the same time as when you confirm that the wallet address is controlled by you. However, it can be done afterwards as well (with some caveats):

Caveats

  • Name matching by API before txConfirm - you need to deactivate the auto-confirmation of wallet addresses as this would automatically move it to ACK. You would use the data pushed by the webhook to check both the address and the beneficiary name.
  • Name matching by API after txConfirm - you cannot have have rules active as they would run immediately once the status hits ACK. You would use the data pushed by the webhook to check both the address and the beneficiary name.
  • Name matching in UI after txConfirm - you cannot have have rules active as they would run immediately once the status hits ACK.

Example

Using fuzzy logic to compare:

           "beneficiaryPersons": [
        {
          "naturalPerson": {
            "name": [
              {
                "nameIdentifier": [
                  {
                    "primaryIdentifier": "Emory",
                    "secondaryIdentifier": "Heller"
                  }


Notabene VASP SG Customer Database v1.234
Customer ID: 123456789
Wallet addr: 3uyZiAC2khxuxC26weZcrcEWubE8vEjY3
Name: Emory Heller
DoB: 01/01/1999
...


Because the name you receive can be written in different ways, using fuzzy matching might be the best way to compare the information:

from fuzzywuzzy import fuzz

customerName = "Emory Way Heller"
primaryIdentifier = "Emory"
secondaryIdentifier = "Heller"
mergedIdentifier = primaryIdentifier+secondaryIdentifier
Ratio = fuzz.ratio(customerName.lower().replace(" ", ""),mergedIdentifier.lower().replace(" ", ""))
print(Ratio)

Ratio:88
  
#You can also use fuzz.token_sort_ratio to cater for mixed-up first and last name:
#In token sort ratio, the strings are tokenized and pre-processed by converting to lower case and getting rid of punctuation. The strings are then sorted alphabetically and joined together. Post this, the Levenshtein distance similarity ratio is calculated between the strings.

If the address is yours and the beneficiary matches your customer, you should call txConfirm to change the status from SENT to ACK and receive the originator information in the travel rule message for sanctions screening.

Ratio = 88
fuzzyMinimum = 87
my_wallets = ["39oSD4x8a9EBb1Ft7weNFbqhZZuz", "3uyZiAC2khxuxC26weZcrcWubE8vEjY3"]
destination = "3uyZiAC2khxuxC26weZcrcWubE8vEjY3"

if (destination in my_wallets):
    if Ratio > fuzzyMinimum:
        txConfirm = requests.request("POST", url1, headers=headers1, data=payload1)
        print("txConfirm")
        
    else:
      	txDecline = requests.request("POST", url2, headers=headers2, data=payload2)
        print("txDecline")
else:
  	txReject = requests.request("POST", url3, headers=headers3, data=payload3)
    print("txReject")