Split Authentication

Split Authentication allows you to separate the authentication and authorisation process. This gives you full control, meaning you can do your own checks before submitting the payment for authorisation.

Note:

  • You must be setup for Split Authentication, before using it with Worldpay. For more information, contact your Relationship Manager or Implementation Manager.
  • This service can only be used with adirect integration.
  • Ensure the <orderCode> used in your authentication request is different to the one in the authorisation request.

Split Authentication Flow

Challenge flow for Split Authentication

Device Data Collection (DDC)

JWT creation

All requests to Cardinal Commerce from the shopper's browser must be authenticated using a JSON Web Token (JWT). Providing this gives the shopper's browser access to resources to complete DDC and Challenges. You must create all JWT's on your server and not in the browser. This is because the JWT MAC Key, used in JWT creation, must only be known to you, Worldpay and Cardinal Commerce.

Best practice: We strongly recommend that you use a third-party library to create the JWT in its entirety.

JWT structure

JWT's consist of three parts (Header, Body and MAC). They are described below:

Header

The purpose of the header is to identify that the body is a JWT and to specify the message authentication algorithm. This is used to create the Message Authentication Code (MAC). The following algorithms are supported:

  • HS256 (HMAC with SHA256)
  • HS512 (HMAC with SHA512)

Example Header:

Copied!
{
  "typ":"JWT",
  "alg":"HS256"
}

Body

A JSON object that contains the claims (name-value pairs) being sent from one party to another. The body must only contain the claims below, adding additional claims results in 400 Bad Request response.

Claim NameM/ODescription
jtiMJWT Id - A unique identifier for this JWT. This field must be set to a random UUID each time a JWT is generated.
iatMIssued At - The epoch time (in seconds - ten digits) of when the JWT was generated. Valid for two hours.
issMIssuer - An identifier of who is issuing the JWT. Use "5bd9e0e4444dce153428c940" in test. We will provide values for live.
expOExpiration - The numeric epoch time (in seconds - ten digits) that the JWT should be considered expired. Anything over two hours in the future will be ignored.
OrgUnitIdMOrganisational Unit Id - An identity associated with your account. Use "5bd9b55e4444761ac0af1c80" in test. We will provide the values for live.

Example Body:

Copied!
{
  "jti": "69adc185-1748-4525-9ef9-43f259a1c2d6",
  "iat": 1548838855,
  "iss": "5bd9e0e4444dce153428c940",
  "exp": 1548838900,
  "OrgUnitId": "5bd9b55e4444761ac0af1c80"
}

MAC

A base64url encoded hash value of the header and payload combined with a JWT MAC Key. This is used to verify that the contents of the JWT have not been tampered with. Authentication codes are verified by the consumer by recreating the MAC from the JWT header, body and JWT MAC Key.

AttributeDescription
JWT MAC KeyPass this as a string and not a number. Use fa2daee2-1fbb-45ff-4444-52805d5cd9e0 in test. We will provide the values for live.

DDC initiation

DDC requires you to change your website to run JavaScript from Cardinal Commerce on your page. The JavaScript runs on the shopper's browser to collect device data as part of the authentication process regardless whether 3DS1 or 3DS2 is used.

Place an invisible iframe on your page. Create a form in the iframe using the POST method with action="https://secure-test.worldpay.com/shopper/3ds/ddc.html. Include the field JWT and Bin as described below. Do not submit this form until the card can no longer be changed.

FieldDescription
JWTThe authentication token, as describedabove.
BinThe card number (PAN). Minimum of first six digits.

Here's an example of one way to do it:

Copied!
<iframe height="1" width="1" style="display: none;">
    <!-- In production this will be a Cardinal Commerce hosted URL -->
    <form id="collectionForm" name="devicedata" method="POST" action="https://secure-test.worldpay.com/shopper/3ds/ddc.html">
      <input type="hidden" name="Bin" value="4444333322221111" />
      <input type="hidden" name="JWT" value="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2OWFkYzE4NS0xNzQ4LTQ1MjUtOWVmOS00M2YyNTlhMWMyZDYiLCJpYXQiOjE1NDg4Mzg4NTUsImlzcyI6IjViZDllMGU0NDQ0ZGNlMTUzNDI4Yzk0MCIsIk9yZ1VuaXRJZCI6IjViZDliNTVlNDQ0NDc2MWFjMGFmMWM4MCJ9.qTyYn4rItMMNdnh6ouqW6ZmcCNzaG9JI_GdWGIaq6rY" />
    </form>

    <script>
      window.onload = function() {
        document.getElementById('collectionForm').submit();
      }
    </script>
  </iframe>

DDC Outcome

You are notified via a JavaScript postMessage that DDC has been completed. Your website must listen for this notification which will contain the following fields:

NameValue
MessageTypeprofile.completed
SessionIdUUID, not present or undefined
Statustrue or false

There are three possible scenarios:

StatusAction
trueSend SessionId as dfReferenceId in initial payment request.
falseSessionId will be empty. Either retry DDC or send empty dfReferenceId which will downgrade authentication to 3DS1.
No callbackEither retry DDC or send empty dfReferenceId which will downgrade authentication to 3DS1.

Example postMessage:

Copied!
{
    "MessageType": "profile.completed",
    "SessionId": "d3197c02-6f63-4ab2-801c-83633d097e32",
    "Status": true
}

Here's some example JavaScript code for reference:

Copied!
window.addEventListener("message", function(event) {
   // The domain for test is https://secure-test.worldpay.com. We will provide A Cardinal Commerce URL upon go live.
   if (event.origin === "https://secure-test.worldpay.com/") {
       var data = JSON.parse(event.data);
       console.warn('Merchant received a message:', data);
       if (data !== undefined && data.Status) {
           // Extract the value of `SessionId` for onward processing.
       }
   }
}, false);

Extract the SessionId, if returned, and retain it for use in your initial payment request.

Authenticate request

The first Split Authentication request is an enrolment check. This request inquires if the shopper and issuer are enrolled for 3DS. For 3DS2 the issuers can authenticate the shopper without a challenge, given the shopper and issuer support 3DS2. This means the cardholder could be authenticated after the first request. Therefore, the authenticate request can invoke different outcomes.

Structure your first authenticate request the same way as the3DS Flexinitial payment request. However, to indicate your request is for Split Authentication you must supply the action attribute in paymentDetails with a value of AUTHENTICATE (<paymentDetails action="AUTHENTICATE">).

Note: We recommend providing an orderCode of less than 50 characters for 3DS Flex requests. Where the orderCode is longer than 50 characters, we will truncate it for downstream processing. This adjusted orderCode is only be used in Cardinal's systems.
This doesn't impact the orderCode that is stored internally, the orderCode that is returned to you, or the orderCode that is visible in the Merchant Admin Interface (MAI).

Supply the following additional sections in your authenticate request:

  1. additional3DSData (Mandatory)
  2. riskData (Recommended to increase chances of a frictionless flow)

Specifying Additional 3DS Data

<additional3DSData> has 3 different attributes:

AttributesDescription
dfReferenceIdThe SessionId returned in the Javascript postMessage after DDC is complete.
challengePreferencePossible Values:
  • noPreference - You have no preference whether a challenge should be performed. This is the default.
  • noChallengeRequested - You prefer that no challenge should be performed.
  • challengeRequested - You prefer that a challenge should be performed.
  • challengeMandated - There are local or regional mandates that mean that a challenge must be performed.

Note: The interpretation of this field will vary from issuer to issuer. Worldpay cannot guarantee any particular behaviour as a result of you setting this field.

challengeWindowSizeChallenge window size the issuer should use to display the challenge. Possible Values:
  • fullPage
  • 250x400
  • 390x400 (default)
  • 500x600
  • 600x400

Here is an example for <additional3DSData>:

Copied!
<order>
  ....

  <additional3DSData
    dfReferenceId="1f1154b7-620d-4654-801b-893b5bb22db1"
    challengeWindowSize="390x400"
    challengePreference="challengeMandated"/>
</order>

Adding Risk Data

Provide additional information in the <riskData> element to increase the chances that the shopper won't be challenged. <riskData> contains three child elements:

Information about the shopper and how they are authenticating with Worldpay.

The <authenticationRiskData> element contains:

ElementDescriptionType
authenticationTimestampDate and time in UTC of the shopper's authentication.<date> which must include the attributes: dayOfMonth, month, year, hour, minute and second
AttributeDescriptionType
authenticationMethodMechansim used by the shopper to authenticate with you.Possible values:
  • guestCheckout - the shopper has not been authenticated
  • localAccount - you have authenticated the shopper using your own systems
  • federatedAccount - you have authenticated the shopper using a Federated ID
  • fidoAuthenticator - you have authenticated the shopper using FIDO Authenticator
  • issuerCredentials- you have authenticated the shopper using issuer credentials
  • thirdPartyAuthentication - you have authenticated the shopper using third-party authentication

Information about the shopper's account with you.

The <shopperAccountRiskData> element contains:

ElementDescriptionType
<shopperAccountCreationDate>Date that the shopper opened the account with the merchant.WPG XML date format: specify sub-attributes dayOfMonth, month, year
<shopperAccountModificationDate>Date that the shopper's account with the merchant was last changed, including Billing or Shipping address, new payment account, or new user(s) added.WPG XML date format: specify sub-attributes dayOfMonth, month, year
<shopperAccountPasswordChangeDate>Date that shopper's account with the merchant had a password change or account reset.WPG XML date format: specify sub-attributes dayOfMonth, month, year.
<shopperAccountShippingAddressFirstUseDate>Indicates when the shipping address used for the transaction was first used.WPG XML date format: specify sub-attributes dayOfMonth, month, year.
<shopperAccountPaymentAccountFirstUseDate>Date the payment account was added to the shopper account.WPG XML date format: specify sub-attributes dayOfMonth, month, year.
AttributeDescriptionType
transactionsAttemptedLastDayNumber of transactions (successful and abandoned) for this shopper account with the merchant across all payment accounts in the previous 24 hours.Integer >=0
transactionsAttemptedLastYearNumber of transactions (successful and abandoned) for this shopper account with the merchant across all payment accounts in the previous year.Integer >=0
purchasesCompletedLastSixMonthsNumber of purchases with this shopper account during the previous six months.Integer >=0
addCardAttemptsLastDayNumber of Add Card attempts in the last 24 hours.Integer >=0
previousSuspiciousActivityIndicates whether the merchant has experienced suspicious activity (including previous fraud) on the shopper account.Boolean (true or false)
shippingNameMatchesAccountNameIndicates if the cardholder name on the account is identical to the shipping name used for this transaction.Boolean (true or false)
shopperAccountAgeIndicatorIndicates how long the shopper had the account with the merchant.Possible Values: noAccount, createdDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays
shopperAccountChangeIndicatorLength of time since the last change to the shopper's account. This includes billing or shipping address, new payment methods or new users added.Possible values: changedDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays
shopperAccountPasswordChangeIndicatorIndicates when the shopper's account password was last changed or reset.Possible Values: noChange, changedDuringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays
shopperAccountShippingAddressUsageIndicatorIndicates when the shipping address was first used.Possible Values: thisTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays
shopperAccountPaymentAccountIndicatorIndicates when the payment account was first used.Possibe Values: noAccount, duringTransaction, lessThanThirtyDays, thirtyToSixtyDays, moreThanSixtyDays

Information about the order.

The <transactionRiskData> element contains:

ElementDescriptionType
<transactionRiskDataGiftCardAmount>For prepaid or gift card purchase, the purchase amount total of prepaid or gift card(s) in major units (for example, USD 123.45 is 123Amount (value, currencyCode, exponent, <debitCreditIndicator>)
<transactionRiskDataPreOrderDate>For a pre-ordered purchase, the expected date the product will be available.Date

AttributeDescriptionType
shippingMethodIndicates shipping method chosen for the transaction.Possible Values:
  • shipToBillingAddress - Ship to shopper billing address
  • shipToVerifiedAddress - Ship to another verified address on file with merchant
  • shipToOtherAddress - Ship to address that is different than billing address
  • shipToStore - Ship to store (store address should be populated on request)
  • digital- Digital goods
  • unshippedTravelOrEventTickets - Travel and event tickets, not shipped
  • other - Other
    deliveryTimeframeIndicates the delivery timeframe.Possible values:
    • electronicDelivery - for products that are only delivered electronically
    • sameDayShipping - for products shipped the same day
    • overnightShipping - for products shipped overnight
    • otherShipping - two-day or more shipping.
    deliveryEmailAddressFor electronically delivered products only. Email address to which the product was delivered.email address
    reorderingPreviousPurchasesIndicates whether the shopper is reordering previously purchased product.Boolean (true or false)
    preOrderPurchaseIndicates whether shopper is placing an order with a future availability or release date.Boolean (true or false)
    giftCardCountTotal count of individual prepaid gift cards purchased.
    Integer >=0

    two digits only

    example: 00 and 99

    Complete initial Authenticate example:

    Copied!
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE paymentService PUBLIC "-//Worldpay//DTD Worldpay PaymentService v1//EN"
      "http://dtd.worldpay.com/paymentService_v1.dtd">
    <paymentService version="1.4" merchantCode="YOUR_MERCHANT_CODE">
      <submit>
        <order orderCode="YOUR_ORDER_CODE"> 
          <description>YOUR DESCRIPTION</description>
          <amount value="2000" currencyCode="EUR" exponent="2"/>
          <orderContent>
            <![CDATA[]]>
          </orderContent>
          <paymentDetails action="AUTHENTICATE">
            <CARD-SSL>
              <cardNumber>4444333322221111</cardNumber>
              <expiryDate>
                <date month="01" year="2020"/>
              </expiryDate>
              <cardHolderName>3DS_V2_CHALLENGE_IDENTIFIED</cardHolderName>
              <cvc>123</cvc>
              <cardAddress>
                <address>
                  <address1>Worldpay</address1>
                  <address2>270-289 The Science Park</address2>
                  <address3>Milton Road</address3>
                  <postalCode>CB4 0WE</postalCode>
                  <city>Cambridge</city>
                  <countryCode>GB</countryCode>
                </address>
              </cardAddress>
            </CARD-SSL>
            <session shopperIPAddress="127.0.0.1" id="SESSION_ID"/> <!--Session id must be unique -->
          </paymentDetails>
          <shopper>
            <shopperEmailAddress>jshopper@myprovider.com</shopperEmailAddress>
            <browser>
              <acceptHeader>text/html</acceptHeader>
              <userAgentHeader>Mozilla/5.0 ...</userAgentHeader>
            </browser>
          </shopper>
          <!-- Optional Risk Data -->
          <riskData>
            <authenticationRiskData authenticationMethod="localAccount">
              <authenticationTimestamp><date second="01" minute="02" hour="03" dayOfMonth="01" month="06" year="2019"/></authenticationTimestamp>
            </authenticationRiskData>
            <shopperAccountRiskData
              transactionsAttemptedLastDay="1"
              transactionsAttemptedLastYear="100"
              purchasesCompletedLastSixMonths="50"
              addCardAttemptsLastDay="1"
              previousSuspiciousActivity="true"
              shippingNameMatchesAccountName="true"
              shopperAccountAgeIndicator="lessThanThirtyDays"
              shopperAccountChangeIndicator="lessThanThirtyDays"
              shopperAccountPasswordChangeIndicator="noChange"
              shopperAccountShippingAddressUsageIndicator="thisTransaction"
              shopperAccountPaymentAccountIndicator="lessThanThirtyDays">          
              <shopperAccountCreationDate><date dayOfMonth="01" month="02" year="2003"/></shopperAccountCreationDate>
              <shopperAccountModificationDate><date dayOfMonth="02" month="03" year="2004"/></shopperAccountModificationDate>
              <shopperAccountPasswordChangeDate><date dayOfMonth="03" month="04" year="2005"/></shopperAccountPasswordChangeDate>
              <shopperAccountShippingAddressFirstUseDate><date dayOfMonth="04" month="05" year="2006"/></shopperAccountShippingAddressFirstUseDate> 
              <shopperAccountPaymentAccountFirstUseDate><date dayOfMonth="05" month="06" year="2007"/></shopperAccountPaymentAccountFirstUseDate>
            </shopperAccountRiskData>
            <transactionRiskData
              shippingMethod="shipToBillingAddress"
              deliveryTimeframe="overnightShipping"
              deliveryEmailAddress="sp@worldpay.com"
              reorderingPreviousPurchases="true"
              preOrderPurchase="false"
              giftCardCount="1">
            <transactionRiskDataGiftCardAmount><amount value="1" currencyCode="EUR" exponent="2"/></transactionRiskDataGiftCardAmount>
              <transactionRiskDataPreOrderDate><date dayOfMonth="06" month="07" year="2008"/></transactionRiskDataPreOrderDate>
            </transactionRiskData>
          </riskData>
          <!-- Additional 3DS data that you must provide to us -->
          <additional3DSData
            dfReferenceId="1f1154b7-620d-4654-801b-893b5bb22db1"
            challengeWindowSize="390x400"
            challengePreference="challengeMandated"/>
        </order>
      </submit>
    </paymentService>

    Authenticate Response

    The authenticate response is a final response, which could be returned if there is a frictionless 3DS2 response, or if the cardholder isn't enrolled for 3DS.

    Below are 3 example responses:

    Copied!
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN"
       "http://dtd.worldpay.com/paymentService_v1.dtd">
    <paymentService version="1.4" merchantCode="YOUR_MERCHANT_CODE">
       <reply>
          <orderStatus orderCode='YOUR_ORDER_CODE'>
             <authenticateResponse>
                <threeDSOutcome>
                   <threeDSVersion>1.0.2</threeDSVersion>
                   <enrolled>N</enrolled>
                   <eci>06</eci>
                </threeDSOutcome>
             </authenticateResponse>
          </orderStatus>
       </reply>
    </paymentService>
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN"
          "http://dtd.worldpay.com/paymentService_v1.dtd">
    <paymentService version="1.4" merchantCode="YOUR_MERCHANT_CODE">
       <reply>
          <orderStatus orderCode='YOUR_ORDER_CODE'>
             <authenticateResponse>
                <threeDSOutcome>
                   <threeDSVersion>1.0.2</threeDSVersion>
                   <authenticationStatus>Y</authenticationStatus>
                   <signatureVerification>Y</signatureVerification>
                   <eci>05</eci>
                   <xid>z9UKb06xLziZMOXBEmWSVA1kwG0=</xid>
                   <cavv>MTIzNDU2Nzg5MDEyMzQ1Njc4OTA=</cavv>
                </threeDSOutcome>
             </authenticateResponse>
          </orderStatus>
       </reply>
    </paymentService>
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN"
          "http://dtd.worldpay.com/paymentService_v1.dtd">
    <paymentService version="1.4" merchantCode="YOUR_MERCHANT_CODE">
       <reply>
          <orderStatus orderCode='YOUR_ORDER_CODE'>
             <authenticateResponse>
                <threeDSOutcome>
                   <threeDSVersion>2.1.0</threeDSVersion>
                   <enrolled>Y</enrolled>
                   <authenticationStatus>Y</authenticationStatus>
                   <signatureVerification>Y</signatureVerification>
                   <cavv>MAAAAAAAAAAAAAAAAAAAAAAAAAA=</cavv>
                   <eci>05</eci>
                   <dsTransactionId>c5b808e7-1de1-4069-a17b-f70d3b3b1645</dsTransactionId>
                </threeDSOutcome>
             </authenticateResponse>
          </orderStatus>
       </reply>
    </paymentService>

    Within the <threeDSOutcome> element, you should expect to receive any of the below elements.

    Note: These elements could appear in any order, and we do not enforce an order in which we will return them to you.

    ElementRequiredFormatDescription
    <threeDSVersion>YAN(10)Tells you whether a 3DS1 or 3DS2 flow follows. This could affect what you do next in your integration.

    Possible Values:
    • 1.0.2,
    • 2.1.0,
    • 2.2.0
    <enrolled>YAN(1)Status of Authentication eligibility.

    Possible Values:
    • Y - Yes, Bank is participating in 3-D Secure protocol and will return the ACSUrl
    • N - No, Bank is not participating in 3-D 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. (3DS Flex premium only)

    Note: If the enrolled value is NOT Y, then the Consumer is NOT eligible for Authentication.

    <eci>YAN(2)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 authorisation transaction to the Gateway/Processor.

    Possible Values:
    • 02 or 05 - Fully Authenticated Transaction
    • 01 or 06 - Attempted Authentication Transaction
    • 00 or 07 - Non 3-D Secure Transaction
    • Mastercard - 02, 01, 00
    • Visa - 05, 06, 07
    <signatureVerification>YAN(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.
    <dsTransactionId>CAN(36)Unique transaction identifier assigned by the Directory Server (DS) to identify a single transaction.

    Note: You must provide this where 3DS2 was used.

    <cavv>C28 - Base64Cardholder Authentication Verification Value (CAVV)
    Authentication Verification Value (AVV)
    Universal Cardholder Authentication Field (UCAF)
    This value should be appended to the authorisation message signifying that the transaction has been successfully authenticated. This value is Base64 encoded. The value when decoded will either be 20 bytes for CAVV or 20 or 24 bytes if the value is AAV (Mastercard UCAF).
    <authenticationStatus>CAN(1)Transactions status result identifier.
    Possible Values:
    • Y - Successful Authentication
    • N - Failed Authentication
    • U - Unable to Complete Authentication
    • A - Successful Attempts Transaction
    • R - Authentication Rejected (Merchant must not submit for authorisation)

    Note: An 'R' status only apply to Consumer Authentication 2.0.
    For information on what your next steps should be, seeMerchant next steps.

    <xid>C28 - Base64Transaction identifier resulting from authentication processing. Base64 encoded.

    Challenge Response

    In most cases, however, you are required to present a challenge to the shopper. The information to complete this is returned in the <challengeRequired> response.

    3DS1 example:

    Copied!
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN"
          "http://dtd.worldpay.com/paymentService v1.dtd">
    <paymentService version="1.4" merchantCode="YOUR_MERCHANT_CODE">
        <reply>
            <orderStatus orderCode='YOUR_ORDER_CODE'>
                <challengeRequired>
                    <threeDSChallengeDetails>
                        <threeDSVersion>1.0.2</threeDSVersion>
                        <transactionId3DS>rUT8fLKDviHXr8aUn3l1</transactionId3DS>
                        <acsURL><![CDATA[www.worldpay.com]]></acsURL>
                        <payload>P.25de9db33221a55eedc6ac352b927a8c3a08d747643c592dd8f8ab7d3...</payload>
                    </threeDSChallengeDetails>
                </challengeRequired>
            </orderStatus>
        </reply>
    </paymentService>

    You receive 3DS related data you need for the next step. These are sent as child elements of <threeDSChallengeDetails>:

    ElementRequiredFormatDescription
    <threeDSVersion>YAN(10)This field contains the 3DS version that was used to process the transaction.

    Possible Values:
    • 1.0.2
    • 2.1.0
    • 2.2.0

    Note: Required for Mastercard Identity Check transactions in Authorisation.

    <acsURL>YAN(2048)The fully qualified URL to redirect the shopper to complete authentication.

    Note: Only available if the shopper is enrolled.

    <transactionId3DS>YAN(20)Authentication transaction identifier. This value identifies the transaction within the Worldpay system. Pass the value in the challenge request.
    <payload>YAN(2048)The encoded payer authentication request.

    Extract the information from the XML response and pass it back to the shopper browser to present the challenge page.

    Present the 3DS Challenge

    Create a challenge JWT on your server that is passed to the browser. Refer toCreating JWTsif you need to.

    The challenge JWT contains more fields than the DDC one:

    Claim NameDescription
    jtiJWT Id - A unique identifier for this JWT. This field must be set to a random UUID each time a JWT is generated.
    iatIssued At - The epoch time (in seconds - ten digits) of when the JWT was generated. Valid for two hours.
    issIssuer - An identifier of who is issuing the JWT. Use "5bd9e0e4444dce153428c940" in test. We will provide values for live.
    OrgUnitIdOrganisational Unit Id is an identity associated with your account. We will provide the valid values that you can use when you are set up in live. Static test value is: "5bd9b55e4444761ac0af1c80"
    ReturnUrlThe URL on your website that will be invoked when the challenge is complete, see below.
    PayloadJSON container for extra data required for a challenge.
    Payload.ACSUrlThe value of the <acsUrl> element from the authenticate response.
    Payload.PayloadThe value of the <payload> element from the authenticate response.
    Payload.TransactionIdThe value of the <transactionId3DS> element from the authenticate response.
    ObjectifyPayloadSee below.

    Depending on which JWT library you choose, you may need to escape the control characters in the JWT:

    ObjectifyPayload set to true: This is not supported by all JWT libraries, but if it is, you can write the JWT payload like this:

    Copied!
    "Payload": {
      "ACSUrl": "https://worldpay.com" ,
      "Payload": "eNpVUV1PwjAUfe4DGhKoaw" ,
      "TransactionId": "sRMPWCQoQrEiVxehTnu0"
    },

    ObjectifyPayload set to false: You need to format the JWT payload with control characters escaped like this:

    Copied!
    "Payload": "{\"ACSUrl\": \"https://worldpay.com\" ,\"Payload\": \"eNpVUV1PwjAUfe4DGhKoaw\", \"TransactionId\": \"sRMPWCQoQrEiVxehTnu0\" }",

    Here's a full example of a challenge JWT:

    Copied!
    {
        "jti": "54438b3a-bb53-12cd-8643-1536be73ff35",
        "iat": 3856729482,
        "iss": "5bd9e0e4444dce153428c940",
        "OrgUnitId": "5bd9b55e4444761ac0af1c80",
        "ReturnUrl" : "https://merchant.example.com/threedschallengecomplete" ,
        "Payload": {
          "ACSUrl": "https://worldpay.com" ,
          "Payload": "VGhpcyBpcyBhIGJhc2UgNjQgZW5jb2RlZCBleGFtcGxlIG9mIGEgM0RTICJwYXlsb2FkIg==" ,
          "TransactionId": "sRMPWCQoQrEiVxehTnu0"
        },
        "ObjectifyPayload": true
      }

    Request Challenge Page

    Create an iframe with an automatic form post to https://secure-test.worldpay.com/shopper/3ds/challenge.html, on the page you redirect the shopper to. The size of this iframe depends on whether you provided a challengeWindowSize and whether a 3DS1 or a 3DS2 process flow is being followed:

    • For <threeDSVersion> value of 1, the size must be 390x400
    • For <threeDSVersion> value of 2, match the value supplied in the authenticate request. For more details of the support challenge Windows sizes seehere.

    Example of the challenge iframe:

    Copied!
    <iframe height="250" width="400">
      <!-- This will be a Cardinal Commerce URL in live -->
      <form id= "challengeForm" method= "POST" action="https://secure-test.worldpay.com/shopper/3ds/challenge.html">
        <input type="hidden" name="JWT" value= "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1NDQzOGIzYS1iYjUzLTEyY2QtODY0My0xNTM2YmU3M2ZmMzUiLCJpYXQiOiIzODU2NzI5NDgyIiwiaXNzIjoiNWJkOWUwZTQ0NDRkY2UxNTM0MjhjOTQwIiwiT3JnVW5pdElkIjoiNWJkOWI1NWU0NDQ0NzYxYWMwYWYxYzgwIiwiUmV0dXJuVXJsIjoiaHR0cDovL21lcmNoYW50LmV4YW1wbGUuY29tL3RocmVlZHNjaGFsbGVuZ2Vjb21wbGV0ZSIsIlBheWxvYWQiOnsiQUNTVXJsIjoiaHR0cHM6Ly9hY3MuZXhhbXBsZS5jb20vM2RzMi9jaGFsbGVuZ2U_aWQ9MTIzNDU2Nzg5IiwiUGF5bG9hZCI6IlZHaHBjeUJwY3lCaElHSmhjMlVnTmpRZ1pXNWpiMlJsWkNCbGVHRnRjR3hsSUc5bUlHRWdNMFJUSUNKd1lYbHNiMkZrSWc9PSIsIlRyYW5zYWN0aW9uSWQiOiJzUk1QV0NRb1FyRWlWeGVoVG51MCJ9LCJPYmplY3RpZnlQYXlsb2FkIjp0cnVlfQ.3Dqjr5MuEC9AG7uvsJCft94-d70NmgR94zIeru8fAYE" />
        <input type="hidden" name="MD" value="1234567890" />
      </form>
      <script>
        window.onload = function() {
          // Auto submit form on page load
          document.getElementById('challengeForm').submit();
        }
      </script>
    </iframe>
    FieldRequiredDescription
    actionYThe live URL will be provided upon boarding. The test value is: "https://secure-test.worldpay.com/shopper/3ds/challenge.html".
    JWTYThe challenge JWT that you generated on the server side.
    MDNMerchant Data. This will be echoed back as a URL parameter to the ReturnUrl.

    Challenge Request Data

    Submit the second request once the challenge is complete. The response from Worldpay will contain the authentication data.

    ElementRequiredDescription
    <transactionId3DS>YCardinal-generated transaction identifier. This value links the request message to the lookup message.

    Example XML

    Copied!
    <!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN" 
      "http://dtd.worldpay.com/paymentService_v1.dtd">
    <paymentService version="1.4" merchantCode="YOUR_MERCHANT_CODE">
        <submit>
            <challenge orderCode="YOUR_ORDER_CODE">
                <transactionId3DS>qzjqQWjJn8R859kLn7Zi</transactionId3DS>
            </challenge>
        </submit>
    </paymentService>

    Once you submit this request, Worldpay will receive the authentication outcome and return this to you in the authenticate response.

    Merchant next steps

    The <authenticationStatus> field tells you all you need to know about what next steps you need to take.

    Authentication Status valueNext steps
    YProceed to authorisation using the information received in the <threeDSOutcome> response.
    NDo not proceed to authorisation. You can ask for an alternative form of payment.
    UYou can retry authentication, or submit for authorisation (without liability shift).
    AYou can submit authorisation using the information received in the <threeDSOutcome> response.
    RDo not proceed to authorisation. You can ask for an alternative form of payment.
    BYou can proceed to authorisation using the information received in the <threeDSOutcome> response.

    Note: Ensure you include the fields you receive in the <threeDSOutcome> response in your External MPI request. This can include: threeDSVersion, xid, cavv, dsTransactionId, eci.

    Errors

    We will return WPG errors if something goes wrong.

    Error CodeDescriptionScenario
    13Connection failure.The connection timed out.
    13Authentication failure.An error was returned by our authentication provider.
    13Authentication not enabled.You're not set up to use 3DS in Secure Test or Production.
    13Merchant not set up in live.Your merchant code is not configured to use Split Authentication.

    Split Authentication error example

    Copied!
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN" 
          "http://dtd.WorldPay.com/paymentService_v1.dtd">
    <paymentService version="1.4" merchantCode="YOUR_MERCHANT_CODE">
      <reply>
        <orderStatus orderCode="YOUR_ORDER_CODE">
          <error code="13">
            <![CDATA[Authentication error.]]>
          </error>
        </orderStatus>
      </reply>
    </paymentService>

    Next

    Once you have received the authentication outcome, you can now submit the payment for authorisation using theExternal MPI API.

    Testing

    How it works

    In Production, you will interact with both Cardinal Commerce and Worldpay. For Secure Test, we have built simulators to allow you to integrate to Worldpay, when you're ready to go live, you must make a few changes to point your connection to both Cardinal and Worldpay.

    1. Create a JWT with static values

    Below are 3 static values to test theJWT creation. All other claims must be present and not empty, but can otherwise take any value.

    AttributeValue
    OrgUnitId5bd9b55e4444761ac0af1c80
    iss5bd9e0e4444dce153428c940
    JWT MAC Keyfa2daee2-1fbb-45ff-4444-52805d5cd9e0 (pass this as a string and not a number)

    2. DDC test URLs

    Run the Javascript tosubmit the Device Databack to the URL of the Worldpay simulator:

    https://secure-test.worldpay.com/shopper/3ds/ddc.html

    3. Create the initialauthenticate request

    Use the below magic values and test card numbers to create your initial authenticate XML.

    Test card numbers

    Insert the below values in <cardNumber>:

    3DS1

    Card typeTest card number
    American Express343434343434343
    Diners36700102000000 and 36148900647913
    JCB3528000700000000
    MasterCard5555555555554444, 5454545454545454 and 2221000000000009
    MasterCard Debit5163613613613613
    Visa4444333322221111, 4911830000000 and 4917610000000000
    Visa Debit4462030000000000 and 4917610000000000003
    Visa Electron (UK only)4917300800000000
    Visa Purchasing4484070000000000

    3DS2

    Card typeTest card number
    MasterCard5555555555554444, 5454545454545454 and 2221000000000009
    MasterCard Debit5163613613613613
    Visa4444333322221111, 4911830000000 and 4917610000000000
    Visa Debit4462030000000000 and 4917610000000000003
    Visa Electron (UK only)4917300800000000
    Visa Purchasing4484070000000000

    Insert the below values in <cardHolderName>:

    3DS1

    Magic valueAuthentication OutcomeError Code and Description
    3DS_V1_CHALLENGE_IDENTIFIEDY - Cardholder authenticated
    3DS_V1_INVALID_SIGNATUREY - Cardholder authenticated, invalid signature
    3DS_V1_CHALLENGE_UNKNOWN_IDENTITYN - Authentication attempted but failed
    3DS_V1_CHALLENGE_NOT_IDENTIFIEDA - Authentication offered but not used
    3DS_V1_TIMEOUT-13 - Connection failure.
    3DS_V1_NOT_ENROLLEDN/A - Customer or issuing bank not enrolled to 3DS
    3DS_V1_UNAVAILABLEU - Unknown enrolment. Cardholder not authenticated
    3DS_V1_LOOKUP_ERROR-13 - Authentication error.
    3DS_V1_CHALLENGE_VALID_ERROR-13 - Authentication error.
    3DS_V1_CHALLENGE_AUTH_UNAVAILABLEU - Authentication unavailable
    3DS_BYPASSEDB - Authentication bypassed

    3DS2

    Magic valueAuthentication StatusError Code and Description
    3DS_V2_FRICTIONLESS_IDENTIFIEDY - Cardholder authenticated
    3DS_V2_FRICTIONLESS_FAILEDN - Frictionless rejected
    3DS_V2_FRICTIONLESS_NOT_IDENTIFIEDA - Authentication offered but not used
    3DS_V2_FRICTIONLESS_UNAVAILABLEU - Frictionless authentication is unavailable
    3DS_V2_FRICTIONLESS_REJECTEDR, N - Authentication rejected
    3DS_V2_AUTH_UNAVAILABLEAuthentication not available
    3DS_V2_BYPASSEDB - Authentication bypassed
    3DS_V2_CHALLENGE_IDENTIFIEDY - Cardholder authenticated
    3DS_V2_CHALLENGE_UNKNOWN_IDENTITYN - Authentication attempted but failed
    3DS_V2_CHALLENGE_UNAVAILABLEU - Cardholder not authenticated
    3DS_V2_BYPASSED_AFTER_CHALLENGEB - 3DS bypassed after challenge
    3DS_V2_LOOKUP_ERROR-13 - Authentication error.
    3DS_V2_LOOKUP_TIMEOUT-13 - Connection failure.
    3DS_V2_AUTHENTICATION_ERROR-13 - Authentication error.

    Note: Ensure you are sending the dfReferenceId attribute in yourauthenticate request. Extract the value for this from the SessionId that is returned by the Worldpay simulator.

    4. Challenge

    If you have decided to use a magic value that invokes achallenge(3DS_V1_CHALLENGE_IDENTIFIED or 3DS_V2_CHALLENGE_IDENTIFIED) you will need to create another JWT. Use the same static values as inStep 1.

    Use the below URL to POST your challenge JWT in an iframe:

    https://secure-test.worldpay.com/shopper/3ds/challenge.html

    The Worldpay simulator will POST back a standard response to the iframe. You will be presented with an OK button. Click this to be redirected to your ReturnUrl.

    5. Challenge request request

    Provide the <transactionId3DS> after the challenge has been completed. The value for this is returned in the first response of your challenge request. This is then passed to Cardinal who return the authentication outcome to us. Worldpay retruns this outcome to you.

    The same applies for Secure Test. Trigger yourchallenge requestincluding the <transactionId3DS> returned to you in the response. Worldpay then sends the authentciation outcome in the challenge response to you.

    Authorisation

    When using Split Authentication, submit the authorisation using our External MPI. To test this, check out theExternal MPIdocumentation for more information.

    About this guide

    To see the latest changes made to this guide please clickhere.