NAV Navbar
  • Sending Internal CoP Name Verification Requests
  • Sending Internal CoP Name Verification Requests

    This tutorial explains how to create an internal Confirmation of Payee (CoP) name verification request to check a payee name against your own accounts using the Form3 API.

    We provide an overview of the name matching functionality of the Confirmation of Payee service and offer a step-by-step guide on how to send a CoP request to bank accounts stored in our system and advise on the possible responses. Examples are provided to personal, business and joint accounts. Each step can be simulated using Form3's Staging environment.

    Confirmation of Payee Overview

    Confirmation of Payee (CoP) is a way of giving end users of payment systems in the UK greater assurance that they are sending their payments to the intended recipient. It is, in essence, an account name checking service that can help avoid payments being misdirected due to errors.

    It can also address certain types of Authorised Push Payment (APP) fraud by introducing another hurdle for fraudsters and by providing effective warnings to customers about the risks of sending to an account where the name did not match the one they provided.

    The CoP service allows Account Servicing Payment Service Providers (ASPSPs) to send and receive messages for name-checking, leveraging the Open Banking security framework. Each ASPSP is required to have a CoP endpoint to which requests can be made.

    CoP in the Form3 API

    Part of Form3's CoP service is a name verification API endpoint that allows you to check a given name against your own accounts. The API endpoint accepts requests and provides answers confirming to the CoP interface standard defined by Open Banking.

    You can use our API when building a self-service CoP endpoint. Simply forward all inbound CoP requests that arrive at your CoP endpoint to our API and funnel the replies back to the requester. The name verification endpoint is also useful for testing purposes.

    Account Information

    To receive transactions for a specific bank account and to provide CoP name-checking against it, you need to register the account with Form3 via our Account API. You do this by creating an Account resource for each bank account.

    When performing CoP name verification, Form3 compare the information in the name-checking request with those provided in the Account resources. The following fields in the Account resource are relevant for Confirmation of Payee:

    Field Description Requirements Occurrence
    name Name of the account holder Array of up to four strings, maximum 140 characters each
    For concatenated personal names, joint account names and organisation names, use only the first array line
    If first and last names of a personal name are separated, use the first array line for first names, the second array line for last names. Titles are ignored and should not be entered
    Mandatory if you are configured for CoP
    alternative_names Aliases of the account holder Array of up to three strings, maximum 40 characters each Optional
    account_classification Marker indicating whether this is a personal or business account Allowed values: personal (default if not provided) or business Optional
    joint_account Marker indicating whether this is an individual or joint account Allowed values: true or false (default if not provided) Optional
    account_matching_opt_out Marker indicating whether this account has opted out of the CoP service Allowed values: true or false (default if not provided) Optional

    See our tutorial to learn more about the Account API and how to register a bank account.

    Name Verification Endpoint

    The name verification endpoint accepts requests provided in the Confirmation of Payee interface format defined by Open Banking and provides responses according to the same standard.

    A name verification request to the Form3 API contains the following fields:

    Attribute Occurance Description
    AccountType Required Personal or Business
    Identification Required Sort code and account number used to look up the account
    Name Required The name of the payee as provided by the payer
    SchemeName Required SortCodeAccountNumber
    SecondaryIdentification Optional The payment reference information as provided by the payer

    Upon receipt of the request, Form3 checks the string provided in Name against the account holder name and alternative bank account names stored for the account specified in Identification. The response contains the following fields:

    Attribute Occurance Description
    Matched Always present true when there is a match or false when there is no match or a close match
    ReasonCode Present if there is not a full match Defined by Pay.UK, see our API documentation for a full list
    Name Present if the matching results in a close match The account name held by us in the Account API in name

    The Matched field indicates if the given name was a match. The ReasonCode field provides a more detailed description of the kind of match. In case the request resulted in a close match, the Name attribute provides the account holder name for comparison.

    Step by Step Guide

    The following sections provide a step by step guide to making requests that create match, close match, and no match responses for testing purposes. The sections cover three types of accounts: personal, joint, and business accounts.

    Prerequisites

    Before getting started, make sure you have the following things ready to follow along:

    Personal Accounts

    A personal account is held by a single private person. The name of the account holder is defined in the name field. Additional name variants are stored in the alternative_names field.

    Create a Personal Account

    First, we register a bank account that the name verification request can be checked against.

    This request creates an Account resource: POST /v1/organisation/accounts

    In the body of the request, provide the following account information:

    {
        "data": {
            "type": "accounts",
            "id": "A_VALID_UUID",
            "version": 0,
            "organisation_id": "YOUR_ORGANISATION_ID",
            "attributes": {
                "country": "GB",
                "base_currency": "GBP",
                "bank_id": "040013",
                "bank_id_code": "GBDSC",
                "account_number": "10000005",
                "customer_id": "234",
                "iban": "GB45XXXX04001310000005",
                "bic": "XXXXGB01",
                "name": [
                    "Joe",
                    "Bloggs"
                ],
                "alternative_names": [
                    "JB"
                ],
                "account_classification": "Personal",
                "joint_account": false,
                "account_matching_opt_out": false,
                "switched": false
            }
        }
    }
    


    The name and field specifies the name of the account holder as "Joe Bloggs". The alternative_names field states that "JB" is also considered a valid account holder name.

    The account_classification field indicates that this is a personal account. account_matching_opt_out is set to false, meaning this account did not opt out of Confirmation of Payee.

    Trigger a Full Match for a Personal Account

    Now it's time to make a name verification request. You can do this with the following request: POST /v1/openbanking/accounts/name-verification

    To trigger a response that reports a full match, use the sort code and account number of the account we registered above in the Identification field. In the Name field, use the complete bank account holder name:

    {
        "Data": {
            "AccountType": "Personal",
            "Identification": "04001310000005",
            "Name": "Joe Bloggs",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    The response confirms that the request results in a match:

    {
        "Data": {
            "VerificationReport": {
                "Matched": true
            }
        }
    }
    

    Trigger a Close Match for a Personal Account

    To trigger a close match, we use a similar but slightly different spelling of the account holder name: Jo Boggs instead of Joe Bloggs. The Identification field and the request URL remain the same as in the full match example above:

    {
        "Data": {
            "AccountType": "Personal",
            "Identification": "04001310000005",
            "Name": "Jo Boggs",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    The response will now report a close match. The Matched field is false, but the reason code MBAM means that "the given string is a close match to the account name" (See the API documentation for a complete list of reason codes). The Name field contains the correct name that would have led to a full match:

    {
        "Data": {
            "VerificationReport": {
                "Matched": false,
                "Name": "Joe Bloggs",
                "ReasonCode": "MBAM"
            }
        }
    }
    

    Trigger a No Match for a Personal Account

    For a no match response, simply use a completely different account name in the name verification request. In this example, we're trying to verify Jane Doe against Joe Bloggs's account:

    {
        "Data": {
            "AccountType": "Personal",
            "Identification": "04001310000005",
            "Name": "Jane Doe",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    As to be expected, the endpoint responds with a no match. The Matched field is false and the reason code ANMM means "the given string does not match the account name". Note that in this case the response does not contain the correct account name:

    {
        "Data": {
            "VerificationReport": {
                "Matched": false,
                "ReasonCode": "ANNM"
            }
        }
    }
    

    Joint Accounts

    A joint account is a personal account that is held by multiple individuals. The names of the account holder are stored in the name field.

    Create a Joint Account

    Create the Account resource with the same API request as the personal account above: POST /v1/organisation/accounts

    In the body of the request, provide the following account information:

    {
        "data": {
            "type": "accounts",
            "id": "A_VALID_UUID",
            "version": 0,
            "organisation_id": "YOUR_ORGANISATION_ID",
            "attributes": {
                "country": "GB",
                "base_currency": "GBP",
                "bank_id": "040013",
                "bank_id_code": "GBDSC",
                "account_number": "10000006",
                "customer_id": "234",
                "iban": "GB45XXXX04001310000006",
                "bic": "XXXXGB01",
                "name": [
                  "Joe Bloggs & Jane Doe"
                ],
                "alternative_names": [
                    "JB"
                ],
                "account_classification": "Personal",
                "joint_account": true,
                "account_matching_opt_out": false,
                "switched": false
            }
        }
    }
    


    The name contains two both full account holder names. You can use either & or and to separate joint account holder names. The account_classification is set to Personal and the joint_account field is true, indicating that this is a joint account.

    Trigger a Full Match for a Joint Account

    To trigger a response that reports a full match, use the sort code and account number of the account we registered above in the Identification field. In the Name field, use the complete bank account holder name, note that the order of the names have been reversed as this has no impact on matching:

    {
        "Data": {
            "AccountType": "Personal",
            "Identification": "04001310000006",
            "Name": "Jane Doe & Joe Bloggs",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    A full match response can also be returned by using only one of the two account holder names:

    {
        "Data": {
            "AccountType": "Personal",
            "Identification": "04001310000006",
            "Name": "Jane Doe",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    The response for both requests above confirms the a full match:

    {
        "Data": {
            "VerificationReport": {
                "Matched": true
            }
        }
    }
    

    Trigger a Close Match for a Joint Account using One Account Holder

    To trigger a close match, we use a similar but slightly different spelling of one of the two account holder name: Jo Boggs instead of Joe Bloggs.

    {
        "Data": {
            "AccountType": "Personal",
            "Identification": "04001310000006",
            "Name": "Jo Boggs",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    The response will now report a close match. The Name field contains the correct name that would have led to a full match. Only the name of the individual whose name was entered in the request is returned, not the other joint account holder:

    {
        "Data": {
            "VerificationReport": {
                "Matched": false,
                "Name": "Joe Bloggs",
                "ReasonCode": "MBAM"
            }
        }
    }
    

    Trigger a No Match for a Joint Account

    For a no match response, use a completely different account name than any of the two joint account holders. In this example, we're trying to verify Orson Wells as the account holder:

    {
        "Data": {
            "AccountType": "Personal",
            "Identification": "04001310000006",
            "Name": "Orson Wells",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    The response confirms a no match with the reason code ANMM ("the given string does not match the account name"):

    {
        "Data": {
            "VerificationReport": {
                "Matched": false,
                "ReasonCode": "ANNM"
            }
        }
    }
    

    Business Accounts

    A business account is an account owned by a business instead of an individual. The name of the business is stored in the name field. Alternative names, such as abbreviations, can be stored in the alternative_names field.

    Create a Business Account

    This request creates an Account resource: POST /v1/organisation/accounts

    In the body of the request, provide the following account information:

    {
        "data": {
            "type": "accounts",
            "id": "A_VALID_UUID",
            "version": 0,
            "organisation_id": "YOUR_ORGANISATION_ID",
            "attributes": {
                "country": "GB",
                "base_currency": "GBP",
                "bank_id": "040013",
                "bank_id_code": "GBDSC",
                "account_number": "10000007",
                "customer_id": "234",
                "iban": "GB45XXXX04001310000007",
                "bic": "XXXXGB01",
                "name": [
                  "Bloggs Commercial Building Supplies Limited"
                ],
                "alternative_names": [
                    "BCBS"
                ],
                "account_classification": "Business",
                "joint_account": false,
                "account_matching_opt_out": false,
                "switched": false
            }
        }
    }
    


    Note that the acronym BCBS has been added as an alias for Bloggs Commercial Building Supplies Limited in alternative_names. The account_classification field identifies the account as a business account.

    Trigger a Full Match for a Business Account using Acronyms

    To trigger a response that reports a full match, use the sort code and account number of the account we registered above in the Identification field. The AccountType must also match the account classification, Business. In the Name field, use the complete bank account holder name or one of the alternative bank account names, in this case, the acronym:

    {
        "Data": {
            "AccountType": "Business",
            "Identification": "04001310000007",
            "Name": "BCBS",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    The response confirms that the request results in a match:

    {
        "Data": {
            "VerificationReport": {
                "Matched": true
            }
        }
    }
    

    Trigger a Close Match for a Business Account

    To trigger a close match, use a similar but slightly different variation of the company name: Bloggs Commercial Supply instead of Bloggs Commercial Building Supplies Limited:

    {
          "Data": {
            "AccountType": "Business",
            "Identification": "04001310000007",
            "Name": "Bloggs Commercial Supply",
            "SchemeName": "SortCodeAccountNumber"
          }
    }
    


    The response will now report a close match. The Name field contains the correct name that would have led to a full match:

    {
        "Data": {
            "VerificationReport": {
                "Matched": false,
                "Name": "Bloggs Commercial Building Supplies Limited",
                "ReasonCode": "MBAM"
            }
        }
    }
    

    Trigger a No Match for a Business Account

    For a no match response, use a completely different account name than the registered business name. This example attempts to verify Form3 as the account holder:

    {
        "Data": {
            "AccountType": "Business",
            "Identification": "04001310000007",
            "Name": "Form3",
            "SchemeName": "SortCodeAccountNumber"
        }
    }
    


    The response confirms a no match with the reason code ANMM ("the given string does not match the account name"):

    {
        "Data": {
            "VerificationReport": {
                "Matched": false,
                "ReasonCode": "ANNM"
            }
        }
    }
    

    Further Reading

    This tutorial provides an introduction on how to use the name verification endpoint of Form3's Confirmation of Payee service. For more information, see the following resources: