The merchant plug-in (MPI) is a software module used during the 3-D Secure process. The MPI identifies the customer’s card details and contacts the card issuer to determine if the card is enrolled in a 3-D Secure scheme. If enrolled, the MPI returns the address of the card issuer’s Access Control Server (ACS). The merchant redirects the customer’s browser to the ACS to verify their identity.
Trust Payments provides you with access to an MPI implementation that is automatically utilised by our JavaScript library during the default payment process, saving you the need for your servers to handle additional sensitive data. However, if you already have your own MPI configured as part of your solution, please follow the alternative process described below:
Requirements
Important: If you use your own MPI, it is your responsibility to ensure your system follows the 3-D Secure specification and keeps up to date with any amendments issued by Visa and Mastercard. You must also provide Trust Payments with valid, unaltered and verified values for each 3-D Secure field specified below.
Failure to follow the specification outlined below may result in forfeiting any liability shift.
If you do not have values for specific fields listed in this section, you must NOT submit the fields in question in any requests to Trust Payments.
Handling enrolled cards
After establishing the card is enrolled in the 3-D Secure scheme and the customer has been authenticated successfully, your system will need to construct and submit an AUTH request to complete the payment.
The specification of the request largely follows that of a standard AUTH, with additional fields required for 3-D Secure, as shown in the example below.
Examples
The following example assumes you have obtained the necessary PCI certification to process and submit sensitive cardholder data in the request. Alternatively, you can submit the cachetoken value in the request.
#!/usr/bin/python
import securetrading
stconfig = securetrading.Config()
stconfig.username = "webservices@example.com"
stconfig.password = "Password1^"
st = securetrading.Api(stconfig)
auth = {
"sitereference": "test_site12345",
"requesttypedescriptions": ["AUTH"],
"accounttypedescription": "ECOM",
"currencyiso3a": "GBP",
"baseamount": "1050",
"orderreference": "My_Order_123",
"pan": "4111111111111111",
"expirydate": "12/2020",
"securitycode": "123",
"cavv":"Q0FWVkNBVlZDQVZWQ0FWVkNBVlY=",
"eci":"05",
"enrolled":"Y",
"status":"Y",
"threedversion":"2.2.0",
"threeddirectorytransactionreference":"f00e1111-0011-00a6-ab00-a00000a00000"
}
strequest = securetrading.Request()
strequest.update(auth)
stresponse = st.process(strequest) #stresponse contains the transaction response
<?php
if (!($autoload = realpath(__DIR__ . '/../../../autoload.php')) && !($autoload = realpath(__DIR__ . '/../vendor/autoload.php'))) {
throw new Exception('Composer autoloader file could not be found.');
}
require_once($autoload);
$configData = array(
'username' => 'webservices@example.com',
'password' => 'Password1^',
);
$requestData = array(
'sitereference' => 'test_site12345',
'requesttypedescriptions' => array('AUTH'),
'accounttypedescription' => 'ECOM',
'currencyiso3a' => 'GBP',
'baseamount' => '1050',
'orderreference' => 'My_Order_123',
'pan' => '4111111111111111',
'expirydate' => '12/2020',
'securitycode' => '123',
'cavv' => 'Q0FWVkNBVlZDQVZWQ0FWVkNBVlY=',
'eci' => '05',
'enrolled' => 'Y',
'status' => 'Y',
'threedversion' => '2.2.0',
'threeddirectorytransactionreference' => 'f00e1111-0011-00a6-ab00-a00000a00000'
);
$api = \Securetrading\api($configData);
$response = $api->process($requestData);
var_dump($response->toArray());
?>
curl --user webservices@example.com:Password1^ <DOMAIN>/json/ -H "Content-type: application/json" -H "Accept: application/json" -X POST -d '{
"alias":"webservices@example.com",
"version": "1.00",
"request": [{
"currencyiso3a": "GBP",
"requesttypedescriptions": ["AUTH"],
"sitereference": "test_site12345",
"baseamount": "1050",
"orderreference": "My_Order_123",
"accounttypedescription": "ECOM",
"pan": "4111111111111111",
"expirydate": "12/2020",
"securitycode": "123",
"cavv":"Q0FWVkNBVlZDQVZWQ0FWVkNBVlY=",
"eci":"05",
"enrolled":"Y",
"status":"Y",
"threedversion":"2.2.0",
"threeddirectorytransactionreference":"f00e1111-0011-00a6-ab00-a00000a00000"
}]
}'
{
"alias":"webservices@example.com",
"version":"1.00",
"request":[{
"currencyiso3a":"GBP",
"requesttypedescriptions":["AUTH"],
"sitereference":"test_site12345",
"baseamount":"1050",
"orderreference":"My_Order_123",
"accounttypedescription":"ECOM",
"pan":"4111111111111111",
"expirydate":"12/2020",
"securitycode":"123",
"cavv":"Q0FWVkNBVlZDQVZWQ0FWVkNBVlY=",
"eci":"05",
"enrolled":"Y",
"status":"Y",
"threedversion":"2.2.0",
"threeddirectorytransactionreference":"f00e1111-0011-00a6-ab00-a00000a00000"
}]
}
<requestblock version="3.67">
<alias>webservices@example.com</alias>
<request type="AUTH">
<merchant>
<orderreference>My_Order_123</orderreference>
</merchant>
<billing>
<payment>
<expirydate>12/2020</expirydate>
<pan>4111111111111111</pan>
<securitycode>123</securitycode>
</payment>
<amount currencycode="GBP">1050</amount>
</billing>
<operation>
<sitereference>test_site12345</sitereference>
<accounttypedescription>ECOM</accounttypedescription>
</operation>
<threedsecure>
<cavv>Q0FWVkNBVlZDQVZWQ0FWVkNBVlY=</cavv>
<eci>05</eci>
<enrolled>Y</enrolled>
<status>Y</status>
<version>2.2.0</version>
<directorytransactionreference>f00e1111-0011-00a6-ab00-a00000a00000</directorytransactionreference>
</threedsecure>
</request>
</requestblock>
Field specification
Field | Format | Description | |
cavv XPath: /threedsecure/cavv |
Alphanumeric (56) |
The unique Cardholder Authentication Verification Value (CAVV) associated with the transaction. Always submit this value when it is available. |
|
eci XPath: /threedsecure/eci |
Alphanumeric (2) |
The ECI (E-Commerce Indicator) security level associated with the transaction. Always submit this value when it is available. |
|
enrolled XPath: /threedsecure/enrolled |
Char (1) | Submit ‘Y’ to indicate that card is enrolled. See below for information on handling not-enrolled cards. | |
status XPath: /threedsecure/status |
Char (1) |
Indicates whether or not the customer was authenticated on the card issuer’s ACS:
|
|
threedversion XPath: /threedsecure/version |
Numeric (6) |
Version of 3-D Secure used to authenticate the payment. (e.g. “2.2.0”) Always submit this value when it is available. |
|
threeddirectorytransactionreference XPath: /threedsecure/directorytransactionreference |
Alphanumeric (48) |
Unique DSTransactionId returned by your MPI provider. Always submit this value when it is available. |
We strongly recommend against proceeding with the transaction if the status is ‘N’ or ‘R’:
- If status is ‘N’, this indicates the customer was not authenticated.
- If status is ‘R’, this indicates the authentication was rejected.
Handling unenrolled cards (or if enrolment is “U” – Unknown)
If both your business and the cardholder’s bank are based within the European Economic Area (EEA) or the UK, your implementation must be compliant with the Revised Directive on Payment Services (PSD2).
PSD2 requires online card payments to be processed with 3-D Secure. If a card is not enrolled, the recommended approach would be to stop the transaction and offer the customer alternative means of payment.
If you have considered the legal implications covered above and are allowed to proceed, your system will need to construct and manually submit an AUTH request to complete the payment with an unenrolled card.
The specification of the request largely follows that of a standard AUTH, with additional fields required for 3-D Secure (as shown in the example below).
Example
The following example assumes you have obtained the necessary PCI certification to process and submit sensitive cardholder data in the request. Alternatively, you can submit the cachetoken value in the request.
#!/usr/bin/python
import securetrading
stconfig = securetrading.Config()
stconfig.username = "webservices@example.com"
stconfig.password = "Password1^"
st = securetrading.Api(stconfig)
auth = {
"sitereference": "test_site12345",
"requesttypedescriptions": ["AUTH"],
"accounttypedescription": "ECOM",
"currencyiso3a": "GBP",
"baseamount": "1050",
"orderreference": "My_Order_123",
"pan": "4111111111111111",
"expirydate": "12/2020",
"securitycode": "123",
"enrolled":"N",
"threedversion":"2.2.0",
"threeddirectorytransactionreference":"f00e1111-0011-00a6-ab00-a00000a00000"
}
strequest = securetrading.Request()
strequest.update(auth)
stresponse = st.process(strequest) #stresponse contains the transaction response
<?php
if (!($autoload = realpath(__DIR__ . '/../../../autoload.php')) && !($autoload = realpath(__DIR__ . '/../vendor/autoload.php'))) {
throw new Exception('Composer autoloader file could not be found.');
}
require_once($autoload);
$configData = array(
'username' => 'webservices@example.com',
'password' => 'Password1^',
);
$requestData = array(
'sitereference' => 'test_site12345',
'requesttypedescriptions' => array('AUTH'),
'accounttypedescription' => 'ECOM',
'currencyiso3a' => 'GBP',
'baseamount' => '1050',
'orderreference' => 'My_Order_123',
'pan' => '4111111111111111',
'expirydate' => '12/2020',
'securitycode' => '123',
'enrolled' => 'N',
'threedversion' => '2.2.0',
'threeddirectorytransactionreference' => 'f00e1111-0011-00a6-ab00-a00000a00000'
);
$api = \Securetrading\api($configData);
$response = $api->process($requestData);
var_dump($response->toArray());
?>
curl --user webservices@example.com:Password1^ <DOMAIN>/json/ -H "Content-type: application/json" -H "Accept: application/json" -X POST -d '{
"alias":"webservices@example.com",
"version": "1.00",
"request": [{
"currencyiso3a": "GBP",
"requesttypedescriptions": ["AUTH"],
"sitereference": "test_site12345",
"baseamount": "1050",
"orderreference": "My_Order_123",
"accounttypedescription": "ECOM",
"pan": "4111111111111111",
"expirydate": "12/2020",
"securitycode": "123",
"enrolled":"N",
"threedversion":"2.2.0",
"threeddirectorytransactionreference":"f00e1111-0011-00a6-ab00-a00000a00000"
}]
}'
{
"alias":"webservices@example.com",
"version":"1.00",
"request":[{
"currencyiso3a":"GBP",
"requesttypedescriptions":["AUTH"],
"sitereference":"test_site12345",
"baseamount":"1050",
"orderreference":"My_Order_123",
"accounttypedescription":"ECOM",
"pan":"4111111111111111",
"expirydate":"12/2020",
"securitycode":"123",
"enrolled":"N",
"threedversion":"2.2.0",
"threeddirectorytransactionreference":"f00e1111-0011-00a6-ab00-a00000a00000"
}]
}
<requestblock version="3.67">
<alias>webservices@example.com</alias>
<request type="AUTH">
<merchant>
<orderreference>My_Order_123</orderreference>
</merchant>
<billing>
<payment>
<expirydate>12/2020</expirydate>
<pan>4111111111111111</pan>
<securitycode>123</securitycode>
</payment>
<amount currencycode="GBP">1050</amount>
</billing>
<operation>
<sitereference>test_site12345</sitereference>
<accounttypedescription>ECOM</accounttypedescription>
</operation>
<threedsecure>
<enrolled>N</enrolled>
<version>2.2.0</version>
<directorytransactionreference>f00e1111-0011-00a6-ab00-a00000a00000</directorytransactionreference>
</threedsecure>
</request>
</requestblock>
Field specification
Field | Format | Description | |
enrolled XPath: /threedsecure/enrolled |
Char (1) | Submit ‘N’ to indicate that card is not enrolled, or ‘U’ to indicate enrolment is unknown. | |
threedversion XPath: /threedsecure/version |
Numeric (6) |
Version of 3-D Secure used to authenticate the payment. (e.g. “2.2.0”) Always submit this value when it is available. |
|
threeddirectorytransactionreference XPath: /threedsecure/directorytransactionreference |
Alphanumeric (48) |
Unique DSTransactionId returned by your MPI provider. Always submit this value when it is available. |