Guides
Direct Integration

Direct Integration

With direct integration, your merchant’s website (complete with secure certificate) captures the user’s personal and credit card details and then forwards these behind the scenes to the secure NPI gateway. NPI then performs any necessary fraud and security checks, clears the payment with the acquiring bank and sends a response back to your merchant’s website, which then delivers a formatted response back to the customer.

Direct integration is more complex than the hosted forms method, but it does mean that the entire shopping process can occur within your merchants’ websites, providing a seamless experience for their customers.

For standard Visa and MasterCard testing use our test cards

Sale Transaction example (with 3-D Secure)

The following example PHP code shows how to send a SALE transaction with support for 3DS, using our SDK:

<?php
 
// Signature key entered on MMS. The demo account is fixed to this value,
$key = 'Circle4Take40Idea';
 
// Gateway URL
$url = 'https://gateway.example.com/direct/';
 
// Setup PHP session as use it to store data between 3DS steps
if (isset($_GET['sid'])) {
    session_id($_GET['sid']);
}
 
session_start();
 
// Compose current page URL (removing any sid and acs parameters)
$pageUrl = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'). $_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] != '80' ? ':' . $_SERVER['SERVER_PORT'] : ''). preg_replace('/(sid=[^&]+&?)|(acs=1&?)/', '', $_SERVER['REQUEST_URI']);
 
// Add back the correct sid parameter (used as session cookie may not be passed when the page is redirected from an IFRAME)
$pageUrl .= (strpos($pageUrl, '?') === false ? '?' : '&') . 'sid=' . urlencode(session_id());
 
// If ACS response into the IFRAME then redirect back to parent window
if (!emptyempty($_GET['acs'])) {
     echo silentPost($pageUrl, array('threeDSResponse' => $_POST), '_parent');
     exit();
}
if (!isset($_POST['threeDSResponse'])) {
// Initial request
// Gather browser info - can be done at any time prior to the checkout
if (!isset($_POST['browserInfo'])) {
    echo collectBrowserInfo();
    exit();
}
 
// Direct Request
$req = array(
'merchantID' => 100001,
'action' => 'SALE',
'type' => 1,
'currencyCode' => 826,
'countryCode' => 826,
'amount' => 1001,
'cardNumber' => '4012001037141112',
'cardExpiryMonth' => 12,
'cardExpiryYear' => 15,
'cardCVV' => '083',
'customerName' => 'Test Customer',
'customerEmail' => 'test@testcustomer.com',
'customerAddress' => '16 Test Street',
'customerPostCode' => 'TE15 5ST',
'orderRef' => 'Test purchase',
// The following fields are mandatory for 3DS
'remoteAddress' => $_SERVER['REMOTE_ADDR'],
'threeDSRedirectURL' => $pageUrl . '&acs=1',
// The following field allows options to be passed for 3DS
// and the values here are for demonstration purposes only
'threeDSOptions' => array(
    'paymentAccountAge' => '20190601',
    'paymentAccountAgeIndicator' => '05',
    ),
);
// Append the fields contained in browserInfo to the request as some are
// mandatory for 3DS as detailed in section 5.5.5 of the Integration Guide.
 
$req += $_POST['browserInfo'];
 
} else {
// 3DS continuation request
$req = array(
// The following field are only required for tbe benefit of the SDK
'merchantID' => 100001,
'action' => 'SALE',
 
// The following field must be passed to continue the 3DS request
'threeDSRef' => $_SESSION['threeDSRef'],
'threeDSResponse' => $_POST['threeDSResponse'],
);
}
 
try {
$res = Gateway::directRequest($req);
} catch (\Exception $e) {
// You should exit gracefully
die('Sorry, the request could not be sent: ' . $e);
}
 
// Check the response code
if ($res['responseCode'] === Gateway::RC_3DS_AUTHENTICATION_REQUIRED) {
    // Send request to the ACS server displaying response in an IFRAME
    // Render an IFRAME to show the ACS challenge (hidden for fingerprint method)
    $style = (isset($res['threeDSRequest']['threeDSMethodData']) ? 'display: none;' : '');
    echo "<iframe name=\"threeds_acs\" style=\"height:420px; width:420px; {$style}\"></iframe>\n";
 
    // Silently POST the 3DS request to the ACS in the IFRAME
    echo silentPost($res['threeDSURL'], $res['threeDSRequest'], 'threeds_acs');
 
    // Remember the threeDSRef as need it when the ACS responds
    $_SESSION['threeDSRef'] = $res['threeDSRef'];
 
} else if ($res['responseCode'] === Gateway::RC_SUCCESS) {
    echo "<p>Thank you for your payment.</p>";
} else {
    echo "<p>Failed to take payment: " . htmlentities($res['responseMessage']) . "</p>";
}
 
// Render HTML to silently POST data to URL in target brower window
function silentPost($url = '?', array $post = null, $target = '_self') {
 
    $url = htmlentities($url);
    $target = htmlentities($target);
    $fields = '';
 
 
    if ($post) {
        foreach ($post as $name => $value) {
        $fields .= Gateway::fieldToHtml($name, $value);
        }
     }
 
    $ret = "
        <form id=\"silentPost\" action=\"{$url}\" method=\"post\" target=\"{$target}\">
        {$fields}
        <noscript><input type=\"submit\" value=\"Continue\"></noscript
        </form>
        <script>
        window.setTimeout('document.forms.silentPost.submit()', 0);
        </script>
    ";
    return $ret;
}
 ?>
 

Sale Transaction example (with 3DS and without SDK)

The following example PHP code shows how to send a SALE transaction with support for 3DS and using CURL instead of SDK:

<?php
// Merchant details and URL to this sample code.
$key = '';
$merchantID = '';
$samplecodeURL = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
 
// Gateway URL
$gatewayURL = 'https://gateway.example.com/direct/';
 
// If this is the first request
if (!isset($_GET['threeDSAcsResponse'])) {
 
    // Request
    $req = array(
    'merchantID' => $merchantID,
    'action' => 'SALE',
    'amount' => 100,
    'type' => 1,
    'countryCode' => '826',
    'currencyCode' => '826',
    'orderRef' => 'CC #112406',
    'transactionUnique' => uniqid(5),
 
    // Credit card details
    'cardNumber' => '4543059999999982',
    'cardExpiryDate' => '1221',
    'cardCVV' => '110',
 
    // Customer details
    'customerAddress' => '76 Test road',
    'customerPostCode' => 'TE548ST',
    'customerName' => 'Test',
    'threeDSVersion' => '2',
 
    // Three DS V2 fields required / Browser Info
    'remoteAddress'             => $_SERVER['REMOTE_ADDR'],
    'threeDSRedirectURL'        => $samplecodeURL . '?threeDSAcsResponse',
    'deviceChannel'				=> 'browser',
    'deviceIdentity'			=> (isset($_SERVER['HTTP_USER_AGENT']) ? htmlentities($_SERVER['HTTP_USER_AGENT']) : null),
    'deviceTimeZone'			=> '0',
    'deviceCapabilities'		=> '',
    'deviceScreenResolution'	=> '1x1x1',
    'deviceAcceptContent'		=> (isset($_SERVER['HTTP_ACCEPT']) ? htmlentities($_SERVER['HTTP_ACCEPT']) : null),
    'deviceAcceptEncoding'		=> 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'deviceAcceptLanguage'		=> (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? htmlentities($_SERVER['HTTP_ACCEPT_LANGUAGE']) : null),
    'deviceAcceptCharset'		=> (isset($_SERVER['HTTP_ACCEPT_CHARSET']) ? htmlentities($_SERVER['HTTP_ACCEPT_CHARSET']) : null),
    );
 
    // Sign the request
    $req['signature'] = createSignature($req, $key);
 
    // Send the request to the gateway and get back the response
    $gatewayResponse = sendRequest($req, $gatewayURL);
 
    // Store the threeDSRef in a cookie for reuse.  (this is just one way of storeing it)
    setcookie('threeDSRef', $gatewayResponse['threeDSRef'], time()+500);
 
    // Output request
    echo '<h2>Request</h2>';
    echo "<pre>";
    print_r($req);
    echo "</pre>";
 
    echo http_build_query($req);
 
    // Output gateway response
    echo '<h2>Response</h2>';
    echo "<pre>";
    print_r($gatewayResponse);
    echo "</pre>";
 
// Else if this is a response from 3DS
}  elseif ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_GET['threeDSAcsResponse'])) {
 
    // Build the request containing the threeDSResponse with data from the 3DS page
    // and include the threeDSRef stored in the cookie.
    $threeDSRequest = array(
        'threeDSRef' => $_COOKIE['threeDSRef'], // This is the threeDSref store in the cookie from the previous gateway response.
        'threeDSResponse' => $_POST, // <-- Note here no fields are hard coded. Whatever is POSTED from 3DS is returned.
    );
 
    // Sign the request
    $threeDSRequest['signature'] = createSignature($threeDSRequest, $key);
 
    // Send the 3DS response back to the gateway and get the response.
    $gatewayResponse = sendRequest($threeDSRequest, $gatewayURL);
 
    // Store the new threeDSRef in the cookie again because it may change.
    setcookie('threeDSRef', $gatewayResponse['threeDSRef'], time()+500);
 
    // Output request
    echo '<h2>Request</h2>';
    echo "<pre>";
    print_r($threeDSRequest);
    echo "</pre>";
 
    echo http_build_query($threeDSRequest);
 
    // Output gateway response
    echo '<h2>Response</h2>';
    echo "<pre>";
    print_r($gatewayResponse);
    echo "</pre>";
 
 
    //This cycle continues until the response is 0 and the transaction is complete.
 
}
 
