Skip to content

Last updated: 30 October 2025 | Change log

Card validation


Validate your customer's card details before processing them.

Warning

The validation does not check if your customer's card details are correct. The validation only checks the format of the entered details.

Get started

Before you begin, ensure:

  • You have added the AccessCheckoutSDK to your project as a Cocoapods dependency
  • You have added an import AccessCheckoutSDK at the top of your swift file

The key components for this integration are:

  • A reference to your AccessCheckoutUITextField's for PAN, expiry date and CVC
  • An AccessCheckoutCardValidationDelegate designed to receive validation events
  • An instance of CardValidationConfig containing all the information required for the initialization of the validation flow, including references to the UI components to enable validation for
  • An AccessCheckoutClient responsible for initializing the validation flow
Full sample integration

You can see an example of the card validation integration here.

Reference your UI components

You must reference your UI components for PAN, expiry date, and CVC, as these are required for card validation. Instructions can be found here.

Implement the validation listener

To receive validation events and card brand updates as your customer enters their card details, you are required to create your own implementation of the AccessCheckoutCardValidationDelegate protocol. Each function of this protocol is optional, giving you the flexibility to listen only to the events that are relevant to your application.

extension ViewController: AccessCheckoutCardValidationDelegate {

    // This event handler is notified when the card brand detected by the SDK has changed
    func cardBrandsChanged(cardBrands: [CardBrand]) {
        // The cardBrands list may contain one brand, or multiple brands for a co-branded card
        // CardBrand objects contains a name and optionally an array of of image objects
        // with a URL and a type (either image/png or image/svg+xml)

        // You might want to display the brand name of the first card brand returned
        // or in the case of a co-branded card, you may want to prompt shoppers with a choice
        // of brands to pay with

        // Don't forget to use the UI thread to update your views
    }

    // This event handler is notified when the PAN becomes valid or invalid
    func panValidChanged(isValid: Bool) {
        // You might want to change the text color
        panAccessCheckoutView.textColor = isValid ? nil : UIColor.red

        if !valid {
            // You might want to disable a submit button which would normally be clicked on when all fields are valid
            submitButton.isEnabled = false
        }
    }

    // This event handler is notified when the expiry date becomes valid or invalid
    func expiryDateValidChanged(isValid: Bool) {
        // You might want to change the text color
        expiryDateAccessCheckoutView.textColor = isValid ? nil : UIColor.red

        if !valid {
            // You might want to disable a submit button which would normally be clicked on when all fields are valid
            submitButton.isEnabled = false
        }
    }

    // This event handler is notified when the CVC becomes valid or invalid
    func cvcValidChanged(isValid: Bool) {
        // You might want to change the text color
        cvcAccessCheckoutView.textColor = isValid ? nil : UIColor.red

        if !valid {
            // You might want to disable a submit button which would normally be clicked on when all fields are valid
            submitButton.isEnabled = false
        }
    }

    // This event handler is notified when the PAN, expiry date and CVC are all valid
    func validationSuccess() {
        // You might want to enable a submit button when all fields are valid
        submitButton.isEnabled = true
    }
}

Function and parameter descriptions

MethodDescription
cardBrandsChangedThis method is called with card brand(s) detected from the card number your customer is entering. The array contains the identified card brand(s), starting with the global brand, followed by the domestic brand if a co-branded card is in use.

If the card brand(s) can't be identified, the method is called with an empty array.

Use this method to:
• display the appropriate card brand logo using the hosted images - PNG/SVG formats available (only global brand contains image resources)
• detect co-branded cards and prompt customers to select their preferred brand for the payment (see our co-branded cards documentation)
• comply with the European Union (EU) Interchange Fee Regulation (IFR) 2015/751
panValidChangedThis method is called with the validity of the pan field. isValid indicates whether the field is in a valid or invalid state.
expiryDateValidChangedThis method is called with the validity of the expiry date field. isValid indicates whether the field is in a valid or invalid state.
cvcValidChangedThis method is called with the validity of the CVC field. isValid indicates whether the field is in a valid or invalid state.
validationSuccessThis method is called when all fields are in a valid state. You typically use this to enable the submit button.

Initialize the AccessCheckoutClient and validation

Recommendation

We highly recommend to do this in the viewDidLoad() handler of your UIViewController.

