Transient Tokens for Accepting Card Information

The response to a successful customer interaction with
Microform Integration
is a transient token. The transient token is a reference to the payment data that is collected on your behalf. Tokens allow secure card or check payments to occur without risk of exposure to sensitive payment information. The transient token is a short-term token that expires after 15 minutes. This reduces your PCI burden/responsibility and ensures that sensitive information is not exposed to your back-end systems.

Transient Token Time Limit

The sensitive data associated with the transient token is available for use only for 15 minutes or until one successful authorization occurs. Before the transient token expires, its data is still usable in other non-authorization services. After 15 minutes, you must prompt the customer to restart the checkout flow.
Example: Creating the Pay Button with Event Listener for Accepting Card Information
payButton.('click', function () { // Compiling MM & YY into optional parameters const options = { expirationMonth: document.querySelector('#expMonth').value, expirationYear: document.querySelector('#expYear').value }; // microform.createToken(options, function (err, token) { if (err) { // handle error console.error(err); errorsOutput.textContent = err.message; } else { // At this point you may pass the token back to your server as you wish. // In this example we append a hidden input to the form and submit it. console.log(JSON.stringify(token)); flexResponse.value = JSON.stringify(token); form.submit(); } }); });
When the customer submits the form,
Microform Integration
securely collects and tokenizes the data in the loaded fields as well as the options supplied to the
createToken()
function. The month and year are included in the request. If tokenization succeeds, your callback receives the token as its second parameter. Send the token to your server, and use it in place of the PAN when you use supported payment services.
Example: Customer-Submitted Form for Accepting Card Information
<script> // Variables from the HTML form const form = document.querySelector('#my-sample-form'); const payButton = document.querySelector('#pay-button'); const flexResponse = document.querySelector('#flexresponse'); const expMonth = document.querySelector('#expMonth'); const expYear = document.querySelector('#expYear'); const errorsOutput = document.querySelector('#errors-output'); // the capture context that was requested server-side for this transaction const captureContext = <% -keyInfo %> ; // custom styles that will be applied to each field we create using Microform const myStyles = { 'input': { 'font-size': '14px', 'font-family': 'helvetica, tahoma, calibri, sans-serif', 'color': '#555' }, ':focus': { 'color': 'blue' }, ':disabled': { 'cursor': 'not-allowed' }, 'valid': { 'color': '#3c763d' }, 'invalid': { 'color': '#a94442' } }; // setup Microform const flex = new Flex(captureContext); const microform = flex.microform({ styles: myStyles }); const number = microform.createField('number', { placeholder: 'Enter card number' }); const securityCode = microform.createField('securityCode', { placeholder: '•••' }); number.load('#number-container'); securityCode.load('#securityCode-container'); // Configuring a Listener for the Pay button payButton.addEventListener('click', function () { // Compiling MM & YY into optional paramiters const options = { expirationMonth: document.querySelector('#expMonth').value, expirationYear: document.querySelector('#expYear').value }; // microform.createToken(options, function (err, token) { if (err) { // handle error console.error(err); errorsOutput.textContent = err.message; } else { // At this point you may pass the token back to your server as you wish. // In this example we append a hidden input to the form and submit it. console.log(JSON.stringify(token)); flexResponse.value = JSON.stringify(token); form.submit(); } }); }); </script>

Transient Token Response Format

The transient token is issued as a JSON Web Token (RFC 7519). A JWT is a string consisting of three parts that are separated by dots:
  • Header
  • Payload
  • Signature
JWT example:
xxxxx.yyyyy.zzzzz
The payload portion of the token is an encoded Base64url JSON string and contains various claims.
IMPORTANT
When you integrate with Cybersource APIs, Cybersource recommends that you dynamically parse the response for the fields that you are looking for. Additional fields may be added in the future.
You must ensure that your integration can handle new fields that are returned in the response. While the underlying data structures will not change, you must also ensure that your integration can handle changes to the order in which the data is returned.
The internal data structure of the JWT can expand to contain additional data elements. Ensure that your integration and validation rules do not limit the data elements contained in responses.
Example: Token Payload for Accepting Card Information
{ "iss": "Flex/00", "exp": 1728911080, "type": "mf-2.0.0", "iat": 1728910180, "jti": "1D1S6JK9RL6EK667H1I370689A63I2I8YLFJSPJ1EUSKIPMJJWEL670D16E89AF8", "content": { "paymentInformation": { "card": { "expirationYear": { "value": "2025" }, "number": { "detectedCardTypes": [ "001" ], "maskedValue": "XXXXXXXXXXXX1111", "bin": "411111" }, "securityCode": {}, "expirationMonth": { "value": "01" } } } } }

Validating the Transient Token

After receiving the transient token, validate its integrity using the public key embedded within the capture context created at the beginning of this flow. This verifies that
Cybersource
issued the token and that no data tampering occurred during transit.
Example: Capture Context Public Key
"jwk": { "kty": "RSA", "e": "AQAB", "use": "enc", "n": "3DhDtIHLxsbsSygEAG1hcFqnw64khTIZ6w9W9mZNl83gIyj1FVk-H5GDMa85e8RZFxUwgU_zQ0kHLtONo8SB52Z0hsJVE9wqHNIRoloiNPGPQYVXQZw2S1BSPxBtCEjA5x_-bcG6aeJdsz_cAE7OrIYkJa5Fphg9_pxgYRod6JCFjgdHj0iDSQxtBsmtxagAGHjDhW7UoiIig71SN-f-gggaCpITem4zlb5kkRVvmKMUANe4B36v4XSSSpwdP_H5kv4JDz_cVlp_Vy8T3AfAbCtROyRyH9iH1Z-4Yy6T5hb-9y3IPD8vlc8E3JQ4qt6U46EeiKPH4KtcdokMPjqiuQ", "kid": "00UaBe20jy9VkwZUQPZwNNoKFPJA4Qhc" }
Use the capture context public key to cryptographically validate the JWT provided from a successful
microform.createToken
call. You might have to convert the JSON Web Key (JWK) to privacy-enhanced mail (PEM) format for compatibility with some JWT validation software libraries.
The
Cybersource
SDK has functions that verify the token response. You must verify the response to ensure that no tampering occurs as it passes through the cardholder device. Do so by using the public key generated at the start of the process.
Example: Validating the Transient Token
console.log('Response TransientToken: ' + req.body.transientToken); console.log('Response CaptureContext: ' + req.body.captureContext); // Validating Token JWT Against Signature in Capture Context const capturecontext = req.body.captureContext; const transientToken = req.body.transientToken; // Extracting JWK in Body of Capture Context const ccBody = capturecontext.split('.')[1]; console.log('Body: ' + ccBody); const atob = require('atob'); const ccDecodedValue = JSON.parse( atob(ccBody)); const jwk = ccDecodedValue.flx.jwk;

Using the Transient Token to Process a Paymemt

After you validate the transient token, you can use it in place of the PAN with payment services for 15 minutes. See Transient Token Time Limit.
When the consuming service receives a request containing a transient token, it retrieves the tokenized data and injects the values into your request before processing, and none of the sensitive data is stored on your systems. In some scenarios, the
jti
value contained in the JWT transient token response must be extracted and used instead of the entire JWT.
Connection Method
Field
Simple Order API
tokenSource_transientToken
SCMP API
transient_token
REST API with Transient Token JSON Web Token
"tokenInformation": {
"transientTokenJwt": "eyJraWQiOiIwNzRsM3p5M2xCRWN5d1gxcnhXNFFoUmJFNXJLN1NmQiIsImFsZyI6IlJTMjU2In0.eyJkYXRhIjp7ImV4cGlyYXRpb25ZZWFyIjoiMjAyMSIsIm51bWJlciI6IjQxMTExMVhYWFhYWDExMTEiLCJleHBpcmF0aW9uTW9udGgiOiIwNSIsInR5cGUiOiIwMDEifSwiaXNzIjoiRmxleC8wOCIsImV4cCI6MTU4ODcwMjkxNSwidHlwZSI6Im1mLTAuMTEuMCIsImlhdCI6MTU4ODcwMjAxNSwianRpIjoiMUU0Q0NMSUw4NFFXM1RPSTFBM0pUU1RGMTZGQUNVNkUwNU9VRVNGWlRQNUhIVkJDWTQwUTVFQjFBRUMzNDZBMCJ9.FB3b2r8mjtvqo3_k05sRIPGmCZ_5dRSZp8AIJ4u7NKb8E0-6ZOHDwEpxtOMFzfozwXMTJ3C6yBK9vFIPTIG6kydcrWNheE2Pfort8KbxyUxG-PYONY-xFnRDF841EFhCMC4nRFvXEIvlcLnSK6opUUe7myKPjpZI1ijWpF0N-DzZiVT8JX-9ZIarJq2OI0S61Y3912xLJUKi5c2VpRPQOS54hRr5GHdGJ2fV8JZ1gTuup_qLyyK7uE1VxI0aucsyH7yeF5vTdjgSd76ZJ1OUFi-3Ij5kSLsiX4j-D0T8ENT1DbB_hPTaK9o6qqtGJs7QEeW8abtnKFsTwVGrT32G2w"
}
REST API with JSON Web Token ID
"tokenInformation": {
    "jti": "1E3GQY1RNKBG6IBD2EP93C43PIZ2NQ6SQLUIM3S16BGLHTY4IIEK5EB1AE5D73A4",    
}
Example: Authorization with a Transient Token Using the REST API
{ "clientReferenceInformation": { "code": "TC50171_3" }, "orderInformation": { "amountDetails": { "totalAmount": "102.21", "currency": "USD" }, "billTo": { "firstName": "Tanya", "lastName": "Lee", "address1": "1234 Main St.", "locality": "Small Town", "administrativeArea": "MI", "postalCode": "98765-4321", "country": "US", "district": "MI", "buildingNumber": "123", "email": "tanyalee@example.com", "phoneNumber": "987-654-3210" } }, "tokenInformation": { "transientTokenJwt": "eyJraWQiOiIwN0JwSE9abkhJM3c3UVAycmhNZkhuWE9XQlhwa1ZHTiIsImFsZyI6IlJTMjU2In0.eyJkYXRhIjp7ImV4cGlyYXRpb25ZZWFyIjoiMjAyMCIsIm51bWJlciI6IjQxMTExMVhYWFhYWDExMTEiLCJleHBpcmF0aW9uTW9udGgiOiIxMCIsInR5cGUiOiIwMDEifSwiaXNzIjoiRmxleC8wNyIsImV4cCI6MTU5MTc0NjAyNCwidHlwZSI6Im1mLTAuMTEuMCIsImlhdCI6MTU5MTc0NTEyNCwianRpIjoiMUMzWjdUTkpaVjI4OVM5MTdQM0JHSFM1T0ZQNFNBRERCUUtKMFFKMzMzOEhRR0MwWTg0QjVFRTAxREU4NEZDQiJ9.cfwzUMJf115K2T9-wE_A_k2jZptXlovls8-fKY0muO8YzGatE5fu9r6aC4q7n0YOvEU6G7XdH4ASG32mWnYu-kKlqN4IY_cquRJeUvV89ZPZ5WTttyrgVH17LSTE2EvwMawKNYnjh0lJwqYJ51cLnJiVlyqTdEAv3DJ3vInXP1YeQjLX5_vF-OWEuZfJxahHfUdsjeGhGaaOGVMUZJSkzpTu9zDLTvpb1px3WGGPu8FcHoxrcCGGpcKk456AZgYMBSHNjr-pPkRr3Dnd7XgNF6shfzIPbcXeWDYPTpS4PNY8ZsWKx8nFQIeROMWCSxIZOmu3Wt71KN9iK6DfOPro7w" } }