Skip to main content
Visa Intelligent Commerce

Make your first API call

Available for use by:
Issuer banks Acquirer banks Merchants Independent developers Issuer banks for small businesses

Make your first API call

Where to start

Call POST /vacp/v2/credentials-for-instruction, the Unified API. This is the primary transaction-time entry point: it enrolls the consumer (when necessary), creates or validates the purchase instruction, and returns a usable payment credential in a single round trip. This assumes the card enrollment sequence (see Card Enrollment) is already complete.

1. Call the endpoint

Send POST /vacp/v2/credentials-for-instruction over mutual TLS, with Content-Type: application/json.

2. Provide the required fields

Your request must include:

  • clientReferenceId: a transactional identifier you assign to this request
  • client: your externalClientId (TRID) and externalAppId, plus an agent object identifying the agent (agentId, and agentSignature if you are a Trusted Agent Provider or Wallet Provider)
  • consumer: the consumer's consumerId, plus countryCode, languageCode, and consumerIdentities if this is a new consumer
  • tokenId: the consumer's previously provisioned vProvisionedTokenID
  • assuranceData: an array of Fast IDentity Online (FIDO) attestation/assertion verification records
  • appInstance: application name, device data, and IP address of the requesting client
  • mandates: the consumer-authorized spend boundary (mandateId, effectiveUntilTime, declineThreshold) for this purchase
  • transactionData: merchant name, merchant URL, transaction amount, the encryptedInstruction payload, and exactly one mandateReferenceData entry
  • purchaseType: one of PURCHASE_HITL (Human-in-the-Loop), PURCHASE_AUTONOMOUS, or PURCHASE_RECURRING

Conditional or triggered purchases (for example, "buy when a condition is met") are only supported when purchaseType is PURCHASE_AUTONOMOUS, and require notifying the consumer and obtaining approval once the condition is met.

3. Review the response

A 200 response returns clientReferenceId, instructionId, and a payload object containing exactly one of signedPayload (unencrypted, JSON Web Signature (JWS)) or encryptedSignedPayload (encrypted, JWE), never both. Save the instructionId; you need it for every subsequent credential, confirmation, or cancel call in this instruction's lifecycle. Other response codes:

  • 400: the request was malformed or invalid
  • 401: your mutual TLS, agent signature, or credentials failed validation
  • 403: the resource is forbidden to you
  • 404: a referenced resource (consumer, client, token) was not found
  • 409: the requested operation cannot be performed against the current state

Before you begin

See Prerequisites for the full onboarding, credential, and certificate checklist. In addition:

  • FIDO2 (FIDO Alliance passwordless authentication standard) or other supported consumer-authentication capability, plus device-fingerprinting collection, already built and tested (not something to build alongside this integration)
  • A signing key pair (Ed25519, RS256, or ES256) and keyId, if your integration requires an agent signature (see Set Up Agent Signature for the exact condition; not required for an Open Source Agent, whose agentId is fixed at 11111111111)

See Card Enrollment for the steps to obtain the tokenId and Visa Payment Passkey setup.

Steps

Step 1: Enroll the consumer, create the purchase instruction, and retrieve the first payment credential

This single call performs inline consumer enrollment (if needed), establishes the purchase instruction with its mandate(s), and returns a usable payment credential.

curl -X POST \
  "https://sandbox.api.visa.com/vacp/v2/credentials-for-instruction" \
  --cert your-client-cert.pem --key your-client-key.pem \
  -H "Content-Type: application/json" \
  -d '{
    "clientReferenceId": "d48ac10b-58cc-4372-a567-0e02b2c3d489",
    "client": {
      "externalClientId": "e48ac10b-58cc-4372-a567-0e02b2c3d489",
      "externalAppId": "e48ac10b-58cc-4372-a567-0e02b2c3d489",
      "agent": {
        "agentId": "50123456789",
        "agentSignature": {
          "signatureInput": {
            "created": "1735689600",
            "keyId": "poqkLGiymh_W0uP6PZFwdvez3QJT5SolqXBCW38r0U",
            "alg": "Ed25519",
            "expires": "1735693200",
            "nonce": "e8N7S2MFd/qrd6T2R3tdfAuuANngKI7LFtKYI7=",
            "tag": "credential-request"
          },
          "signature": "jdq0SqOwHdyHr9+r5jw3iYZH6aNGKijYp/EstF4RQTQdi5N5YYKD+mCT1HA1nZDsi6nJKuHxUi/5Syp3rLWBA=="
        }
      }
    },
    "consumer": {
      "consumerId": "c48ac10b-58cc-4372-a567-0e02b2c3d489",
      "countryCode": "US",
      "languageCode": "en",
      "consumerIdentities": [
        { "identityType": "USER_NAME", "identityValue": "johndoe123", "identityProvider": "PARTNER" }
      ]
    },
    "appInstance": {
      "applicationName": "My Shopping App",
      "ipAddress": "192.168.1.100",
      "deviceData": { "type": "Mobile Phone", "manufacturer": "Apple", "brand": "iPhone", "model": "iPhone 15 Pro" }
    },
    "tokenId": "d48ac10b-58cc-4372-a567-0e02b2c3d489",
    "assuranceData": [
      {
        "verificationEntity": "10",
        "verificationMethod": "23",
        "verificationResults": "01",
        "verificationTimestamp": "1735690745"
      }
    ],
    "mandates": [
      {
        "mandateId": "mandate-12345",
        "declineThreshold": { "amount": "500.00", "currencyCode": "USD" },
        "effectiveUntilTime": "1767225600"
      }
    ],
    "transactionData": {
      "transactionReferenceId": "txn-ref-12345",
      "merchantName": "Best Buy",
      "merchantUrl": "https://www.bestbuy.com",
      "transactionAmount": { "transactionAmount": "99.99", "transactionCurrencyCode": "USD" },
      "transactionReferenceIdType": "ENCRYPTED",
      "encryptedInstruction": "eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMjU2R0NNIn0.EncryptedKey.IV.Ciphertext.AuthTag",
      "mandateReferenceData": [ { "mandateId": "mandate-12345" } ]
    },
    "purchaseType": "PURCHASE_HITL"
  }'
Copied!

Confirm success

A successful response looks like this:

{
  "clientReferenceId": "d48ac10b-58cc-4372-a567-0e02b2c3d489",
  "instructionId": "f72bd91c-4a13-4c8e-9b2f-71c5d3e8a904",
  "payload": {
    "signedPayload": "eyJhbGciOiJSUzI1NiJ9...",
    "network": "visa",
    "panLastFour": "1111",
    "panExpirationMonth": "12",
    "panExpirationYear": "2028",
    "paymentAccountReference": "V0010013819330972362282455516"
  }
}
Copied!

How to verify: Confirm instructionId is non-empty and that exactly one of payload.signedPayload or payload.encryptedSignedPayload is populated. The response never contains both. Save instructionId for every subsequent credential, confirmation, or cancel call against this instruction.

Confirming successful integration

You have successfully integrated with Visa Intelligent Commerce when you can call POST /vacp/v2/credentials-for-instruction and receive a valid instructionId and payload (signed or encrypted) containing a network token, cryptogram, and Electronic Commerce Indicator (ECI) value.

  • You can complete an authorized commerce transaction at a merchant site within the limits of the consumer's mandate using the returned credential.
  • For recurring flows, a subsequent Retrieve Payment Credential call against the same instructionId resolves correctly without re-enrollment.