Blink Integration
Introduction
The aim of this guide is to show you how to integrate your website with the Blink gateway so that you can accept payments straight from your website. If you require a more advanced integration, please contact our Integrations Team.
Important Update: 🚀 Explore our revamped REST API!
To take advantage of our latest features and improvements, we invite you to check out our new and updated REST API documentation. Head over to the New API Documentation for the most up-to-date information and seamless integration.
Prerequisites
Merchant Gateway ID e.g.
233508
Secret Key e.g.
<T4NW>)dic
Basic understanding of php and web development.
Integration Types
Hosted
The request is made using the URL: https://gateway2.blinkpayment.co.uk/hosted/modal, with the merchant credentials (MID and encrypted signature key), amount, reference and customer details.
When initiated, the hosted integration will redirect the customer from the merchant site to the Blink , where the customer fills in their card details and pays.
Once the customer has completed the payment, they can be redirected back to the merchant site. The response fields can be sent to the merchant site.
Benefits
Easy setup
Secure (Payment journey is handled completely by Blink)
Disadvantages
Redirects - Customer has to leave merchant site ( the gateway can be opened in an iframe, overlaying the merchant site, which mitigates this issue).
Takes longer for customer to go through payment journey.
Customisation is difficult and limited.
Direct
The IP address of the merchant site must be whitelisted by Blink.
The merchant site must have a valid SSL (for 3DS transactions).
The request is made using the URL: https://gateway2.blinkpayment.co.uk/direct. unlike the hosted integration, all the required fields (amount, name, card number…) can be sent in one form, making the payment journey quicker and easier.
When initiated, the transaction request details are sent to the gateway from the site.
Once the payment is complete, the response is sent immediately to the merchant site.
Benefits
Customer stays on the merchant site for the whole payment life cycle.
Fully customisable.
Disadvantages
More vulnerable to security issues/ attacks (using hosted fields can mitigate this issue).
Troubleshooting can be more difficult.
Set up is more complicated as it requires IP whitelisting and implementing 3DS checking code.
Request
Required Fields
Field Name | Description | |
---|---|---|
1 | Merchant ID | Your Merchant Gateway ID (Can be found on Take a Payment and Request a Payment) |
2 | signature
| Unique key related to your merchant ID. Please contact our support team to find out your signature key. |
3 | action | The Action requested. Typically, SALE |
4 | amount | Transaction Amount |
5 | type | 1 - E-commerce (ECOM) - standard online payments. 2 - Mail Order Telephone Order (MOTO) - the merchant inputs the customer’s card details. 9 - Continuous Authority (CA) - for recurring and rerunning transactions. |
6 | countryCode | Merchant’s Location (for UK 826) |
7 | currencyCode | Transaction currency code (for UK 826) |
8 | cardNumber | The primary account number (PAN). Digits and spaces only - Direct Integration Only |
9 | cardExpiryMonth | The card’s expiry month from 1 to 12. - Direct Integration Only |
10 | cardExpiryYear | The card’s expiry year from 00 to 99. - Direct Integration Only |
11 | cardCVV | Payment card’s security number. The 3 or 4 digit number printed on the signature strip. - Direct Integration Only |
Recommended (Optional) Fields
Field Name | Description | |
---|---|---|
1 | transactionUnique | You can supply a unique identifier for this transaction. This is an added security feature to combat transaction spoofing. |
2 | customerName | Name of Customer |
3 | customerEmail | Email Address of customer |
4 | customerAddress | Address of customer - may be required depending on AVS checks |
5 | customerPostCode | Post code of customer - may be required depending on AVS checks |
6 | orderRef | Free format text field to store order details, reference numbers, etc. for the Merchant’s records. Essentially, an additional identifier. |
7 | redirectURL | URL to which the hosted form will redirect the Customer’s browser after the transaction has been completed. (Only relevant to Hosted integration) |
8 | rtAgreementType | Providing the Customer agrees, the Merchant is allowed to ‘store’ the transaction with the Gateway and re-use the card details for future transactions (using the 'xref' field mentioned below) This allows the Merchant to rerun a previous SALE (or to capture a Pre-Auth or Verify on the Blink platform itself). You must send this field through for the subsequent transactions to be successful Recommended value: cardonfile |
Advanced Fields
Field Name | Description | |
---|---|---|
1 | orderDate | Recorded date of the transaction |
2 | xref | Refers to a pervious transaction, this is used to rerun or refund previous transactions. |
3 | captureDelay | Delay the actual money transfer by an amount of days. |
4 | merchantPwd | Additional password to increase authentication security. |
Response
Field Name | Always Returned? | Description |
---|---|---|
responseCode | Yes | A numeric code providing the specific outcome. Common values are: 0 - Successful / authorised transaction. 1 - Card referred – Refer to card issuer. 2 - Card referred – Special condition. 4 - Card declined – Keep card. 5 - Card declined |
responseStatus | Yes | A numeric code providing the outcome category. Possible values are: 0 – Authorisation Approved / No reason to decline 1 – Authorisation Declined. 2 – Authorisation Error / Transaction malformed. |
responseMessage | Yes | Message received from the Acquiring bank, or any error message. |
transactionID | Yes | A unique ID assigned by the Gateway. |
acquirerResponseXXXX | Depends on the acquirer | Additional Response sent by acquirer |
xref | Yes | Used to rerun or refund transactions at a later point. |
state | Yes | Transaction state |
timestamp | Yes | The time when the transaction was last modified |
cardNumberMask | Yes | The first 4 digits and last 4 digits of the customer’s PAN card number. The rest of the digits are encrypted. |
transactionUnique | If sent in request | Any value supplied in the initial request. |
orderRef | If sent in request | Any value supplied in the initial request. |
authorisationCode | If transaction was successful | Authorisation code (Auth Code) received from Acquirer. |
amountReceived | If transaction was successful | Amount the Acquirer authorised. This should always be the full amount in the request. |
cardTypeCode | Yes | Code identifying the type of card used. |
cardType | Yes | Description of the type of card used. |
cardSchemeCode | Yes | Code identifying the Card Scheme used. |
cardScheme | Yes | Description of the Card Scheme used. |
cardIssuer | Yes | Card Issues name |
cardIssuerCountry | Yes | Card issuing country’s name |
cardIssuerCountryCode | Yes | Card issuing country’s ISO-3166 2-letter code |
amountRefunded | If it is a refund | Total amount of original SALE that has so far been refunded. Returned when action is REFUND_SALE |
Test Accounts
If you would like to test an integration, please be in touch with our integrations team, who will send you Blink test account credentials. The merchant will be able to see the test transactions on their Blink account.
Test Card Details
Card Type | Card Number | CVV | Expiry Date | Address |
---|---|---|---|---|
Visa Credit | 4929 4212 3460 0821 | 356 | 12/24 | Flat 6 Primrose Rise 347 Lavender Road Northampton NN17 8YG |
4543 0599 9999 9982 | 110 | 12/24 | 76 Roseby Avenue Manchester M63X 7TH | |
4543 0599 9999 9990 | 689 | 12/24 | 23 Rogerham Mansions 4578 Ermine Street Borehamwood WD54 8TH | |
Visa Debit | 4539 7910 0173 0106 | 289 | 12/24 | Unit 5 Pickwick Walk 120 Uxbridge Road Hatch End Middlesex HA6 7HJ |
5301 2500 7000 0191 | 419 | 12/24 | Mews 57 Ladybird Drive Denmark 65890 | |
Mastercard Credit
| 5301 2500 7000 0191 | 419 | 12/24 | 25 The Larches Narborough Leicester LE10 2RT |
5413 3390 0000 1000 | 304 | 12/24 | Pear Tree Cottage The Green Milton Keynes MK11 7UY | |
5434 8499 9999 9951 | 470 | 12/24 | 34a Rubbery Close Cloisters Run Rugby CV21 8JT | |
5434 84999 999 9993 | 557 | 12/24 | 4-7 The Hay Market Grantham NG32 4HG | |
Mastercard Debit | 5573 4712 3456 7898 | 159 | 12/24 | Merevale Avenue Leicester LE10 2BU |
UK Maestro | 6759 0150 5012 3445 002 | 309 | 12/24 | The Parkway 5258 Larches Approach Hull North Humberside HU10 5OP |
6759 0168 0000 0120 097 | 701 | 12/24 | The Manor Wolvey Road Middlesex TW7 9FF | |
American Express | 3742 4545 5400 001 | 4887 | 12/24 | The Hunts Way Southampton SO18 1GW |
Electron | 4917 4800 0000 0008 | 009 | 12/24 | 5-6 Ross Avenue Birmingham B67 8UJ |
JCB | 3540 5999 9999 1047 | 209 | 12/24 | 2 Middle Wallop Merideth-in-the-Wolds Lincolnshire LN2 8HG |
Test Transactions Limits
Range (£) | Authorisation Response | Settlement Outcome |
---|---|---|
0.00-0.99 | 66311 (Invalid Test Amount) | N/A |
1.00 -24.99 | (0) AUTH CODE: XXXXXX | ACCEPTED |
25.00-49.99 | (0) AUTH CODE: XXXXXX | REJECTED |
50.00-74.99 | (1) CARD REFERRED | ACCEPTED |
75.00-99.99 | (1) CARD REFERRED | REJECTED |
100.00-149.99 | (5) CARD DECLINED | N/A |
150.00-199.99 | (4) CARD DECLINED – KEEP CARD | N/A |
200.00-249.99 | (65) CARD DECLINED - SCA REQUIRED | ACCEPTED |
250.00-299.99 | (65) CARD DECLINED - SCA REQUIRED (0) AUTH CODE: XXXXX | N/A |
300 and greater | 66311 (Invalid Test Amount) | N/A |
Sample Codes
Hosted Integration
<?php
//Merchant ID
$merchantID = '233508';
// Merchant Signature key
$key = '<T4NW>)dic';
// Gateway URL
$url = 'https://gateway2.blinkpayment.co.uk/hosted/modal';
if (!isset($_POST['responseCode'])) {
// Send request to gateway
// Request
$req = array(
'merchantID' => $merchantID,
'action' => 'SALE',
'type' => 1,
'countryCode' => 826,
'currencyCode' => 826,
'amount' => 1001,
'orderRef' => 'Test purchase',
'rtAgreementType' => 'cardonfile',
'transactionUnique' => uniqid(),
'redirectURL' => ($_SERVER['HTTPS'] == 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'],
);
// Create the signature using the function called below.
$req['signature'] = createSignature($req, $key);
echo '<form action="' . htmlentities($url) . '" method="post">' . php_EOL;
foreach ($req as $field => $value) {
echo ' <input type="hidden" name="' . $field . '" value="' . htmlentities($value) . '">' . php_EOL;
}
echo ' <input type="submit" value="Pay Now">' . php_EOL;
echo '</form>' . php_EOL;
// Check the return signature
if (!$signature || $signature !== createSignature($res, $key)) {
// You should exit gracefully
die('Sorry, the signature check failed');
}
// Check the response code
if ($res['responseCode'] === "0") {
echo "<p>Thank you for your payment.</p>";
} else {
echo "<p>Failed to take payment: " . htmlentities($res['responseMessage']) . "</p>";
}
}
// Function to create a message signature
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);
}
?>
Direct Integration (with 3DS)
<?php
// Gateway Merchant ID
$merchantID = '233508';
// Signature key. The demo account is fixed to this value,
$key = '<T4NW>)dic';
// If you don't know your Merchant ID or signature key, please be in touch.
// Gateway URL
$url = 'https://gateway2.blinkpayment.co.uk/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 (!empty($_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' => $merchantID,
'action' => 'SALE',
'type' => 1,
'currencyCode' => 826,
'countryCode' => 826,
'amount' => 901,
'cardNumber' => '4543059999999990',
'cardExpiryMonth' => 12,
'cardExpiryYear' => 24,
'cardCVV' => '689',
'customerName' => 'Test Customer',
'customerEmail' => 'test@testcustomer.com',
'customerAddress' => '16 Test Street',
'customerPostCode' => 'Tef 5ST',
'orderRef' => '3DS test purchase',
'rtAgreementType' => 'cardonfile',
// The following fields are mandatory for 3DS v2
'remoteAddress' => $_SERVER['REMOTE_ADDR'],
'threeDSRedirectURL' => $pageURL . '&acs=1',
// The following field allows options to be passed for 3DS v2
// and the values here are for demonstration purposes only
'threeDSOptions' => array(
'paymentAccountAge' => '20190601',
'paymentAccountAgeIndicator' => '05',
),
);
// Add the browser info as it is mandatory for 3DS v2
$req += $_POST['browserInfo'];
} else {
// 3DS continuation request
$req = array(
'threeDSRef' => $_SESSION['threeDSRef'],
'threeDSResponse' => $_POST['threeDSResponse'],
);
}
// Create the signature using the function called below.
$req['signature'] = createSignature($req, $key);
// Initiate and set cURL options to post to the gateway
$ch = cURL_init($url);
cURL_setopt($ch, CURLOPT_POST, true);
cURL_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($req));
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
if (($res = cURL_exec($ch)) === false) {
// You should exit gracefully
die('Sorry, the request could not be sent: ' . cURL_error($ch));
}
parse_str($res, $res);
// Close the connection to the gateway
cURL_close($ch);
// Extract the return signature as this isn't hashed
$signature = null;
if (isset($res['signature'])) {
$signature = $res['signature'];
unset($res['signature']);
}
// Check the return signature
if (!$signature || $signature !== createSignature($res, $key)) {
// You should exit gracefully
die('Sorry, the signature check failed');
}
// Check the response code
if ((int)$res['responseCode'] === 65802) {
// 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 ((int)$res['responseCode'] === 0) {
echo "<p>Thank you for your payment.</p>";
} else {
echo $res['responseCode'];
echo "<p>Failed to take payment: :( " . htmlentities($res['responseMessage']) . "</p>";
}
// Function to create a message signature
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);
}
// Return HTML to render a hidden form used to collect some browser details
function collectBrowserInfo(array $options = null) {
$form_attrs = 'id="collectBrowserInfo" method="post" action="?"';
if (isset($options['formAttrs'])) {
$form_attrs .= $options['formAttrs'];
}
$device_data = array(
'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' => (isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? htmlentities($_SERVER['HTTP_ACCEPT_ENCODING']) : null),
'deviceAcceptLanguage' => (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? htmlentities($_SERVER['HTTP_ACCEPT_LANGUAGE']) : null),
'deviceAcceptCharset' => (isset($_SERVER['HTTP_ACCEPT_CHARSET']) ? htmlentities($_SERVER['HTTP_ACCEPT_CHARSET']) : null),
);
$form_fields = fieldToHtml('browserInfo', $device_data);
if (isset($options['formData'])) {
foreach ((array)$options['formData'] as $name => $value) {
$form_fields .= fieldToHtml($name, $value);
}
}
$ret = <<<EOS
<form {$form_attrs}>
{$form_fields}
</form>
<script>
var screen_width = (window && window.screen ? window.screen.width : '0');
var screen_height = (window && window.screen ? window.screen.height : '0');
var screen_depth = (window && window.screen ? window.screen.colorDepth : '0');
var identity = (window && window.navigator ? window.navigator.userAgent : '');
var language = (window && window.navigator ? (window.navigator.language ? window.navigator.language : window.navigator.browserLanguage) : '');
var timezone = (new Date()).getTimezoneOffset();
var java = (window && window.navigator ? navigator.javaEnabled() : false);
var fields = document.forms.collectBrowserInfo.elements;
fields['browserInfo[deviceIdentity]'].value = identity;
fields['browserInfo[deviceTimeZone]'].value = timezone;
fields['browserInfo[deviceCapabilities]'].value = 'javascript' + (java ? ',java' : '');
fields['browserInfo[deviceAcceptLanguage]'].value = language;
fields['browserInfo[deviceScreenResolution]'].value = screen_width + 'x' + screen_height + 'x' + screen_depth;
window.setTimeout('document.forms.collectBrowserInfo.submit()', 0);
</script>
EOS;
return $ret;
}
// 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 .= 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;
}
// Return a value as hidden HTML FORM fields
function fieldToHtml($name, $value) {
$ret = '';
if (is_array($value)) {
foreach ($value as $n => $v) {
$ret .= fieldToHtml($name . '[' . $n . ']', $v);
}
} else {
// Convert all applicable characters or none printable characters to HTML entities
if(!$value) $value = " ";
$value = preg_replace_callback('/[\x00-\x1f]/', function($matches) { return '&#' . ord($matches[0]) .';'; }, htmlentities($value, ENT_COMPAT, 'UTF-8', true));
$ret = "<input type=\"hidden\" name=\"{$name}\" value=\"{$value}\" />\n";
}
return $ret;
}
?>
Ecommerce Modules
Blink offers ready-to-use plugins for WooCommerce and Magento websites. They use the hosted integration and are fully connected to the reporting, and tracking features on both platforms, i.e. a successful payment will generate an order for the merchant to fill.