Menu

Cardinal Cruise Documentation

The Cardinal Cruise libraries make it easy for you to activate CCA (Cardinal Consumer Authentication) into your checkout flow. In a few simple steps, you will be prepared to provide a great user experience to your consumers, while providing the benefits of 3-D Secure.

Getting Started

Last updated - 2016-08-17

Prerequisites

Authentication within the Cardinal Cruise ecosystem is handled via JWT (JSON Web Token). In order to initialize the system for processing, it is required that a JWT is generated and passed into the first call in the chain.

Within the JWT, you will be required to specify your OrgUnitId, APIKey, & APIIdentifier. If you were not provided these values upon registration, please contact your account manager.

For more information on generating a JWT, please see the following instructions:

Activation Steps

It is Cardinal's goal to get you up and running with CCA as quickly, and painlessly, as possible. This section of the document will outline the simple steps necessary in order to take advantage of Cardinal Cruise.

Step 1 - Include the JavaScript

This script tag can be placed directly on your page, or as part of a bundling tool within your framework of choice.

<script src="https://includestest.ccdc02.com/cardinalcruise/v1/songbird.js"></script>

Step 2 - Configure Cardinal Cruise

There are a number of configuration options for Cardinal Cruise. During your development, you will most likely want control over the logging volume from the library. Configure logging as follows:

For available configuration options, please see here.

Cardinal.configure({
	logging: {
		level: "on"
	}
});

Step 3 - Setup the Initial Call to Cardinal Cruise

Next we need to authenticate you and set up CCA for use. Calling Cardinal.setup() will begin communicating with Cardinal to ensure your consumer's experience is seamless. By the time the consumer is ready to checkout, all pre-processing necessary will be completed.

NOTE: the following function must be placed after the script include shown in Step 1.

Cardinal.setup("init", {
	jwt: [Insert your JWT here]
});

A common way to pass your JWT into this JavaScript function is to place the JWT value into a hidden input on page load. Within Cardinal.setup(), you can then look for that element and select its value.

Hidden Input Example:

<input type="hidden" id="JWTContainer" value="[Insert your JWT here]" />
Cardinal.setup("init", {
	jwt: document.getElementById("JWTContainer").value
});

Once you have added the calling function for Cardinal.setup(), you can then subscribe to the completion of it. You may want to do this to perform additional processing on the page after all of your payment options have successfully loaded.

Cardinal.on("payments.setupComplete", function() {
	// For example, you may have your Submit button disabled on page load. Once you are setup
	// for CCA, you may then enable it. This will prevent users from submitting their order
	// before CCA is ready.
    document.getElementById("submitButton").disabled = false;
});

Step 4 - Invoke CCA (Cardinal Consumer Authentication)

Now that Cardinal Cruise is configured and set up on your page, we are now ready to accept a consumer payment. You have the ability to invoke CCA on any event, such as a button click.

The function to invoke is as follows:

Cardinal.start("cca", data);

In this example, the second argument of data is a Request Order Object. You can construct this object ahead of time or pass it directly, as shown here:

Cardinal.start("cca", {
  OrderDetails: {
    OrderNumber: "1234567890"
  },
  Consumer: {
    Account: {
    AccountNumber: "XXXXXXXXXXXX1234",
    ExpirationMonth: "01",
    ExpirationYear: "2099"
  }
}
  ...
});

Note: AccountNumber in the above example is splatted only for security in this document. You must pass the full AccountNumber. The Order Object used in the example was shortened for brevity.

As seen previously in Cardinal.setup() to retrieve the JWT value, a similar method is commonly used to fill the Order Object.

var order = {
  OrderDetails: {
    OrderNumber: document.getElementById("OrderNumber").value
  },
  Consumer: {
    Account: {
    AccountNumber: document.getElementById("AccountNumber").value,
    ExpirationMonth: document.getElementById("ExpirationMonth").value,
    ExpirationYear: document.getElementById("ExpirationYear").value
  }
 }
   ...
}
Note: Request Order Object was shortened for brevity.

Step 5 - Handle CCA Response

Once the Cardinal.start() call completes, we need to handle its response. This is done by adding an event handler to your page for the payments.validated event. Inside of this event is where you will place your logic instructing the page what to do on a CCA success and a CCA failure. The first argument of the payments.validated event will contain the response Payload, which has been decoded from the JWT for your convenience. Using these values, you will be able to conduct conditional logic in each CCA response case on the front end. The second argument passed into the payments.validated event is the full response JWT returned to you from Cardinal. This value should be passed back to the server side and validated prior to accepting any success cases. We recommend that any values sent to a third party come from the JWT since you can detect when values have been tampered with.

Before moving forward with a transaction be sure to verify the response values by validating the JWT on the server side.

Cardinal.on("payments.validated", function (data, jwt) {
	switch(data.ActionCode){
	  case "SUCCESS":
	  // Handle successful authentication scenario
	  break;
    
	  case "NOACTION":
	  // Handle unenrolled scenario
	  break;
    
	  case "FAILURE":
	  // Handle authentication failed or error encounter scenario
	  break;
    
	  case "ERROR":
	  // Handle service level error
	  break;
  }
});

Further Reading

This guide has walked you through the basics of integrating Cardinal Cruise, however we have additional documentation we recommend you review before releasing your product.

Available Configuration Options

Configuration Key Type Description Possible Values Default
logging object An object for configuring logging settings
logging.level String Set the level of logging to output to console.
  • Off - Disable logging, use this in Production environments
  • On - Output some helpful logs to console
  • verbose - Output all logs to console
Off
timeout Int Set the default timeout value in milliseconds for making requests to Cardinal 8000

Generating a Server JWT

Cardinal Cruise utilizes a JWT to handle authentication and to assist in passing secure data between you and Cardinal. The JWT must be created server-side and sent to the front end to be injected into the JavaScript initialization code. Creating a JWT client-side is not a valid activation option. Each order should have a uniquely generated JWT associated with it.

The current intergration you're reviewing uses JWT's as a method of transmitting transactional data. The below examples will reflect the passing of transactional data. Please be aware if you're integrating more than 1 Songbird.js call you may have different JWT data requirements between the 2 calls.

Learn more about JWT's

JWT Fields

A valid Cardinal Cruise JWT used for to pass transactional data must have the following elements:

Required Fields

Please note that each Claim key is case sensitive.

Claim Description
jti JWT Id - This is created by you and is a unique identifier that can be used to reference a particular JWT within Cardinal's system.
iat Issued At Time - This is a timestamp of when the JWT was created. A JWT will be considered expired by Cardinal after 2hrs.
iss Issuer - Identifies who is generating the JWT. This field should contain your API Identifier value provided to you during merchant registration.
OrgUnitId Organization Unit Id - This value was provided to you during merchant registration.
Payload The JSON Order object that describes the Order the JWT is being created for. We strongly recommend to include as much data within the JWT as possible.
ObjectifyPayload A Boolean value that indicates the type of the Payload claim. When set to true the Payload field is an object literal. When set to false the Payload claim is a serialized object. Refer to your Jwt libraries documentation on how it handles object claims. Some libraries will automatically serialize the object while others do not.

Optional Fields

The following Claims are available for use but are not currently required for a valid JWT:

Claim Description
exp Expiration - The time you would like Cardinal to consider your JWT expired. This value is only valid when it is less than Cardinal's max expiration time of 2hrs. This can be leveraged to create a shorter expiration period if your security requirements prefer a shorter TTL (Time-To-Live).
ReferenceId This is an optional field that can be used to reference this session.
ConfirmUrl The return url Cardinal should redirect users to when the user has been redirected away from your website to complete an alternative payment brand. This url will need to receive a post with the response JWT.

Cardinal Credentials

As part of registering for Cardinal Cruise you will have received 3 values that are used to authenticate yourself with Cardinal. Failure to properly authenticate using these values will result in API failures and will prevent transaction processing.

API Identifier - A non-secure value that should be passed within the JWT under the iss claim.

Org Unit Id - a non-secure value that should be passed within the JWT under the OrgUnitId claim.

API Key - A secure value that should only ever be known between you and Cardinal. This value should never be rendered or displayed anywhere your users could find it. The API Key should only be used to sign the JWT and to verify a JWT signature from Cardinal. It should never be included within the JWT itself.

JWT Payload Example

Below is an example of the JSON content of a basic JWT Payload where we are passing an object within the Payload claim:


{
	"jti": "a5a59bfb-ac06-4c5f-be5c-351b64ae608e",
	"iat": 1448997865,
	"iss": "56560a358b946e0c8452365ds",
	"OrgUnitId": "565607c18b946e058463ds8r",
	"Payload": {
		"OrderDetails": {
			"OrderNumber": "0e5c5bf2-ea64-42e8-9ee1-71fff6522e15",
			"Amount": "1500",
			"CurrencyCode": "840"
		}
	},
	"ObjectifyPayload": true,
	"ReferenceId": "c88b20c0-5047-11e6-8c35-8789b865ff15",
	"exp": 1449001465,
	"ConfirmUrl": 'https://mywebsite.com/confirmHandler'
}

Below is an example of the JSON content of a basic JWT Payload where we are passing a string within the Payload claim:


{
	"jti": "29311a10-5048-11e6-8c35-8789b865ff15",
	"iat": 1448997875,
	"iss": "56560a358b946e0c8452365ds",
	"OrgUnitId": "565607c18b946e058463ds8r",
	"Payload": "{\"OrderDetails\":{\"OrderNumber\":\"19ec6910-5048-11e6-8c35-8789b865ff15\",\"Amount\":\"1500\",\"CurrencyCode\":\"840\"}}",
	"ObjectifyPayload" false
	"ReferenceId": "074fda80-5048-11e6-8c35-8789b865ff15"
	"exp":1449001465,
	"ConfirmUrl": 'https://mywebsite.com/confirmHandler'
}

Generating a Server JWT in .NET

We recommend using an existing third party library to assist you in generating a JWT. Some of our recommendations are:

JSON Web Token Handler - www.nuget.org

JWT - GitHub.com

The JWT.io website contains a list of additional approved libraries, with their feature sets. Check it out here.


// This sample code was written using the JSON Web Token Handler library.

using System.Configuration;
using System.Web.Mvc;
using CardinalCruiseDemoSite.Helpers;
using CardinalCruiseDemoSite.Models.View;

namespace CardinalCruiseDemoSite.Controllers
{
    public class HomeController : Controller
    {
        private readonly JwtHelper _jwtHelper = new JwtHelper();

        public ActionResult Index()
        {
            var apiKey = ConfigurationManager.AppSettings["APIKey"];
            var apiIdentifier = ConfigurationManager.AppSettings["APIIdentifier"];
            var orgUnitId = ConfigurationManager.AppSettings["OrgUnitId"];

            var jwt = _jwtHelper.GenerateJwt(apiKey, apiIdentifier, orgUnitId);

            return View(new CardinalCruiseViewModel {JWT = jwt});
        }
    }
}

namespace CardinalCruiseDemoSite.Models.View
{
    public class CardinalCruiseViewModel
    {
        public string JWT { get; set; }
    }
}

This is an example of a JWT object class.


using System;
using System.Collections.Generic;
using CardinalCruiseDemoSite.Models;
using JWT;

namespace CardinalCruiseDemoSite.Helpers
{
    public class JwtHelper
    {
        public string GenerateJwt(string apiKey, string apiIdentifier, string orgUnitId)
        {
            var payload = new Dictionary<string, object>
            {
                {"exp", DateTime.UtcNow.AddDays(365).ToUnixTime()},
                {"iat", DateTime.Now.ToUnixTime()},
                {"jti", Guid.NewGuid()},
                {"iss", apiIdentifier},
                {"OrgUnitId", orgUnitId},
                {
                    "Payload", new Order
                    {
                        OrderDetails = new OrderDetails
                        {
                            OrderNumber = Guid.NewGuid().ToString()
                        }
                    }
                }
            };

            return JsonWebToken.Encode(payload, apiKey, JwtHashAlgorithm.HS256);
        }
    }
}

It is important that you generate the JWT expiration using UNIX time. We recommend using a library such as NodaTime from NodaTime.org to help with this. If you are unable to use a third party library, here is a helper function you may use (this is used in the example above):


using System;

namespace CardinalCruiseDemoSite.Helpers
{
    public static class DateTimeHelper
    {
        public static long ToUnixTime(this DateTime date)
        {
            var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            return Convert.ToInt64((date - epoch).TotalSeconds);
        }
    }
}

Generating a Server JWT in Java

We recommend using an existing third party library to assist you in generating a JWT. The JWT.io website contains a list of approved libraries, with their feature sets. Check it out here.


// This sample code was written using the Java JWT
// library (https://github.com/jwtk/jjwt) found at JWT.io

import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.Key;
import java.util.Date;
import java.util.UUID;

import javax.crypto.spec.SecretKeySpec;

public class generateJWT {
  
	public static String apiKey = "";
	public static String apiIdentifier = "";
	public static String orgUnitId = "";
  
	// Sample method to construct a JWT
	public static String createJWT(String jwtId, long ttlMillis, Order orderObject) {
  
		// The JWT signature algorithm we will be using to sign the token
		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
  
		long nowMillis = System.currentTimeMillis();
		Date now = new Date(nowMillis);
  
		// We will sign our JWT with our API Key
		byte[] apiKeySecretBytes = apiKey.getBytes();
		Key signingKey = new SecretKeySpec(apiKeySecretBytes, 
		signatureAlgorithm.getJcaName());
  
		// Let's set the JWT Claims
		JwtBuilder builder = Jwts.builder()
			.setId(jwtId)     
			.setIssuedAt(now)
			.setIssuer(apiIdentifier)
			.claim("OrgUnitId", orgUnitId)
			.claim("Payload", orderObject)
			.signWith(signatureAlgorithm, signingKey);
  
		// Add the expiration or TTL (Time To Live) for this JWT
		if (ttlMillis > 0) {
			long expMillis = nowMillis + ttlMillis;
			Date exp = new Date(expMillis);
			builder.setExpiration(exp);
		}
  
		// Builds the JWT and serializes it to a compact, URL-safe string
		return builder.compact();
	}
}

Generating a Server JWT in PHP

We recommend using an existing third party library to assist you in generating a JWT. The JWT.io website contains a list of approved libraries, with their feature sets. Check it out here.


<?php
	/* 
	composer.json Example:
	{
		"require": {
			"lcobucci/jwt": "3.1.0" // Note: Requires PHP 7
			}
	}
	*/
	
	require "vendor/autoload.php"; // Autoload.php is generated by Composer
	
	use Lcobucci\JWT\Builder;
	use Lcobucci\JWT\Signer\Hmac\Sha256;
	
	$GLOBALS['ApiKey'] = '[INSERT_API_KEY_HERE]';
	$GLOBALS['ApiId'] = '[INSERT_API_KEY_ID_HERE]';
	$GLOBALS['OrgUnitId'] = '[INSERT_ORG_UNIT_ID_HERE]';
	
	$_SESSION['TransactionId'] = uniqid();
	
	$_SESSION['Order'] = array(
		"OrderDetails" => array(
			"OrderNumber" =>  'ORDER-' . strval(mt_rand(1000, 10000)),
			"Amount" => '1500',
			"CurrencyCode" => '840'
			)
	);
	
	function generateJwt($orderTransactionId, $orderObj){
	
		$currentTime = time();
		$expireTime = 3600; // expiration in seconds - this equals 1hr
	
		$token = (new Builder())->setIssuer($GLOBALS['ApiId']) // API Key Identifier (iss claim)
					->setId($orderTransactionId, true) // The Transaction Id (jti claim)
					->setIssuedAt($currentTime) // Configures the time that the token was issued (iat claim)
					->setExpiration($currentTime + $expireTime) // Configures the expiration time of the token (exp claim)
					->set('OrgUnitId', $GLOBALS['OrgUnitId']) // Configures a new claim, called "OrgUnitId"
					->set('Payload', $_SESSION['Order']) // Configures a new claim, called "Payload", containing the OrderDetails
					->set('ObjectifyPayload', true)
					->sign(new Sha256(), $GLOBALS['ApiKey']) // Sign with API Key
					->getToken(); // Retrieves the generated token
	
		return $token; // The JWT String
	}
	
	echo generateJwt($_SESSION['TransactionId'], $_SESSION['Order']);
?>

Validating a Cardinal Response JWT

Cardinal will respond back to all requests made through Cardinal Cruise with a JWT when it can. To validate that the response data was sent by Cardinal and can be trusted, you should always validate the JWT signature on the server side. It's recommended that you choose a JWT library with signature verification built in instead of doing this by hand. In most cases validating a JWT with a library is a simple 1 line command

The payments.validated event will pass back 2 arguments. The decoded data object from the JWT and the raw response JWT. The decoded data object is the decoded JWT payload passed back for your convience to allow front end logic to be easily executed based on the response. The decoded data object is returned without validating the data hasn't been tampered with. Once you validate the raw response JWT, the values pulled from the raw JWT should always be more trusted than values passed back in the decoded data object. Response JWT validation should always take place in your backend systems to ensure that the Api Key is kept secrete.

When passing response fields to third parties, we recommend using the JWT values since you're able to determine if they have been tampered with.

There are some limited cases where a response JWT will not be returned to the payments.validated event. Each cases will result in an ActionCode of ERROR.

  • Songbird.js times out when sending messages to Cardinal servers. Since no connection was made to Cardinal servers we will not be able to return back a response JWT.
  • Cardinal Servers were unable to verify the callers identity. This can occur if there is a problem with how the credentials are being used on the request JWT. Often a missing require field or the wrong API key was used to sign the request JWT.

If you ever receive an ActionCode of SUCCESS or NOACTION and do not receive a JWT, you should consider this to be a failure and reject the transaction.

JWT Fields

A valid Cardinal Cruise JWT used for to pass transactional data must have the following elements:

Required Fields

Please note that each Claim key is case sensitive.

Claim Description
aud Merchant jti Id - This is the 'jti' field from your request JWT echoed back. This field allows you to match up your request JWT with Cardinals response JWT.
jti JWT Id - A unique identifier for this response JWT. This value is generated by Cardinal.
iat Issued At Time - This is a timestamp of when the JWT was created.
iss Issuer - The request JWT's iss field echoed back.
ConsumerSessionId The unique session Id for the current user.
OrgUnitId Organization Unit Id - The request JWT's OrgUnitId echoed back.
Payload The response object for your request. This field will contain any actual state information on the transaction. This is the decoded data object that is passed into the payments.validated event as the first argument.

JWT Payload Example

Below is an example of the JSON content of a basic response JWT Payload where we are passing an object within the Payload claim:


{
    "iss": "56560a358b946e0c8452365ds",
    "iat": 1471014492,
    "exp": 1471021692,
    "jti": "8af34811-f97d-495a-ad19-ec2f68004f28",
    "ConsumerSessionId": "0e1ae450-df2b-4872-94f7-f129a2ddab18",
    "Payload": {
        "Validated": true,
        "Payment": {
            "Type": "CCA",
            "ExtendedData": {
                "CAVV": "AAABAWFlmQAAAABjRWWZEEFgFz+=",
                "ECIFlag": "05",
                "PAResStatus": "Y",
                "SignatureVerification": "Y",
                "XID": "MHEyQjFRQkttemdpaFlRdHowWTA=",
                "Enrolled": "Y"
            }
        },
        "ActionCode": "SUCCESS",
        "ErrorNumber": 0,
        "ErrorDescription": "Success"
    }
}
    

