Card Tokenization
Register external payment cards for push to card transfers.
Before You Start
Read the following guides before proceeding:
| Guide | Why |
|---|---|
| Getting Started | Platform overview and setup |
| Api Basics | Required headers and request configuration |
| Authentication | How to obtain access tokens |
| Onboarding | User and wallet registration |
| KYC | KYC verification requirements |
| Recipients | Recipient management |
Overview
Before initiating push to card transfers, external cards must be registered and tokenized. This is a two-step process:
- Tokenize Card — Submit card details to Wirex PCI-compliant secure environment
- 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}
| Parameter | Description |
|---|---|
user_id | User 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
}| Field | Type | Required | Description |
|---|---|---|---|
card_number | string | Yes | Full card number (PAN) |
cardholder_name | string | Yes | Name as printed on the card (uppercase) |
card_label | string | Yes | Display label for the card |
is_saved | boolean | Yes | true to save for future transfers |
is_third_party | boolean | Yes | false for user's own card, true for third-party card |
Response
{
"value": "tok_a1b2c3d4e5f6789012345678"
}| Field | Type | Description |
|---|---|---|
value | string | Card 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"
}
}| Field | Type | Required | Description |
|---|---|---|---|
first_name | string | Yes* | Recipient first name |
last_name | string | Yes* | Recipient last name |
company_name | string | Yes* | Company name (for business recipients) |
is_business | boolean | Yes | false for personal, true for business |
type | string | Yes | Must be Card |
currencies | string[] | Yes | Supported currencies for transfers |
card.card_id | string | Yes | Token from PCI tokenization step |
card.card_pan_last | string | Yes | Last 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
| Type | is_third_party | Description |
|---|---|---|
| First-party | false | User's own card — user is the cardholder |
| Third-party | true | Card 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)
| HTTP | Error | Description |
|---|---|---|
| 400 | Invalid card number | Card number failed Luhn validation |
| 400 | Unsupported card type | Only Visa and Mastercard are supported |
| 400 | Card expired | Card expiration date is in the past |
| 400 | Missing required field | Required field not provided |
Recipient Creation Errors
| Error Reason | Field | Description |
|---|---|---|
ErrorMissingField | first_name | First name required for personal recipients |
ErrorMissingField | last_name | Last name required for personal recipients |
ErrorMissingField | company_name | Company name required for business recipients |
ErrorMissingField | type | Payment type is required |
ErrorMissingField | card | Card details required when type is Card |
ErrorMissingField | card.card_id | Card token is required |
ErrorMissingField | card.card_pan_last | Last 4 digits required |
ErrorInvalidField | card.card_pan_last | Must be exactly 4 digits |
ErrorInvalidField | first_name | Invalid format for first name |
ErrorInvalidField | last_name | Invalid 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"
}
]
}Updated about 20 hours ago