/**
 * Send request
 *
 * @param Array $request
 * @param String $gatewayURL
 *
 * @return Array $responseponse
 */
function sendRequest($request, $gatewayURL) {
 
    // Send request to the gateway
 
    // Initiate and set curl options to post to the gateway
    $ch = curl_init($gatewayURL);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($request));
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
    // Send the request and parse the response
    parse_str(curl_exec($ch), $response);
 
    // Close the connection to the gateway
    curl_close($ch);
 
    // Check the response code for 3DS Authentication (65802). If 3DS authentication required
    // Build a HTML form to submit to the threeDSURL
 
    if ($response['responseCode'] == 65802) {
 
    // Start of HTML form with URL
    echo "<p>Your transaction requires 3D Secure Authentication</p>
            <form action=\"" . htmlentities($response['threeDSURL']) . "\"method=\"post\">";
 
    // Add threeDSRef from the gateway response
    echo '<input type="hidden" name="threeDSRef" value="'. $response['threeDSRef'] . '">';
 
    // For each of the fields in threeDSRequest output a hidden input field with it's key/value
    foreach($response['threeDSRequest'] as $key => $value) {
        echo '<input type="hidden" name="'. $key .'" value="'. $value. '">';
    }
 
    // End of html form with submit button.
    echo "<input type=\"submit\" value=\"Continue\">
            </form>";
 
 
    // If 3DS authentication isn't required check gateway response.
    } else if ($response['responseCode'] === "0") {
        echo "<p>Thank you for your payment.</p>";
 
    } else {
        echo "<p>Failed to take payment: " . htmlentities($response['responseMessage']) .  "</p>";
    }
 
    return $response;
}
 
/**
 * Sign request
 *
 * @param Array $data
 * @param String $key
 *
 * @return String Hash
 */
function createSignature(array $data, $key) {
    // Sort by field name
    ksort($data);
 
    // Create the URL encoded signature string
    $ret = http_build_query($data, '', '&');
 
    // Normalise all line endings (CRNL|NLCR|NL|CR) to just NL (%0A)
    $ret = str_replace(array('%0D%0A', '%0A%0D', '%0D'), '%0A', $ret);
 
    // Hash the signature string and the key together
    return hash('SHA512', $ret . $key);
}
 ?>
 
Last updated on November 3, 2023