Below is an example of the JSON content of a basic response JWT Payload where we are passing a string within the Payload claim. This would occur when the request JWT included a ObjectifyPayload flag set to false:


}
    "iss": "56560a358b946e0c8452365ds",
    "iat": 1471015342,
    "exp": 1471022542,
    "jti": "55ebfa2a-665f-4d6b-81ea-37d1d4d12d9e",
    "ConsumerSessionId": "fb3a97a3-0344-4d3d-93ea-6482d866ec97",
    "Payload": "{\"Validated\":true,\"Payment\":{\"Type\":\"CCA\",\"ExtendedData\":{\"CAVV\":\"AAABAWFlmQAAAABjRWWZEEFgFz+\\u003d\",\"ECIFlag\":\"05\",\"PAResStatus\":\"Y\",\"SignatureVerification\":\"Y\",\"XID\":\"MFpjUVpwb0FXcHdwMWJBdldwNDA\\u003d\",\"Enrolled\":\"Y\"}},\"ActionCode\":\"SUCCESS\",\"ErrorNumber\":0,\"ErrorDescription\":\"Success\"}"
}
    

Validating a Response JWT in .NET

We recommend using an existing third party library to assist you in generating and validating JWTs. Some of our recommendations are:

JSON Web Token Handler - www.nuget.org

JWT - GitHub.com

The JWT.io website contains a list of additional approved libraries, with their feature sets. Check it out here.


    public string DecodeAndValidateResponseJwt(string responseJwt)
    {
        string jsonPayload = string.Empty;
        try
        {
            var apiKey = ConfigurationManager.AppSettings["APIKey"];

            jsonPayload = JWT.JsonWebToken.Decode(responseJwt, apiKey);
            Console.WriteLine(jsonPayload);
        }
        catch (JWT.SignatureVerificationException)
        {
            Console.WriteLine("Signature validation failed! JWT is not valid!");
        }

        return jsonPayload;
    }
    

Validating a Response JWT in Java

We recommend using an existing third party library to assist you in generating and validating JWTs. The JWT.io website contains a list of approved libraries, with their feature sets. Check it out here.


    // The jwt argument is the Cardinal response jwt handed back to the payments.validated event. 
    // This value is NOT the request jwt generated by the merchant and sent to Cardinal.
    public static boolean validateJwt(String jwt) {
        
        try{
            // The API Key used here to validate the Cardinal response is the same 
            // API Key you use to generate your request jwt.
            Claims claims = (Claims) Jwts.parser()
                .setSigningKey(apiKey.getBytes())
                .parse(jwt)
                .getBody();
                
            System.out.println("Signature Verified");
                        
            return true;
            
        } catch(SignatureException se) {
            System.out.println("Signature Validation Failed! JWT is not valid.");
        } catch(Exception ex){
        	System.out.println("General Error: " + ex.getMessage());
        }
        
        return false;
    }
    

Validating a Response JWT in PHP

We recommend using an existing third party library to assist you in generating and validating JWTs. The JWT.io website contains a list of approved libraries, with their feature sets. Check it out here.


<?php

    /* 
    composer.json Example:
    {
        "require": {
            "firebase/php-jwt": "^4.0"
        }
    }
    */

    require "vendor/autoload.php"; // Autoload.php generated by Composer
    
    use Firebase\JWT\JWT;

    $GLOBALS['ApiKey'] = '[INSERT_API_KEY_HERE]';
    $GLOBALS['ApiId'] = '[INSERT_API_KEY_ID_HERE]';
    $GLOBALS['OrgUnitId'] = '[INSERT_ORG_UNIT_ID_HERE]';

    function validateJwt($jwt) {
        // This will validate JWT Requests or Responses from Cardinal.
        try{
            // Validate the JWT by virtue of successful decoding
            $decoded = JWT::decode($jwt, $GLOBALS['ApiKey'], array('HS256'));
            // Cardinal JWT Request & Responses should always contain the Merchants OrgUnitId
            return strcmp($decoded->OrgUnitId,  $GLOBALS['OrgUnitId']) == 0;
        } catch (Exception $e) {
            echo "Exception in validateJwt: ", $e->getMessage(), "\n";
        }
        return false;
    }
?>
    

Object Definitions

Below are the objects needed to complete a Cardinal Cruise activation. Most objects will be re-used between Request and Response.

Request Order Object

This object is used in the Cardinal.start() event to pass Order data to Cardinal.

Field Type Description
OrderDetails OrderDetails The object that describes basic details about the order
Consumer Consumer Consumer object containing BillingAddress, ShippingAddress, and Account
Cart List<CartItem> The items in the cart for the current transaction
Token Token The token details associated with this transaction
Options Options An object containing any additional option flags

Response Object

This object is returned on the payments.validated event to pass the results of Cardinal.start() back to you.

Field Type Description
ActionCode AN(30) The resulting state of the transaction. Possible values:
  • SUCCESS - The transaction resulted in success for the payment type used. For example, with a CCA transaction this would indicate the user has successfully completed authentication.
  • NOACTION - The transaction was successful but requires in no additional action. For example, with a CCA transaction this would indicate that the user is not currently enrolled in 3-D Secure, but the API calls were successful.
  • FAILURE - The transaction resulted in an error. For example, with a CCA transaction this would indicate that the user failed authentication or an error was encountered while processing the transaction.
  • ERROR - A service level error was encountered. These are generally reserved for connectivity or API authentication issues. For example if your JWT was incorrectly signed, or Cardinal services are currently unreachable.
