Getting Started

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.

Creating the Server-Side Context

The first step in integrating with
Microform Integration
is developing the server-side code that generates the capture context. The capture context is a digitally signed JWT that provides authentication, one-time keys, and the target origin to the
Microform Integration
application. The target origin is the protocol, URL, and port number (if used) of the page on which you will host the microform. You must use the
https://
protocol unless you use
http://localhost
. For example, if you are serving Microform on example.com, the target origin is
https://example.com.
You can also configure microform to filter out cards by designating the accepted card types.
Sample
Microform Integration
projects are available for download in the Flex samples on GitHub.
  1. Send an authenticated POST request to
    https://apitest.cybersource.com
    /microform/v2/sessions
    . Include the target origin URL and at least one accepted card type in the content of the body of the request.
    For example:
            
    { "targetOrigins": ["https://www.example.com"], "allowedCardNetworks": ["VISA"], "clientVersion": "v2" }
    Optionally, you can include multiple target origins and a list of your accepted card types. For example:
            
    { "targetOrigins": ["https://www.example.com", "https://www.example.net"] "allowedCardNetworks": ["VISA", "MAESTRO", "MASTERCARD", "AMEX", "DISCOVER", "DINERSCLUB", "JCB", "CUP", "CARTESBANCAIRES", "CARNET" ], "clientVersion": "v2" }
  2. Pass the capture context response data object to your front-end application. The capture context is valid for 15 minutes.

AFTER COMPLETING THE TASK

Important Security Note:
  • Ensure that all endpoints within your ownership are secure with some kind of authentication so they cannot be called at will by bad actors.
  • Do not pass the
    targetOrigin
    in any external requests. Hard code it on the server side.

Validating the Capture Context

The capture context that you generated is a JSON Web Token (JWT) data object. The JWT is digitally signed using a public key. The purpose is to ensure the validity of the JWT and confirm that it comes from
Cybersource
. When you do not have a key specified locally in the JWT header, you should follow best cryptography practices and validate the capture context signature.
To validate a JWT, you can obtain its public key. This public RSA key is in JSON Web Key (JWK) format. This public key is associated with the capture context on the
Cybersource
domain.
To get the public key of a capture context from the header of the capture context itself, retrieve the key ID associated with the public key. Then, pass the key ID to the
public-keys
endpoint.
Example
From the header of the capture context, get the key ID (
kid
) as shown in this example:
      
{
"kid": "3g"
, "alg": "RS256" }
Append the key ID to the endpoint
/flex/v2/public-keys/
3g
. Then, call this endpoint to get the public key.
IMPORTANT
When validating the public key, some cryptographic methods require you to convert the public key to PEM format.

Resource

Pass the key ID (kid), that you obtained from the capture context header, as a path parameter, and send a GET request to the
/public-keys
endpoint:
  • Test:
    https://apitest.cybersource.com
    /flex/v2/public-keys/
    {kid}
  • Production:
    https://api.cybersource.com
    /flex/v2/public-keys/
    {kid}
The resource returns the public key. Use this public RSA key to validate the capture context.

Example

    
eyJraWQiOiIzZyIsImFsZyI6IlJTMjU2In0.eyJmbHgiOnsicGF0aCI6Ii9mbGV4L3YyL3Rva2VucyIsImRhdGEiOiI2bUFLNTNPNVpGTUk5Y3RobWZmd2doQUFFRGNqNU5QYzcxelErbm8reDN6WStLOTVWQ2c5bThmQWs4czlTRXBtT21zMmVhbEx5NkhHZ29oQ0JEWjVlN3ZUSGQ5YTR5a2tNRDlNVHhqK3ZoWXVDUmRDaDhVY1dwVUNZWlZnbTE1UXVFMkEiLCJvcmlnaW4iOiJodHRwczovL3Rlc3RmbGV4LmN5YmVyc291cmNlLmNvbSIsImp3ayI6eyJrdHkiOiJSU0EiLCJlIjoiQVFBQiIsInVzZSI6ImVuYyIsIm4iOiJyQmZwdDRjeGlkcVZwT0pmVTlJQXcwU1JCNUZqN0xMZjA4U0R0VmNyUjlaajA2bEYwTVc1aUpZb3F6R3ROdnBIMnFZbFN6LVRsSDdybVNTUEZIeTFJQ3BfZ0I3eURjQnJ0RWNEanpLeVNZSTVCVjNsNHh6Qk5CNzRJdnB2Smtqcnd3QVZvVU4wM1RaT3FVc0pfSy1jT0xpYzVXV0ZhQTEyOUthWFZrZFd3N3c3LVBLdnMwNmpjeGwyV05STUIzTS1ZQ0xOb3FCdkdCSk5oYy1uM1lBNU5hazB2NDdiYUswYWdHQXRfWEZ0ZGItZkphVUVUTW5WdW9fQmRhVm90d1NqUFNaOHFMOGkzWUdmemp2MURDTUM2WURZRzlmX0tqNzJjTi1OaG9BRURWUlZyTUtiZ3QyRDlwWkJ1d2gzZlNfS3VRclFWTVdPelRnT3AzT2s3UVFGZ1EiLCJraWQiOiIwOEJhWXMxbjdKTUhjSDh1bkcxc1NDUVdxN2VveWQ1ZyJ9fSwiY3R4IjpbeyJkYXRhIjp7InRhcmdldE9yaWdpbnMiOlsiaHR0cHM6Ly93d3cudGVzdC5jb20iXSwibWZPcmlnaW4iOiJodHRwczovL3Rlc3RmbGV4LmN5YmVyc291cmNlLmNvbSJ9LCJ0eXBlIjoibWYtMC4xMS4wIn1dLCJpc3MiOiJGbGV4IEFQSSIsImV4cCI6MTYxNjc3OTA5MSwiaWF0IjoxNjE2Nzc4MTkxLCJqdGkiOiJ6SG1tZ25uaTVoN3ptdGY0In0.GvBzyw6JKl3b2PztHb9rZXawx2T817nYqu6goxpe4PsjqBY1qeTo19R-CP_DkJXov9hdJZgdlzlNmRY6yoiziSZnGJdpnZ-pCqIlC06qrpJVEDob3O_efR9L03Gz7F5JlLOiTXSj6nVwC5mRlcP032ytPDEx5TMI9Y0hmBadJYnhEMwQnn_paMm3wLh2v6rfTkaBqd8n6rPvCNrWMOwoMdoTeFxku-d27jlA95RXqJWfhJSN1MFquKa7THemvTX2tnjZdTcrTcpgHlxi22w7MUFcnNXsbMouoaYiEdAdSlCZ7LCXrS1Brdr_FWDp7v0uwqHm7OALsGrw8QbGTafF8w
Base64 decode the capture context to get the key ID (
kid
) from its header:
      