You must first initialize the AccessCheckoutClient using the AccessCheckoutClientBuilder, providing your accessBaseUrl and checkoutId. Instructions can be found here.

After implementing the AccessCheckoutCardValidationDelegate, initialize validation for your views by creating a CardValidationConfig using the builder and passing it to the initialiseValidation method of AccessCheckoutClient.

import AccessCheckoutSDK

class MyViewController: UIViewController {
    private let accessBaseUrl = "TARGET_BASE_URL"
    private let checkoutId = "YOUR_CHECKOUT_ID"

    @IBOutlet weak var panAccessCheckoutView: AccessCheckoutUITextField!
    @IBOutlet weak var expiryDateAccessCheckoutView: AccessCheckoutUITextField!
    @IBOutlet weak var cvcAccessCheckoutView: AccessCheckoutUITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // other fields omitted

        do {
            // Initialize the AccessCheckoutClient
            let accessCheckoutClient = try AccessCheckoutClientBuilder()
                .accessBaseUrl(accessBaseUrl)
                .checkoutId(checkoutId)
                .build()

            // Create the validation configuration
            let validationConfig = try CardValidationConfig.builder()
                .pan(panAccessCheckoutView)
                .expiryDate(expiryDateAccessCheckoutView)
                .cvc(cvcAccessCheckoutView)
                .validationDelegate(self)
                .build()

            // Initialize validation using the client
            accessCheckoutClient.initialiseValidation(validationConfig)
        } catch {
            // Handle initialization error (e.g., log or show alert)
        }
    }
}

Card validation rules

The validation logic in the SDK, is based off a set of default rules for any card type. Specific brand rules are fetched from a CardTypes JSON file, which holds the validation rules and card brand logos for each brand. The icons are available in both SVG and PNG.

Validation rules

The table below shows the rules that our SDK uses to validate your customer's card details.

Card nameBIN rangePAN lengthCVC length
Amex34, 37154
Diners300-305, 3095, 36, 38, 3914, 16, 193
Discover6011, 644 - 649, 6516, 193
JCB2131, 1800, 3088 - 3094, 3096 - 3102, 3112 - 3120, 3158 - 3159, 3337 - 3349, 3528 - 358916, 17, 18, 193
Maestro493698, 500000 - 506698, 506779 - 508999, 56 - 59, 63, 67, 612, 13, 14, 15, 16, 17, 18, 193
MasterCard51 - 55, 2221 - 2229, 223 - 229, 23 - 26, 270 - 271, 2720: optimized using 22 - 27163
Visa413, 16, 18, 193

Additional configuration options

Card brand restriction

The SDK enables you to optionally provide a list of card brands that you support. This means that if you do not support a certain card brand, the SDK notifies your code of an invalid PAN if an unsupported brand is recognized.

By default, the SDK allows cards from any brand. If you do not wish to restrict the card brands that you accept then you do not need to pass any configuration.

Example configuration

To restrict the card brands that you accept, simply pass in an array of the brands that you do wish to accept when initializing the SDK.

The following validation configuration restricts the SDK to accept only American Express, Visa or Mastercard BIN ranges.

let validationConfig = try! CardValidationConfig.builder()
    ...
    .acceptedCardBrands(["visa", "mastercard", "AMEX"])
    ...
    .build()

Currently supported card brands

The table below shows the card brands recognized by our SDK.

BrandCode
American Express"amex"
Diners"diners"
Discover"discover"
JCB"jcb"
Maestro"maestro"
Mastercard"mastercard"
Visa"visa"
Note

If the SDK does not recognize a PAN as one of the above brands, it will be permitted as long as it meets the usual criteria for a valid PAN.

PAN formatting

The SDK allows PAN formatting as the customer types. This feature is disabled by default.

The PAN is formatted in the following way:

Card typeFormatting
Visa, Mastercard, JCB, Discover, Diners, MaestroXXXX XXXX XXXX XXXX
AmexXXXX XXXXXX XXXXX

Enabling PAN formatting

To enable the PAN formatting behavior, simply call the enablePanFormatting method on the CardValidationConfig builder.

let validationConfig = try! CardValidationConfig.builder()
    ...
    .enablePanFormatting()
    ...
    .build()

Next steps


Create a session to pay with a card or
Create sessions to pay with a card and CVC