
Example Integration Code
Quick Find
Go straight to the section you need.
1.0 Gateway Integration →
2.0 New Transactions →
3.0 Management Requests →
4.0 AVS/CV2 Checking →
5.0 3-D Secure Authentication →
11 Receipts and Notifications →
17 Advanced Data →
17.7 Device Information Fields
19 Gateway Wallet →
26 Digital Wallet Transactions →
Appendix
A-1 Response Codes
A-1.1 Authorisation Response Codes
A-2 AVS / CV2 Check Response Codes
A-3 Secure Authentication Data
A-4 3-D Secure Enrolment/Authentication Only
A-9 Duplicate Transaction Checking
A-10 Capture Delay
A-13 Sample Signature Calculation
A-14 Transaction Life cycle
A-14.1 Authorise, Capture and Settlement
A-15.2 Mail Order/Telephone Order (MOTO)
A-15.3 Continuous Authority (CA)
A-16 Payment Tokenisation
A-16.1 PREAUTH, SALE, REFUND, VERIFY requests
A-16.3 CANCEL or CAPTURE requests
A-16.5 SALE or REFUND Referred Authorisation requests
A-18 PSD2 SCA Compliance
A-18.1 Obtaining Strong Customer Authentication
A-18.3 Exemptions to Strong Customer Authentication
A-19 Hosted Payment Page Options
A-20 Integration Libraries
A-20.1 Gateway Integration Library
A-20.2 Hosted Payment Page Library
A-20.3 Hosted Payment Fields Library
A-21 Example HTTP Requests
A-22 Example Integration Code
A-23 Example Library Code
A-23.1 Gateway Integration Library
A-22 Example Integration Code
The follow section provides samples of how to integrate with the Gateway using the PHP scripting language to communicate directly with the API without the use of any our SDKs.
A-22.1 Hosted Integration
A-22.1.1 Sale Transaction
The following example PHP code shows how to send a SALE transaction:
<?PHP
// Signature key entered on MMS. The demo accounts is fixed to this value,
$merchantID = ‘100856’;//sandbox
$key = ‘Circle4Take40Idea’;//sandbox
// Gateway URL
$url = ‘https://gateway.cardstream.com/hosted/’;//sandbox
$samplecodeURL = (isset($_SERVER[‘HTTPS’]) && $_SERVER[‘HTTPS’] === ‘on’ ? “https” : “http”) . “://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]”;
if (!isset($_POST[‘responseCode’])) {
// Send request to gateway
// Request
$req = array(
‘merchantID’ => $merchantID,
‘action’ => ‘SALE’,
‘amount’ => ‘100’,
‘countryCode’ => ‘GBR’,
‘currencyCode’ => ‘GBP’,
‘customerAddress’ => ‘1 Second Street’,
‘customerEmail’ => ‘john.smith@gmail.com’,
‘customerName’ => ‘John Smith’,
‘customerPostcode’ => ‘RG1 1AB’,
‘orderRef’ => ‘Order reference/SKU’,
‘redirectURL’ => $samplecodeURL,
‘transactionUnique’=> ‘PSTECH-‘ . uniqid(2),
// Pre fill form – this is here for reference only
// ‘cardNumber’ => ‘4012001037141112’,
// ‘cardExpiryMonth’ => 12,
// ‘cardExpiryYear’ => 21,
// ‘cardCVV’ => ‘083’,
);
// 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;
} else {
// Handle the response posted back
$res = $_POST;
print_r($_POST);
// 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 ($res[‘responseCode’] === “0”) {
echo “<p>Thank you for your payment.</p>” . $res[‘xref’];
} else {
echo “<p>Failed to take payment ” . $res[‘xref’]. “: ” . 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);
}
?>
A-22.2 Direct Integration
A-22.2.1 Sale Transaction (with 3-D Secure)
The following example PHP code shows how to send a SALE transaction with support for 3-D Secure:
1. <?PHP
2.
3. // Signature key entered on MMS. The demo account is fixed to this value,
4. $key = ‘Circle4Take40Idea’;
5.
6. // Gateway URL
7. $url = ‘https://gateway.example.com/direct/’;
8.
9. // Setup PHP session as use it to store data between 3DS steps
10. if (isset($_GET[‘sid’])) {
11. session_id($_GET[‘sid’]);
12. }
13.
14. session_start();
15.
16. // Compose current page URL (removing any sid and acs parameters)
17. $pageUrl = ((isset($_SERVER[‘HTTPS’]) && $_SERVER[‘HTTPS’] == ‘on’) ? ‘https://’ : ‘http://’)
18. . $_SERVER[‘SERVER_NAME’] . ($_SERVER[‘SERVER_PORT’] != ’80’ ? ‘:’ . $_SERVER[‘SERVER_PORT’] : ”)
19. . preg_replace(‘/(sid=[^&]+&?)|(acs=1&?)/’, ”, $_SERVER[‘REQUEST_URI’]);
20.
21. // Add back the correct sid parameter (used as session cookie may not be passed when the page is redirected fr
om an IFRAME)
22. $pageUrl .= (strpos($pageUrl, ‘?’) === false ? ‘?’ : ‘&’) . ‘sid=’ . urlencode(session_id());
23.
24.
25. // If ACS response into the IFRAME then redirect back to parent window
26. if (!emptyempty($_GET[‘acs’])) {
27. echo silentPost($pageUrl, array(‘threeDSResponse’ => $_POST), ‘_parent’);
28. exit();
29. }
30.
31. if (!isset($_POST[‘threeDSResponse’])) {
32. // Initial request
33.
34. // Gather browser info – can be done at any time prior to the checkout
35. if (!isset($_POST[‘browserInfo’])) {
36. echo collectBrowserInfo();
37. exit();
38. }
39.
40. // Direct Request
41. $req = array(
42. ‘merchantID’ => 100001,
43. ‘action’ => ‘SALE’,
44. ‘type’ => 1,
45. ‘currencyCode’ => 826,
46. ‘countryCode’ => 826,
47. ‘amount’ => 1001,
48. ‘cardNumber’ => ‘4012001037141112’,
49. ‘cardExpiryMonth’ => 12,
50. ‘cardExpiryYear’ => 15,
51. ‘cardCVV’ => ‘083’,
52. ‘customerName’ => ‘Test Customer’,
53. ‘customerEmail’ => ‘test@testcustomer.com’,
54. ‘customerAddress’ => ’16 Test Street’,
55. ‘customerPostCode’ => ‘TE15 5ST’,
56. ‘orderRef’ => ‘Test purchase’,
57.
58. // The following fields are mandatory for 3DS v2
59. ‘remoteAddress’ => $_SERVER[‘REMOTE_ADDR’],
60. ‘threeDSRedirectURL’ => $pageUrl . ‘&acs=1’,
61.
62. // The following field allows options to be passed for 3DS v2
63. // and the values here are for demonstration purposes only
64. ‘threeDSOptions’ => array(
65. ‘paymentAccountAge’ => ‘20190601’,
66. ‘paymentAccountAgeIndicator’ => ’05’,
67. ),
68. );
69.
70. // Add the browser info as it is mandatory for 3DS v2
71. $req += $_POST[‘browserInfo’];
72.
73. } else {
74. // 3DS continuation request
75. $req = array(
76. ‘threeDSRef’ => $_SESSION[‘threeDSRef’],
77. ‘threeDSResponse’ => $_POST[‘threeDSResponse’],
78. );
79.
80. }
81.
82. // Create the signature using the function called below.
83. $req[‘signature’] = createSignature($req, $key);
84.
85. // Initiate and set curl options to post to the gateway
86. $ch = curl_init($url);
87. curl_setopt($ch, CURLOPT_POST, true);
88. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($req));
89. curl_setopt($ch, CURLOPT_HEADER, false);
90. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
91. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
92.
93. // Send the request and parse the response
94. if (($res = curl_exec($ch)) === false) {
95. // You should exit gracefully
96. die(‘Sorry, the request could not be sent: ‘ . curl_error($ch));
97. }
98.
99. parse_str($res, $res);
100.
101.// Close the connection to the gateway
102.curl_close($ch);
103.
104.// Extract the return signature as this isn’t hashed
105.$signature = null;
106.if (isset($res[‘signature’])) {
107. $signature = $res[‘signature’];
108. unset($res[‘signature’]);
109.}
110.
111.// Check the return signature
112.if (!$signature || $signature !== createSignature($res, $key)) {
113. // You should exit gracefully
114. die(‘Sorry, the signature check failed’);
115.}
116.
117.// Check the response code
118.if ((int)$res[‘responseCode’] === 65802) {
119. // Send request to the ACS server displaying response in an IFRAME
120.
121. // Render an IFRAME to show the ACS challenge (hidden for fingerprint method)
122. $style = (isset($res[‘threeDSRequest’][‘threeDSMethodData’]) ? ‘display: none;’ : ”);
123. echo “<iframe name=\”threeds_acs\” style=\”height:420px; width:420px; {$style}\”></iframe>\n”;
124.
125. // Silently POST the 3DS request to the ACS in the IFRAME
126. echo silentPost($res[‘threeDSURL’], $res[‘threeDSRequest’], ‘threeds_acs’);
127.
128. // Remember the threeDSRef as need it when the ACS responds
129. $_SESSION[‘threeDSRef’] = $res[‘threeDSRef’];
130.
131.} else if ((int)$res[‘responseCode’] === 0) {
132. echo “<p>Thank you for your payment.</p>”;
133.} else {
134. echo “<p>Failed to take payment: ” . htmlentities($res[‘responseMessage’]) . “</p>”;
135.}
136.
137.// Function to create a message signature
138.function createSignature(array $data, $key) {
139. // Sort by field name
140. ksort($data);
141.
142. // Create the URL encoded signature string
143. $ret = http_build_query($data, ”, ‘&’);
144.
145. // Normalise all line endings (CRNL|NLCR|NL|CR) to just NL (%0A)
146. $ret = str_replace(array(‘%0D%0A’, ‘%0A%0D’, ‘%0D’), ‘%0A’, $ret);
147.
148. // Hash the signature string and the key together
149. return hash(‘SHA512’, $ret . $key);
150.}
151.
152.// Return HTML to render a hidden form used to collect some browser details
153.function collectBrowserInfo(array $options = null) {
154.
155. $form_attrs = ‘id=”collectBrowserInfo” method=”post” action=”?”‘;
156.
157. if (isset($options[‘formAttrs’])) {
158. $form_attrs .= $options[‘formAttrs’];
159. }
160.
161. $device_data = array(
162. ‘deviceChannel’ => ‘browser’,
163. ‘deviceIdentity’ => (isset($_SERVER[‘HTTP_USER_AGENT’]) ? htmlentities($_SERVER[‘HTTP_USER_
AGENT’]) : null),
164. ‘deviceTimeZone’ => ‘0’,
165. ‘deviceCapabilities’ => ”,
166. ‘deviceScreenResolution’ => ‘1x1x1’,
167. ‘deviceAcceptContent’ => (isset($_SERVER[‘HTTP_ACCEPT’]) ? htmlentities($_SERVER[‘HTTP_ACCEPT’])
: null),
168. ‘deviceAcceptEncoding’ => (isset($_SERVER[‘HTTP_ACCEPT_ENCODING’]) ? htmlentities($_SERVER[‘HTTP_
ACCEPT_ENCODING’]) : null),
169. ‘deviceAcceptLanguage’ => (isset($_SERVER[‘HTTP_ACCEPT_LANGUAGE’]) ? htmlentities($_SERVER[‘HTTP_
ACCEPT_LANGUAGE’]) : null),
170. ‘deviceAcceptCharset’ => (isset($_SERVER[‘HTTP_ACCEPT_CHARSET’]) ? htmlentities($_SERVER[‘HTTP_A
CCEPT_CHARSET’]) : null),
171. );
172.
173. $form_fields = fieldToHtml(‘browserInfo’, $device_data);
174.
175. if (isset($options[‘formData’])) {
176. foreach ((array)$options[‘formData’] as $name => $value) {
177. $form_fields .= fieldToHtml($name, $value);
178. }
179. }
180.
181. $ret = <<<EOS
182. <form {$form_attrs}>
183. {$form_fields}
184. </form>
185. <script>
186. var screen_width = (window && window.screen ? window.screen.width : ‘0’);
187. var screen_height = (window && window.screen ? window.screen.height : ‘0’);
188. var screen_depth = (window && window.screen ? window.screen.colorDepth : ‘0’);
189. var identity = (window && window.navigator ? window.navigator.userAgent : ”);
190. var language = (window && window.navigator ? (window.navigator.language ? window.navigator.languag
e : window.navigator.browserLanguage) : ”);
191. var timezone = (new Date()).getTimezoneOffset();
192. var java = (window && window.navigator ? navigator.javaEnabled() : false);
193. var fields = document.forms.collectBrowserInfo.elements;
194. fields[‘browserInfo[deviceIdentity]’].value = identity;
195. fields[‘browserInfo[deviceTimeZone]’].value = timezone;
196. fields[‘browserInfo[deviceCapabilities]’].value = ‘javascript’ + (java ? ‘,java’ : ”);
197. fields[‘browserInfo[deviceAcceptLanguage]’].value = language;
198. fields[‘browserInfo[deviceScreenResolution]’].value = screen_width + ‘x’ + screen_height + ‘x’ + s
creen_depth;
199. window.setTimeout(‘document.forms.collectBrowserInfo.submit()’, 0);
200. </script>
201.EOS;
202.
203. return $ret;
204.}
205.
206.// Render HTML to silently POST data to URL in target brower window
207.function silentPost($url = ‘?’, array $post = null, $target = ‘_self’) {
208.
209. $url = htmlentities($url);
210. $target = htmlentities($target);
211. $fields = ”;
212.
213. if ($post) {
214. foreach ($post as $name => $value) {
215. $fields .= fieldToHtml($name, $value);
216. }
217. }
218.
219. $ret = “
220. <form id=\”silentPost\” action=\”{$url}\” method=\”post\” target=\”{$target}\”>
221. {$fields}
222. <noscript><input type=\”submit\” value=\”Continue\”></noscript>
223. </form>
224. <script>
225. window.setTimeout(‘document.forms.silentPost.submit()’, 0);
226. </script>
227. “;
228.
229. return $ret;
230.}
231.
232.// Return a value as hidden HTML FORM fields
233.function fieldToHtml($name, $value) {
234. $ret = ”;
235. if (is_array($value)) {
236. foreach ($value as $n => $v) {
237. $ret .= fieldToHtml($name . ‘[‘ . $n . ‘]’, $v);
238. }
239. } else {
240. // Convert all applicable characters or none printable characters to HTML entities
241. $value = preg_replace_callback(‘/[\x00-\x1f]/’, function($matches) { return ‘&#’ . ord($matches[0]) .
‘;’; }, htmlentities($value, ENT_COMPAT, ‘UTF-8’, true));
242. $ret = “<input type=\”hidden\” name=\”{$name}\” value=\”{$value}\” />\n”;
243. }
244.
245. return $ret;
246.}
247.
248.
249.?>
A-22.2.2 Sale Transaction (without 3-D Secure)
The following sample PHP code shows how to send a SALE transaction without support for 3-D Secure:
- <?PHP
- // Signature key entered on MMS. The demo account is fixed to this value,
- $key = ‘Circle4Take40Idea’;
- // Gateway URL
- $url = ‘https://gateway.swipen.com/direct/’;
- // Request
- $req = array(
- ‘merchantID’ => ‘100001’,
- ‘action’ => ‘SALE’,
- ‘type’ => 1,
- ‘countryCode’ => 826,
- ‘currencyCode’ => 826,
- ‘amount’ => 1001,
- ‘cardNumber’ => ‘4012001037141112’,
- ‘cardExpiryMonth’ => 12,
- ‘cardExpiryYear’ => 15,
- ‘cardCVV’ => ‘083’,
- ‘customerName’ => ‘Test Customer’,
- ‘customerEmail’ => ‘test@testcustomer.com’,
- ‘customerPhone’ => ‘+44 (0) 123 45 67 890’,
- ‘customerAddress’ => ’16 Test Street’,
- ‘customerPostCode’ => ‘TE15 5ST’,
- ‘orderRef’ => ‘Test purchase’,
- ‘transactionUnique’ => uniqid(),
- );
- // 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
- parse_str(curl_exec($ch), $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 ($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);
- }
- ?>
A-22.3 Batch Integration
A-22.3.1 Batch Submission
The following example PHP code shows how to send a batch request containing three SALE transactions:
- <?PHP
- // Signature key entered on MMS. The demo account is fixed to this value,
- $key = ‘Circle4Take40Idea’;
- // Gateway URL
- $url = ‘https://gateway.swipen.com/batch/’;
- // Create a unique multipart boundary
- $boundary = uniqid();
- // Requests
- $reqs = array(
- 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’,
- ‘transactionUnique’ => uniqid(),
- ‘threeDSRequired’ => ‘N’,
- ‘avscv2CheckRequired’ => ‘N’,
- ),
- array(
- ‘merchantID’ => 100001,
- ‘action’ => ‘SALE’,
- ‘type’ => 1,
- ‘currencyCode’ => 826,
- ‘countryCode’ => 826,
- ‘amount’ => 2002,
- ‘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’,
- ‘transactionUnique’ => uniqid(),
- ‘threeDSRequired’ => ‘N’,
- ‘avscv2CheckRequired’ => ‘N’,
- ),
- array(
- ‘merchantID’ => 100001,
- ‘action’ => ‘SALE’,
- ‘type’ => 1,
- ‘currencyCode’ => 826,
- ‘countryCode’ => 826,
- ‘amount’ => 3003,
- ‘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’,
- ‘transactionUnique’ => uniqid(),
- ‘threeDSRequired’ => ‘N’,
- ‘avscv2CheckRequired’ => ‘N’,
- ),
- );
- // Create the batch parts
- $parts = array();
- foreach ($reqs as $req) {
- // Create the signature using the function called below.
- $req[‘signature’] = createSignature($req, $key);
- $parts[] =
- “Content-Id: TX{$req[‘transactionUnique’]}\r\n” .
- “Content-Type: application/x-www-form-urlencoded; charset=\”UTF-8\”\r\n” .
- “\r\n” .
- http_build_query($req);
- }
- // Join the parts together separated by the boundary string
- $post = “\r\n–{$boundary}\r\n” . join(“\r\n–{$boundary}\r\n”, $parts) . “\r\n–{$boundary}–\r\n”;
- // 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, $post);
- curl_setopt($ch, CURLOPT_HEADER, true);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
100.curl_setopt($ch, CURLOPT_HTTPHEADER, array(
- ‘Content-type: multipart/mixed; charset=”UTF-8″; boundary=’ . $boundary,
- ‘Content-length: ‘ . strlen($post),
103.));
105.// Send the request
106.$res = curl_exec($ch);
108.// Normally would process the response here, but for this example just echo it out
109.header (‘Content-Type: text/plain’);
110.echo $res . PHP_EOL;
112.// Close the connection to the gateway
113.curl_close($ch);
115.// Function to create a message signature
116.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);
128.}
130.?>