Documentation/API/Cards

Cards Service

API reference for managing payment cards

VERTEX ENGINE

00

Introduction

The Cards API allows you to manage payment cards for your organization. You can request new cards, view card details, activate cards, set PINs, and manage card status and limits.

Virtual card lifecycle

Simple flow

3 stepsVirtual-onlyCardholder access
1

Step 1

Request card

svc.card.{partner}.request

Call: svc.card.{partner}.request

Send: { account_id, user_id, name, type: 1, use_type: 2, features, limits?, extras? }

Note: use_type must be 2 (multi-use); single-use cards are not available.

Result

Receive: { id }

This id becomes the card_id after approval.

2

Step 2

Track approval

svc.card.{partner}.list_requests

Call: svc.card.{partner}.list_requests

Send: { account_id } (optionally add user_ids).

Success signal

Look for status: "APPROVED" on the request with the same id.

3

Step 3

Get card details (PAN/CVV)

svc.card.{partner}.get_details

Call: svc.card.{partner}.get_details

Send: { account_id, id } where id is from Step 1.

Receive

{ card_number, expiry_date: "MMYY", cvv }

Virtual cards are active by default.

Optional - List cards (UI/Discovery)

  • Call: svc.card.{partner}.list_cards
  • Send: { entity_id, account_id, user_ids? }
  • Receive: { id: entity_id, cards: [ { id, last_4, status, ... } ] }
  • Behavior: last_4 is "****" when INACTIVE and visible when ACTIVE.

Optional - Cardholder actions

  • set_pin (svc.card.{partner}.set_pin): { account_id, id, pin: "1234" }
  • update_status (svc.card.{partner}.update_status): { account_id, id, status: "ACTIVE" | "FROZEN" }

Card Features and Limits

Card Features

Controls which transaction types and features are enabled for a card.

CardFeatures Object(json)
{
  "domestic": true,       // Allow domestic transactions
  "international": false, // Allow international transactions (default: false)
  "e_commerce": true,     // Allow online/e-commerce purchases
  "atm": true,            // Allow ATM withdrawals
  "pos": true,            // Allow point-of-sale transactions
  "contactless": true     // Allow contactless payments
}

Default Values & Behavior

When requesting a card, the following behavior applies:

  • domestic: Always forced to true (ignores request payload)
  • international: Always forced to false (ignores request payload)
  • e_commerce: Honors request payload (default: true if not specified)
  • atm: Honors request payload (default: true if not specified)
  • pos: Honors request payload (default: true if not specified)
  • contactless: Honors request payload (default: true if not specified)

Usage in Endpoints

  • request: ⚠️ Partial (forces domestic and international; honors e_commerce, atm, pos, contactless)
  • list_requests, list_cards: ✅ Returns complete features
  • get_details, update_status, activate_card, set_pin: ❌ Not used

Implementation Notes

⚠️ The international toggle is present in the API but full enablement may be staged.

Card Limits

Transaction spending limits that can be configured for a card. All amounts are in minor units (e.g., cents) of the account currency.

CardLimits Object(json)
{
  "transaction_enabled": true,  // Enable per-transaction limit
  "transaction": 100000,        // Maximum per transaction (e.g., $1,000.00 = 100000 cents)
  "daily_enabled": true,        // Enable daily spending limit
  "daily": 100000,              // Maximum daily spend (e.g., $1,000.00)
  "monthly_enabled": true,      // Enable monthly spending limit
  "monthly": 500000,            // Maximum monthly spend (e.g., $5,000.00)
  "yearly_enabled": false,      // Enable yearly spending limit
  "yearly": 0                   // Maximum yearly spend (disabled)
}

Validation Rules

  • At least one limit required: At least one limit amount must be greater than 0
  • Transaction vs Periodic: transaction ≤ max(daily, monthly, yearly)
  • Daily vs Transaction: dailytransaction
  • Monthly vs Daily: monthlydaily
  • Yearly vs Monthly: yearlymonthly

⚠️ Note: Rules 2 and 3 together mean that when both transaction and daily limits are enabled, they must be equal.

Usage in Endpoints

  • request: ✅ Required (full validation applied)
  • list_requests, list_cards: ✅ Returns complete limits with enabled flags
  • get_details, update_status, activate_card, set_pin: ❌ Not used

