--- title: "Name validation" description: "Validate the cardholder name when making a payment." url: "https://docs.adyen.com/payment-methods/cards/name-validation" source_url: "https://docs.adyen.com/payment-methods/cards/name-validation.md" canonical: "https://docs.adyen.com/payment-methods/cards/name-validation" last_modified: "2022-08-09T11:45:00+02:00" language: "en" --- # Name validation Validate the cardholder name when making a payment. [View source](/payment-methods/cards/name-validation.md) Name validation allows you to verify if the cardholder name provided by a shopper matches the cardholder name on file at the issuing bank. The service is offered by Visa and Mastercard, and requires you to pay a fee for each transaction where name validation is performed. You can request this validation with a [zero-value auth](/get-started-with-adyen/adyen-glossary/#zero-value-auth) transaction to: * Reduce fraud and chargeback losses. * Comply with Know Your Customer (KYC) requirements. * Improve the reliability of [payouts](/payouts/payout-service/) by making sure funds are sent to the right person. ## Requirements Before you begin, take into account the following requirements, limitations, and preparations. | Requirement | Description | | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Integration type** | An [online payments integration using the Advanced flow](/online-payments/build-your-integration/advanced-flow) with Checkout API v69 or later. | | **[API credential roles](/development-resources/api-credentials/roles/)** | You need an API credential with an API key and the **Checkout webservice role**. | | **Limitations** | This feature is dependent on issuer readiness, and is only supported for:- Zero-value auth transactions. - Visa and Mastercard payments in the United States, United Kingdom, and Europe. | ## How it works ##### Learn more Our name validation feature uses the validation services offered by card schemes. * [Mastercard Account Validation](https://developer.mastercard.com/account-validation/documentation/) * [Visa Account Name Inquiry](https://corporate.visa.com/content/dam/VCOM/regional/na/us/support-legal/documents/account-name-inquiry-onesheet-merchant-version.pdf) To validate a cardholder's name: 1. You make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request for a zero-value auth transaction. In the request, you include the cardholder's name and the `paymentValidations` object to [request a name validation](#request-a-name-validation). 2. Adyen forwards the validation request to Visa or Mastercard. 3. The cardholder's issuing bank checks if the name the shopper provided matches the name they have on file. 4. [Adyen receives the result and forwards it to you](#validation-results) in the `paymentValidations` object within the synchronous API response. 5. You monitor the `result` object to get the outcome of the name validation. 6. You build your own logic based on the validation outcome. For example, depending on the match results, you can proceed to authorize the payment or request additional verification. We are working on expanding the `paymentValidations` field with support for additional validation types, such as the [Address Verification System](/risk-management/avs-checks). We recommend you prepare your implementation to handle new verification objects that will be introduced in `paymentValidations`. ![](/user/pages/docs/08.payment-methods/04.cards/name-validation/Name-validation.svg?decoding=auto\&fetchpriority=auto) ## Request a name validation To request a name validation, [use your online payments integration](/online-payments/build-your-integration/advanced-flow/?platform=Web\&integration=API%20only\&version=latest#make-a-payment) to make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request, and include: | Field | Description | | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `amount.value` | The transaction amount. Set to **0** when performing a name validation. | | `paymentMethod` | The payment details. For cards, set `type` to **scheme**, and send the encrpyted card fields. If you are fully [PCI compliant](/development-resources/pci-dss-compliance-guide), send the unencrypted card fields. | | [shopperName](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-shopperName) | The name of the cardholder, consisting of `firstName` and `lastName`. If you do not include this field when requesting a name validation, we will [fallback](#fallback-logic) to the `paymentMethod.holderName`. | | `paymentValidations.name.status` | Set to **requested** to request a name validation. | [Apple Pay](/payment-methods/apple-pay) and [Google Pay](/payment-methods/google-pay) do not return the shopper name. For these payment methods, you must build your own logic to pass the details your [shopper enters at checkout](/online-payments/build-your-integration/advanced-flow?platform=Web\&integration=API%20only\&version=71#collect-shopper-details) from your front-end to the [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request. The following example shows how to request a name validation for John Smith. **Request name validation** #### curl ```bash curl https://checkout-test.adyen.com/v72/payments \ -H 'x-api-key: ADYEN_API_KEY' \ -H 'content-type: application/json' \ -d '{ "amount": { "currency": "EUR", "value": 0 }, "reference": "YOUR_ORDER_NUMBER", "shopperName": { "firstName": "John", "lastName": "Smith" }, "paymentMethod": { "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737", "holderName": "John Smith" }, "paymentValidations": { "name": { "status": "requested" } }, "merchantAccount": "YOUR_MERCHANT_ACCOUNT" }' ``` #### Java ```java // Adyen Java API Library v40.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.checkout.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.model.RequestOptions; import com.adyen.service.checkout.*; // For the LIVE environment, also include your liveEndpointUrlPrefix. Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Create the request object(s) Amount amount = new Amount() .currency("EUR") .value(0L); Name name = new Name() .firstName("John") .lastName("Smith"); CardDetails cardDetails = new CardDetails() .encryptedCardNumber("test_4111111111111111") .holderName("John Smith") .encryptedSecurityCode("test_737") .encryptedExpiryYear("test_2030") .encryptedExpiryMonth("test_03") .type(CardDetails.TypeEnum.SCHEME); PaymentRequest paymentRequest = new PaymentRequest() .reference("YOUR_ORDER_NUMBER") .amount(amount) .shopperName(name) .merchantAccount("YOUR_MERCHANT_ACCOUNT") .paymentMethod(new CheckoutPaymentMethod(cardDetails)); // Send the request PaymentsApi service = new PaymentsApi(client); PaymentResponse response = service.payments(paymentRequest, new RequestOptions().idempotencyKey("UUID")); ``` #### PHP ```php setXApiKey("ADYEN_API_KEY"); // For the LIVE environment, also include your liveEndpointUrlPrefix. $client->setEnvironment(Environment::TEST); // Create the request object(s) $amount = new Amount(); $amount ->setCurrency("EUR") ->setValue(0); $name = new Name(); $name ->setFirstName("John") ->setLastName("Smith"); $checkoutPaymentMethod = new CheckoutPaymentMethod(); $checkoutPaymentMethod ->setEncryptedCardNumber("test_4111111111111111") ->setHolderName("John Smith") ->setEncryptedSecurityCode("test_737") ->setEncryptedExpiryYear("test_2030") ->setEncryptedExpiryMonth("test_03") ->setType("scheme"); $paymentRequest = new PaymentRequest(); $paymentRequest ->setReference("YOUR_ORDER_NUMBER") ->setAmount($amount) ->setShopperName($name) ->setMerchantAccount("YOUR_MERCHANT_ACCOUNT") ->setPaymentMethod($checkoutPaymentMethod); $requestOptions['idempotencyKey'] = 'UUID'; // Send the request $service = new PaymentsApi($client); $response = $service->payments($paymentRequest, $requestOptions); ``` #### C\# ```cs // Adyen .NET API Library v32.2.1 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Checkout; using Adyen.Service.Checkout; // For the LIVE environment, also include your liveEndpointUrlPrefix. var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Create the request object(s) Amount amount = new Amount { Currency = "EUR", Value = 0 }; Name name = new Name { FirstName = "John", LastName = "Smith" }; CardDetails cardDetails = new CardDetails { EncryptedCardNumber = "test_4111111111111111", HolderName = "John Smith", EncryptedSecurityCode = "test_737", EncryptedExpiryYear = "test_2030", EncryptedExpiryMonth = "test_03", Type = CardDetails.TypeEnum.Scheme }; PaymentRequest paymentRequest = new PaymentRequest { Reference = "YOUR_ORDER_NUMBER", Amount = amount, ShopperName = name, MerchantAccount = "YOUR_MERCHANT_ACCOUNT", PaymentMethod = new CheckoutPaymentMethod(cardDetails) }; // Send the request var service = new PaymentsService(client); var response = service.Payments(paymentRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"}); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v30.0.0 const { Client, CheckoutAPI } = require('@adyen/api-library'); // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const paymentRequest = { amount: { currency: "EUR", value: 0 }, reference: "YOUR_ORDER_NUMBER", shopperName: { firstName: "John", lastName: "Smith" }, paymentMethod: { type: "scheme", encryptedCardNumber: "test_4111111111111111", encryptedExpiryMonth: "test_03", encryptedExpiryYear: "test_2030", encryptedSecurityCode: "test_737", holderName: "John Smith" }, paymentValidations: { name: { status: "requested" } }, merchantAccount: "YOUR_MERCHANT_ACCOUNT" } // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` #### Go ```go // Adyen Go API Library v21.1.0 import ( "context" "github.com/adyen/adyen-go-api-library/v21/src/common" "github.com/adyen/adyen-go-api-library/v21/src/adyen" "github.com/adyen/adyen-go-api-library/v21/src/checkout" ) // For the LIVE environment, also include your liveEndpointUrlPrefix. client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Create the request object(s) amount := checkout.Amount{ Currency: "EUR", Value: 0, } name := checkout.Name{ FirstName: "John", LastName: "Smith", } cardDetails := checkout.CardDetails{ EncryptedCardNumber: common.PtrString("test_4111111111111111"), HolderName: common.PtrString("John Smith"), EncryptedSecurityCode: common.PtrString("test_737"), EncryptedExpiryYear: common.PtrString("test_2030"), EncryptedExpiryMonth: common.PtrString("test_03"), Type: common.PtrString("scheme"), } paymentRequest := checkout.PaymentRequest{ Reference: "YOUR_ORDER_NUMBER", Amount: amount, ShopperName: &name, MerchantAccount: "YOUR_MERCHANT_ACCOUNT", PaymentMethod: checkout.CardDetailsAsCheckoutPaymentMethod(&cardDetails), } // Send the request service := client.Checkout() req := service.PaymentsApi.PaymentsInput().IdempotencyKey("UUID").PaymentRequest(paymentRequest) res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v13.6.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.client.platform = "test" # The environment to use library in. # Create the request object(s) json_request = { "amount": { "currency": "EUR", "value": 0 }, "reference": "YOUR_ORDER_NUMBER", "shopperName": { "firstName": "John", "lastName": "Smith" }, "paymentMethod": { "type": "scheme", "encryptedCardNumber": "test_4111111111111111", "encryptedExpiryMonth": "test_03", "encryptedExpiryYear": "test_2030", "encryptedSecurityCode": "test_737", "holderName": "John Smith" }, "paymentValidations": { "name": { "status": "requested" } }, "merchantAccount": "YOUR_MERCHANT_ACCOUNT" } # Send the request result = adyen.checkout.payments_api.payments(request=json_request, idempotency_key="UUID") ``` #### Ruby ```rb # Adyen Ruby API Library v11.0.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' # For the LIVE environment, also include your liveEndpointUrlPrefix. adyen.env = :test # Set to "live" for live environment # Create the request object(s) request_body = { :amount => { :currency => 'EUR', :value => 0 }, :reference => 'YOUR_ORDER_NUMBER', :shopperName => { :firstName => 'John', :lastName => 'Smith' }, :paymentMethod => { :type => 'scheme', :encryptedCardNumber => 'test_4111111111111111', :encryptedExpiryMonth => 'test_03', :encryptedExpiryYear => 'test_2030', :encryptedSecurityCode => 'test_737', :holderName => 'John Smith' }, :paymentValidations => { :name => { :status => 'requested' } }, :merchantAccount => 'YOUR_MERCHANT_ACCOUNT' } # Send the request result = adyen.checkout.payments_api.payments(request_body, headers: { 'Idempotency-Key' => 'UUID' }) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v30.0.0 import { Client, CheckoutAPI, Types } from "@adyen/api-library"; // For the LIVE environment, also include your liveEndpointUrlPrefix. const config = new Config({ apiKey: "ADYEN_API_KEY", environment: EnvironmentEnum.TEST }); const client = new Client(config); // Create the request object(s) const amount: Types.checkout.Amount = { currency: "EUR", value: 0 }; const name: Types.checkout.Name = { firstName: "John", lastName: "Smith" }; const cardDetails: Types.checkout.CardDetails = { encryptedCardNumber: "test_4111111111111111", holderName: "John Smith", encryptedSecurityCode: "test_737", encryptedExpiryYear: "test_2030", encryptedExpiryMonth: "test_03", type: Types.checkout.CardDetails.TypeEnum.Scheme }; const paymentRequest: Types.checkout.PaymentRequest = { reference: "YOUR_ORDER_NUMBER", amount: amount, shopperName: name, merchantAccount: "YOUR_MERCHANT_ACCOUNT", paymentMethod: cardDetails }; // Send the request const checkoutAPI = new CheckoutAPI(client); const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" }); ``` ### Fallback logic If you do not include the [shopperName](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments#request-shopperName) when requesting a name validation, we use the `paymentMethod.holderName` field to populate the shopper name fields. We take the characters until the first space or period(`.`) to populate the first name. To ensure accuracy and get the best validation results, we strongly recommend to include the `shopperName` field instead of relying on the `paymentMethod.holderName` fallback. ## Validation results When you make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request to validate a cardholder's name, Adyen forwards the information you provide to the schemes to perform the name validation. The API response includes: * [The status of the name validation](#status). * [The outcome of the name validation](#outcome). ### Status The `paymentValidations.name.status` field in the response informs you if name validation was performed. For Visa, you also receive the raw status value that Adyen receives in the `paymentValidations.name.rawResponse.status` field. Mastercard does not return a `rawResponse.status`. | Adyen `status` values | Description | Visa `rawResponse.status` values | | --------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------- | | **performed** | Name validation was performed. | **00** | | **notPerformed** | Name validation was not performed. | **01** | | **notSupported** | Name validation is not supported by the issuer for this card, you will not be charged for name validation. | **02** | ### Outcome The `paymentValidations.name` object in the response includes the following objects that inform you of the name validation results. * `result`: the scheme-agnostic match values returned by Adyen. * `rawResponse`: the raw response(s) we receive from the scheme.\ For example, the `result.fullName` contains the Adyen value, and `rawResponse.fullName` contains the value we received from Visa or Mastercard. For Visa, the response includes match values for the full name, along with first name, middle name, and last name. For Mastercard, the response only includes the full name match value. The match value for the full name is determined by combining the match results for the first, middle, and last name. The logic to determine the outcome of this combination is built and maintained by schemes, and is not transparent to Adyen. | Adyen `result` values | Visa `rawResponse` values | Mastercard `rawResponse` values | Description | | --------------------- | ------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | **match** | **01** | **A** | The name matches the name on file at the issuing bank. | | **partialMatch** | **50** | **B** | The name partially matches the name on file. For example, the first name matches but the last name does not, or there is a typo. | | **noMatch** | **99** | **C** | The name does not match the name on file. | The following response examples show the name validation responses for Visa and Mastercard. ### Tab: Visa **Example name validation result Visa** ```json { "pspReference": "KHQC5N7G84BLNK43", "resultCode": "Authorised", "amount": { "currency": "EUR", "value": 0 }, "paymentValidations": { "name": { "status": "performed", "result": { "fullName": "partialMatch", "firstName": "match", "middleName": "match", "lastName": "partialMatch" }, "rawResponse": { "status": "00", "fullName": "50", "firstName": "01", "middleName": "01", "lastName": "50" } } } } ``` ### Tab: Mastercard **Example name validation result Mastercard** ```json { "pspReference": "FKSPNCQ8HXSKGK82", "resultCode": "Authorised", "amount": { "currency": "EUR", "value": 0 }, "paymentValidations": { "name": { "status": "performed", "result": { "fullName": "match" }, "rawResponse": { "fullName": "A" } } } } ``` ## Testing To test different name validation responses and match results: 1. In your test [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request, request a name validation. 2. Use our [Visa](/development-resources/test-cards-and-credentials/test-card-numbers#visa) and [Mastercard](/development-resources/test-cards-and-credentials/test-card-numbers#mastercard) test cards. 3. Set the `shopperName` field to the following test shopper names to test different match statuses. If you do not provide the name in this field, we fall back to the holder name you provide in the `paymentMethod` object. | Match status | First name | Middle name | Last name | | ----------------- | ---------- | ----------- | --------- | | **Match** | John | Maria | Smith | | **Partial match** | Jon | Mariah | Smyth | | **No match** | Alice | Peter | Brown | Keep in mind that the logic to determine the full name match is based on the combination of the first, middle, and last name values are maintained by the schemes and not transparent to Adyen. The following section shows some example test scenarios and the results they are expected to trigger per scheme. 4. Test that your implementation correctly handles the match statuses you receive in the name validation outcome. The following table contains example scenarios and the results they are expected to trigger per scheme. ### Tab: Visa Visa returns individual match statuses for the first name, middle name, last name, and the full name. | Shopper name | Logic applied | Visa `rawResponse` | Adyen `result` | | --------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------- | ---------------------------- | | **John Maria Smith** | All names are a match. | `firstName`: **01**, `middleName`: **01**, `lastName`: **01**, `fullName`: **01** | `fullName`: **match** | | **Jon Peter Smyth** | Two partial matches, and one no match. | `firstName`: **50**, `middleName`: **99**, `lastName`: **50**, `fullName`: **50** | `fullName`: **partialMatch** | | **Alice Peter Brown** | None of the names match. | `firstName`: **99**, `middleName`: **99**, `lastName`: **99**, `fullName`: **99** | `fullName`: **noMatch** | | **John Peter Smith** | Mix of match and no matches. | `firstName`: **01**, `middleName`: **99**, `lastName`: **01**, `fullName`: **01** | `fullName`: **partialMatch** | | **John Mariah Brown** | One match, one partial match, and one no match. | `firstName`: **01**, `middleName`: **50**, `lastName`: **99**, `fullName`: **50** | `fullName`: **partialMatch** | | **Jon Smyth** | Two partial matches. | `firstName`: **50**, `lastName`: **50** | `fullName`: **partialMatch** | ### Tab: Mastercard Mastercard returns a single result that corresponds to the match status of the full name. | Shopper name | Logic applied | Mastercard `rawResponse` | Adyen `result` | | ---------------------- | ----------------------------------------------- | ------------------------ | ---------------------------- | | **John Maria Smith** | All names are a match. | `fullName`: **A** | `fullName`: **match** | | **Jon Peter Smyth** | Two partial matches, and one no match. | `fullName`: **B** | `fullName`: **partialMatch** | | **Alice Peter Brown** | None of the names match. | `fullName`: **C** | `fullName`: **noMatch** | | **John Peter Brown** | Mix of match and no matches. | `fullName`: **B** | `fullName`: **partialMatch** | | **Alice Mariah Smyth** | One match, one partial match, and one no match. | `fullName`: **B** | `fullName`: **partialMatch** | ### Test the unhappy flow To trigger the scenario where name validation is not supported, or not performed: 1. In your test [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request, request a name validation. 2. Use our [Visa](/development-resources/test-cards-and-credentials/test-card-numbers#visa) and [Mastercard](/development-resources/test-cards-and-credentials/test-card-numbers#mastercard) test cards. 3. To test the scenario where the name validation is not performed, use any combination of the test shopper name values and set the `reference` to **NotPerformed**. 4. To test the scenario where name validation is not supported, use any combination of the test shopper name values and set the `reference` to **NotSupported**.\ Alternatively, you can also use a shopper name that's not part of the test shopper names. 5. Test that your integration can correctly handle scenarios where name validation is not successful. For example, if you set the `reference` to **NotSupported**, with any combination of the test shopper names, the response will contain: * `paymentValidations.name.status`: **notSupported** * Only for Visa, `paymentValidations.name.rawResponse.status`: **02** ## See also * [Cards](/payment-methods/cards) * [Risk management](/risk-management)