{
"kid": "3g"
, "alg": "RS256" }
Get its public key from
/flex/v2/public-keys/3g
:
      
{ "kty":"RSA", "use":"enc", "kid":"3g", "n":"ir7Nl1Bj8G9rxr3co5v_JLkP3o9UxXZRX1LIZFZeckguEf7Gdt5kGFFfTsymKBesm3Pe 8o1hwfkq7KmJZEZSuDbiJSZvFBZycK2pEeBjycahw9CqOweM7aKG2F_bhwVHrY4YdKsp _cSJe_ZMXFUqYmjk7D0p7clX6CmR1QgMl41Ajb7NHI23uOWL7PyfJQwP1X8HdunE6ZwK DNcavqxOW5VuW6nfsGvtygKQxjeHrI-gpyMXF0e_PeVpUIG0KVjmb5-em_Vd2SbyPNme nADGJGCmECYMgL5hEvnTuyAybwgVwuM9amyfFqIbRcrAIzclT4jQBeZFwkzZfQF7MgA6QQ", "e":"AQAB" }

Setting Up the Client Side

You can integrate
Microform Integration
with your native payment acceptance web page or mobile application.

Web Page

Initiate and embed
Microform Integration
into your payment acceptance web page.
  1. Add the
    Microform Integration
    JavaScript library to your page by loading it directly from
    Cybersource
    . You should do this dynamically per environment by using the asset path returned in the JWT from
    /microform/v2/sessions
    . For example:
              
    ctx": [ { "data": { "clientLibrary": https://testflex.
    cybersource
    .com/microform/bundle/v2/flex-microform.min.js, ...
    • Test
      :
    • Production
      :
  2. Create the HTML placeholder objects to attach to the microforms.
    Microform Integration
    attaches the microform fields to containers within your HTML. Within your HTML checkout, replace the payment card and CVN tag with a simple container.
    Microform Integration
    uses the container to render an iframe for secured credit card input. The following example contains simple
    div
    tags to define where to place the PAN and CVN fields within the payment acceptance page:
    . See Example: Checkout Payment Form.
  3. Invoke the Flex SDK by passing the capture context that was generated in the previous step to the microform object.
    var flex = new Flex(captureContext);
  4. Initiate the microform object with styling to match your web page.
    After you create a new Flex object, you can begin creating your Microform. You will pass your baseline styles and ensure that the button matches your merchant page.
    var microform = flex.microform({ styles: myStyles });
  5. Create and attach the microform fields to the HTML objects through the Microform Integration JavaScript library.
              
    var number = microform.createField('number', { placeholder: 'Enter card number' }); var securityCode = microform.createField('securityCode', { placeholder: '•••' }); number.load('#number-container'); securityCode.load('#securityCode-container');
  6. Create a function for the customer to submit their payment information, and invoke the tokenization request to
    Microform Integration
    for the transient token.

Mobile Application

To initiate and embed
Microform Integration
into native payment acceptance mobile application, follow the steps for web page setup, and ensure that these additional requirements are met:
  • The card acceptance fields of PAN and CVV must be hosted on a web page.
  • The native application must load the hosted card entry form web page in a web view.

AFTER COMPLETING THE TASK

As an alternative, you can use the Mobile SDKs hosted on GitHub:

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.
        

Checkout

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
        
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: Token Payload with Multiple Card Types
        
{ "iss": "Flex/08", "exp": 1661350495, "type": "mf-2.0.0", "iat": 1661349595, "jti": "1C174LLWIFFR9OV0V0IJQOY0IB1JQP70ZNF4TBI3V6H3AIOY0W1T6306325F91C0", "content": { "paymentInformation": { "card": { "expirationYear": { "value": "2023" }, "number": { "detectedCardTypes": [ "042", "036" ], "maskedValue": "XXXXXXXXXXXX1800", "bin": "501767" }, "securityCode": {}, "expirationMonth": { "value": "01" } } } } }
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" } }