Card Tokenization

Register external payment cards for push to card transfers.

Before You Start

Read the following guides before proceeding:

GuideWhy
Getting StartedPlatform overview and setup
Api BasicsRequired headers and request configuration
AuthenticationHow to obtain access tokens
OnboardingUser and wallet registration
KYCKYC verification requirements
RecipientsRecipient management

Overview

Before initiating push to card transfers, external cards must be registered and tokenized. This is a two-step process:

  1. Tokenize Card — Submit card details to Wirex PCI-compliant secure environment
  2. Create Recipient — Register the tokenized card as a recipient with payment details

The PCI tokenization ensures sensitive card data (PAN) is never stored or transmitted outside the secure environment.


Step 1: Tokenize Card

Submit card details to the PCI secure environment to receive a card identifier.

Authentication

This endpoint requires a user-scoped token obtained via User Token Issuance (Login as User). S2S tokens are not supported for this endpoint.

Endpoint

POST {pci_base_url}/b2b/cards/oct?user_id={user_id}
ParameterDescription
user_idUser UUID from GET /api/v2/user response (id field)

See Environments for PCI environment base URLs.

Request

{
  "card_number": "4242424242424242",
  "cardholder_name": "ALEX GREY",
  "card_label": "My Visa Card",
  "is_saved": true,
  "is_third_party": false
}
FieldTypeRequiredDescription
card_numberstringYesFull card number (PAN)
cardholder_namestringYesName as printed on the card (uppercase)
card_labelstringYesDisplay label for the card
is_savedbooleanYestrue to save for future transfers
is_third_partybooleanYesfalse for user's own card, true for third-party card

Response

{
  "value": "tok_a1b2c3d4e5f6789012345678"
}
FieldTypeDescription
valuestringCard token identifier for use in recipient creation

Card Validation

The endpoint validates:

  • Card number passes Luhn check
  • Card is Visa or Mastercard
  • Card is not expired (if expiry provided)

Step 2: Create Card Recipient

After tokenizing the card, create a recipient with personal info and card payment details in a single call.

Endpoint

POST /api/v2/recipients

Request

{
  "first_name": "Alex",
  "last_name": "Grey",
  "is_business": false,
  "type": "Card",
  "currencies": ["EUR", "USD", "GBP"],
  "card": {
    "card_id": "tok_a1b2c3d4e5f6789012345678",
    "card_pan_last": "4242"
  }
}
FieldTypeRequiredDescription
first_namestringYes*Recipient first name
last_namestringYes*Recipient last name
company_namestringYes*Company name (for business recipients)
is_businessbooleanYesfalse for personal, true for business
typestringYesMust be Card
currenciesstring[]YesSupported currencies for transfers
card.card_idstringYesToken from PCI tokenization step
card.card_pan_laststringYesLast 4 digits of card number

*Provide either first_name + last_name for personal recipients, or company_name for business recipients.

Response

{
  "id": "77fc49bd-1d7d-41d9-beea-a0aee0dc8c35",
  "personal_info": {
    "first_name": "Alex",
    "last_name": "Grey",
    "is_business": false
  },
  "payment_details": [
    {
      "id": "c34908da-d980-4a9c-9b39-4dabd6f6144e",
      "type": "Card",
      "currencies": ["EUR", "USD", "GBP"],
      "card": {
        "card_id": "tok_a1b2c3d4e5f6789012345678",
        "card_pan_last": "4242"
      }
    }
  ]
}

The payment_details[].id value is used as external_card_id in transfer requests.


First-Party vs Third-Party Cards

Typeis_third_partyDescription
First-partyfalseUser's own card — user is the cardholder
Third-partytrueCard belongs to another person — recipient is different from user

Third-party transfers may have additional compliance requirements and limits.


Recipient Webhook

When a card recipient is created, a webhook is delivered.

Endpoint: POST {base_url}/v2/webhooks/recipients

{
  "id": "77fc49bd-1d7d-41d9-beea-a0aee0dc8c35",
  "personal_info": {
    "first_name": "Alex",
    "last_name": "Grey",
    "is_business": false
  },
  "payment_details": [
    {
      "id": "c34908da-d980-4a9c-9b39-4dabd6f6144e",
      "type": "Card",
      "currencies": ["EUR", "USD", "GBP"],
      "card": {
        "card_id": "tok_a1b2c3d4e5f6789012345678",
        "card_pan_last": "4242"
      }
    }
  ]
}

Error Handling

Tokenization Errors (PCI Environment)

HTTPErrorDescription
400Invalid card numberCard number failed Luhn validation
400Unsupported card typeOnly Visa and Mastercard are supported
400Card expiredCard expiration date is in the past
400Missing required fieldRequired field not provided

Recipient Creation Errors

Error ReasonFieldDescription
ErrorMissingFieldfirst_nameFirst name required for personal recipients
ErrorMissingFieldlast_nameLast name required for personal recipients
ErrorMissingFieldcompany_nameCompany name required for business recipients
ErrorMissingFieldtypePayment type is required
ErrorMissingFieldcardCard details required when type is Card
ErrorMissingFieldcard.card_idCard token is required
ErrorMissingFieldcard.card_pan_lastLast 4 digits required
ErrorInvalidFieldcard.card_pan_lastMust be exactly 4 digits
ErrorInvalidFieldfirst_nameInvalid format for first name
ErrorInvalidFieldlast_nameInvalid format for last name

Error Response Format

{
  "error_reason": "ErrorMissingField",
  "error_description": "card.card id is required",
  "error_category": {
    "category": "CategoryValidationFailure",
    "http_status_code": 400
  },
  "error_details": [
    {
      "key": "field",
      "details": "card.card_id"
    },
    {
      "key": "issue",
      "details": "missing"
    }
  ]
}