PluginProbe
imoje / 4.2.0
imoje v4.2.0
4.16.1 4.16.0 trunk 3.1.1 3.2.0 3.2.1 3.2.3 3.2.4 3.2.6 3.2.7 3.2.8 3.3.0 3.3.1 3.3.2 3.3.3 4.0.0 4.1.0 4.1.1 4.10.1 4.11.0 4.12.0 4.14.0 4.15.0 4.15.1 4.15.2 All 39 releases
imoje / includes / libs / payment-core / src / Notification.php

Notification.php in imoje 4.2.0, at includes/libs/payment-core/src/Notification.php

316 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Imoje\Payment;
4
5 use Exception;
6
7 /**
8 * Class Notification
9 *
10 * @package Imoje\Payment
11 */
12 class Notification
13 {
14
15 // region notification codes
16
17 /**
18 * @const int
19 */
20 const NC_OK = 0;
21
22 /**
23 * @const int
24 */
25 const NC_INVALID_SIGNATURE = 1;
26
27 /**
28 * @const int
29 */
30 const NC_SERVICE_ID_NOT_MATCH = 2;
31
32 /**
33 * @const int
34 */
35 const NC_ORDER_NOT_FOUND = 3;
36
37 /**
38 * @const int
39 */
40 const NC_INVALID_SIGNATURE_HEADERS = 4;
41
42 /**
43 * @const int
44 */
45 const NC_EMPTY_NOTIFICATION = 5;
46
47 /**
48 * @const int
49 */
50 const NC_NOTIFICATION_IS_NOT_JSON = 6;
51
52 /**
53 * @const int
54 */
55 const NC_INVALID_JSON_STRUCTURE = 7;
56
57 /**
58 * @const int
59 */
60 const NC_INVALID_ORDER_STATUS = 8;
61
62 /**
63 * @const int
64 */
65 const NC_AMOUNT_NOT_MATCH = 9;
66
67 /**
68 * @const int
69 */
70 const NC_UNHANDLED_STATUS = 10;
71
72 /**
73 * @const int
74 */
75 const NC_ORDER_STATUS_NOT_CHANGED = 11;
76
77 /**
78 * @const int
79 */
80 const NC_CART_NOT_FOUND = 12;
81
82 /**
83 * @const int
84 */
85 const NC_ORDER_STATUS_IS_NOT_SETTLED_ORDER_ARRANGEMENT_AFTER_IPN = 13;
86
87 /**
88 * @const int
89 */
90 const NC_ORDER_EXISTS_ORDER_ARRANGEMENT_AFTER_IPN = 14;
91
92 /**
93 * @const int
94 */
95 const NC_REQUEST_IS_NOT_POST = 15;
96
97 /**
98 * @const int
99 */
100 const NC_MISSING_ORDER_ID_IN_POST = 16;
101
102 /**
103 * @const int
104 */
105 const NC_CURL_IS_NOT_INSTALLED = 17;
106
107 /**
108 * @const int
109 */
110 const NC_MISSING_SIGNATURE_IN_POST = 18;
111
112 /**
113 * @const int
114 */
115 const NC_COULD_NOT_INSERT_TRANSACTION_ID_TO_DB = 20;
116
117 /**
118 * @const int
119 */
120 const NC_IMOJE_REFUND_IS_NOT_SETTLED = 21;
121
122 /**
123 * @const int
124 */
125 const NC_ORDER_STATUS_IS_INVALID_FOR_REFUND = 22;
126
127 /**
128 * @const int
129 */
130 const NC_TRANSACTION_NOT_FOUND = 23;
131
132 /**
133 * @const int
134 */
135 const NC_UNKNOWN = 100;
136 // endregion
137
138 // region notification status
139 const NS_OK = 'ok';
140 const NS_ERROR = 'error';
141 // endregion
142
143 // region transaction type
144 const TRT_SALE = 'sale';
145 const TRT_REFUND = 'refund';
146 // endregion
147
148 // region transaction status
149 const TRS_SETTLED = 'settled';
150 const TRS_REJECTED = 'rejected';
151 const TRS_NEW = 'new';
152 //endregion
153
154 const HEADER_SIGNATURE_NAME = 'HTTP_X_IMOJE_SIGNATURE';
155
156 /**
157 * @var string
158 */
159 private $serviceId = '';
160
161 /**
162 * @var string
163 */
164 private $serviceKey = '';
165
166 /**
167 * @var string
168 */
169 private $isDebugMode = '';
170
171 /**
172 * @var string|bool
173 */
174 private $orderArrangement = '';
175
176 /**
177 * Notification constructor.
178 *
179 * @param string $serviceId
180 * @param string $serviceKey
181 * @param bool $isDebugMode
182 */
183 public function __construct($serviceId, $serviceKey, $isDebugMode, $orderArrangement = false)
184 {
185 $this->serviceId = $serviceId;
186 $this->serviceKey = $serviceKey;
187 $this->isDebugMode = $isDebugMode;
188
189 if($orderArrangement) {
190 $this->orderArrangement = $orderArrangement;
191 }
192 }
193
194 /**
195 * @param string $status
196 * @param string $code
197 * @param string|int|null $statusBefore
198 * @param string|int|null $statusAfter
199 *
200 * @return string
201 */
202 public function formatResponse($status, $code = '', $statusBefore = null, $statusAfter = null)
203 {
204 $response = [
205 'status' => $status,
206 ];
207
208 if($this->isDebugMode && $code) {
209 $response['data'] = [
210 'code' => $code,
211 ];
212 }
213
214 if($this->orderArrangement) {
215 $response['data']['creatingOrderMode'] = $this->orderArrangement;
216 }
217
218 if($statusBefore) {
219 $response['data']['statusBefore'] = $statusBefore;
220 }
221
222 if($statusAfter) {
223 $response['data']['statusAfter'] = $statusAfter;
224 }
225
226 // region adds additional data for some cases and set proper header
227 switch($status) {
228 case self::NS_OK:
229
230 header('HTTP/1.1 200 OK');
231 break;
232 case self::NS_ERROR:
233
234 header('HTTP/1.1 404 Not Found');
235 break;
236 default:
237
238 break;
239 }
240 // endregion
241
242 header('Content-Type: application/json');
243
244 return json_encode($response);
245 }
246
247 /**
248 * @param array $payloadDecoded
249 * @param int $amount
250 * @param string $currency
251 *
252 * @return bool
253 */
254 public static function checkRequestAmount($payloadDecoded, $amount, $currency)
255 {
256 return $payloadDecoded['transaction']['amount'] === $amount && $payloadDecoded['transaction']['currency'] === $currency;
257 }
258
259 /**
260 * Verify notification body and signature
261 *
262 * @return bool|array
263 * @throws Exception
264 */
265 public function checkRequest()
266 {
267
268 if(!isset($_SERVER['CONTENT_TYPE'], $_SERVER[self::HEADER_SIGNATURE_NAME]) || strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== 0) {
269
270 return self::NC_INVALID_SIGNATURE_HEADERS;
271 }
272
273 $payload = file_get_contents('php://input', true);
274
275 if(!$payload) {
276
277 return self::NC_EMPTY_NOTIFICATION;
278 }
279
280 if(!Util::isJson($payload)) {
281
282 return self::NC_NOTIFICATION_IS_NOT_JSON;
283 }
284
285 $header = $_SERVER[self::HEADER_SIGNATURE_NAME];
286 $header = (explode(';', $header));
287
288 $algoFromNotification = explode('=', $header[3]);
289 $algoFromNotification = $algoFromNotification[1];
290
291 $headerSignature = explode('=', $header[2]);
292
293 if($headerSignature[1] !== Util::hashSignature($algoFromNotification, $payload, $this->serviceKey)) {
294
295 return self::NC_INVALID_SIGNATURE;
296 }
297
298 try {
299
300 Validate::notification($payload);
301 } catch(Exception $e) {
302
303 return self::NC_INVALID_JSON_STRUCTURE;
304 }
305
306 $payloadDecoded = json_decode($payload, true);
307
308 if($payloadDecoded['transaction']['serviceId'] !== $this->serviceId) {
309
310 return self::NC_SERVICE_ID_NOT_MATCH;
311 }
312
313 return $payloadDecoded;
314 }
315 }
316