Error Messages

  • "at least one limit must be provided"
  • "single transaction limit cannot be greater than periodic limit"
  • "daily limit cannot be greater than single transaction limit"
  • "monthly limit cannot be greater than daily limit"
  • "yearly limit cannot be greater than monthly limit"

Request Card

Request a new card for a user in your organization.

Endpoint

svc.card.{partner_id}.request

Request

RequestCardRequest(json)
{
  "account_id": "550e8400-e29b-41d4-a716-446655440000",  // Required - account ID (UUID)
  "user_id": "40ec785e-d915-49de-9053-4630042d8182",     // Required - user ID (UUID)
  "name": "John Doe",                                     // Required - name to appear on the card
  "type": 1,                                              // Required - card type: 1=Virtual, 2=Physical
  "use_type": 2,                                          // Required - card use type: 1=Single (rejected), 2=Multi
  "features": {                                           // Required - API honours these booleans (except international, currently ignored)
    "domestic": true,
    "international": false,
    "e_commerce": true,
    "atm": true,
    "pos": true,
    "contactless": true
  },
  "limits": {                                             // Required - include ≥1 non-zero amount; if transaction & daily enabled they must be equal
    "transaction_enabled": true,
    "transaction": 20000,
    "daily_enabled": true,
    "daily": 20000,
    "monthly_enabled": true,
    "monthly": 20000,
    "yearly_enabled": false,
    "yearly": 0
  },
  "extras": {                                             // Accepted but currently ignored (auto_lock stored with no enforcement yet)
    "auto_lock": "2023-12-31T23:59:59Z"
  }
}

Response

RequestCardResponse(json)
{
  "id": "7aa53a6d-5869-c814-5cee-2af0f5d92aa5"  // UUID of the created card request (becomes card_id upon approval)
}

Limit Validation

Limit validation is strict: at least one amount must be non-zero, and whenever multiple limits are enabled the hierarchy must hold (transaction ≥ daily ≥ monthly ≥ yearly).

Authorization Required

  • The returned id becomes the card_id after the request is approved.
  • Virtual cards are auto‑approved. Physical cards may require Owner/Accountant approval.

List Card Requests

List card requests for an account. Members see their own; owners/accountants can see all.

Endpoint

svc.card.{partner_id}.list_requests

Request

ListOrganisationCardRequestsRequest(json)
{
  "account_id": "550e8400-e29b-41d4-a716-446655440000",  // Required - account ID
  "user_ids": ["40ec785e-d915-49de-9053-4630042d8182"]   // Optional - filter by users
}

Response

ListOrganisationCardRequestsResponse(json)
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "requests": [
    {
      "id": "7aa53a6d-5869-c814-5cee-2af0f5d92aa5",
      "name": "John Doe",
      "type": 1,
      "use_type": 2,
      "created_at": "2023-11-15T10:30:45Z",
      "requested_by": "40ec785e-d915-49de-9053-4630042d8182",
      "assigned_to": "40ec785e-d915-49de-9053-4630042d8182",
      "features": {
        "domestic": true,
        "international": false,
        "e_commerce": true,
        "atm": true,
        "pos": true,
        "contactless": true
      },
      "limits": {
        "transaction_enabled": true,
        "transaction": 20000,
        "daily_enabled": true,
        "daily": 20000,
        "monthly_enabled": true,
        "monthly": 20000,
        "yearly_enabled": false,
        "yearly": 0
      },
      "extras": {},
      "status": "PENDING"
    }
  ]
}

Visibility enforced by upstream auth/policy; service returns by account and optional user_ids.

Respond to Card Request

Approve or reject a card request. Typically restricted to Owner/Accountant roles; enforce via access control. Note that virtual cards are auto-approved.

Endpoint

svc.card.{partner_id}.respond_to_request

Request

RespondToCardRequestRequest(json)
{
  "entity_id": "7632a09c-9408-4cf0-b8dd-cada3f089240",  // Required - entity ID
  "account_id": "550e8400-e29b-41d4-a716-446655440000",  // Required - account ID
  "request_id": "7aa53a6d-5869-c814-5cee-2af0f5d92aa5",  // Required - card request ID
  "approved": true                                        // Optional - omit or false to record a rejection
}

Response

RespondToCardRequestResponse(json)
{}

Authorization

Ensure appropriate role checks (Owner/Accountant) are enforced in your integration.

List Cards