Validated bool This value represents whether CCA was run successfully or not.
ErrorNumber AN(255) Application error number. A non-zero value represents the error encountered while attempting the process the message request.
ErrorDescription AN(255) Application error description for the associated error number.
Payment Payment Payment object. Please see the specification below.
Consumer Consumer Consumer object. Please see the specification below.
Token Token Token object. Please see the specification below.
Authorization Authorization Authorization object. Please see the specification below.
AuthorizationProcessor AuthorizationProcessor AuthorizationProcessor object. Please see the specification below.
JWE String An optional response field that will only be present when secure data that needs to be transported encrypted is being returned on the response. This is most commonly seen in wallet integrations, like Visa Wallet, where a card number is returned for the merchant to authorize and capture against.

Account Object

This object should be used to pass account information to Cardinal.

NOTE: If you are using tokenization, either the Account object should be passed on a CCA request or a Token object. A valid CCA request cannot have both.

Field Type Description
AccountNumber N(19) Consumer's Account Number. This represents the Consumer's Credit Card Number.
ExpirationMonth N(2) Account/Credit Card Expiration Month in MM format.
Example: January = 01
ExpirationYear N(4) Account/Credit Card Expiration Year in YYYY format.
Example: 2016
NameOnAccount AN(50) Name on the Consumer's Account/Credit Card.
CardCode N(4) This is the CVV Code present on the back (or on the front in the case of AMEX) of a Consumer's Credit Card . This is required on Credit Card transactions.

Address Object

This object will be used for both Billing and Shipping address information.

Field Type Description
FirstName AN(50) Consumer's First Name.
MiddleName AN(50) Consumer's Middle Name.
LastName AN(50) Consumer's Last Name.
Address1 AN(50) Consumer's address information.
Address2 AN(50) Consumer's address information.
Address3 AN(50) Consumer's address information.
City AN(50) Consumer's City.
State AN(50) Consumer's State.
PostalCode AN(10) Consumer's Postal Code.
CountryCode AN(3) Consumer's Country Code.
Phone1 AN(20) Consumer's primary Phone Number.
Phone2 AN(20) Consumer's alternative Phone Number.

Authorization Object

Field Type Description
AuthorizeAccount bool An indicator of whether you would like to run an authorization on this transaction or not. This value will default to your preference inside of your Merchant profile, if not provided.
Status AN(50) Possible Values:
  • Success - Authorization was completed successfully.
  • Declined - Authorization was declined.
  • NA

Authorization Processor Object

This object describes the result of seeding a transaction for authorization with a 3rd party gateway service.

Field Type Description
ProcessorOrderId AN(255) The OrderId returned back from the Processor.
ProcessorTransactionId AN(255) The Transaction Identifier returned back from the Processor.
ReasonCode AN(255) Third party error number. A non-zero value represents the error encountered while attempting the process the message request.
ReasonDescription AN(255) Third party error description for the associated ReasonCode.

Authorization Result Object

This object describes the result of an authorization attempt.

Field Type Description
Status AN(30) The result of the authorization attempt. Possible Values:
  • Success - The authorization attempt was successful and you will be accepting this payment.
  • Failure - The authorization attempt failed, and you will not be accepting this payment.

CartItem Object

Field Type Description
Name AN(128) Name of Item Purchased.
SKU AN(20) Merchant SKU of Item.
Quantity N(20) Count of Item being purchased.
Description AN(256) Brief description of the Item being purchased.

Consumer Object

Field Type Description
Email1 AN(255) Consumer's primary E-mail Address .
Email2 AN(255) Consumer's alternate E-mail Address.
ShippingAddress Address Consumer's Shipping Address.
BillingAddress Address Consumer's Billing Address.
Account Account Consumer's Account information.

Payment Object

The payment object is a generic container for the response fields of the specific payment action that has been completed. The ExtendedData field will contain a single payment extension object of the type passed back in the Type field. So for example a CCA response object would contain a Payment object with a Type of 'CCA' and a CCAExtension ExtendedData object.

Field Type Description
Type AN(50) The payment type of this transaction.
Possible Values:
  • CCA - Cardinal Consumer Authentication
  • Paypal
  • Wallet
  • VisaCheckout
  • ApplePay
  • DiscoverWallet
ReasonCode AN(255) Third party error number. A non-zero value represents the error encountered while attempting the process the message request.
ReasonDescription AN(255) Third party error description for the associated ReasonCode.
ProcessorTransactionId AN(255) The Transaction Identifier returned back from the Processor.
OrderId AN(255) Centinel generated order identifier. Used to link multiple actions (authorize, capture, refund, etc) on a single order to a single identifier. Mod-10 compliant and unique BIN range to CardinalCommerce services.
OrderNumber AN(255) Order Number or transaction identifier from the Merchant website.
BillingAddress Address Consumers billing address. This field may not be present in every payment brand.
ShippingAddress Address Consumers shipping address. This field may not be present in every payment brand.
ExtendedData Payment Extension Object This will contain an extension object that corresponds to the Payment Type of this transaction. Refer to the Payment object Type field for what extension type this field is.

Token Object

