· 5 years ago · Jun 12, 2020, 04:56 PM
1<?php
2
3if (!defined('ABSPATH'))
4 exit; //защита от прямого доступа
5
6
7add_action('plugins_loaded', 'woocommerce_am', 0);
8function woocommerce_am() {
9 load_plugin_textdomain('anymoney', false, dirname(plugin_basename(__FILE__)) . '/lang/');
10
11 if (!class_exists('WC_Payment_Gateway'))
12 return;
13 if (class_exists('WC_AM'))
14 return;
15
16 class WC_AM extends WC_Payment_Gateway {
17 public function __construct() {
18
19 $plugin_dir = plugin_dir_url(__FILE__);
20
21 global $woocommerce;
22
23 $this->id = 'am';
24 $this->icon = apply_filters('woocommerce_am_icon', '' . $plugin_dir . 'am.png');
25 $this->has_fields = false;
26
27 $this->init_form_fields();
28 $this->init_settings();
29
30 $this->domain = $this->get_option('domain');
31 $this->public_key = $this->get_option('public_key');
32 $this->secret_key = $this->get_option('secret_key');
33 $this->title = 'AnyMoney';
34 $this->description = __('Оплата платежной системой Any.Money', 'am');
35
36 add_action('woocommerce_receipt_' . $this->id, array($this, 'receipt_page'));
37
38 add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
39
40 add_action('woocommerce_api_wc_' . $this->id, array($this, 'callback'));
41
42
43 }
44
45 public function admin_options() {
46 ?>
47 <h3><?php _e('AnyMoney', 'am'); ?></h3>
48 <p><?php _e('Настройка приема электронных платежей Any.Money.', 'am'); ?></p>
49
50 <table class="form-table">
51
52 <?php
53 $this->generate_settings_html();
54 ?>
55 </table><!--/.form-table-->
56
57 <?php
58 }
59
60 function init_form_fields() {
61 $this->form_fields = array(
62 'enabled' => array(
63 'title' => __('Включить/Выключить', 'am'),
64 'type' => 'checkbox',
65 'label' => __('Включен', 'am'),
66 'default' => 'yes'
67 ),
68 'domain' => array(
69 'title' => __('API url', 'am'),
70 'type' => 'text',
71 'description' => __('Вставьте API url', 'am'),
72 'default' => ''
73 ),
74 'public_key' => array(
75 'title' => __('Merchant ID', 'am'),
76 'type' => 'text',
77 'description' => __('Скопируйте Merchant ID со страницы проекта в системе Any.Money', 'am'),
78 'default' => ''
79 ),
80 'secret_key' => array(
81 'title' => __('SECRET KEY API', 'woocommerce'),
82 'type' => 'text',
83 'description' => __('Скопируйте SECRET KEY API со страницы проекта в системе Any.Money', 'am'),
84 'default' => ''
85 )
86
87 );
88 }
89
90
91 public function generate_form($order_id) {
92 $order = new WC_Order($order_id);
93
94 $currency = $order->get_order_currency();
95
96 $data = [
97 'amount' => number_format($order->order_total, 2, '.', ''),
98// 'callback_url' => $_SERVER['SERVER_NAME'] . '/?wc-api=wc_anymoney',
99 'client_email' => $order->billing_email,
100 'externalid' => uniqid(),
101 'in_curr' => "$currency",
102// 'redirect_url' => $_SERVER['SERVER_NAME']
103 ];
104
105 $dataPost = array(
106 "method" => "invoice.create",
107 "params" => $data,
108 "jsonrpc" => "2.0",
109 "id" => uniqid()
110 );
111
112 $utc_now = strval(((int)round(microtime(true) * 1000)));
113
114 $data_string = json_encode($dataPost);
115
116 $ch = curl_init($this->domain);
117 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
118 curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
119 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
120 curl_setopt($ch, CURLOPT_HTTPHEADER, array(
121 'Content-Type: application/json',
122 'Content-Length: ' . strlen($data_string),
123 'x-merchant: ' . $this->public_key,
124 'x-signature: ' . $this->sign_data($this->secret_key, $dataPost['params'] ?: array(), $utc_now),
125 'x-utc-now-ms: ' . $utc_now)
126 );
127
128 $result = curl_exec($ch);
129
130 $response = json_decode($result);
131
132 header('Location: ' . $response->result->paylink);
133 exit();
134 }
135
136 public function sign_data($key, array $data, $utc_now) {
137 ksort($data);
138 $s = '';
139 foreach($data as $k=>$value) {
140 if (in_array(gettype($value), array('array', 'object', 'NULL')) ){
141 continue;
142 }
143 if(is_bool($value)){
144 $s .= $value ? "true" : "false";
145 } else {
146 $s .= $value;
147 }
148 }
149 $s .= $utc_now;
150 return hash_hmac('sha512', strtolower($s), $key);
151 }
152
153
154 function process_payment($order_id) {
155 $order = new WC_Order($order_id);
156
157 return array(
158 'result' => 'success',
159 'redirect' => add_query_arg('order', $order->id, add_query_arg('key', $order->order_key, get_permalink(woocommerce_get_page_id('pay'))))
160 );
161 }
162
163 function receipt_page($order) {
164 echo '<p>' . __('Спасибо за Ваш заказ, пожалуйста, нажмите кнопку ниже, чтобы заплатить.', 'am') . '</p>';
165 echo $this->generate_form($order);
166 }
167
168 function callback() {
169 header('Content-type:application/json; charset=utf-8');
170
171 $method = '';
172 $params = array();
173
174 if ((isset($_GET['params'])) && (isset($_GET['method'])) && (isset($_GET['params']['signature']))) {
175 $params = $_GET['params'];
176 $method = $_GET['method'];
177 $signature = $params['signature'];
178
179
180 if (empty($signature)) {
181 $status_sign = false;
182 } else {
183 $secret_key = $this->secret_key;
184 $status_sign = $this->verifySignature($params, $method, $secret_key);
185 }
186 } else {
187 $status_sign = false;
188 }
189
190// $status_sign = true;
191
192 if ($status_sign) {
193 switch ($method) {
194 case 'check':
195 $result = $this->check($params);
196 break;
197 case 'pay':
198 $result = $this->payment($params);
199 break;
200 case 'error':
201 $result = $this->error($params);
202 break;
203 default:
204 $result = array('error' =>
205 array('message' => __('Неверный метод', 'am'))
206 );
207 break;
208 }
209 } else {
210 $result = array('error' =>
211 array('message' => __('Неверная сигнатура', 'am'))
212 );
213 }
214
215 echo json_encode($result);
216 die();
217 }
218
219
220 function verifySignature($params, $method, $secret) {
221 return $params['signature'] == $this->getSignature($method, $params, $secret);
222 }
223
224 function getSignature($method, array $params, $secretKey) {
225 // https://docs.any.money/ru/auth/
226 }
227
228 function check($params) {
229 $order = new WC_Order($params['account']);
230
231 if (!$order->id) {
232 $result = array('error' =>
233 array('message' => __('Заказа не существует', 'am'))
234 );
235 } else {
236
237 $sum = number_format($order->order_total, 2, '.', '');
238 $currency = $order->get_order_currency();
239
240 if ((float)$sum != (float)$params['orderSum']) {
241 $result = array('error' =>
242 array('message' => __('Не совпадает сумма заказа', 'am'))
243 );
244 } elseif ($currency != $params['orderCurrency']) {
245 $result = array('error' =>
246 array('message' => __('Не совпадает валюта заказа', 'am'))
247 );
248 } else {
249 $result = array('result' =>
250 array('message' => __('Запрос успешно обработан', 'am'))
251 );
252 }
253 }
254
255 return $result;
256 }
257
258 function payment($params) {
259
260 $order = new WC_Order($params['account']);
261
262 if (!$order->id) {
263 $result = array('error' =>
264 array('message' => __('Заказа не существует', 'am'))
265 );
266 } else {
267
268 $sum = number_format($order->order_total, 2, '.', '');
269 $currency = $order->get_order_currency();
270
271 if ((float)$sum != (float)$params['orderSum']) {
272 $result = array('error' =>
273 array('message' => __('Не совпадает сумма заказа', 'am'))
274 );
275 } elseif ($currency != $params['orderCurrency']) {
276 $result = array('error' =>
277 array('message' => __('Не совпадает валюта заказа', 'am'))
278 );
279 } else {
280
281 $order->payment_complete();
282
283 $result = array('result' =>
284 array('message' => __('Запрос успешно обработан', 'am'))
285 );
286 }
287 }
288
289 return $result;
290 }
291
292 function error($params) {
293 $order = new WC_Order($params['account']);
294
295 if (!$order) {
296 $result = array('error' =>
297 array('message' => __('Заказа не существует', 'am'))
298 );
299 } else {
300 $order->update_status('failed', __('Payment error', 'am'));
301 $result = array('result' =>
302 array('message' => __('Запрос успешно обработан', 'am'))
303 );
304 }
305 return $result;
306 }
307
308 }
309
310
311 function add_am_gateway($methods) {
312 $methods[] = 'WC_AM';
313 return $methods;
314 }
315
316 add_filter('woocommerce_payment_gateways', 'add_am_gateway');
317}
318
319?>