Skip to content

Commit b6a8a04

Browse files
authored
Merge pull request #4 from sequra/feature/PAR-571-Add-SeQura-Merchant-Id-header
Feature/PAR-571 Add Sequra-Merchant-Id header
2 parents 3008f43 + 102ebab commit b6a8a04

File tree

1 file changed

+139
-36
lines changed

1 file changed

+139
-36
lines changed

src/Client.php

Lines changed: 139 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88

99
class Client
1010
{
11+
const HEADER_SEQURA_MERCHANT_ID = 'Sequra-Merchant-Id';
12+
const HEADER_ACCEPT = 'Accept';
13+
const HEADER_CONTENT_TYPE = 'Content-Type';
14+
const HEADER_CONTENT_LENGTH = 'Content-Length';
15+
const TYPE_JSON = 'application/json';
16+
const TYPE_HTML = 'text/html';
1117

1218
public static $endpoint = '';
1319
public static $user = '';
@@ -22,11 +28,60 @@ class Client
2228

2329
private $success = false;
2430
private $cart_has_changed;
25-
private $headers;
31+
private $response_headers;
2632
private $status;
2733
private $curl_result = null;
2834
private $json = null;
2935
private $ch = null;
36+
/**
37+
* An array to store request headers.
38+
* @var array<string, string>
39+
*/
40+
private $request_headers;
41+
42+
/**
43+
* Sets a request header for the cURL request.
44+
*
45+
* @param string $name The name of the header. Must not be empty.
46+
* @param string $value The value of the header. Must not be empty.
47+
*/
48+
private function setRequestHeader($name, $value)
49+
{
50+
if (!is_array($this->request_headers)) {
51+
$this->resetRequestHeaders();
52+
}
53+
$name = trim((string) $name);
54+
$value = trim((string) $value);
55+
if ($value === '' || $name === '') {
56+
return;
57+
}
58+
$this->request_headers[$name] = $value;
59+
}
60+
61+
/**
62+
* Returns the request headers as an array of strings formatted as "Name: Value".
63+
*
64+
* @return array<string> An array of request headers formatted as "Name: Value".
65+
*/
66+
private function getRequestHeaders()
67+
{
68+
if (!is_array($this->request_headers)) {
69+
return array();
70+
}
71+
$headers = array();
72+
foreach ($this->request_headers as $name => $value) {
73+
$headers[] = $name . ': ' . $value;
74+
}
75+
return $headers;
76+
}
77+
78+
/**
79+
* Reset the request headers to an empty array.
80+
*/
81+
private function resetRequestHeaders()
82+
{
83+
$this->request_headers = array();
84+
}
3085

3186
public function __construct($user = null, $password = null, $endpoint = null, $debug = false, $logfile = null)
3287
{
@@ -42,14 +97,15 @@ public function __construct($user = null, $password = null, $endpoint = null, $d
4297
$this->log(self::class . " created!");
4398
}
4499

45-
public function isValidAuth($merchant = '')
100+
public function isValidAuth($merchant_id = '')
46101
{
47102
$this->initCurl(
48103
$this->_endpoint .
49-
'/merchants' .
50-
($merchant?'/'.urlencode($merchant):'').
51-
'/credentials'
104+
'/merchants' .
105+
($merchant_id ? '/' . urlencode($merchant_id) : '') .
106+
'/credentials'
52107
);
108+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $merchant_id);
53109
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'GET');
54110
$this->sendRequest();
55111
$this->dealWithResponse();
@@ -63,6 +119,7 @@ public function startSolicitation($order)
63119
}
64120

65121
$this->initCurl($this->_endpoint . '/orders');
122+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $order['merchant']['id'] ?? '');
66123
$this->verbThePayload('POST', array('order' => $order));
67124
$this->dealWithResponse();
68125
curl_close($this->ch);
@@ -80,25 +137,38 @@ public function qualifyForSolicitation($order)
80137
return true;
81138
}
82139

83-
public function getIdentificationForm($uri, $options = array())
140+
/**
141+
* Retrieves the identification form for a given URI and options.
142+
*
143+
* @param string $uri The URI to retrieve the identification form from.
144+
* @param array $options An associative array of options for the form.
145+
* @param string $merchant_id The merchant ID to be used in the request.
146+
*
147+
* @return string The HTML content of the identification form.
148+
*/
149+
public function getIdentificationForm($uri, $options = array(), $merchant_id = '')
84150
{
85151
$options["product"] = array_key_exists('product', $options) ? $options["product"] : "i1";
86152
$options["ajax"] = (isset($options["ajax"]) && $options["ajax"]) ? "true" : "false";
87153
$this->initCurl($uri . '/form_v2' . '?' . http_build_query($options));
88154
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'GET');
89-
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('Accept: text/html'));
155+
156+
$this->setRequestHeader(self::HEADER_ACCEPT, self::TYPE_HTML);
157+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $merchant_id);
158+
90159
$this->sendRequest();
91160
$this->dealWithResponse();
92161
curl_close($this->ch);
93162
return $this->curl_result;
94163
}
95164