Field Type Description
Token AN(20) If the merchant account has tokenization enabled through Cardinal or another payment platform, the token will be returned in this field
ExpirationMonth N(2) Account/Credit Card Expiration Month in MM format.
Example: January = 01
ExpirationYear N(4) Account/Credit Card Expiration Year in YYYY format.
Example: 2016
ReasonCode AN(255) Third party error number. A non-zero value represents the error encountered while attempting the process the message request.
ReasonDescription AN(255) Third party error description for the associated ReasonCode.

Options Object

The options object is used to enable or disable different functionality in Cardinal Cruise. This object is optional, but can be used in advanced activations to further customize the Cardinal Cruise experiece.

Field Type Description
EnableCCA bool

A flag that will enable or disable CCA processing for this transaction.

Possible Values:
  • true - Enables CCA for this transaction
  • false - Disables CCA for this transaction

NOTE: While this flag can be used to enable CCA, your merchant account must be configured to process CCA beforehand. This flag simply lets you control when CCA will be used to authenticate consumers.

OrderDetails Object

Field Type Required Description
OrderNumber AN(50) YES This represents your Order Number or transaction identifier.
Amount N(20) YES Unformatted total transaction amount without any decimalization.
Example: $100.00 = 10000, $123.67 = 12367, $.99 = 99
CurrencyCode N(3) YES 3 digit ISO 4217 value. Accepts either the Currency Number or Currency Code.
Example: "840" or "USD"
OrderDescription AN(256) Brief Description of Items purchased.
OrderChannel AN(16) Specifies the order channel where the transaction was initiated.
  • M – MOTO (Mail Order Telephone Order)
  • R – Retail
  • S – eCommerce
  • P – Mobile Device
  • T – Tablet
TransactionId AN(50) This value is the TransactionId field from a cmpi_lookup response from Centinel. This field is only used with a hybrid integration. This field is required for a hybrid integration.

Payment Extensions

CCAExtension

This object contains the specific response values used in CCA.

Field Type Description
Enrolled AN(1)

Status of Authentication eligibility.

Possible Values:
  • Y = Yes- Bank is participating in 3D Secure protocol and will return the ACSUrl
  • N = No - Bank is not participating in 3D Secure protocol
  • U = Unavailable - The DS or ACS is not available for authentication at the time of the request
  • B = Bypass- Merchant authentication rule is triggered to bypass authentication in this use case

NOTE: If the Enrolled value is NOT Y, then the Consumer is NOT eligible for Authentication.
CAVV AN(40) Cardholder Authentication Verification Value (CAVV). Also known as:
  • Authentication Verification Value (AVV)
  • Universal Cardholder Authentication Field (UCAF).

This value should be appended to the authorization message signifying that the transaction has been successfully authenticated. This value will be encoded according to the your merchant profile configuration in either Base64 or Hex encoding. A Base64 encoding configuration will produce values of 28 or 32 characters. A Hex encoding configuration will produce values of 40 or 48 characters. The value when decoded will either be 20 bytes for CAVV or 20 or 24 bytes if the value is AAV (MasterCard UCAF).

ECIFlag AN(40) Electronic Commerce Indicator (ECI). The ECI value is part of the 2 data elements that indicate the transaction was processed electronically. This should be passed on the authorization transaction to the gateway/processor.

MasterCard Visa Amex JCB Diners Club Elo
00 05 05 05 05 05
01 06 06 06 06 06
02 07 07 07 07 07
PAResStatus AN(1) Transaction status result identifier.

Possible Values:
  • Y – Successful Authentication
  • N – Failed Authentication
  • U – Unable to Complete Authentication
  • A – Successful Attempts Transaction
SignatureVerification AN(1) Transaction Signature status identifier.

Possible Values:
  • Y - Indicates that the signature of the PARes has been validated successfully and the message contents can be trusted.
  • N - Indicates that the PARes could not be validated. This result could be for a variety of reasons; tampering, certificate expiration, etc., and the result should not be trusted.
XID AN(2) Transaction identifier resulting from authentication processing.

NOTE: Gateway/Processor API specification may require this value to be appended to the authorization message. This value will be encoded according to the your merchant profile configuration in either Base64 or Hex encoding. A Base64 encoding configuration will produce values of 28 characters. A Hex encoding configuration will produce values of 40 characters.
UCAFIndicator AN(1)

Universal Cardholder Authentication Field (UCAF) Indicator value provided by the issuer.

Possible Values:
  • 0 - Non-SecureCode transaction, bypassed by the Merchant
  • 1 - Merchant-Only SecureCode transaction
  • 2 - Fully authenticated SecureCode transaction

NOTE: This field is only returned for MasterCard transactions

Error Handling

In the event Songbird.js encounters an error and is unable to continue with the transaction, it will always trigger the payments.validated event and pass back as much data as it has. Songbird will always keep to the standard response object when triggering an error flow like this so there is no need to worry about having to handle 2 types of objects within payments.validated. However in all likelyhood it will not include a valid JWT if the error occurred within Songbird itself. Errors that Songbird may throw include events like timeouts to Cardinal and miss configuration. Below are the possible errors Songbird will generate itself.