List cards for an organization/account. Members see their own; owners/accountants can see all.

Endpoint

svc.card.{partner_id}.list_cards

Request

ListOrganisationCardsRequest(json)
{
  "entity_id": "7632a09c-9408-4cf0-b8dd-cada3f089240",   // Required - entity ID
  "account_id": "550e8400-e29b-41d4-a716-446655440000",  // Required - account ID
  "user_ids": ["40ec785e-d915-49de-9053-4630042d8182"]    // Optional - filter by users
}

Response

ListOrganisationCardsResponse(json)
{
  "id": "7632a09c-9408-4cf0-b8dd-cada3f089240",  // Entity ID (echoes request.entity_id)
  "cards": [
    {
      "id": "7aa53a6d-5869-c814-5cee-2af0f5d92aa5",
      "name": "John Doe",
      "type": 1,
      "use_type": 2,
      "last_4": "1234",  
      "date_created": "2023-11-15T10:30:45Z",
      "user_id": "40ec785e-d915-49de-9053-4630042d8182",
      "org_id": "7632a09c-9408-4cf0-b8dd-cada3f089240",
      "features": {
        "domestic": true,
        "international": false,
        "e_commerce": true,
        "atm": true,
        "pos": true,
        "contactless": true
      },
      "limits": {
        "transaction_enabled": true,
        "transaction": 20000,
        "daily_enabled": true,
        "daily": 20000,
        "monthly_enabled": true,
        "monthly": 20000,
        "yearly_enabled": false,
        "yearly": 0
      },
      "extras": {},                                  // Currently empty in list responses
      "status": "ACTIVE"
    }
  ]
}

Visibility enforced by upstream auth/policy; service filters by request parameters.

Masking Behavior

When a card is INACTIVE, the last_4 may be masked ("****"). Virtual cards are ACTIVE on creation.

Get Card Details

Retrieve sensitive card details such as the full card number, expiry date, and CVV. This endpoint should be used with caution and only when necessary.

Endpoint

svc.card.{partner_id}.get_details

Request

GetCardDetailsRequest(json)
{
  "account_id": "550e8400-e29b-41d4-a716-446655440000",  // Required - account ID
  "id": "7aa53a6d-5869-c814-5cee-2af0f5d92aa5"            // Required - card ID
}

Response

GetCardDetailsResponse(json)
{
  "card_number": "4111111111111234",  // Full card number
  "expiry_date": "1225",              // Card expiry date (MMYY)
  "cvv": "123"                        // Card verification value
}

Security Warning

This endpoint returns sensitive card information. Ensure you handle this data securely and in compliance with PCI DSS requirements.

Update Card Status

Change a card's status to ACTIVE or FROZEN. Freezing a card prevents transactions.

Endpoint

svc.card.{partner_id}.update_status

Request

UpdateCardStatusRequest(json)
{
  "account_id": "550e8400-e29b-41d4-a716-446655440000",  // Required - account ID
  "id": "7aa53a6d-5869-c814-5cee-2af0f5d92aa5",            // Required - card ID
  "status": "FROZEN"                                       // New status: ACTIVE or FROZEN
}

Response

UpdateCardStatusResponse(json)
{}

Activate Card

Activate a physical card after it has been received by the user. This is required before the card can be used for transactions.

Endpoint

svc.card.{partner_id}.activate_card

Request

ActivateCardRequest(json)
{
  "account_id": "550e8400-e29b-41d4-a716-446655440000",  // Required - account ID
  "id": "7aa53a6d-5869-c814-5cee-2af0f5d92aa5",            // Optional - card ID (can activate by last_4 only)
  "last_4": "1234"                                         // Required - last 4 digits for verification
}

Response

ActivateCardResponse(json)
{}

Set PIN

Set or change the PIN for a card. The PIN must be exactly 4 digits. A cooldown applies between PIN set requests.

Endpoint

svc.card.{partner_id}.set_pin

Request

SetPINRequest(json)
{
  "account_id": "550e8400-e29b-41d4-a716-446655440000",  // Required - account ID
  "id": "7aa53a6d-5869-c814-5cee-2af0f5d92aa5",            // Required - card ID
  "pin": "1234"                                            // New 4-digit PIN
}

Response

SetPINResponse(json)
{}

Security Warning

PINs are encrypted in transit and storage. Handle this data with care in your application.