Microform Integration
replaces the primary account number (PAN) or card verification number (CVN) field, or both, in your payment input form. It has two components:
  • Server-side component to create a capture context request that contains limited-use public keys from the
    Flex API
    v2 suite.
  • Client-side JavaScript library that you integrate into your digital payment acceptance web page for the secure acceptance of payment information.
Version Numbering
Microform Integration
follows Semantic Versioning.
Cybersource
recommends referencing the latest major version, v2, to receive the latest patch and minor versions automatically. Referencing a specific patch version is not supported.
Upgrade Paths
Because of semantic versioning, every effort will be made to ensure that upgrade paths and patch releases are backwards-compatible and require no code change. During initial 0.x.x releases, if this is not possible, we will provide clear upgrade steps.

Getting Started Examples

Example: Node.js REST Code Snippet

try { var instance = new
cybersourceRestApi
.KeyGenerationApi(configObj); var request = new
cybersourceRestApi
.GeneratePublicKeyRequest(); request.encryptionType = 'RsaOaep256'; request.targetOrigin = 'http://localhost:3000'; var opts = []; opts['format'] = 'JWT'; console.log('\n*************** Generate Key ********************* '); instance.generatePublicKey(request, opts, function (error, data, response) { if (error) { console.log('Error : ' + error); console.log('Error status code : ' + error.statusCode); } else if (data) { console.log('Data : ' + JSON.stringify(data)); console.log('CaptureContext: '+data.keyId); res.render('index', { keyInfo: JSON.stringify(data.keyId)}); } console.log('Response : ' + JSON.stringify(response)); console.log('Response Code Of GenerateKey : ' + response['status']); callback(error, data); }); } catch (error) { console.log(error); }

Example: Checkout Payment Form

This simple payment form captures the name, PAN, CVN, month, and year, and a pay button for submitting the information.
<h1>Checkout</h1> <div id="errors-output" role="alert"></div> <form action="/token" id="my-sample-form" method="post"> <div class="form-group"> <label for="cardholderName">Name</label> <input id="cardholderName" class="form-control" name="cardholderName" placeholder="Name on the card"> <label id="cardNumber-label">Card Number</label> <div id="number-container" class="form-control"></div> <label for="securityCode-container">Security Code</label> <div id="securityCode-container" class="form-control"></div> </div> <div class="form-row"> <div class="form-group col-md-6"> <label for="expMonth">Expiry month</label> <select id="expMonth" class="form-control"> <option>01</option> <option>02</option> <option>03</option> <option>04</option> <option>05</option> <option>06</option> <option>07</option> <option>08</option> <option>09</option> <option>10</option> <option>11</option> <option>12</option> </select> </div> <div class="form-group col-md-6"> <label for="expYear">Expiry year</label> <select id="expYear" class="form-control"> <option>2021</option> <option>2022</option> <option>2023</option> </select> </div> </div> <button type="button" id="pay-button" class="btn btn-primary">Pay</button> <input type="hidden" id="flexresponse" name="flexresponse"> </form>

Example: Creating the Pay Button with Event Listener

payButton.addEventListener('click', function() { // Compiling MM & YY into optional parameters var 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(); } }); });

Example: Customer-Submitted Form

<script> // Variables from the HTML form var form = document.querySelector('#my-sample-form'); var payButton = document.querySelector('#pay-button'); var flexResponse = document.querySelector('#flexresponse'); var expMonth = document.querySelector('#expMonth'); var expYear = document.querySelector('#expYear'); var errorsOutput = document.querySelector('#errors-output'); // the capture context that was requested server-side for this transaction var captureContext = <%-keyInfo%> ; // custom styles that will be applied to each field we create using Microform var 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 var flex = new Flex(captureContext); var microform = flex.microform({ styles: myStyles }); var number = microform.createField('number', { placeholder: 'Enter card number' }); var 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 var 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>

Example: Token Payload

{ // token id to be used with
Cybersource
services "jti": "408H4LHTRUSHXQZWLKDIN22ROVXJFLU6VLU00ZWL8PYJOZQWGPS9CUWNASNR59K4", // when the token was issued "iat": 1558612859, // when the token will expire "exp": 1558613759, // info about the stored data associated with this token // any sensitive data will be masked "data": { "number": "444433XXXXXX1111", "type": "001", "expirationMonth": "06", "expirationYear": "2025" } }

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" }

Example: Validating the Transient Token

This example shows how to extract the signature key from the capture context and use the key to validate the transient token object returned from a successful microform interaction.
console.log('Response TransientToken: ' + req.body.transientToken); console.log('Response CaptureContext: ' + req.body.captureContext); // Validating Token JWT Against Signature in Capture Context var capturecontext = req.body.captureContext; var transientToken = req.body.transientToken; // Extracting JWK in Body of Capture Context var ccBody = capturecontext.split('.')[1]; console.log('Body: ' + ccBody); var atob = require('atob'); var ccDecodedValue = JSON.parse( atob(ccBody)); var jwk = ccDecodedValue.flx.jwk; console.log('CaptureContext JWK: ' + JSON.stringify(jwk)); // Converting JWK to PEM var jwkToPem = require('jwk-to-pem'), jwt = require('jsonwebtoken'); var pem = jwkToPem(jwk); // Validating JWT var validJWT = jwt.verify(transientToken, pem); console.log('Validated Resposonse: ' + JSON.stringify(validJWT));

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" } }