JavaScript Reference for Click to Pay SDK
Merchants and payment service providers
Click to Pay SDK documentations
Visa Click to Pay SDK Overview
The Visa Click to Pay SDK provides JavaScript APIs to be used by a SRC initiator (SRCi) to communicate between the Digital Payment Application (DPA) and the Visa SRC system.
The SRCi has the responsibility to initialize the SDK for use with a DPA, which includes providing values to control and customize the DPA’s interaction with the Digital Card Facilitator (DCF), and the Visa SRC system. After initialization by calling init, the SDK can be used to:
- Determine whether the consumer is recognized on the device (isRecognized)
- Determine whether the consumer is recognized by email address or mobile number in the SRC system (identityLookup)
- Initiate validation of the consumer on the device (initiateIdentityValidation)
- Complete the validation of the consumer (completeIdentityValidation)
- Get the consumer’s profile, which contains payment instruments for selection (getSrcProfile)
- Checkout (ability to return authentication results) and report DCF status (checkout)
- Perform authentication using the selected card and returns authentication data (authenticate)
- Disassociate the DPA or device from the consumer’s SRC Profile (unbindAppInstance)
Relationship Between the Visa Click to Pay System and Other Click to Pay Systems
Visa and other participating networks, such as MasterCard or American Express, each provide an SRC system to handle transactions under the EMV® Secure Remote Commerce Standards. Each SRC system provides a JavaScript API to invoke operations on the SRC system.
Important: This document only provides information about the Visa Secure Remote Commerce implementation of SRC. Refer to other networks’ documentation for non-Visa implementations of SRC.
You will need to take similar actions or call similarly named methods for each network you choose to support. The specifics of all non-Visa SRC methods and actions are outside the scope of this document; however, the following guidelines might be helpful:
- You must set up the Visa SRC SDK on each page from which you invoke the SDK’s JavaScript method. You will need to take similar actions to set up other networks as well.
- Before a card has been selected, you must call the same JavaScript method for each SRC system; for example, you must call the init method for each SRC system to start a transaction and call the isRecognized method for each SRC system to determine whether the consumer is known to any of the SRC systems.
- After a payment instrument has been selected, you call just the method specific to the associated network; for Visa cards, you call the Visa SRC SDK’s checkout JavaScript method.
- In some cases, you can call any (but only one) network’s method; for example, you could call any network’s implementation of initiateIdentityValidation to initiate passcode validation on a device and not call any other network’s similar method.
Setting Up the JavaScript API
Before calling init, you must load the SRC SDK. The SDK creates a WindowRef that connects the digital terminal to the DCF.
The JavaScript SDK endpoint to use depends on whether you want to run the Digital Terminal SRC initiator (SRCi) in the sandbox or in production:
|
Environment |
JavaScript SDK Endpoint |
|---|---|
Sandbox |
https://sandbox-assets.secure.checkout.visa.com/ checkout-widget/resources/js/src-i-adapter/visaSdk.js?v2 |
Production |
https://assets.secure.checkout.visa.com/ checkout-widget/resources/js/src-i-adapter/visaSdk.js?v2 |
<head>
...
</head>
<body>
<script src="https://sandbox-assets.secure.checkout.visa.com/checkout-widget/resources/js/src-i-adapter/visaSdk.js?v2">
</script>
<script>
let vSrcAdapter = window.vAdapters.VisaSRCI;
let vSrc = new vSrcAdapter();
</script>
</body>
Internally, a WindowRef is used to host the UI. When presenting any SRC UI, the SRC SDK controls the seamless operation of the window as either a pop-up window or an iFrame. The SRC SDK passes the WindowRef to the Digital Card Facilitator (DCF) so that the DCF UI can be rendered in the referenced window.
Providing Keys and Certificates
You must create keys for source validation, encryption of PANs, decrypting the payload, and providing authentication of your requests. Visa supports both symmetric and asymmetric data encryption; however, asymmetric data encryption keys require a public certificate from the entity performing the decryption.
Authenticated Data Token for Checkout Response
The purpose of the authentication data token is to provide authentication and integrity protection to the SRC summary payload.
Authenticated Data Token Notes
- The authenticated data is valid only for one particular request
- This is recommended to be used as an authorization header with the PoP (Proof-of- Possession) authentication scheme to connect to the SRC Initiator servers to fetch the full payload.
Authenticated Data Token JWS Header
|
Field |
Description |
|---|---|
kid |
Key identifier for the signing key. When Visa generates this header, the signing key is used to lookup the Outbound Message Authentication key. When Visa verifies the signature of this header, the signing key is used to lookup the Inbound Message Authentication key. Format: Alphanumeric |
alg |
Algorithm used to sign this ID token Format: It is one of the following values:
|
iat |
Issuance time in UTC Time at which the JWT was issued. This should not be before the expiration time (exp). Format: UNIX Epoch timestamp, in milliseconds |
jti |
Unique identifier for the token. The jti can be used as a nounce. Format: Case-sensitive string |
JavaScript Methods
init()
Initializes the app with common state. The init method must be called before any other methods. It is synchronous in operation.
Method Signature
init({
required String srciTransactionId;
conditional String srciDpaId;
required String srcInitiatorId;
conditional DpaData dpaData;
required DpaTransactionOptions dpaTransactionOptions;
})
Parameters
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
srciTransactionId |
String | Required | A unique transaction ID created by the SRCi, which may be created on the merchant page. It must be passed through to all networks (SRC systems) and DCFs. Format: Maximum 100 characters. |
srciDpaId |
String | Conditional | A unique ID provided by the SRCi for the DPA, which can be used as an external client ID. Conditionality: Required if srciDpaId in dpaData is not provided. |
srcInitiatorId |
String | Required | SRCi identifier generated by an SRC system during the onboarding process. |
dpaData |
DpaData | Conditional | DPA registration data. Conditionality: Required if srciDpaId is not provided. |
dpaTransactionOptions |
DpaTransactionOptions | Required | DPA configuration data, which overrides the configu ration on the SRC system that was created during DPA registration. |
Returns
None
Code Samples
var initParams = {
"srciTransactionId": "cdf753d2-097e-...-02f64ff91205",
"srciDpaId": "ma...dpa2",
"srcInitiatorId": "V6YPL0DFJ2V5...cx6KMF6iTHGM",
"dpaData": {
"srcDpaId": "",
"dpaPresentationName": "dpaPresentationName",
"dpaUri": "https://www.visa.com"
},
"dpaTransactionOptions": {
"dpaLocale": "en_US",
"dpaAcceptedBillingCountries": [
"US",
"CA"
],
"dpaAcceptedShippingCountries": [
"US",
"CA"
],
"dpaBillingPreference": "FULL",
"dpaShippingPreference": "NONE",
"consumerNameRequested": true,
"consumerEmailAddressRequested": true,
"consumerPhoneNumberRequested": true,
"paymentOptions": {
"dpaDynamicDataTtlMinutes": 2,
"dynamicDataType": "DYNAMIC_CARD_SECURITY_CODE",
"dpaPanRequested": false
},
"reviewAction": "continue",
"transactionType": "PURCHASE",
"orderType": "REAUTHORIZATION",
"payloadTypeIndicator": "SUMMARY",
"transactionAmount": {
"transactionAmount": "99.95",
"transactionCurrencyCode": "USD"
},
"merchantOrderId": "28b1b61b-bbec-...-33babc3b5187",
"merchantCategoryCode": "3000",
"merchantCountryCode": "US",
"threeDsPreference": "NONE",
"threeDsInputData": {
"requestorId": "requestorId",
"acquirerId": "acquirerId",
"acquirerMid": "acquirerMid"
},
"customInputData": {
// For Merchant Orchestrated Checkout Experience:
"checkoutOrchestrator": "merchant"
}
}
};
async function init(initParams, cb) {
const promiseData = await
vSrc.init(initParams).then(function (response) {
return response;
})
.catch(function (error) {
return error;
});
cb(promiseData);
}
function callInit() {
init(initParams, function (result) {
console.log(result);
if (!Object.keys(result).length) {
console.log("init() successful");
//Next -> call isRecognized() callIsRecognized();
} else {
console.log("init() failure");
// Some error in init, validate input or retry
}
});
}
Errors
|
Reason Code |
Description |
|---|---|
SRCI_ID_MISSING |
The identifier for the SRCi (scrInitiatorId) is missing. |
DPA_ID_MISSING |
srcDpaId and dpaData both are missing. SRC system cannot identify the DPA. |
SRCI_TXN_ID_MISSING |
srciTransactionId is missing. |
Also, see Standard Error Codes.
isRecognized()
Determines whether the consumer is recognized, e.g. by detecting the presence of a local cookie in the browser environment.
If the user is recognized, this method obtains the JSON Web Token (JWT) to optionally pass to precheckout call to other SRC. This method may then (as an optimization) initiate the Get Precheckout Data request.
Method Signature
isRecognized()
Parameters
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
recognitionToken |
List<JWT> |
Optional | List of recognition tokens, such as Merchant Recognition Token (MRT) claims, issued by the SRC System. |
idToken |
JWT | Optional | List of federated ID Tokens issued by the SRCi based on successful consumer identity validation. |
Sample request body with an external identity token
{
"idTokens": [
"ey...j"
]
}
Sample request body with a merchant recognition token
{
"recognitionTokens": [
"ey...j"
]
}
Sample request body with both MRT and external identity tokens
{
"idTokens": [
"ey...u"
],
"recognitionTokens": [
"ey...j"
]
}
Returns
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
recognized |
Boolean |
Required | Whether the consumer is recognized. It is one of the following values:
|
idTokens |
List<JWT> | Conditional | A token that allows the SRC systems to communicate with each other for SRC consumer identity verification; This SRC ID token should be discarded at the end of an SRC checkout transaction. Conditionality: Required if the consumer is recognized; Not need to be present if the consumer is not recognized. |
Recognized
{
"recognized": true,
"idTokens": [
"eyJ...0g"
]
}
Not Recognized
{
"recognized": false,
"idTokens": []
}
Code Example
async function isRecognized(cb) {
const promiseData = await vSrc.isRecognized()
.then(function (data) {
return data;
})
.catch(function (err) {
return err;
});
cb(promiseData);
}
function callIsRecognized() {
isRecognized((response) => {
console.log(response);
if (response.recognized) {
// Store the token -> response.idTokens
// User is recognized. Call getSrcProfile with tokens,
// get masked card details, present in UI callGetSrcProfile(response.idTokens);
} else {
// User is not recognized -> Call identityLookup callIdentityLookup();
}
});
}
Errors
|
Reason Code |
Description |
|---|---|
ACCT_INACCESSIBLE |
The account exists but is not currently accessible, e.g., it is locked. |
See Standard Error Codes.
getSrcProfile()
Obtains the masked card and other account profile data associated with the userId.
The method uses a JWT, or a secure cookie from the browser to identify the user. The returned data can be used for card selection.
Method Signature
getSrcProfile({
optional List<JWT> idTokens;
})
Parameters
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
idTokens |
List<JWT> | Optional | A unique identifier associated with the masked token, mostly used for multi-SRC systems. If not specified, the SRC system may fetch cards based on cookie recognition or not return any cards. The SRCi can provide token IDs received from SRC systems based on consumer recognition performed via OTP (for unrecognized customer flow) or cookie (for recognized customer flow). |
Sample request body with an identity token
{
"idTokens": [
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
]
}
Returns
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
profiles |
List<SrcProfile> |
Required | SRC profiles associated with each recognized user using JWT (idToken). |
srcCorrelationId |
String | Conditional | The unique identifier generated by SRC system to track and link SRC messages. This is used as a transaction identifier assigned by the SRC system for this particular transaction. Conditionality: Returned when the cards are returned successfully. Format: Universially Unique Identifier (UUID) |
Response Example
{
"profiles": [
{
"idToken": "eyJ...g",
"maskedCards": [
{
"cardError": null,
"dateofCardCreated": 1556589662806,
"dateofCardLastUsed": 1563181766426,
"digitalCardData": {
"artHeight": 105,
"artUri": "https://sandbox.secure.checkout.visa.com/VmeCardArts/.png",
"artWidth": 164,
"status": "ACTIVE"
},
"eligible": true,
"maskedBillingAddress": {
"addressId": "e0d...01",
"city": "*****",
"countryCode": "US",
"line1": "Asd*****",
"line2": null,
"line3": null,
"state": "VA",
"zip": "*****"
},
"panBin": null,
"panExpirationMonth": "12",
"panExpirationYear": "2023",
"panLastFour": "1111",
"srcDigitalCardId": "c96...01"
},
{
"cardError": null,
"dateofCardCreated": 1512433695415,
"dateofCardLastUsed": 1562743621206,
"dcf": {
"type": null
},
"digitalCardData": {
"artHeight": 105,
"artUri": "https://sandbox.secure.checkout.visa.com/VmeCardArts/.png",
"artWidth": 164,
"status": "ACTIVE"
},
"eligible": true,
"maskedBillingAddress": {
"addressId": "89e...01",
"city": "*****",
"countryCode": "CA",
"line1": "Can*****",
"line2": null,
"line3": null,
"state": "ON",
"zip": "*****"
},
"panBin": null,
"panExpirationMonth": "09",
"panExpirationYear": "2019",
"panLastFour": "2958",
"srcDigitalCardId": "301...01"
}
],
"maskedConsumer": {
"firstName": "T*****",
"lastName": "K*****",
"fullName": "T***** K*****",
"emailAddress": "the**@gmail.com",
"countryCode": "US",
"languageCode": "en-US"
}
}
],
"srcCorrelationId": "750...01"
}
Code Example
async function getSrcProfile(input, cb) {
let promiseData = await vSrc.getSrcProfile(input)
.then(function (data) {
return data;
})
.catch(function (err) {
return err;
});
cb(promiseData);
}
function callGetSrcProfile(_idTokens) {
getSrcProfile(_idTokens, function (result) {
console.log(result);
// Present the list of cards to user for selection
// List of Cards -> result.profiles[0].maskedCards
});
}
Errors
|
Reason Code |
Description |
|---|---|
SRCI_ID_MISSING |
The identifier for the SRCi (scrInitiatorId) is missing. |
DPA_ID_MISSING |
srcDpaId and dpaData both are missing. SRC system cannot identify the DPA. |
SRCI_TXN_ID_MISSING |
srciTransactionId is missing. |
Also, see Standard Error Codes.
identityLookup()
Performs consumer identity lookup within the SRC System using the provided email address or mobile number.
Method Signature
identityLookup({
required ConsumerIdentity consumerIdentity;
})
Parameters
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
consumerIdentity |
ConsumerIdentity | Required | The consumers identity to be used for identity lookup. |
Returns
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
consumerPresent |
Boolean | Required | Whether the consumer exists in the SRC system. Format: It is one of the following values:
|
| lastUsedCardTimestamp | String | Conditional | Timestamp of the last used Visa card associated with the consumer identity. Conditionality: If no used card is available, this value will not be sent back. Format: UNIX Epoch Timestamp. The value is in milliseconds. |
Response Example
{
"consumerPresent": true,
"lastUsedCardTimestamp": "1737068464"
}
Code for email address lookup
async function identityLookup(input, cb) {
let promiseData = await vSrc.identityLookup(input)
.then(function (data) {
return data;
})
.catch(function (err) {
return err;
});
cb(promiseData);
}
function callIdentityLookup() {
var consumerIdentity = {
identityProvider: 'SRC',
identityValue: '[email protected]',
type: 'EMAIL_ADDRESS'
}
identityLookup(consumerIdentity, function (result) {
console.log(result);
if (result.consumerPresent) {
// Consumer present -> call initiateIdentityValidation callInitiateIdentityValidation();
} else {
// ...
};
});
}
Code for mobile number lookup
async function identityLookup(input, cb) {
let promiseData = await vSrc.identityLookup(input)
.then(function (data) {
return data;
})
.catch(function (err) {
return err;
});
cb(promiseData);
}
function callIdentityLookup() {
var consumerIdentity = {
identityProvider: 'SRC',
identityValue: '16145551212',
type: 'MOBILE_PHONE_NUMBER'
}
identityLookup(consumerIdentity, function (result) {
console.log(result);
if (result.consumerPresent) {
// Consumer present -> call initiateIdentityValidation callInitiateIdentityValidation();
} else {
// ...
};
});
}
Errors
|
Reason Code |
Description |
|---|---|
FRAUD |
The user account was locked or disabled. |
ID_FORMAT_UNSUPPORTED |
Unsupported ID format. |
CONSUMER_ID_MISSING |
Consumer identity is missing in the request. |
ACCT_INACCESSIBLE |
The account exists but is not currently accessible, e.g. it is locked. |
Also, see Standard Error Codes.
initiateIdentityValidation()
Sends a validation code to the specified consumer.
This method sends a one-time password (OTP) to the consumer to start validation. Call this method before using profile data returned from getSrcProfile.
Method Signature
initiateIdentityValidation()
Parameters
None
Returns
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
maskedValidationChannel |
String | Required | Masked email and phone number, if available, used to deliver the validation code (like OTP). Example: "u**@example.com,*********67" |
Response Example
{
"maskedValidationChannel": "use**@example.com,********6676",
"profileCountry": "840",
"profileLocale": "en-US"
}
Code Example
async function initiateIdentityValidation(cb) {
let promiseData = await vSrc.initiateIdentityValidation()
.then(function (data) {
return data;
})
.catch(function (err) {
return err;
});
cb(promiseData);
}
function callInitiateIdentityValidation() {
initiateIdentityValidation(function (result) {
console.log(result); if (result.maskedValidationChannel) {
// Present UI and get the OTP from user
}
});
}
Errors
|
Reason Code |
Description |
|---|---|
OTP_SEND_FAILED |
The OTP could not be sent to the recipient. |
RETRIES_EXCEEDED |
The number of retries for generating the OTP exceeded the limit. |
ID_INVALID |
Invalid ID. |
UNRECOGNIZED_CONSUMER_ID |
Consumer ID could not be recognized. |
ACCT_INACCESSIBLE |
The account exists but is not currently accessible, e.g. it is locked. |
Also, see Standard Error Codes.
completeIdentityValidation()
Receives the validation code sent to the specified consumer, which validates the consumer’s identity..
This method completes the identity validation by receiving the one-time password (OTP) sent to the consumer to start validation. Check the returned code against maskedValidationChannel. Call this method before using profile data returned from getSrcProfile.
Method Signature
completeIdentityValidation({
required String validationData;
})
Parameters
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
validationData |
String | Required | A 6-digit One Time Password (OTP) code, submitted by the consumer. |
Returns
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
idToken |
JWT | Required | SRC ID token created by the SRC system after successful consumer authentication. |
Response Example
{
"idToken": "eyJ...0g"
}
Code Example
function callCompleteIdValidationClicked() {
var otp = document.getElementById('otpBtnVal').value; validationData = {
validationData: otp
};
callCompleteIdValidation(validationData);
}
async function completeIdentityValidation(input, cb) {
let promiseData = await vSrc.completeIdentityValidation(input)
.then(function (data) {
return data;
})
.catch(function (err) {
return err;
});
cb(promiseData);
}
function callCompleteIdValidation(otp) {
completeIdentityValidation(otp, function (result) {
console.log(result); if (!result.error) {
// Store the token -> result.idToken
// call getSrcProfile with tokens,
// get masked card details, present in UI
var idTokens = []; // Or get previous idTokens array, if any idTokens.push(result.idToken);
callGetSrcProfile(idTokens);
} else {
// validation error
}
});
}
Errors
|
Reason Code |
Description |
|---|---|
CODE_INVALID |
The supplied OTP value was invalid. Try again. |
CODE_EXPIRED |
The OTP is expired. Regenerate the OTP and try again. |
RETRIES_EXCEEDED |
The limit for the number of retries for OTP generation was exceeded. |
VALIDATION_DATA_MISSING |
Validation data missing. |
ACCT_INACCESSIBLE |
The account exists but is not currently accessible, e.g. it is locked. |
Also, see Standard Error Codes.
checkout()
This method performs checkout using the selected card. If successful, the response contains summary checkout information and, conditionally, an encrypted payload containing PCI and/or PII data, depending on the configuration of the dpaTransactionOptions.
This method is called after the consumer has chosen a masked card for checkout from the SRC's candidate list. Typically, the SRCi calls back DPA to retrieve any additional data that the DPA may have, such as updated dpaTransactionOptions, based on the selected card. If the DPA returns some data via this callback, then the SRCi should insert that data without modification into the checkout request.
The checkout method also supports a card being provided during the checkout flow. When the combined flow is executed, the client should provide the encrypted card object, instead of ID of the digital card identifier, as an input parameter. The card will be enrolled into the SRC system and used for checkout.
Requirements When Checking Out With a New Card
You must include the following fields in the encrypted card (encryptedCard) parameter:
- primaryAccountNumber
- panExpirationMonth
- panExpirationYear
- cardSecurityCode
- cardholderFullName
An additional field in the consumer parameter is required, depending on the value of the identityType field in the consumerIdentity structure:
- If the identityType field contains EMAIL_ADDRESS, you must pass the mobileNumber field in the consumer parameter.
- If the identityType field contains MOBILE_PHONE_NUMBER, you must pass the emailAddress field in the consumer parameter.
- If no identityType has been defined in getSrcProfile() response, both email address and mobile number must be provided in the consumer parameter.
Optionally, you can include the billing address in the encryptedCard parameter and the appropriate consumer parameter (either mobileNumber or emailAddress).
Note: When checking out with a new card and the Consumer Identity already exists, the checkout() method launches a Visa-hosted user interface to facilitate identity validation via a one-time passcode if not yet performed by the SRCi, similar to calling the idLookup(), initiateIdentityValidation() and completeIdentityValidation() methods.
Requirements When Checking Out With an Existing Card
You must specify the ID of the selected card in the srcDigitalCardId parameter.
Requirements to Initiate Authentication
To initiate authentication, the following fields must be passed to the checkout() API:
- acquirerMerchantId
- acquirerBIN
- merchantName
- transactionAmount
Method Signature
checkout({
optional String srcCorrelationId;
required String srciTransactionId;
conditional String srcDigitalCardId;
conditional String <JWE> encryptedCard;
conditional String <JWT> idToken;
optional Window windowRef;
conditional DpaTransactionOptions dpaTransactionOptions;
conditional Consumer consumer;
optional ComplianceSettings complianceSettings;
conditional AuthenticationMethod authenticationMethod;
optional Address shippingAddress;
optional AssuranceData assuranceData;
optional Address encryptedBillingAddress;
})
Parameters
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
srcCorrelationId |
String | Optional | Correlation ID generated by the SRC system and returned by getSrcProfile. Format: Universally Unique Identifier (UUID) |
srciTransactionId |
String | Required | A unique ID created by the SRCi Format: Alphanumeric, maximum 100 characters |
srcDigitalCardId |
String | Conditional | ID of the selected card. Conditionality: Required if any card is selected from the SRC profile, returned by the SRC system. |
encryptedCard |
JWE<Card> |
Conditional | An encrypted card object, which describes the card to be enrolled with the SRC system. The public key of the target SRC system is used for encryption. This is a JWE with a single composite JSON Card object at the root with card as the claimset element. Conditionality: Required if a new card is added to the SRC profile. For details, see Generating a JWE for PAN Encryption. |
idToken |
JWT | Conditional | A 3rd party federated identity token that allows the SRC systems to communicate with each other for SRC user identity verification. When a card is selected, it might be necessary to pass the ID token corresponding to the selected card, if this information is available in SRCi. Required when a consumer enters a new card, particularly in the following scenarios:
|
windowRef |
Window | Optional | The window handle to open a custom URI in the popup/iframe window. This window hosts the user interface. Visa recommends to pass Windowref as a popup when payloadRequested is ‘Authenticated’ for the SRC system to facilitate authentication and not pass Windowref when payloadRequested is ‘Not_Authenticated’.
|
dpaTransactionOptions |
DpaTransactionOptions | Conditional | DPA configuration data, which overrides the configu ration on the SRC system that was created during DPA registration. Conditionality: Required if not supplied in the init call or if authentication is requested. |
consumer |
Consumer | Conditional | Consumer identity or profile information collected by an SRCi, payment service provider, or merchant. Conditionality: Required when adding a new card. |
complianceSettings |
ComplianceSettings | Optional | Compliance settings that provide data needed for DCF suppression in the add card flow. |
authenticationContext Deprecated |
AuthenticationContext | Transaction context data that SRC System uses to perform authentication; required for some Visa regions, such as Europe. | |
authenticationMethod |
AuthenticationMethod | Conditional | Authentication method indicated by the SRCi to the SRC System. Conditionality: Required if authentication is requested. |
shippingAddress |
Address | Optional | Shipping address. Recommended when SRCi preference to perform authentication and to receive authentication data for the transaction is true; determined by the authenticatedCredentialRequested field in the dpaTransactionOptions structure. |
assuranceData |
AssuranceData | Optional | Information about any risk assessment operations performed by the SRC system. |
| encryptedBillingAddress | Address | Optional | Billing address; it is recommended to include this field when a billing address has not been associated with the selected card. |
Returns
|
Field |
Type |
Mandate |
Description |
|---|---|---|---|
checkoutResponse |
Conditional |
The JWS of the checkout response. Condtionality: Required when dcfActionCode is COMPLETE. |
|
dcfActionCode |
String |
Required |
Indicates the action code received from the DCF. Format: String, it is one of the following values:
|
unbindAppInstance |
Boolean |
Required |
Disassociates the consumer’s application and device from the consumer’s SRC profile on each network. Format: String, it is one of the following values:
|
idToken |
JWT |
Required |
A token that allows the SRC systems to communicate with each other for SRC consumer identity verification; This SRC ID token should be discarded at the end of an SRC checkout transaction. Format: ID Token in JWT Format |
recognitionToken |
JWT |
Conditional |
A Merchant Recognition Token (MRT) issued by the SRC System that uniquely identifies a returning user. The MRT is associated with an SRC Profile and is bound to a specific device. The SRC System shares this token with the SRC Initiator (SRCi) or merchant when the consumer has provided consent to be remembered. |
Response Examples
Full Checkout Returns
{
"checkoutResponse": "eyJ...Q=",
"dcfActionCode": "COMPLETE",
"unbindAppInstance": false
}
Full Checkout Returns for Remember Me
Full checkout returns when complianceType : REMEMBER_ME
{
"checkoutResponse": "eyJ...Q=",
"dcfActionCode": "COMPLETE",
"unbindAppInstance": false,
"recognitionToken": "ey…..Q"
}
Summary Checkout Returns
{
"checkoutResponse": "eyJ..DQ",
"dcfActionCode": "COMPLETE"
}
Decrypted Full Checkout Response
The full checkout response includes the encrypted payload string, which provides the consumer’s information listed in the Payload chapter when the string is decrypted:
{
"srcCorrelationId": "023...02",
"srciTransactionId": "hIZ...u7",
"maskedCard": {
"srcDigitalCardId": "efb...02",
"panBin": "430753",
"panLastFour": "0008",
"panExpirationMonth": "12",
"panExpirationYear": "2023",
"digitalCardData": {
"status": "ACTIVE",
"presentationName": ". ",
"descriptorName": ". "
},
"dateofCardCreated": 1583133529903,
"dateofCardLastUsed": 1585274333914,
"maskedBillingAddress": {
"addressId": "e43. 02",
"countryCode": "US"
},
"eligible": true
},
"shippingAddressZip": "94404",
"shippingCountryCode": "US",
"maskedConsumer": {
"srcConsumerId": "H5p. A=",
"firstName": ". ",
"lastName": ". ",
"fullName": ". ",
"emailAddress": "xyz**@visa.com",
"mobileNumber": {},
"countryCode": "US",
"languageCode": "en-US",
"status": "ACTIVE"
},
"encryptedPayload": "eyJ. nA",
"assuranceData": {
"cardVerificationResults": "01"
},
"isGuestCheckout": false,
"isNewUser": false
}
Decrypted Summary Checkout Response
The summary checkout response does not include the encrypted payload string.
{
"srcCorrelationId": "ed6...01",
"srciTransactionId": "5cc...8e",
"maskedCard": {
"srcDigitalCardId": "857...01",
"panBin": "400552",
"panLastFour": "3375",
"panExpirationMonth": "12",
"panExpirationYear": "2023",
"digitalCardData": {
"status": "ACTIVE",
"presentationName": "New Last",
"artUri": "https://sandbox.secure.checkout.visa.com/VmeCardArts/. png",
"artHeight": 105,
"artWidth": 164
},
"pendingEvents": [
"PENDING_CARDHOLDER_AUTHENTICATION",
"PENDING_CONSUMER_IDV",
"PENDING_CONSUMER_DEVICE_BINDING"
],
"dateofCardCreated": 1564445093245,
"dateofCardLastUsed": 1565813106869,
"maskedBillingAddress": {
"addressId": "5c4. 01",
"line1": "901*****",
"city": "*****",
"state": "CA",
"zip": "*****",
"countryCode": "US"
},
"eligible": true
},
"shippingAddressZip": "94404",
"shippingCountryCode": "US",
"maskedConsumer": {
"srcConsumerId": "H5p. uA=",
"firstName": "F*****",
"lastName": "L*****",
"fullName": "F***** L*****",
"emailAddress": "din**@visa.com",
"mobileNumber": {},
"countryCode": "US",
"languageCode": "en-US",
"status": "ACTIVE"
},
"assuranceData": {
"cardVerificationResults": "01"
},
"isGuestCheckout": false,
"isNewUser": false
}
Assurance Data for 3DS in the Decrypted Checkout Response:
3DS provides additional fields in the response.
"assuranceData": {
"verificationData": [
{
"methodResults": {
"transStatus": "Y",
"dsTransId": "06c...16",
"acsTransId": "6f5...09"
}
}
],
"eci": "05"
}
Code Examples
async function checkout(input, cb)
const promiseData = await vSrc.checkout(input)
.then(function (data) {
return data;
})
.catch(function (err) {
return err;
});
cb(promiseData);
}
function callCheckout() {
var checkoutInput = {}; // Check SDK Specs for input format checkout(checkoutInput, function (result) {
console.log(result);
// Check response for payload or for any errors
});
}
Checkout input when existing card is selected:
{
"srciActionCode": "",
"srcCorrelationId": "376...01",
"srciTransactionId": "ns9...WJ",
"srcDigitalCardId": "e83...01",
"encryptedCard": "",
"idToken": "eyJ...eA",
"windowRef": "",
"dpaTransactionOptions": {
"dpaLocale": "en_US",
"dpaAcceptedBillingCountries": [
"US",
"CA"
],
"dpaAcceptedShippingCountries": [
"US",
"CA"
],
"dpaBillingPreference": "FULL",
"dpaShippingPreference": "FULL",
"consumerNameRequested": true,
"consumerEmailAddressRequested": true,
"consumerPhoneNumberRequested": true,
"paymentOptions": {
"dynamicDataType": "CARD_APPLICATION_CRYPTOGRAM_LONG_FORM",
"dpaPanRequested": false
},
"reviewAction": "continue",
"checkoutDescription": "Sample checkout",
"transactionType": "PURCHASE",
"orderType": "REAUTHORIZATION",
"payloadTypeIndicator": "FULL",
"transactionAmount": {
"transactionAmount": "99.95",
"transactionCurrencyCode": "USD"
},
"merchantOrderId": "ABC12345",
"merchantCategoryCode": "...",
"merchantCountryCode": "US"
}
}
Checkout input when existing card is selected – Issuer OTP/Online Banking version:
{
"srciTransactionId": "86e09698-54c3-46f1-8b8d-97380d57fc88",
"srcDigitalCardId": "6e928267-9daf-1681-02dc-190c859cdf01",
"windowRef": "",
"dpaTransactionOptions": {
"transactionAmount": {
"transactionAmount": "99.95",
"transactionCurrencyCode": "USD"
},
"authenticationPreferences": {
"payloadRequested": "AUTHENTICATED"
},
"acquirerMerchantId": "12345678",
"acquirerBIN": "455555",
"merchantName": "NewM"
}
}
Note: The merchant or SRCI can include "payloadRequested": "AUTHENTICATED" in the checkout request. Merchants or SRCI must include "dynamicDataType": "CARD_APPLICATION_CRYPTOGRAM_LONG_FORM" in init() API.
Checkout input when existing card is selected – 3DS version:
{
"srciActionCode": "",
"srcCorrelationId": "376...01",
"srciTransactionId": "ns9...WJ",
"srcDigitalCardId": "e83...01",
"encryptedCard": "",
"idToken": "eyJ...eA",
"windowRef": "",
"dpaTransactionOptions": {
"dpaLocale": "en_US",
"dpaAcceptedBillingCountries": [
"US",
"CA"
],
"dpaAcceptedShippingCountries": [
"US",
"CA"
],
"dpaBillingPreference": "FULL",
"dpaShippingPreference": "FULL",
"consumerNameRequested": true,
"consumerEmailAddressRequested": true,
"consumerPhoneNumberRequested": true,
"paymentOptions": {
"dynamicDataType": "CARD_APPLICATION_CRYPTOGRAM_LONG_FORM",
"dpaPanRequested": false
},
"reviewAction": "continue",
"checkoutDescription": "Sample checkout",
"transactionType": "PURCHASE",
"orderType": "REAUTHORIZATION",
"payloadTypeIndicator": "FULL",
"transactionAmount": {
"transactionAmount": "99.95",
"transactionCurrencyCode": "USD"
},
"merchantOrderId": "ABC12345",
"merchantCategoryCode": "...",
"merchantCountryCode": "US",
"merchantName": "Test Merchant",
"acquirerBIN": "455555",
"acquirerMerchantId": "12345678",
"authenticationPreferences": {
"authenticationMethods": [
{
"authenticationMethodType": "3DS",
"authenticationSubject": "CARDHOLDER",
"methodAttributes": {
"challengeIndicator": "01"
}
}
],
"payloadRequested": "AUTHENTICATED"
}
}
}
Checkout input when new card is added:
{
"srcCorrelationId": "376...01",
"srciTransactionId": "416...16",
"srcDigitalCardId": "",
"encryptedCard": "eyJ...mQ",
"idToken": "",
"windowRef": "",
"dpaTransactionOptions": {
"dpaLocale": "en_US",
"dpaAcceptedBillingCountries": [
"US",
"CA"
],
"dpaAcceptedShippingCountries": [
"US",
"CA"
],
"dpaBillingPreference": "FULL",
"dpaShippingPreference": "FULL",
"consumerNameRequested": true,
"consumerEmailAddressRequested": true,
"consumerPhoneNumberRequested": true,
"paymentOptions": {
"dynamicDataType": "CARD_APPLICATION_CRYPTOGRAM_LONG_FORM",
"dpaPanRequested": false
},
"reviewAction": "continue",
"checkoutDescription": "Sample checkout",
"transactionType": "PURCHASE",
"orderType": "REAUTHORIZATION",
"payloadTypeIndicator": "FULL",
"transactionAmount": {
"transactionAmount": "99.95",
"transactionCurrencyCode": "USD"
},
"merchantOrderId": "ABC12345",
"merchantCategoryCode": "...",
"merchantCountryCode": "US"
}
}
Checkout input when new card is added – 3DS version:
{
"srcCorrelationId": "376...01",
"srciTransactionId": "416...16",
"srcDigitalCardId": "",
"encryptedCard": "eyJ...mQ",
"idToken": "",
"windowRef": "",
"dpaTransactionOptions": {
"dpaLocale": "en_US",
"dpaAcceptedBillingCountries": [
"US",
"CA"
],
"dpaAcceptedShippingCountries": [
"US",
"CA"
],
"dpaBillingPreference": "FULL",
"dpaShippingPreference": "FULL",
"consumerNameRequested": true,
"consumerEmailAddressRequested": true,
"consumerPhoneNumberRequested": true,
"paymentOptions": {
"dynamicDataType": "CARD_APPLICATION_CRYPTOGRAM_LONG_FORM",
"dpaPanRequested": false
},
"reviewAction": "continue",
"checkoutDescription": "Sample checkout",
"transactionType": "PURCHASE",
"orderType": "REAUTHORIZATION",
"payloadTypeIndicator": "FULL",
"transactionAmount": {
"transactionAmount": "99.95",
"transactionCurrencyCode": "USD"
},
"merchantOrderId": "ABC12345",
"merchantCategoryCode": "...",
"merchantCountryCode": "US",
"merchantName": "Test Merchant",
"acquirerBIN": "455555",
"acquirerMerchantId": "12345678",
"authenticationPreferences": {
"authenticationMethods": [
{
"authenticationMethodType": "3DS",
"authenticationSubject": "CARDHOLDER",
"methodAttributes": {
"challengeIndicator": "01"
}
}
],
"payloadRequested": "AUTHENTICATED"
}
}
}
Unencrypted Card Information in the Request
{
"card": {
"billingAddress": {
"addressId": "",
"name": "Firstname Lastname ",
"line1": "1 Streetname Street",
"line2": "",
"line3": "",
"city": "Miami",
"state": "FL",
"countryCode": "US",
"zip": "33126",
"createTime": "",
"lastUsedTime": ""
},
"cardSecurityCode": "099",
"cardholderFullName": "Firstname Lastname ",
"panExpirationMonth": 10,
"panExpirationYear": 2025,
"primaryAccountNumber": "...",
"cardholderFirstName": "Firstname",
"cardholderLastName": "Lastname",
"paymentAccountReference": ""
}
}
Consumer Information in the Request
{
"consumer": {
"emailAddress": "[email protected]",
"consumerIdentity": {
"identityProvider": "SRC",
"identityType": "EMAIL_ADDRESS",
"identityValue": "[email protected]"
},
"mobileNumber": {
"phoneNumber": "1..0",
"countryCode": "1"
},
"countryCode": "US",
"languageCode": "EN",
"firstName": "Alex",
"lastName": "Miller",
"fullName": "Alex Miller"
}
}
Compliance Settings in the Request
{
"srcCorrelationId": "",
"srciTransactionId": "c3a...9c",
"srcDigitalCardId": "",
"encryptedCard": "eyJ...Gw",
"idToken": "",
"windowRef": "",
"consumer": {
"emailAddress": "foi...r.com",
"consumerIdentity": {
"identityProvider": "SRC",
"identityType": "EMAIL_ADDRESS",
"identityValue": "foi...r.com"
},
"mobileNumber": {
"phoneNumber": "408...22",
"countryCode": "1"
},
"nationalIdentifier": "USA",
"countryCode": "US",
"languageCode": "EN",
"firstName": "PSP",
"lastName": "Tester",
"fullName": "Test"
},
"dpaTransactionOptions": {
"dpaLocale": "US",
"dpaAcceptedBillingCountries": [
"US",
"CA"
],
"dpaAcceptedShippingCountries": [
"US",
"CA"
],
"dpaBillingPreference": "FULL",
"dpaShippingPreference": "FULL",
"consumerNameRequested": true,
"consumerEmailAddressRequested": true,
"consumerPhoneNumberRequested": true,
"paymentOptions": {
"dpaDynamicDataTtlMinutes": 2,
"dynamicDataType": "CARD_APPLICATION_CRYPTOGRAM_LONG_FORM",
"dpaPanRequested": false
},
"reviewAction": "continue",
"checkoutDescription": "Sample checkout",
"transactionType": "PURCHASE",
"orderType": "REAUTHORIZATION",
"payloadTypeIndicator": "SUMMARY",
"transactionAmount": {
"transactionAmount": "99.95",
"transactionCurrencyCode": "USD"
},
"merchantOrderId": "ABC12345",
"merchantCategoryCode": "merchantCategoryCode",
"merchantCountryCode": "US"
},
"payloadTypeIndicatorCheckout": "SUMMARY",
"recipientIdCheckout": "",
"payloadTypeIndicatorPayload": "SUMMARY",
"recipientIdPayload": "",
"assuranceData": {
"verificationData": [
{
"verificationType": "CARDHOLDER",
"verificationEntity": "01",
"verificationMethod": "01",
"verificationResults": "01",
"verificationTimestamp": "1646416550"
}
]
},
"srciActionCode": "NEW_USER",
"complianceSettings": {
"complianceResources": [
{
"complianceType": "TERMS_AND_CONDITIONS",
"uri": "usa.visa.com/legal/checkout/terms-of-service.html"
},
{
"complianceType": "PRIVACY_POLICY",
"uri": "usa.visa.com/legal/global-privacy-notice.html"
},
{
"complianceType": "REMEMBER_ME",
"uri": "visa.checkout.com/privacy"
}
]
}
}
Errors
|
Reason Code |
Description |
|---|---|
CARD_ADD_FAILED |
Unable to add card. |
CARD_SECURITY_CODE_MISSING |
Card security must be supplied. |
CARD_INVALID |
Invalid card number. |
CARD_EXP_INVALID |
Invalid card expiration date. |
CARD_MISSING |
Either encryptedCard or srcDigitalCardId is required but is missing. |
CARD_NOT_RECOGNIZED |
The specified card was not recognized. |
ACCT_INACCESSIBLE |
The account exists but is not currently accessible, e.g., is locked. |
MERCHANT_DATA_INVALID |
Merchant data is invalid. |
UNABLE_TO_CONNECT |
Unable to connect to or launch card experience. |
AUTH_INVALID |
Invalid federated ID token. |
TERMS_AND_CONDITIONS_NOT_ACCEPTED |
Terms and conditions not accepted. |
| IDENTITY_VALIDATION_REQUIRED | Consumer identity validation is required. |
Also, see Standard Error Codes.
authenticate()
Performs authentication using the selected card and returns authentication data.
Method Signature
authenticate({
optional String srcClientId;
optional String serviceId;
optional String srcCorrelationId;
required String srciTransactionId;
conditional String authenticationSessionId;
conditional AccountReference accountReference;
conditional AuthenticationContext authenticationContext;
required AuthenticationMethod authenticationMethod;
})
Parameters
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
srcClientId |
String | Optional | Reference identifier. Format: Universally Unique Identifier (UUID) |
serviceId |
String | Optional | Service identifier associated to an SRC systemspecific configuration. Format: Universally Unique Identifier (UUID) |
srcCorrelationId |
String | Optional | Correlation ID generated by the SRC system and returned by getSrcProfile. Format: Universally Unique Identifier (UUID) |
srciTransactionId |
String | Required | A unique ID created by the SRCi Format: Alphanumeric, maximum 100 characters |
authenticationSessionId |
String | Conditional | Authentication session ID. Conditionality: Required if available from a previously initiated authentication event. |
accountReference |
AccountReference | Conditional | Account reference. Conditionality: Required if authenticationSessionId is not available. |
authenticationContext |
AuthenticationContext | Conditional | Transaction context data that SRC System uses to perform authentication. Conditionality: Required if authenticationSessionId is not available. |
authenticationMethod |
AuthenticationMethod | Required | Authentication method indicated by the SRCi to the SRC System. |
Returns
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
srcCorrelationId |
String | Required | The SRC Correlation ID returned by the SRC system Format: Universally Unique Identifier (UUID) |
srciTransactionId |
String | Required | A unique ID created by the SRCi Format: Alphanumeric, maximum 100 characters |
authenticationResult |
String | Required | Authentication status. Format: It is one of the following values:
|
authenticationStatus |
String | Required | Authentication status. Format: It is one of the following values:
|
assuranceData |
AssuranceData | Required | Information about any risk assessment operations performed by the SRC system. |
methodResults |
MethodResults | Conditional | Method results. Conditionality: Returned when 3DS authentication was performed. |
Examples
Request Payload
{
"srciTransactionId": "c21...9e",
"srcCorrelationId": "de2...01",
"authenticationMethod": {
"authenticationMethodType": "EMAIL_OTP",
"authenticationSubject": "CARDHOLDER",
"methodAttributes": {
"otpValue": "553401",
"stepUpIdentifier": "MGE...="
}
}
}
Response Payload
{
"srcCorrelationId": "de2...01",
"srciTransactionId": "c21...9e",
"authenticationResult": "AUTHENTICATED",
"authenticationStatus": "COMPLETE",
"assuranceData": {
"verificationData": [
{
"verificationType": "CARDHOLDER",
"verificationEntity": "03",
"verificationEvents": [
"01"
],
"verificationMethod": "04",
"verificationResults": "01",
"verificationTimestamp": "1692781875"
}
]
}
Errors
|
Reason Code |
Description |
|---|---|
ACCT_REF_FORMAT_UNSUPPORTED |
Unsupported accountReference |
ACCT_REF_MISSING |
The accountReference parameter is missing |
AUTHENTICATION_METHOD_ NOT_SUPPORTED |
The supplied authentication method doesn’t match the authenti cation context |
OTP_SEND_FAILED |
The OTP could not be sent to the recipient |
RETRIES_EXCEEDED |
The limit for the number of retries exceeded |
VAL_DATA_MISSING |
The validationData parameter is missing |
VAL_DATA_EXPIRED |
The validationData is expired |
VAL_DATA_INVALID |
The supplied validationData is invalid |
AUTHENTICATE_FAILURE |
Default error case for all other reasons of authenticate failure. |
unbindAppInstance()
Disassociates the Consumer application or Device from the Consumer’s SRC Profile.
Method Signatures
unbindAppInstance({
optional JWT idToken
})
Parameters
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
idToken |
JWT | Optional | The token ID returned by the checkout method that indicates which SRC Profile and SRC System the app instance should be unbound from. If not provided, the app instance will be unbound from the Visa SRC System. Format: ID Token in JWT Format |
Returns
|
Field |
Type | Mandate |
Description |
|---|---|---|---|
srcCorrelationId |
String | Required | The SRC Correlation ID returned by the SRC system Format: Universally Unique Identifier (UUID) |
Examples
Input
{
"idToken": "eyJ...eA"
}
Returns
{
"srcCorrelationId": "1b3...01"
}
Code Example
async function unbindAppInstance(input, cb) {
let promiseData = await vSrc.unbindAppInstance(input).then(function(data) {
return data;
}).catch(function(err) {
return err;
});
cb(promiseData);
}
function callUnbind(idToken) {
unbindAppInstance(idToken, function(result) {
console.log(result);
if (!result.error) {
// Prompt user that the device has been disassociated
} else {
// Prompt error
}
});
}
Errors
|
Reason Code |
Description |
|---|---|
AUTH_INVALID |
Invalid federated ID token. |
ACCT_INACCESSIBLE |
The account exists but is not currently accessible, e.g. it is locked. |
JavaScript API Error Handling
An error response notifies the caller that the action relating to the promise has failed. Use the error.reason field to drive your error handling logic. Errors such as INVALID_PARAMETER or INVALID_REQUEST are considered integration errors.
Error Structure and Usage
Error reasons and messages appear in a standard error structure, which is returned when the API request could not be handled. For programmatic actions, you should only rely on the value in error.reason. Errors are also provided with a human readable error description in error.message field; however, this field should be used only to understand the problem. You may prefer to provide your own description based on the value in error.reason. In some cases, the error.details structure provides additional information.
Error Response Fields
|
Field |
Description |
|---|---|
message |
The internal error message, which should not be displayed or used in the logic of your digital terminal; it is provided as a convenience. Format: String |
reason |
Mnemonic identifying the kind of error; use this field to trigger error handling logic in your digital terminal. Format: String |
details |
One or more pairs of field name and associated error message that identify validation errors. Format: details structure. |
The details structure provides additional information, if it is returned:
|
Field |
Description |
|---|---|
location |
The value of this field uses an XPATH expression to point to the field that fails validation. Format: String |
message |
The specific error associated with the field. Format: String |
Example
{
"error": {
"reason": "CARD_MISSING",
"message": "Either encryptedCard or srcDigitalCardId is required but is missing",
"details": [
{
"code": "custom",
"message": "Either encryptedCard or srcDigitalCardId is required but is missing",
"path": [
"srcDigitalCardId"
]
}
]
},
"unbindAppInstance": false
}
Standard Error Codes
API-specific error codes are listed in each API. All APIs can return the following standard error codes in addition to API-specific ones:
|
Reason |
Description |
|---|---|
UNKNOWN_ERROR |
Unknown error. |
REQUEST_TIMEOUT |
Request timeout. |
SERVER_ERROR |
General server error |
INVALID_PARAMETER |
The value provided for one or more request parameters is considered invalid. This error is also generated in case of a missing required field. Typically, this is an integration error; whenever possible, should provide client-side validation to avoid a round trip to the server. For user errors, handle this error by prompting the user to change the value. |
INVALID_REQUEST |
The server could not interpret the request. Usually, these are the cases, when a data field has to be in a particular format but is not. Examples include:
The message field may provide additional clarification of what part or field of the request is considered incorrect. Please, refer to the API specification for the structure, format, and constraints on the API request. |
AUTH_ERROR |
The server understands the request, but cannot authenticate. |
NOT_FOUND |
The requested resource/business entity does not exist. The resource might also be hidden for security reasons. |
RATE_LIMIT_EXCEEDED |
Too many requests have been sent in a given amount of time. Intended for use with rate limiting schemes.
Retry delay in milliseconds = (2 ^ n) * 1000 + randomDelayMs, where n is your retry count, such as 0, 1, 2, 3, …, and random DelayMs is random delay in milliseconds, such as an integer between 0 and 1,000. |
SERVICE_ERROR |
An error occurred on the server. Either show a generic message, or retry the same request again (it might succeed). |
Unencrypted Payload Contents
Payload
Payload provides metadata that includes the information based on if the consumer uses the PAN, or token.
|
Field |
Description |
|---|---|
card |
Card data associated with the PAN used for the purchase. Supplied if the indicated payload type is FULL or PAYMENT and the SRC system determines that a PAN-based payload is returned. Note: Either a Card or a Payment Token credential is returned, never both Format: Card structure |
token |
Payment Token data associated with the PAN used for the purchase. Supplied if the indicated payload type is FULL or PAYMENT and the SRC system determines that a Payment Token- based payload is returned. Note: Either a Card or a Payment Token credential is returned, never both Format: PaymentToken structure |
paymentAccountReference |
The Payment Account Reference (PAR) associated with the cardholder account that uniquely identifies the account to which the payment card is associated. Format: String |
dynamicData |
Dynamic data (cryptograms) applicable for transactions. If Click to Pay facilitates Issuer Authentication (3DS), then CAVV will be provided in the dynamic data. Format: List of DynamicData structures |
billingAddress |
Billing address of the selected card. Format: Address structure |
shippingAddress |
Shipping address of the consumer; supplied when available, for example:
Format: Address structure |
consumer |
Consumer's information. Format: Consumer structure |
panExpirationYear |
The year when the account number is set to expire. Format: Numeric; 4 digits |
threeDsOutputData |
(Deprecated) Result of 3DS payment authentication. |
Decrypted PAN Payload Example
{
"card": {
"primaryAccountNumber": "430...08",
"panExpirationMonth": "12",
"panExpirationYear": "2023",
"cardholderFullName": ". ",
"cardholderFirstName": ". ",
"cardholderLastName": ". "
},
"billingAddress": {
"addressId": "e43. 02",
"countryCode": "US"
},
"shippingAddress": {
"addressId": "5c4. 01",
"line1": ". ",
"city": ". ",
"state": ". ",
"zip": ". ",
"countryCode": "US"
},
"consumer": {
"firstName": ". ",
"lastName": ". ",
"fullName": ". ",
"emailAddress": "[email protected]",
"mobileNumber": {},
"countryCode": "US",
"languageCode": "en-US"
},
"threeDsOutputData": []
}
Decrypted Token Payload Example
{
"token": {
"paymentToken": "489...69",
"tokenExpirationMonth": "12",
"tokenExpirationYear": "2024"
},
"paymentAccountReference": "V00...23",
"dynamicData": [
{
"dynamicData": "AgA...A=",
"dynamicDataType": "CARD_APPLICATION_CRYPTOGRAM_LONG_FORM",
"dynamicDataExpiration": "Thu Jun 25 03:23:13 GMT 2020"
},
{
"dynamicDataValue": "Y2F...g=",
"dynamicDataType": "CARDHOLDER_AUTHENTICATION_CRYPTOGRAM"
}
],
"billingAddress": {
"addressId": "b3f...02",
"countryCode": "GB"
},
"shippingAddress": {
"addressId": "89e...01",
"line1": "...",
"city": "...",
"state": "ON",
"zip": "K1G 4B5",
"countryCode": "CA"
},
"consumer": {
"firstName": "...",
"lastName": "...",
"fullName": ". ",
"emailAddress": ". @gmail.com",
"mobileNumber": {},
"countryCode": "US",
"languageCode": "en-US"
},
"threeDsOutputData": []
}
Decrypted 3DS Assurance Data
3DS provides additional fields in the response.
"assuranceData": {
"verificationData": [
{
"methodResults": {
"transStatus": "Y",
"dsTransId": "06c...16",
"acsTransId": "6f5...09"
}
}
],
"eci": "05"
}
Appendix
Appendix A - Decrypting the SRC Payload
Java Example for SRC Payload Symmetric Decryption
The following Java code, using the JOSE4j API jose4j-0.6.5.jar, provides an example of decrypting the payload.
package ...;
import java.security.MessageDigest;
import javax.crypto.spec.SecretKeySpec; import org.jose4j.jwe.JsonWebEncryption;
public class DecryptJWE {
public static String decryptJWE(String secret, String jwe) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] digest = md.digest(secret.getBytes("UTF-8"));
JsonWebEncryption jweDecryptor = new JsonWebEncryption(); jweDecryptor.setCompactSerialization(jwe); jweDecryptor.setKey(new SecretKeySpec(digest, "AES"));
return jweDecryptor.getPlaintextString();
}
}
Node.js Example for SRC Payload Symmetric Decryption
var jose = require('node-jose'); var crypto = require('crypto');
module.exports = {
decryptJWE: function (secret, payload) {
return new Promise(function (resolve, reject) {
var SS_Hashed =
crypto.createHash('sha256').update(secret).digest('hex'); jose.JWK.asKey({
kty: 'oct', k: Buffer.from(SS_Hashed,
'hex')
})
.then(function (key) {
jose.JWE.createDecrypt(key)
.decrypt(payload)
.then(function (result) {
resolve(result);
})
.catch(function (error) {
reject(error);
});
})
.catch(function (error) {
reject(error);
});
});
}
};
Appendix B - Generating a JWE for PAN Encryption
Encrypting the PAN
This code snippet is used for creating PAN JWE on the browser side. This example uses the node-jose library in browserify format.
// getNodeJoseLib(); Get node-jose library in browserify format
// Code to generate JWE using node-jose library
/**
* @param kid kid for public certificate. Contact Visa representative for this value
* @param keys Public key to be used for encryption.
Contact Visa representative for *
@param payload Card information to be encrypted,
{"card":{ "primaryAccountNumber":"424..2", "panExpirationMonth":"10",
.."panExpirationYear":"2022", "cardSecurityCode":"123",
.."cardholderFullName":"cardholder name"}
}
* @param cb Returning encrypted PAN as JWE string to this callback function */
function generateJWE(kid, keys, payload, cb) {
const keyInput = {
"kty": "RSA",
"e": keys.e, // Public key exponent "kid": kid,
"use": "enc",
"n": keys.n, // Public key modulus "alg": "RSA-OAEP-256",
"ext_content": "payload"
};
jose.JWK.asKey(keyInput)
.then((key) => {
console.log("JWK ", JSON.stringify(key)); const contentAlg = 'A25..CM';
let options = {
format: 'compact',
contentAlg: contentAlg, fields: {
kid: key.kid, typ: 'JOSE',
iat: Date.now(), alg: key.alg, enc: contentAlg
}
};
jose.JWE.createEncrypt(options, key).update(payload).
final().then((serializedJWE) => {
console.log("Encrypted data: ", JSON.stringify(serializedJWE));
cb(serializedJWE);
}, (error) => {
console.log("Error occurred: ", error.message); cb(null);
});
}, (error) => {
console.log("Error occurred: ", error.message); cb(null);
})
}
Appendix C - JWE Composition Details
JSON Web Encryption (JWE) Using Shared Secret
The encryption key provided during onboarding is used to encrypt and decrypt payloads. JSON Web Encryption (JWE) content should be signed or encrypted using the shared secret that was provided to client at the time of onboarding.
Introduction
Visa uses JSON Web Encryption (JWE) to encode sensitive field level information. Encrypted input parameters should be constructed before sending them in API requests.
Visa Installment Solutions APIs use the following naming convention for fields that require encryption in this document.
"enc<FIELD>" : "JWE ( ... ) "
See the complete specification for JWE: https://tools.ietf.org/html/draft-ietf-jose-json-web- encryption-40.
JWE Composition and Conventions
BASE64URL (UTF8 (JWE Header)) || ‘.’ ||
BASE64URL (JWE Encrypted Key) || ‘.’ || BASE64URL (JWE IV) || ‘.’ ||
BASE64URL (JWE Ciphertext) || ‘.’ || BASE64URL (JWE Authentication Tag)
The conventions are as follows:
- BASE64URL encoding with NO padding.
- Compact serialization style (elements separated by “.”)
- Use a CEK (Content Encryption Key) of 256bits size.
- Authentication Tag will be generated as an additional output of the AES-GCM-256 encryption. Size of this field is 128 bits.
- All String to byte and vice-versa conversions are done with UTF-8 charset.
Note: The JWE Protected Header is input as the AAD (Additional Authenticated Data) parameter of the authenticated encryption (AES-GCM) of the “text to encrypt”.
Sample JWE Header for Asymmetric Encryption
"header": {
"alg": "RSA-OAEP-256""typ": "JOSE",
"kid": "50charAPIKey", // API key "enc": "A256GCM"
}
Sample JWE Header for Symmetric Encryption
"header": {
"alg": "AGCM256KW""typ": "JOSE",
"tag": "<128bitvalue>", // HMAC generated from applying AES-256-GCM-KW to the CEK
"kid": "50charAPIKey", // API key "enc": "AGCM256"
}
Sample JWE Body
- encrypted_key: base64 encoded form. CEK encrypted using AGCM256KW (alg) algorithm and the CEK IV
- iv: base64 encoded form. IV for the text encryption. Size of IV is to be 96 bit Base64 encoded form
- ciphertext: encrypted blob generated using the AES-GCM encryption (enc) of the text to encrypt
- tag: base64 encoded form. HMAC generated using the AES-GCM encryption of the text to encrypt. The size of the tag should be 128 bits
“encrypted_key”: “UghIOgu ... MR4gp_A=”, “iv”: “AxY8DctDa….GlsbGljb3RoZQ=”,
“ciphertext”: “KDlTthhZTGufMY…….xPSUrfmqCHXaI9wOGY=”, “tag”: “Mz-VPPyU4…RlcuYv1IwIvzw=”