96-
public function sendIdentificationForm($uri, $options = array())
165+
public function sendIdentificationForm($uri, $options = array(), $merchant_id = '')
97166
{
98167
$options["product"] = array_key_exists('product', $options) ? $options["product"] : "i1";
99168
$options["product_code"] = $options["product"];
100169
$options["channel"] = array_key_exists('channel', $options) ? $options["channel"] : "sms";
101170
$this->initCurl($uri . '/form_deliveries');
171+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $merchant_id);
102172
$this->verbThePayload('POST', $options);
103173
$this->dealWithResponse();
104174
curl_close($this->ch);
@@ -112,16 +182,20 @@ public function startCards($order)
112182
}
113183

114184
$this->initCurl($this->_endpoint . '/cards');
185+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $order['merchant']['id'] ?? '');
115186
$this->verbThePayload('POST', array('order' => $order));
116187
$this->dealWithResponse();
117188
curl_close($this->ch);
118189
}
119190

120-
public function getCardsForm($uri, $options = array())
191+
public function getCardsForm($uri, $options = array(), $merchant_id = '')
121192
{
122193
$this->initCurl($uri . '?' . http_build_query($options));
123194
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'GET');
124-
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('Accept: text/html'));
195+
196+
$this->setRequestHeader(self::HEADER_ACCEPT, self::TYPE_HTML);
197+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $merchant_id);
198+
125199
$this->sendRequest();
126200
$this->dealWithResponse();
127201
curl_close($this->ch);
@@ -138,51 +212,68 @@ public function qualifyForstartCards($order)
138212
);
139213
}
140214

141-
public function getMerchantPaymentMethods($merchant)
215+
public function getMerchantPaymentMethods($merchant_id)
142216
{
143-
$this->getPaymentMethods($this->_endpoint . '/merchants/' . $merchant);
217+
$this->getPaymentMethods($this->_endpoint . '/merchants/' . $merchant_id, array(), $merchant_id);
144218
}
145219

146-
public function getPaymentMethods($uri, $options = array())
220+
public function getPaymentMethods($uri, $options = array(), $merchant_id = '')
147221
{
148222
if (!preg_match('!^https?://!', $uri)) {
149223
$uri = $this->_endpoint . '/orders/' . $uri;
150224
}
151225
$this->initCurl($uri . '/payment_methods' . (count($options) > 0 ? '?' . http_build_query($options) : ''));
226+
227+
$this->setRequestHeader(self::HEADER_ACCEPT, self::TYPE_JSON);
228+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $merchant_id);
229+
152230
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'GET');
153-
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
154231
$this->sendRequest();
155232
$this->dealWithResponse();
156233
curl_close($this->ch);
157234
}
158235

159-
public function getAvailableDisbursements ($merchant) {
160-
$this->initCurl($this->_endpoint . '/merchants/' . $merchant . '/disbursements');
236+
public function getAvailableDisbursements($merchant_id)
237+
{
238+
$this->initCurl($this->_endpoint . '/merchants/' . $merchant_id . '/disbursements');
161239
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'GET');
162-
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
240+
241+
$this->setRequestHeader(self::HEADER_ACCEPT, self::TYPE_JSON);
242+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $merchant_id);
243+
163244
$this->sendRequest();
164245
$this->dealWithResponse();
165246
curl_close($this->ch);
166247
}
167248

168-
public function getDisbursementDetails ($path) {
249+
public function getDisbursementDetails($path)
250+
{
169251
$this->initCurl($this->_endpoint . $path);
170252
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'GET');
171-
curl_setopt($this->ch, CURLOPT_HTTPHEADER, array('Accept: application/json'));
253+
254+
$this->setRequestHeader(self::HEADER_ACCEPT, self::TYPE_JSON);
255+
256+
if (preg_match('~merchants/([^/]+)/disbursements~', $path, $matches)) {
257+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $matches[1]);
258+
}
259+
172260
$this->sendRequest();
173261
$this->dealWithResponse();
174262
curl_close($this->ch);
175263
}
176264

