Documentation

SaltPay, all rights reserved. 2022 ©

Introduction

RPG supports 3DSecure authorization requests. When accepting 3DSecure payments a few additional steps are required before the payment is performed, this process introduces a few additional concepts:

  • RPG - SaltPay's Restful Payment Gateway
  • MPI - Merchant Plugin Interface, used to determine whether authentication is available for a card number and validating the digital signature of a 3D Secure message.
  • ACS - Access Control Server, a server provided by the issuer of the card which verifies whether authentication is available for a card number and authenticates specific transactions.
  • DS - Directory Server run by the card scheme. It determines whether authentication is available for a specific card number, and if so, it returns the URL of the appropriate Access Control Server.
  • PaRes - Payer Authentication Response. A message formatted, digitally signed, and sent from the Access Control Server providing the results of the issuer's 3D Secure cardholder authentication.
  • CRes - CRes base64 url encoded in case of 3DS2. Challenge response in 3DS 2.x protocol.

To be able to perform 3DSecure authorization requests a merchant must have access to a MPI, this can be provided by SaltPay or a merchant can select another MPI service provider. When using the MPI provided by SaltPay the merchant can make use of the /MPI endpoint of RPG to simplify the MPI process.

Using the RPG MPI endpoint

Enrollment Requests

Before performing a 3DSecure payment the cardholder must be authenticated by the issuer of the card, when using the MPI endpoint provided by RPG this process is started by performing an enrollment request.

Enrollment Request

The RPG enrollment request will be forwarded to the MPI which will contact the appropriate Directory Server. The Directory server will return information on if the cardholder and merchant support 3DSecure and if so it will return information on how to redirect the cardholder to the appropriate ACS server. In a enrollment response where 3DSecure is supported a HTML form will be provided which will redirect the cardholder the the ACS. Some ACS provide a list of data fields which will enable the merchant to construct a custom HTML form to redirect the cardholder.

Example of an enrollment request:

{
    "CardDetails": {
        "PaymentType": "Card",
        "PAN": "5587********2110",
        "ExpMonth": "01",
        "ExpYear": "20"
    },
    "PurchAmount": 100,
    "Currency": "352",
    "Exponent": 0,
    "TermUrl": "https://myreturnurl",
    "MD": "My MD",
    "Description": "Payment for goods"
}

Note that the merchant must provide a TermUrl parameters. This will be the URL the cardholder will be redirected back to when the 3DSecure procedure has finished.

Example of an enrollment response:

{
    "ResultStatus": 0,
    "MessageId": "BW925668420200327100013394",
    "EnrollmentStatus": "Y",
    "MdErrorMessage": "To be redirected to ACS",
    "MdStatus": "9",
    "RedirectToACSForm": "<!DOCTYPE html SYSTEM \"about:legacy-compat\"><html><form>...</form></html>",
    "MD": "My MD",
    "RedirectToACSData": [
        {
            "Name": "actionURL",
            "Value": "URL OF ACS"
        },
        {
            "Name": "PaReq",
            "Value": "PaReq Data to post to ACS"
        },
        {
            "Name": "MD",
            "Value": "Same as in enrollment request"
        },
        {
            "Name": "TermUrl",
            "Value": "Same as in enrollment request"
        }
    ],
    "MpiToken": "3d_MYTOKEN"
}

The most important value in the enrollment response is the MdStatus which tells the merchant whether to proceed with the cardholder authentication or not. If MdStatus is 1 (Authenticated) then the merchant can go straight to performing the authorization request using the MpiToken. If MdStatus is 9 then the merchant should redirect the cardholder to the ACS using the data provided in the response. Other MdStatuses at this point indicate various failure states, see MdStatus list.

Another key value in the enrollment response is the MpiToken, this token can be provided when the authorization is performed to make RPG fill in the appropriate 3DS values in the authorization request.

If Redirect data was provided in the enrollment response then the merchant must redirect the cardholder to the ACS. When the 3DSecure procedure has finished on the ACS side the cardholder is redirected via HTML POST back to the TermUrl provided in the enrollment request.

ACS Redirection

The POST data will include the Merchant Data (MD), if provided, in the enrollment request and a PaRes or CRes value to be verified by the MPI.

PARes/CRes validation requests

The PARes or CRes value must be sent back to the MPI interface for validation by performing a validation request.

Example of an validation request:

{
    "PARes": "PARes data received from ACS"
}

PARes Validation

The RPG validation request will be forwarded to the MPI which will validate and interpret the data. It will then provide a response containing the final 3DSecure result.

Example of an validation response:

{
    "XId": "XId data",
    "MdStatus": "1",
    "MdErrorMessage": "Authenticated",
    "EnrollmentStatus": "Y",
    "AuthenticationStatus": "Y",
    "ECI": "02",
    "CAVV": "CAVV data",
    "CAVVAlgorithm": "3",
    "PAResVerified": "false",
    "PAResSyntaxOK": "true"
}

In the example above the 3DSecure procedure was successful, again the most important value to observe is MdStatus which will indicate if the 3DSecure procedure was successful or not. see MdStatus list. Other values are used if you will manage the 3DSecure data in the authorization request manually instead of using the MPI token from the Enrollment request.

Example of 3DSecure enabled payment:

{
    "TransactionType": "Sale",
    "Amount": 10000,
    "Currency": "352",
    "TransactionDate": "2018-10-15T13:41:26",
    "OrderId": "OrderId",
    "PaymentMethod": {
        "PaymentType": "TokenMulti",
        "Token": "tm_MYTOKEN",
        "CVC2": "***"
    },
    "ThreeDSecure": {
        "DataType": "Token",
        "MpiToken": "3d_MYTOKEN"
    }
}

WARNING: If you are performing transactions in ISK currency the exponent for ISK in RPG is 2 (e.g. 100 ISK -> Amount: 10000) but the MPI uses exponent 0 for ISK by default. See Notes on ISK

Example 1

Successful 3DSecure procedure using MPI Token.

Enrollment Request:
[POST] api/mpi/v2/enrollment
{
    "CardDetails": {
        "PaymentType": "Card",
        "PAN": "5587<strong><em>**</em></strong>2110",
        "ExpMonth": "01",
        "ExpYear": "20",
        "CVC2": "***"
    },
    "PurchAmount": 100,
    "Currency": "352",
    "Exponent": 0,
    "TermUrl": "https://myreturnurl",
    "MD": "My MD",
    "Description": "Payment for goods"
}
Enrollment Response:
{
    "ResultStatus": 0,
    "MessageId": "BW925668420200327100013394",
    "EnrollmentStatus": "Y",
    "MdErrorMessage": "To be redirected to ACS",
    "MdStatus": "9",
    "RedirectToACSForm": "<!DOCTYPE html SYSTEM \"about:legacy-compat\"><html><form id=\"webform0\" name=\"red2ACSv1\" method=\"POST\" action=\"https://ACSURL\" accept_charset=\"UTF-8\"><input type=\"hidden\" name=\"_charset_\" value=\"UTF-8\"><input type=\"hidden\" name=\"PaReq\" value=\"PAREQDATA\"><input type=\"hidden\" name=\"MD\" value=\"\"><input type=\"hidden\" name=\"TermUrl\" value=\"https://test.borgun.is/mpilanding2/mpireturnpage.aspx\"><input type=\"submit\" name=\"submitBtn\" value=\"Please click here to continue\"></form></html>",
    "MD": "My MD",
    "MpiToken": "3d_MYTOKEN"
}
ACS Redirect form
<!DOCTYPE html SYSTEM "about:legacy-compat">
<html>
    <form id="webform0" name="red2ACSv1" method="POST" action="https://ACSURL" accept_charset="UTF-8">
        <input type="hidden" name="<em>charset</em>" value="UTF-8"><input type="hidden" name="PaReq" value="PAREQDATA">
        <input type="hidden" name="MD" value="My MD">
        <input type="hidden" name="TermUrl" value="https://test.borgun.is/mpilanding2/mpireturnpage.aspx">
        <input type="submit" name="submitBtn" value="Please click here to continue">
    </form>
</html>
ACS Response Post Data
Param NameValue
PaResPARESData
MDMy MD
PaRes validation request:
[POST] api/mpi/v2/validation
{
    "PARes": "PARes DATA"
}
PaRes validation response:
{
    "XId": "XId data",
    "MdStatus": "1",
    "MdErrorMessage": "Authenticated",
    "EnrollmentStatus": "Y",
    "AuthenticationStatus": "Y",
    "ECI": "02",
    "CAVV": "CAVV data",
    "CAVVAlgorithm": "3",
    "PAResVerified": "false",
    "PAResSyntaxOK": "true"
}
Authorization request:
[POST] api/payment
  {
    "TransactionType": "Sale",
    "Amount": 10000,
    "Currency": "352",
    "TransactionDate": "2018-10-15T13:41:26",
    "OrderId": "OrderId",
    "PaymentMethod": {
        "PaymentType": "TokenMulti",
        "Token": "tm_MYTOKEN",
    },
    "ThreeDSecure": {
        "DataType": "Token",
        "MpiToken": "3d_MYTOKEN"
    }
}

Request Objects

Enrollment Request

Request Parameters

Name Description
CardDetails CardDetails object
PurchAmount Max 12-digit numeric amount in minor units of currency with all punctuation removed. Examples: Display Amount USD 1.23 Purchase Amount 123.
Exponent
Optional
The minor units of currency specified in ISO 4217. For example, US Dollars has a value of 2; Icelandic Krona and Japanese Yen has a value of 0. If value not specified the ISO 4217 value for currency will be used. Please see Appendix for special case regarding ISK.
Currency Currency code. ISO 4217, 3 digit numeric.
TermURL URL of the merchant that MPI will insert as termUrl in ACS redirection template (also refferred as notificationURL in 3DS2). As a result after cardholder authentication ACS will return PARes/CRes to Merchant instead of MPI. Warning: some schemes may reject that URL if contains query parameters (?...).
MD
Optional
Merchant state data that will be returned to the merchant when cardholder returns to TermURL. Note: Never store sensitive data in the MD parameter
Description
Required
Brief description of items purchased, determined by the merchant. Maximum size is 125 characters. Note: description is in most cases displayed to the cardholder during 3DS authentication.

CardDetails

Name Description
PaymentType
Required
Type of card details. Allowed values: 'Card', 'TokenSingle', 'TokenMulti'.
Token
Conditional
Single or multi use card token. Required if PaymentType is TokenSingle or TokenMulti.
PAN
Conditional
Credit card number. Required if PaymentType is Card.
ExpYear
Conditional
Expiration year on card, format: YYYY. Required if PaymentType is Card.
ExpMonth
Conditional
Expiration month on card, format: MM. Required if PaymentType is Card.
CVC2
Optional
CVC value, if provided the value will be tokenized and if MPIToken is provided when performing payment the CVC value will be populated automatically.

Response parameters

Name Description
ResultStatus Result status from SaltPay systems, 0 means the operation was successfully performed.
MessageId MessageId in MPI system, this is useful for tracing request if issues occurr.
AuthenticationStatus The actual value of PARes tx status or ARes/RReq transStatus. "Y", "N", "U", "A","R" or "-" if value is not available due errors or not enrolled. This is usually not provided during enrollment request.
EnrollmentStatus The actual value of veres enrollement status like "Y" (Enrolled), "N" (Not enrolled), "U" (Unknown) or "-" if value is not available due errors etc. In case of 3DS 2 this is set to Y if connection to directory is established.
MdErrorMessage Up to 128 bytes alphanumeric description of the error or message from MPI.
MdStatus End status of the transaction from MPI. mdStatus field provides all the information that is needed to determine how to manage the transaction in the merchant system. For possible values please see MdStatus list.
RedirectToACSForm HTML form to redirect cardholder to ACS.
MD Merchant Data echo if Merchant Data was provided in request.
MPIEnrollmentResponseACSField List of MPIEnrollmentResponseACSField objects. Contains Form data for ACS redirection, if provided by issuer. "actionURL" field will contain the ACS URL.
Message Message if error occurs.
MpiToken Token that can be used to populate 3DS data automatically when charging the card. Note: The time while a MpiToken is valid is limited and it should be used within an hour from creation.

MPIEnrollmentResponseACSField

Name Description
Name Name of field.
Value Value of field.

Validation Request

Request Parameters

Name Description
PARes PARes value received from ACS.
CRes CRes value received from ACS in case of 3DS2. Note: PARes or CRes value must be present, not both. If both are present the PARes value is used and CRes value is ignored.
MD Merchant Data.

Response Parameters

Name Description
XId Unique transaction identifier. Contains a 20 byte statistically unique value that has been Base64 encoded, giving a 28 byte result.
MdStatus End status of the transaction from MPI. mdStatus field provides all the information that is needed to determine how to manage the transaction in the merchant system. For possible values please see MdStatus list.
MdErrorMessage Up to 128 bytes alphanumeric description of the error or message from MPI.
EnrollmentStatus The actual value of VERes enrollment status like "Y", "N", "U" or "-" if value is not available due errors etc. In case of 3DS 2 this is set to Y if connection to directory is established.
AuthenticationStatus The actual value of PARes tx status or ARes/RReq transStatus "Y" (Authenticated), "N" (Not authenticated), "U" (Unknown), "A" (Attempt),"R" or "-" if value is not available due errors or not enrolled.
ECI Electronic Commerce Indicator With Visa cards, the value to be passed in Authorization Message (exactly 2 decimal digits). ECI fields determine the final status of the transaction.
CAVV Cardholder Authentication Verification Value determined by ACS.
CAVVAlgorithm A positive integer indicating the algorithm used to generate the Cardholder Authentication Verification Value. Current defined values are: 0 = HMAC, 1 = CVV, 2 = CVV with ATN , 3 = MasterCard AAV.
PAResVerified If signature validation of the return message is successful, the value is true. If PARes message is not received or signature validation fails, the value is false.
PAResSyntaxOK If PARes validation is syntactically correct, the value is true. Otherwise value is false.
TxId MPI internal transaction id if available.
Protocol 3DS protocol version.
DSTransId Transaction ID provided by directory server, required in 3DS 2.X

Appendix

MdStatus List

MDStatus Recommended action Notes
0 - Not Authenticated Do not continue transaction Cardholder did not finish the 3DSecure procedure successfully
1 - Authenticated Continue transaction Cardholder successfully authenticated.
2,3 - Not participating Continue transaction Cardholder not enrolled in 3DSecure or issuer of the card is not participating in 3DSecure
4 - Attempt Continue transaction 3DSecure attempt recognized by card issuer.
5 - Authentication unavailable Continue transaction if risk manageable or retry 3DSecure procedure Issuer is unable to process 3DSecure request. Merchant can decide to continue with transaction if merchant considers risk as low. Please see Notes on ISK for a special case when processing ISK.
6 - 3DSecure error Continue transaction if risk manageable or retry 3DSecure procedure Invalid field in 3-D Secure message generation, error message received or directory server fails to validate the merchant.
7 - MPI/Our error Continue transaction if risk manageable or retry 3DSecure procedure Error occured on MPI side, this may happen when the input data is invalid, this may also be returned if the MPI does not support 3DSecure for the particular card brand.
8 - Fraud score block Do not continue transaction 3DS attempt was blocked by MPI
9 - Pending Perform 3DSecure procedure MdStatus in enrollment response when merchant should start 3DSecure procedure.
50 - In 3DS Method Perform 3DS Method An extra authentication step is required before 3DSecure procedure is started. Please see Appendix for how to deal with MDStatus 50.
91 - Network error Continue transaction if risk manageable or retry 3DSecure procedure Network error, connection to directory server times out.
92 - Directory error Continue transaction if risk manageable or retry 3DSecure procedure Directory response read timeout or other failure.
93 - Configuration error Continue transaction if risk manageable or retry 3DSecure procedure Service is disabled, invalid configuration, etc.
94 - Input error Continue transaction if risk manageable or retry 3DSecure procedure Merchant request had errors
95 - No directory error Continue transaction if risk manageable No directory server found configured for PAN/card type.
97 - Unable to locate live transaction Continue transaction if risk manageable or retry 3DSecure procedure Unable to locate live transaction, too late or already processed.
96 - No directory error Continue transaction if risk manageable No version 2 directory server found configured for PAN/card type and flow requires version 2 processing.
99 - System error Continue transaction if risk manageable or retry 3DSecure procedure System error

Note when using MPI Token: If using MPI token with payment request then RPG will perform authorization attempts for MDStatuses: (1,2,3,5,6 and 9X)

Notes on ISK

There are two versions of the ISO 4217 standard in use. A previous version of the standard defines ISK as using 2 decimal places f.ex. 1ISK as "100", but the current version of the standard defines ISK as with 0 decimal places f.ex. 1ISK as "1".

Most issuers follow the ISO 4217 standard for exponents in their ACS servers so ISK amounts should be presented with 0 decimal places. In some rare cases issuers may follow the old version of the ISO 4217 standard and only accept ISK amounts with 2 decimal places.

When dealing with amounts in ISK we recommend that if the PaRes validation results in mdStatus = 5 then the Enrollment request should be retried using the other version of the ISO 4217 standard. For example if "Exponent" was set as "0" in the original request then the next one should set "Exponent" as 2. Remember to adjust the PurchAmount parameter accordingly.

