Create cards
Cards is in beta and may change as we continue to improve it. Please review the documentation and endpoints carefully, test everything in the sandbox, and reach out to the Solutions team if you need help.
Cards can only be issued to customers created using the Customers v1 and Agreements v1 APIs. Customers created via the v2 onboarding flow are not yet supported for card issuance.
This guide walks you through the full cards integration. By the end, you will be able to issue virtual cards, securely display card details, manage the card lifecycle, and receive transaction webhooks.
Prerequisites
Before you begin, ensure the following requirements are met:
- The Cards feature is enabled for your account by BVNK.
- You have API credentials (see Generate API keys).
- Your customers are already onboarded and verified by BVNK.
- Each customer has a USDC wallet created.
- Each customer has a verified phone number and email address on file.
- You are PCI-compliant (not PCI-certified).
Check customer eligibility
Before issuing a card, verify the customer meets all eligibility requirements. Send the GET /card/v1/customer-eligibility-status request with the customer ID and ledger type. For example, GET /card/v1/customer-eligibility-status?customerId=4f2a76a4-0954-4999-b555-f9f2bec78c50&ledgerType=BVNK_EPC_WALLET
If the customer is eligible, the response returns eligible: true with an empty requirements list:
{
"customerId": "4f2a76a4-0954-4999-b555-f9f2bec78c50",
"requirements": [],
"eligible": true
}
If the customer is not yet eligible, the response returns eligible: false with a list of unmet requirements:
{
"customerId": "4f2a76a4-0954-4999-b555-f9f2bec78c50",
"requirements": [
{
"type": "REQUIRED_DATA",
"key": "customer.phoneNumber",
"label": "Phone number",
"description": "Customer must have a verified phone number on file"
}
],
"eligible": false
}
Resolve all requirements before proceeding to card issuance.
Create card agreement signing session
Before issuing a card, the customer must accept the card's terms and conditions, including the card issuer's terms. The customer must be onboarded and verified by BVNK before you can create a card agreement session.
The customer must reside in a jurisdiction that supports cards and be associated with a BVNK entity authorised to issue cards.
Your onboarding and card issuance UI must be approved by BVNK. Submit your designs early to avoid rework.
-
Send the
POST platform/v1/customers/agreement/sessionsrequest to create an agreement signing session with the cards use case:{"customerType": "INDIVIDUAL","countryCode": "DE","useCase": "CARD_AGREEMENT","customerReference": "b4e5c3d1-9a42-4e7b-8f34-7c6b2a89f3df"}BVNK returns the agreement signing session details.
-
Present the terms to the customer in your UI.
-
After the customer accepts, submit the customer's decision by sending the
PUT platform/v1/customers/agreement/sessions/{reference}request.{"status": "SIGNED","ipAddress": "192.172.1.16"}
BVNK records consent to the card issuer's terms. Signed agreements are stored with the customer record.
Issue a card
After the customer signs the Cards agreements, issue a virtual card linked to their USDC wallet by sending the POST /card/v1/cards request.
{
"reference": "card-ref-001",
"customerId": "4f2a76a4-0954-4999-b555-f9f2bec78c50",
"ledger": {
"type": "BVNK_EPC_WALLET",
"mainWalletId": "acc:22101919109000:wYzI5:0"
},
"assetCode": "USDC",
"limit": {
"type": "DAILY",
"value": 5000
},
"cardArt": "cool-art-42"
}
Validation rules:
- The customer must have signed the Cards agreements.
- Each customer may have only one active card or pending application.
- The card must be linked to a USDC wallet.
- Customer must have phone number and email on file.
BVNK responds with a CREATED status. Shortly after, the asynchronous issuing process starts and the card transitions to PENDING:
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"customerId": "4f2a76a4-0954-4999-b555-f9f2bec78c50",
"assetCode": "USDC",
"last4Digits": "4829",
"status": "CREATED",
"createdAt": "2026-05-21T10:30:00Z",
"updatedAt": "2026-05-21T10:30:00Z",
"expiresAt": "2029-05",
"ledger": {
"id": "acc:22101919109000:wYzI5:0",
"type": "BVNK_EPC_WALLET"
},
"limit": {
"configured": {
"type": "DAILY",
"value": 5000
},
"available": 5000,
"nextResetAt": "2026-05-22T00:00:00Z"
},
"cardTransactionStats": null,
"provisionedWallets": [],
"audit": [],
"cardArt": "cool-art-42"
}
Once the issuing process completes, BVNK sends a card status change webhook with the final status (ACTIVE or CANCELLED).
BVNK does not provide the reason for cancellation. If the card is cancelled during issuance, the customer may reapply.
Set virtual card art
You can customise the appearance of your virtual cards by setting the cardArt field when creating a card. The process works as follows:
- Design your card artwork and submit it to your BVNK Solutions or Account Manager (via email or other offline channel). Card schemes enforce specific rules on card design and layout, so consult BVNK before finalising your designs.
- BVNK reviews and approves your artwork. The approval process typically takes 2-3 weeks.
- Once approved, BVNK provides you with a card art identifier, for example,
cool-art-42. - Pass that identifier in the
cardArtfield when creating a card.
If you have multiple approved designs, you can choose which art to apply per card; each card uses one design at a time.
If you omit cardArt, the default card art for your program is applied.
BVNK does not currently surface card art identifiers or previews in the Portal or API. Store your identifiers and corresponding designs on your side.
View cards
To retrieve a list of all cards, including pending applications, send the GET /card/v1/cards request.
You can filter by card ID or customer reference.
The response includes each card's
- Status
- Asset currency
- Creation, update, and expiry dates
- Spend limit (configured value, available balance, and next reset time)
- Last four digits
- Last authorisation date
- Provisioned digital wallets.
[
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"customerId": "4f2a76a4-0954-4999-b555-f9f2bec78c50",
"assetCode": "USDC",
"last4Digits": "4829",
"status": "ACTIVE",
"createdAt": "2026-05-21T10:30:00Z",
"updatedAt": "2026-05-21T12:00:00Z",
"expiresAt": "2029-05",
"ledger": {
"id": "acc:22101919109000:wYzI5:0",
"type": "BVNK_EPC_WALLET"
},
"limit": {
"configured": {
"type": "DAILY",
"value": 5000
},
"available": 4250.00,
"nextResetAt": "2026-05-22T00:00:00Z"
},
"cardTransactionStats": {
"latestAuthorizedAt": "2026-05-21T14:22:00Z"
},
"provisionedWallets": [],
"audit": [
{
"id": "a1b2c3d4-5678-90ab-cdef-111222333444",
"metadata": {
"type": "STATUS_CHANGE",
"newStatus": "ACTIVE"
},
"reason": "Card activated after provisioning",
"actorName": "System",
"actorType": "SYSTEM",
"createdAt": "2026-05-21T10:35:00Z"
}
],
"cardArt": "cool-art-42"
}
]
Only one card or application is returned per customer. If a customer has multiple applications, only the most recent record is provided.
View sensitive card details
Sensitive card data (PAN, CVC, expiry, cardholder name) is displayed securely through BVNK. Your application never accesses these sensitive values. See Display sensitive card details using SDK to render card details inside a sandboxed iframe served from BVNK's card vault.
Receive status webhook
Subscribe to the following webhook events to keep your system synchronised:
| Event | Trigger |
|---|---|
| Card status change | Card status transitions (e.g. CREATED → PENDING → ACTIVE or CANCELLED, or frozen, unfrozen, blocked, unblocked) |
| Card transaction created | New authorisation, refund, or credit on the card |
| Card transaction status update | Transaction status changes (e.g. auth → settled, pending → declined) |
For more information about webhook configuration, see Configure webhooks.
Test in sandbox
All Cards APIs are available in the sandbox environment. Use simulation endpoints to generate test transactions and exercise the full transaction lifecycle without real card network activity.
Simulate an authorisation
Send the POST /card/v1/simulation/transactions request to create a simulated authorisation for an active card:
{
"cardId": "550e8400-e29b-41d4-a716-446655440000",
"amount": 50.00,
"currency": "USD",
"merchantName": "The Daily Grind",
"merchantCategoryCode": "5812"
}
To simulate a declined transaction, include declineReason:
{
"cardId": "550e8400-e29b-41d4-a716-446655440000",
"amount": 10000.00,
"currency": "USD",
"merchantName": "Luxury Store",
"merchantCategoryCode": "5944",
"declineReason": "Insufficient funds"
}
The response includes the simulated transaction ID and status:
{
"id": "018f1234-5678-7abc-def0-123456789abc",
"status": "AUTHORIZED",
"declineReason": null,
"completionReason": null
}
Simulate a transaction state change
Send the PATCH /card/v1/simulation/transactions/{transactionId} request to settle, reverse, or refund a previously simulated authorisation:
{
"action": "SETTLE"
}
Available actions:
| Action | Description |
|---|---|
SETTLE | Settle the authorization. Optionally pass newAmount to settle a different amount: less than the original for a partial settlement, or more for an overcapture. |
REVERSE | Cancel the authorisation entirely. Funds are released back to the wallet. |
REFUND | Refund a settled transaction. Funds are credited back to the wallet. |
What's next?
Once your cards are live, see Manage Cards for freezing, unfreezing, cancelling cards, and viewing transaction history.