177-
public function getCreditAgreements($amount, $merchant, $locale = 'es-ES', $country = 'ES', $currency = 'EUR')
265+
public function getCreditAgreements($amount, $merchant_id, $locale = 'es-ES', $country = 'ES', $currency = 'EUR')
178266
{
179267
$uri = $this->_endpoint .
180-
'/merchants/' . urlencode($merchant) .
268+
'/merchants/' . urlencode($merchant_id) .
181269
'/credit_agreements?total_with_tax=' . urlencode($amount) .
182270
'&currency=' . urlencode($currency) .
183271
'&locale=' . urlencode($locale) .
184272
'&country=' . urlencode($country);
185273
$this->initCurl($uri);
274+
275+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $merchant_id);
276+
186277
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, 'GET');
187278
$this->sendRequest();
188279
$this->dealWithResponse();
@@ -195,6 +286,7 @@ public function updateOrder($uri, $order, $verb = 'PUT')
195286
$uri = $this->_endpoint . '/orders/' . $uri;
196287
}
197288
$this->initCurl($uri);
289+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $order['merchant']['id'] ?? '');
198290
$this->verbThePayload($verb, array('order' => $order));
199291
$this->dealWithResponse();
200292
if ($this->status == 409) {
@@ -206,6 +298,7 @@ public function updateOrder($uri, $order, $verb = 'PUT')
206298
public function sendDeliveryReport($delivery_report)
207299
{
208300
$this->initCurl($this->_endpoint . '/delivery_reports');
301+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $delivery_report['merchant']['id'] ?? '');
209302
$this->verbThePayload('POST', array('delivery_report' => $delivery_report));
210303
$this->dealWithResponse();
211304
curl_close($this->ch);
@@ -217,6 +310,7 @@ public function orderUpdate($order)
217310
'/merchants/' . urlencode($order['merchant']['id']) .
218311
'/orders/' . urlencode($order['merchant_reference']['order_ref_1']);
219312
$this->initCurl($uri);
313+
$this->setRequestHeader(self::HEADER_SEQURA_MERCHANT_ID, $order['merchant']['id'] ?? '');
220314
$this->verbThePayload('PUT', array('order' => $order));
221315
$this->dealWithResponse();
222316
if ($this->status == 409) {
@@ -262,7 +356,7 @@ public function getRawResult()
262356

263357
public function getOrderUri()
264358
{
265-
if ($this->headers && preg_match('/^Location:\s+([^\n\r]+)/mi', $this->headers, $m)) {
359+
if ($this->response_headers && preg_match('/^Location:\s+([^\n\r]+)/mi', $this->response_headers, $m)) {
266360
return $m[1];
267361
}
268362
}
@@ -281,6 +375,11 @@ public function dump()
281375

282376
// Private methods below
283377

378+
/**
379+
* Initializes the cURL session with the given URL and sets the necessary options.
380+
*
381+
* @param string $url The URL to initialize the cURL session with.
382+
*/
284383
private function initCurl($url)
285384
{
286385
$this->success = $this->json = null;
@@ -293,24 +392,20 @@ private function initCurl($url)
293392
// http://www.supermind.org/blog/763/solved-curl-56-received-problem-2-in-the-chunky-parser
294393
curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
295394
// From http://it.toolbox.com/wiki/index.php/Use_curl_from_PHP_-_processing_response_headers
296-
curl_setopt($this->ch, CURLOPT_HEADERFUNCTION, array(&$this, 'storeHeaders'));
297-
$this->headers = '';
395+
curl_setopt($this->ch, CURLOPT_HEADERFUNCTION, array(&$this, 'storeResponseHeaders'));
396+
$this->response_headers = '';
298397
}
299398

300399
private function verbThePayload($verb, $payload)
301400
{
302401
$data_string = json_encode(Helper::removeNulls($payload));
303402
curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, $verb);
304403
curl_setopt($this->ch, CURLOPT_POSTFIELDS, $data_string);
305-
curl_setopt(
306-
$this->ch,
307-
CURLOPT_HTTPHEADER,
308-
array(
309-
'Accept: application/json',
310-
'Content-Type: application/json',
311-
'Content-Length: ' . strlen($data_string)
312-
)
313-
);
404+
405+
$this->setRequestHeader(self::HEADER_ACCEPT, self::TYPE_JSON);
406+
$this->setRequestHeader(self::HEADER_CONTENT_TYPE, self::TYPE_JSON);
407+
$this->setRequestHeader(self::HEADER_CONTENT_LENGTH, (string) strlen($data_string));
408+
314409
$this->sendRequest();
315410
}
316411

@@ -320,11 +415,19 @@ private function sendRequest()
320415
if ($this->_debug) {
321416
curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
322417
}
418+
419+
$headers = $this->getRequestHeaders();
420+
if (!empty($headers)) {
421+
curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
422+
}
423+
$this->resetRequestHeaders();
424+
323425
$this->curl_result = curl_exec($this->ch);
426+
324427
if ($this->curl_result === false) {
325428
$this->log(
326429
"cURL error: " . curl_errno($this->ch) .
327-
" msg: " . curl_error($this->ch)
430+
" msg: " . curl_error($this->ch)
328431
);
329432
}
330433
$this->status = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
@@ -354,9 +457,9 @@ private function log($msg)
354457
}
355458
}
356459

357-
private function storeHeaders($ch, $header)
460+
private function storeResponseHeaders($ch, $header)
358461
{
359-
$this->headers .= $header;
462+
$this->response_headers .= $header;
360463

361464
return strlen($header);
362465
}

0 commit comments

Comments
 (0)