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 theFlex APIv2 suite.
- Client-side JavaScript library that you integrate into your digital payment acceptance web page for the secure acceptance of payment information.
Implementing
Microform Integration
is a three-step process: 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.
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.- Send an authenticated POST request to. Include the target origin URL and at least one accepted card type in the content of the body of the request.https://apitest.cybersource.com/microform/v2/sessions
ADDITIONAL INFORMATION
For example:{ "targetOrigins": ["https://www.example.com"], "allowedCardNetworks": ["VISA"], "clientVersion": "v2.0" }ADDITIONAL INFORMATION
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.0" } - Pass the capture context response data object to your front-end application. The capture context is valid for 15 minutes.
ADDITIONAL INFORMATION
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 thetargetOriginin 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/
. Then,
call this endpoint to get the public key. 3g
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.- Add theMicroform IntegrationJavaScript library to your page by loading it directly fromCybersource. See Version Numbering. You should do this dynamically per environment by using the asset path returned in the JWT from/microform/v2/sessions. For example:
ADDITIONAL INFORMATION
ctx": [ { "data": { "clientLibrary": https://testflex.cybersource.com/microform/bundle/v2/flex-microform.min.js, ...- Test:<script src="https://testflex.cybersource.com/microform/bundle/v2/flex-microform.min.js"></script>
- Production:<script src="https://flex.cybersource.com/microform/bundle/v2/flex-microform.min.js"></script>
- Create the HTML placeholder objects to attach to the microforms.
ADDITIONAL INFORMATION
Microform Integrationattaches the microform fields to containers within your HTML. Within your HTML checkout, replace the payment card and CVN tag with a simple container.Microform Integrationuses the container to render an iframe for secured credit card input. The following example contains simpledivtags to define where to place the PAN and CVN fields within the payment acceptance page:<div id="number-container" class="form-control"></div>. See Example: Checkout Payment Form. - Invoke the Flex SDK by passing the capture context that was generated in the previous step to the microform object.
ADDITIONAL INFORMATION
var flex = new Flex(captureContext); - Initiate the microform object with styling to match your web page.
ADDITIONAL INFORMATION
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 }); - Create and attach the microform fields to the HTML objects through the Microform Integration JavaScript library.
ADDITIONAL INFORMATION
var number = microform.createField('number', { placeholder: 'Enter card number' }); var securityCode = microform.createField('securityCode', { placeholder: '•••' }); number.load('#number-container'); securityCode.load('#securityCode-container'); - Create a function for the customer to submit their payment information, and invoke the tokenization request toMicroform Integrationfor 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:
- Android sample: https://github.com/CyberSource/flex-v2-android-sample
- iOS sample: https://github.com/
- Android sample: https://github.com/
Transient Token Time Limit
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.
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.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
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.
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. See Example: Capture Context Public Key.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.Using the Transient Token
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", } |
Getting Started Examples
Example: Node.js REST Code Snippet
try { var instance = newcybersourceRestApismartpayFuseRestApi.KeyGenerationApi(configObj); var request = newcybersourceRestApismartpayFuseRestApi.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); }
Back to Creating the Server-Side Context
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>
Back to Setting Up the Client Side.
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(); } }); });
Back to Transient Token Time Limit.
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>
Back to Transient Token Time Limit.
Example: Token Payload
{ // token id to be used withCybersourceservices "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" } }
Back to Transient Token Response Format.
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" } } } } }
Back to Transient Token Response Format.
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" }
Back to Validating the Transient Token.
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));
Back to Validating the Transient Token.
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" } }
Back to Using the Transient Token.