Error Number Description
10001 Connection failure while trying to complete an Init request.
10002 Connection failure while trying to complete a Start request.
10003 Connection failure while trying to complete a Validate request.
10004 A general error has occurred.
10005 No JWT was found configured in a flow that requires JWTs.
10006 A required configuration value is missing, the transaction is unable to continue.
10007 Connection failure while trying to complete a Confirm request.
10008 A required cardinal response JWT was not passed into setup.
10009 Connection failure while trying to complete a Continue request.
10010 The response JWT was malformed and could not be parsed.

JavaScript Error Handling

Its good practice to wrap all JavaScript within a try / catch block to prevent JavaScript errors going unhandled. We recommend that all your Cardinal Cruise related functions are wrapped within a try / catch block. This will help catch any errors that occur when you're calling or processing a Cardinal Cruise transaction, and allow you to handle them as your business logic dictates. Below is an example of creating an in browser order object wrapped with a try / catch. You can read more about the use of try / catch here at Mozilla.org.


function generateOrderObject(){
	  var cardData;
	
	  try{
	    cardData = {
	      Consumer: {
	        Account: {
	          AccountNumber: $("#cardNumber").val(),
	          NameOnAccount: $("#nameOnCard").val(),
	          ExpirationMonth: $("#expMo").val(),
	          ExpirationYear: $("#expYr").val(),
	          CardCode: $("#cardCode").val()
	        },
	        BillingAddress: {
	          FirstName: $("#billingFirstName").val(),
	          LastName: $("#billingLastName").val()
	        },
	      },
	      OrderDetails: {
	        Amount: $("#amount").val(),
	        CurrencyCode: $("#currencyCode").val()
	      }
	    };
	
	  } catch(e){
	    // An error occurred within the order object creation call
	    console.log("Error while building order object: " + e);
	  }
	
	  return cardData;
	}

Detect Missing Cardinal Namespace

It's possible that there could be issues on the client side when download the Cardinal Cruise library. Your activation should be able to detect and handle this to match your business requirements. This can be done a number of ways but the easiest way is to wrap all calls utilizing the Cardinal namespace in a try / catch block. Below is an example of how this could be done.

Passively Catch a Reference Error

This methodology will catch any error your scripts generate. So it has the added benefit of allowing you to catch any error and handle it in a centralized place. This may or may not fit your activation well.


try{
  Cardinal.setup("init", {
    jwt:"[jwt here]"
  });

  Cardinal.configure({
    logging: {
    debug: "verbose"
    }
  });

  function startTransaction() {
    Cardinal.start("cca", {
      OrderDetails: {
        OrderNumber: Math.random(0, 1000000) + "-shzs", // OrderNumbers need to be unique
        Amount:"100",
        CurrencyCode:" 840"
      },
      Consumer:{
        Account: {
          AccountNumber: "4000000000000002",
          ExpirationMonth: "01",
          ExpirationYear: "2099",
          CardCode: "123",    // Required for Tokenization
          NameOnAccount:"John Smith"
        }
      }
    });
  }     

  Cardinal.on("payments.validated", function (data, jwt) {
    switch(data.ActionCode){
      case "SUCCESS":
        // Handle successful authentication scenario
        break;
      
      case "NOACTION":
        // Handle unenrolled scenario
        break;
      
      case "FAILURE":
        // Handle authentication failed or error encounter scenario
        break;
      
      case "ERROR":
        // Handle service level error
        break;
    }
  });

} catch(e){
  // An error occurred
  console.log( (window["Cardinal"] === undefined ? "Cardinal Cruise did not load properly. " : "An error occurred during processing. ") + e );
}

Actively Checking for the Namespace Before Use

As an alternative methodology, you can also test for the Cardinal namespace on the window object prior to using it. If you use this strategy we recommend you still wrap all your JavaScript calls in try / catch blocks.


if(window["Cardinal"] !== undefined){
  // Cardinal namespace was found, we are ok to use 'Cardinal'
} else {
  // Cardinal namespace was not found, handle error
}

Handling Connection Errors

While it should never happen, its important to include code that handles the case where the consumer's browser is unable to reach Cardinal servers to complete a transaction. In this case we will always hand back control to the payments.validated event with the familiar json response object and no JWT. The JWT is not included and will be undefined because there was no response from the service that generates JWT's in a normal flow.


Cardinal.on("payments.validated", function (data, jwt) {
  switch(data.ActionCode){
    case "SUCCESS":
      // Handle successful authentication scenario
      break;

    case "NOACTION":
      // Handle unenrolled scenario
      break;

    case "FAILURE":
      // Handle authentication failed or error encounter scenario
      break;

    case "ERROR":
      // An ActionCode of 'ERROR' indicates there was a fatal connection issue somewhere within the transaction.
      // This could be to a 3rd party, to a dependent system within the Cardinal infrastructure, or to the Cardinal
      // servers all together. We need to review the ErrorNumber for more details.

      // ErrorNumbers in the 10,000 range are generated by Cardinal Cruise.
      if(data.ErrorNumber === 10001 || data.ErrorNumber === 10002 || data.ErrorNumber === 10003){
      	// Cardinal Cruise is unable to contact the Cardinal servers.
      }
      break;
  }  
}