Important note: In RPG ISK amounts are represented as having 2 decimal places, f.ex. even if you perform the 3DSecure procedure using 0 decimal places then you must use 2 decimal places then inputing the amount to RPG (f.ex. 1ISK in MPI = "1" and 1 ISK in RPG = "100").

Notes on MDStatus 50

In some cases a card issuer may respond to an Enrollment request with MDStatus=50, when this occurs an additional step must be performed by the merchant before the 3DSecure procedure can continue.

Enrollment Request

A normal enrollment request is performed and the issuer responds with MDStatus=50, in this case there is javascript/iframe data that should be rendered in the cardholder's browser in the TDSMethodContent field.

You can provide a URL in TDS2ThreeDSMethodNotificationURL in the EnrollmentRequest. This URL will be notified by the issuer upon TDSMethod completion.

Example of a enrollment request with TDS2ThreeDSMethodNotificationURL set:

{
    "CardDetails": {
        "PaymentType": "Card",
        "PAN": "4242-****-****-4242",
        "ExpMonth": "04",
        "ExpYear": "21",
        "CVC2": "***"
    },
    "PurchAmount": 10,
    "Currency": "352",
    "Exponent": 0,
    "TermUrl": "https://borgun.is/threedsecurecompleted",
    "Description": "Borgun testing",
    "TDS2ThreeDSMethodNotificationURL": "https://borgun.is/tdsmethodcompletion"
}

Note: You will need to keep track of two extra fields which are needed in the second step of the enrollment procedure, these fields are XId and TxId, see second enrollment request below.

Example of an enrollment response with MDStatus 50:

{
    "ResultStatus": 0,
    "MessageId": "BW925668420200327100013394",
    "EnrollmentStatus": "-",
    "MdErrorMessage": "3DS method requested before enrollment",
    "MdStatus": "50",
    "XId": "MjAyMTA0MTMxNNUyMjAANTI2MTk=",
    "TxId": "1108892233",
    "MD": "My MD",
    "TDSMethodContent": "&lt;iframe id=\"tdsMmethodTgtFrame\" name=\"tdsMmethodTgtFrame\" ...",
    "MpiToken": "3d_MYTOKEN"
}

Enrollment Request

According to the specification the merchant should render the TDSMethodContent in browser and 'wait' up to 10 seconds (in most cases 2-3 seconds) and then continue with the enrollment procedure. If TDS2ThreeDSMethodNotificationURL is provided in the original enrollment request then that URL will be notified upon TDSMethod completion.

The second enrollment request should be performed after the TDSMethodContent delay has been performed and should only contain two fields: XId and TxId.

Example of a second enrollment request:

[POST] {{BAPIUrl}}/api/mpi/v2/enrollment
{
    "XId": "MjAyMTA0MTMxNNUyMjAANTI2MTk=",
    "TxId": "1108892233"
}

If you provided TDS2ThreeDSMethodNotificationURL in the original enrollment request you should set TDS2ThreeDSCompInd parameter as "Y" in the second enrollment request.

Example of a second enrollment request with TDS2ThreeDSCompInd set:

[POST] {{BAPIUrl}}/api/mpi/v2/enrollment
{
    "XId": "MjAyMTA0MTMxNNUyMjAANTI2MTk=",
    "TxId": "1108892233",
    "TDS2ThreeDSCompInd": "Y"
}

Note: The MpiToken is only returned during the initial Enrollment Request.

The 3DSecure procedure can then proceed as normal according the MDStatus received from second enrollment response.

Example of an enrollment response:

{
    "ResultStatus": 0,
    "MessageId": "BW925668420200327100013394",
    "EnrollmentStatus": "Y",
    "MdErrorMessage": "To be redirected to ACS",
    "MdStatus": "9",
    "RedirectToACSForm": "<!DOCTYPE html SYSTEM \"about:legacy-compat\"><html><form>...</form></html>",
    "MD": "My MD",
    "RedirectToACSData": [
        {
            "Name": "actionURL",
            "Value": "URL OF ACS"
        },
        {
            "Name": "PaReq",
            "Value": "PaReq Data to post to ACS"
        },
        {
            "Name": "MD",
            "Value": "Same as in enrollment request"
        },
        {
            "Name": "TermUrl",
            "Value": "Same as in enrollment request"
        }
    ]
}