Select Card
POST https://api.firmly.work/api/v1/wallets/agentic-pay/select-card
Overview
The Select Card endpoint starts a payment flow from a stored card. It takes the virtual_card_id from a prior enrollment and returns the same shape as /enroll — a flow_token whose status is already enrolled, so verification is skipped — plus verification_methods. The existing handshake, intent, and order completion chain is reused unchanged.
Destinations persist card_art and masked from the initial /enroll response for the saved-card UI. /select-card does not re-fetch card metadata.
Authentication
x-firmly-authorization(string, required) — API token for authentication
Request Body
-
network(string, required) — Card network:"visa","mastercard", or"discover" -
virtual_card_id(string, required) — Thevirtual_card_idreturned from the original/enrollresponse -
consumer(object) — Cardholder information. Required for Visa (emailis mandatory for device binding — omitting it returns a400). Optional for Mastercard. Fields:email(string) — Cardholder email address (required for Visa)country_code(string) — ISO country code (e.g.,"US")
Response
Returns the same shape as /enroll.
-
flow_token(string) — Encrypted state token for subsequent calls (status:enrolled). -
virtual_card_id(string) — Samevirtual_card_idpassed in the request. -
verification_methods(array) — Available verification methods. Visa returns anembed_iframe_handshake(capture asecure_tokenbefore calling/intent). Mastercard and Discover return an empty array — proceed directly to/intent. -
card_art(null) — Alwaysnullon/select-card. Use thecard_artpersisted from the original/enrollresponse. -
masked(null) — Alwaysnullon/select-card. Use themaskeddetails persisted from the original/enrollresponse.
Code Examples
curl --request POST \--url https://api.firmly.work/api/v1/wallets/agentic-pay/select-card \--header 'Content-Type: application/json' \--header 'x-firmly-authorization: YOUR_API_TOKEN' \--data '{"network": "visa","virtual_card_id": "cf90be5c86363de702ed19beec46e102","consumer": {"email": "jane@example.com","country_code": "US"}}'
const response = await fetch('https://api.firmly.work/api/v1/wallets/agentic-pay/select-card', {method: 'POST',headers: {'Content-Type': 'application/json','x-firmly-authorization': 'YOUR_API_TOKEN'},body: JSON.stringify({network: 'visa',virtual_card_id: 'cf90be5c86363de702ed19beec46e102',consumer: {email: 'jane@example.com',country_code: 'US'}})});const { flow_token, verification_methods } = await response.json();// Continue with handshake → /intent → /intent/challenge → /wallet-complete-order
import requestsresponse = requests.post('https://api.firmly.work/api/v1/wallets/agentic-pay/select-card',headers={'Content-Type': 'application/json','x-firmly-authorization': 'YOUR_API_TOKEN'},json={'network': 'visa','virtual_card_id': 'cf90be5c86363de702ed19beec46e102','consumer': {'email': 'jane@example.com','country_code': 'US'}})data = response.json()# Continue with handshake → /intent → /intent/challenge → /wallet-complete-orderprint(data['flow_token'])print(data['verification_methods'])
Response Example
{"flow_token": "<encrypted-jwe-token>","virtual_card_id": "cf90be5c86363de702ed19beec46e102","verification_methods": [{"id": "VISA_IFRAME_HANDSHAKE","type": "embed_iframe_handshake","attributes": {"uri": "https://sbx.vts.auth.visa.com/vts-auth/authenticate?apiKey=...","next_steps": ["Load this iframe in the cardholder browser","Capture sessionContext.secureToken from postMessage","Send to /intent as secure_token"]}}]}
Error Responses
| Error Code | Status | Description |
|---|---|---|
BadRequest |
400 | network or virtual_card_id missing, or consumer.email missing for a Visa card. |
PaymentMethodNotAvailable |
409 | Stored-card payment is not supported or not enabled for this network. |
400 - Missing Required Fields
{"code": 400,"error": "BadRequest","description": "network and virtual_card_id required"}
400 - Missing Email (Visa)
{"code": 400,"error": "BadRequest","description": "consumer.email is required for Visa stored-card selection"}
409 - Network Not Available
{"code": 409,"error": "PaymentMethodNotAvailable","description": "Stored-card payment not supported for this network"}
Related Endpoints
- Enroll Card — First-time card enrollment (requires PAN)
- Create Intent — Next step after select-card