Issue a Virtual Card
Outcome
Use this guide to issue a virtual card through PayAPI and understand the records that must exist beforehand.
A virtual card is created by the standard Create Card API with card_type: 2. The API creates the card and returns the Paymentology public card token. It does not create a digital-wallet token for Apple Pay, Google Pay, VTS, or MDES.
Who this is for
| Audience | Responsibility |
|---|---|
| Backend Engineer | Orchestrates the APIs, stores identifiers, implements idempotency and error handling. |
| Product Manager | Confirms the product, initial card state, customer experience, and follow-on lifecycle journeys. |
Overview
Prerequisites
Before issuing any cards, the following program-level configuration is enabled in cooperation with Paymentology:
| Prerequisites | Description |
|---|---|
| Client and API access | A valid client_id and permission to call the required PayAPI endpoints. The configuration is done during the onboarding in cooperation the Paymentology Implementation team. |
| Root parent account | An existing account hierarchy root. Account creation requires a parent account and cannot bootstrap the hierarchy. The root parent account is created during the onboarding in cooperation the Paymentology Implementation team. It is done in PayControl>Clients List>Add Client. |
| Card product | A configured card product, referenced by crd_prdct_id. The product controls properties such as BIN range, currencies, card stack, manufacturer, authorization model, and rules.The configuration is done during the onboarding in cooperation the Paymentology Implementation team. It is available in PayControl>Clients List>Add Product. |
| Card image | The requested image_name must be configured for the client in PayControl.The configuration is done during the onboarding in cooperation the Paymentology Implementation team. It is done in PayControl>Clients List>Upload Virtual Card Image. |
Recommended issuance flow
Create the customer
Create the cardholder first to receive a durable customer ID (cu_id).
API Reference: Create Customer V2
Required inputs:
| Field | Value / purpose |
|---|---|
client_id | Your program client ID |
api_call_unique_identifier | Idempotency identifier for this issuance attempt |
cu_fname | Customer first name |
cu_mobile | Customer mobile number |
cu_sname | Customer last name |
Store the returned cu_id. It should be reused for future cards and accounts belonging to the same customer.
Create a child account
Create an account for the customer under the program’s existing parent account.
API Reference: Create account V2
Key inputs:
| Field | Value / purpose |
|---|---|
client_id | Your program client ID |
api_call_unique_identifier | Idempotency identifier for this issuance attempt |
ac_parent_id | Existing parent account |
ac_set_ccy | Settlement currency |
ac_bill_ccy | Billing currency |
cu_id | Customer to associate with the account |
account_name | Account holder name |
Store the returned account id (ac_id).
Create the virtual card
API Reference: Create Card V2
Key inputs:
| FIeld | Value / purpose |
|---|---|
client_id | Your program client ID |
api_call_unique_identifier | Idempotency identifier for this issuance attempt |
card_type | 2 for a virtual card |
crd_prdct_id | Existing configured card product |
cu_id | Existing customer ID |
ac_id | Existing child account ID |
status_nwk | Pass 1000 to create a card in active state or 1005 to create a card in a blocked state.More information about the card statuses is available at Card status. |
token_group_id | An optional request field used to associate the card’s public token with a token group. Token groups provide a way to apply common controls or rules - such as spending limits, transaction restrictions, or fraud and risk policies - to multiple cards. This grouping is separate from the account-level grouping provided by group_id, so cards from different accounts can belong to the same token group. For example, token_group_id: "21345" associates the public card token with token group 21345; a request may also include "group_id": "55" for account-level grouping. |
image_delivery | Instructs the platform whether and how to include the generated card image in the response;
image_delivery does not determine which details appear in the image - that is controlled by image_fields. |
image_name | Case sensitive configured virtual-card image template. The configuration is done during the onboarding in cooperation the Paymentology Implementation team. It is done in PayControl>Clients List>Upload Virtual Card Image. |
image_fields | Controls which details are included inside the generated card image, in this order: PAN, CVV, expiry date, public token, and emboss name, so "10000" means the image contains the PAN but not the CVV, expiry, token, or emboss name. |
xml_fields | Controls which card details are returned as separate JSON fields, in this order: PAN, CVV, expiry date, public token, and emboss name; therefore, "00000" hides all five from the JSON response. |
client_card_ref | Recommended client-side idempotent business reference |
The API returns the newly created card’s public token. Store this as the main identifier for subsequent card operations.
What is created by Create Card
| Record | Created by Create Card? |
|---|---|
| Card | Yes |
| Public card token | Yes; returned as token |
| Link between card and supplied account | Yes |
| Child account | Yes, only when ac_parent_id is used instead of ac_id |
| Customer | The request supports cardholder data in place of an existing cu_id; use the dedicated customer endpoint for explicit customer management |
| Digital wallet token | No |
Optional shortcut: create the child account during card issuance
Instead of supplying an existing ac_id, Create Card can receive:
ac_parent_idac_name- optional account reference and currency inputs
In this mode, PayAPI creates a child account and links it to the card. The response returns the generated ac_id.
This is valid for simpler flows, but the recommended production pattern is to create the customer and account explicitly. It makes customer ownership, account reuse, reconciliation, and retry handling clearer.
Optional shortcut: create the customer during card issuance
Instead of supplying an existing cu_id, Create Card can receive cardholder details in the same request.
In this mode, omit cu_id and provide the required ch_* cardholder fields. PayAPI passes those details into the card-creation flow, which creates the customer record and associates it with the card.
Use this approach only when creating the customer is part of a single, one-time issuance flow. The recommended production pattern remains to create the customer explicitly first. This gives the client a durable customer identifier before account and card creation, and makes duplicate prevention, customer updates, reconciliation, and support investigations clearer.
When cu_id is omitted, provide a complete cardholder profile appropriate for the selected product and delivery design:
- ch_title
- ch_fname
- ch_sname
- ch_addr1
- ch_addr2
- ch_pcode
- ch_city
- ch_country
- ch_email
- ch_mobile
- ch_region
- ch_dob
The exact mandatory subset can be enforced by downstream product and customer rules. Validate the intended payload in UAT.
For the simplest single-call flow, also omit ac_id and provide:
- ac_parent_id
- ac_name
- Optional account reference and currency fields
In this mode, PayAPI creates the customer, creates a child account under the supplied parent account, and links the new card to that account.
Do not assume that the Create Card response will always contain the generated cu_id. Persist the returned card token and ac_id, then verify how your target environment exposes or reconciles the customer identifier before relying on this shortcut in production.
Activate a card issued in a blocked state
If the card was created with status_nwk: 1005, activate it after your activation criteria have been met.
API Reference: Set Card Status V2
| Field | Value / purpose |
|---|---|
client_id | Your program client ID |
api_call_unique_identifier | Idempotency identifier for this issuance attempt |
status_nwk | Set to 1000 to active |
token | Card’s public token |
Use the returned public card token and set the target status according to your program’s activation policy.
Important Considerations
- A virtual card is selected per issuance request using
card_type: 2; it is not a separate product type.
- The product ID is mandatory. The API does not create a product automatically during card issuance.
- Treat PAN and CVV as sensitive authentication data. Request, store, display, and log them only in accordance with PCI and your program’s security design.
- The API layer validates the request shape, but product eligibility, BIN availability, and other operational rules can be enforced downstream. Validate the configured product in the target environment before production rollout.
- Treat the create operation as idempotent. Persist the business reference and
api_call_unique_identifierbefore making the request; retry a timed-out request using the same identifier only when its payload is unchanged.
- A failure response means no successful issuance has been confirmed. Reconcile before retrying so that a network timeout cannot create an unintended second card.
- To convert an issued virtual card into a physical card, use
POST /pws/v2/pws_virtual_to_physical/at Card Conversion V2.
Testing
| Test case | Expected result |
|---|---|
| Happy path: existing customer and account | A virtual card is created; the response returns the expected identifiers and public card token. |
| Happy path: new customer and child account | Customer, account, and virtual card are created or linked as designed. |
| Invalid product or missing hierarchy | The request fails clearly and no usable card is issued. |
| Duplicate submission | Repeating the same request with the same idempotency identifier does not create an unintended second card. |
| Timeout and reconciliation | The client can determine whether the original request succeeded before retrying. |
| Initial blocked-state flow | The card is created in the intended state and changes state only through the approved lifecycle API. |
| Sensitive-data handling | PAN/CVV are absent from application logs, monitoring traces, analytics, and support tickets. |
| Functional card test | Execute the agreed UAT card scenario through the permitted simulator or test channel. |
Errors, retries, and request correction
Use header.error_id and header.error_desc as the primary outcome signal. Do not decide whether to retry from the HTTP status alone.
For an uncertain or retryable issuance attempt, resend the identical payload with the same api_call_unique_identifier. Never create a new identifier until you have reconciled whether the original attempt created a card.
A successful re-use of the same identifier replays the original successful response. This is important because the response contains the public card token created by the original attempt.
Retry automatically
| Error ID | Error description | Automatic retry? | Required retry behaviour |
|---|---|---|---|
| No response | No PayAPI response received | Yes | Retry the same payload and identifier after backoff. Do not generate another identifier or change issuance inputs. |
1066 | Original request still processing. Please try again later. | Yes, after waiting | Do not send a parallel Create Card request. Wait, then resend the same payload and identifier. |
987 | We are temporarily unable to handle the request. Please try again later. | Yes | Use bounded retry with the same identifier and unchanged payload. This ID is allow-listed for V2 reprocessing. |
988 | Error executing Request. Contact Paymentology for support | Yes | Use bounded retry with the same identifier and unchanged payload. Escalate after retry exhaustion. |
989 | Error executing Request. Contact Paymentology for support | Yes | Perform a controlled retry with the same identifier and unchanged payload. Reconcile repeated failures. |
1034 | Failed to create card,please contact the paymentology support | Controlled only | This ID is allow-listed for V2 reprocessing. Retry once with the same request, then investigate and escalate if it persists. |
Do not retry automatically
| Error ID | Error description | Automatic retry? | Required action |
|---|---|---|---|
995 | model Validation Failed | No | Correct the invalid request fields, then submit a new issuance request with a new identifier. Typical examples are an invalid status_nwk or omitting both ac_id and ac_parent_id. |
990 | The client_id is invalid! Please provide a valid client id | No | Correct the client ID or target-environment configuration. |
991 | The parent account number is invalid | No | Use an existing, valid parent account. Confirm the account hierarchy before retrying as a new request. |
992 | The account id is invalid ! | No | Correct the supplied ac_id, or use valid child-account creation inputs. |
993 | api_call_unique_identifier already been used! | No | Reconcile the original issuance. Generate a new identifier only for a genuinely new card-issuance request. |
996 | Permission denied ! The client does not have access to this web service. Contact Paymentology | No | Correct the API entitlement. Although the V2 implementation permits reprocessing this stored ID, it is not a transient technical failure. |
997 | Description varies; for example, Account Mapping list Not Found | No | Correct the missing card, account, customer, product, configuration, or relationship indicated by error_desc. |
1014 | The product id is not available in repository | No | Use an existing product configured for the client and target environment. |
1016 | product Bin Low/Bin is Not Matching with the available bins or Customer stack is empty ! | No | Correct product, BIN, or customer-stack configuration. The V2 processor allow-lists this ID for reprocessing after the configuration defect is fixed, but it must not be retried automatically. |
1017 | card image data is not configured | No | Configure the requested virtual-card image, or correct image_name before creating a new issuance request. |
1018 | Account Already assigned to card , Please create new account and create card | No | Review the intended account-to-card relationship. Create or select the correct account instead of retrying the same issuance request. |
1020 | Please Provide Parent account or account id to Create the card | No | Supply a valid existing ac_id, or provide ac_parent_id and the required child-account inputs. |
1033 | Failed to create card, try again or contact the paymentology | No automatic retry | This virtual-card-specific failure is not in the V2 reprocessing allow-list. Reconcile whether a card was created, then escalate repeated failures. |
1035 | Failed to create card image ,please contact the paymentology support | No automatic retry | Check the configured virtual-card image and sensitive-response settings. Escalate persistent failures. |
Related APIs
- Create customer: Create Customer V2
- Create account: Create account V2
- Create virtual card: Create card V2
- Set card status: Set Card Status V2
- Link card, account and cardholder: Link account card V2
- Convert virtual to physical: Card Conversion V2
Updated 22 days ago

