Changeset 2825657
- Timestamp:
- 11/29/2022 07:02:57 AM (3 years ago)
- Location:
- idpay-payment-learnpress/trunk
- Files:
-
- 6 edited
-
idpay-learnpress.php (modified) (1 diff)
-
inc/class-lp-gateway-idpay.php (modified) (2 diffs)
-
inc/load.php (modified) (1 diff)
-
readme.txt (modified) (1 diff)
-
templates/form.php (modified) (1 diff)
-
templates/payment-error.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
idpay-payment-learnpress/trunk/idpay-learnpress.php
r2408293 r2825657 5 5 Description: IDPay payment gateway for LearnPress. 6 6 Author:IDPay 7 Version: 1. 0.17 Version: 1.1.0 8 8 Author URI: https://github.com/idpay/ 9 9 Tags: learnpress, idpay -
idpay-payment-learnpress/trunk/inc/class-lp-gateway-idpay.php
r2408293 r2825657 5 5 * @author IDPay 6 6 * @package LearnPress/IDPay/Classes 7 * @version 1. 0.17 * @version 1.1.0 8 8 */ 9 9 … … 12 12 13 13 if (!class_exists('LP_Gateway_IDPay')) { 14 /**15 * Class LP_Gateway_IDPay16 */17 class LP_Gateway_IDPay extends LP_Gateway_Abstract18 {19 14 /** 20 * @var array15 * Class LP_Gateway_IDPay 21 16 */ 22 private $form_data = array(); 23 24 /** 25 * @var 26 */ 27 private $link; 28 29 /** 30 * @var string 31 */ 32 protected $payment_endpoint; 33 34 /** 35 * @var string 36 */ 37 protected $verify_endpoint; 38 39 /** 40 * @var array|bool|mixed|null 41 */ 42 private $api_key = null; 43 44 /** 45 * @var array|bool|mixed|null 46 */ 47 private $sandbox = null; 48 49 /** 50 * @var array|null 51 */ 52 protected $settings = null; 53 54 /** 55 * @var null 56 */ 57 protected $order = null; 58 59 /** 60 * @var null 61 */ 62 protected $posted = null; 63 64 65 /** 66 * LP_Gateway_IDPay constructor. 67 */ 68 public function __construct() 17 class LP_Gateway_IDPay extends LP_Gateway_Abstract 69 18 { 70 $this->payment_endpoint = 'https://api.idpay.ir/v1.1/payment'; 71 $this->verify_endpoint = 'https://api.idpay.ir/v1.1/payment/verify'; 72 73 $this->id = 'idpay'; 74 $this->method_title = __('IDPay', 'learnpress-idpay');; 75 $this->method_description = __('Make a payment with IDPay.', 'learnpress-idpay'); 76 $this->icon = ''; 77 78 // Get settings 79 $this->title = LP()->settings->get("{$this->id}.title", $this->method_title); 80 $this->description = LP()->settings->get("{$this->id}.description", $this->method_description); 81 $this->api_key = LP()->settings->get("{$this->id}.api_key"); 82 $this->sandbox = LP()->settings->get("{$this->id}.sandbox"); 83 84 $settings = LP()->settings; 85 // Add default values for fresh installs 86 if (!$settings->get("{$this->id}.enable")) { 87 $this->settings = array(); 88 $this->settings['api_key'] = $settings->get("{$this->id}.api_key"); 89 $this->settings['sandbox'] = $settings->get("{$this->id}.sandbox"); 90 } 91 92 if (did_action('learn_press/idpay-add-on/loaded')) { 93 return; 94 } 95 96 // check payment gateway enable 97 add_filter('learn-press/payment-gateway/' . $this->id . '/available', array( 98 $this, 99 'idpay_available' 100 ), 10, 2); 101 102 do_action('learn_press/idpay-add-on/loaded'); 103 104 parent::__construct(); 105 106 // web hook 107 if (did_action('init')) { 108 $this->register_web_hook(); 109 } else { 110 add_action('init', array($this, 'register_web_hook')); 111 } 112 113 add_action('learn_press_web_hooks_processed', array($this, 'web_hook_process_idpay')); 114 add_action("learn-press/before-checkout-order-review", array($this, 'error_message')); 19 /** 20 * @var array 21 */ 22 private $form_data = array(); 23 24 /** 25 * @var 26 */ 27 private $link; 28 29 /** 30 * @var string 31 */ 32 protected $payment_endpoint; 33 34 /** 35 * @var string 36 */ 37 protected $verify_endpoint; 38 39 /** 40 * @var array|bool|mixed|null 41 */ 42 private $api_key = null; 43 44 /** 45 * @var array|bool|mixed|null 46 */ 47 private $sandbox = null; 48 49 /** 50 * @var array|null 51 */ 52 protected $settings = null; 53 54 /** 55 * @var null 56 */ 57 protected $order = null; 58 59 /** 60 * @var null 61 */ 62 protected $posted = null; 63 64 65 /** 66 * LP_Gateway_IDPay constructor. 67 */ 68 public function __construct() 69 { 70 $this->payment_endpoint = 'https://api.idpay.ir/v1.1/payment'; 71 $this->verify_endpoint = 'https://api.idpay.ir/v1.1/payment/verify'; 72 73 $this->id = 'idpay'; 74 $this->method_title = __('IDPay', 'learnpress-idpay');; 75 $this->method_description = __('Make a payment with IDPay.', 'learnpress-idpay'); 76 $this->icon = ''; 77 78 // Get settings 79 $this->title = LP()->settings->get("{$this->id}.title", $this->method_title); 80 $this->description = LP()->settings->get("{$this->id}.description", $this->method_description); 81 $this->api_key = LP()->settings->get("{$this->id}.api_key"); 82 $this->sandbox = LP()->settings->get("{$this->id}.sandbox"); 83 84 $settings = LP()->settings; 85 // Add default values for fresh installs 86 if (!$settings->get("{$this->id}.enable")) { 87 $this->settings = array(); 88 $this->settings['api_key'] = $settings->get("{$this->id}.api_key"); 89 $this->settings['sandbox'] = $settings->get("{$this->id}.sandbox"); 90 } 91 92 if (did_action('learn_press/idpay-add-on/loaded')) { 93 return; 94 } 95 96 // check payment gateway enable 97 add_filter('learn-press/payment-gateway/' . $this->id . '/available', array( 98 $this, 99 'idpay_available' 100 ), 10, 2); 101 102 do_action('learn_press/idpay-add-on/loaded'); 103 104 parent::__construct(); 105 106 // web hook 107 if (did_action('init')) { 108 $this->register_web_hook(); 109 } else { 110 add_action('init', array($this, 'register_web_hook')); 111 } 112 113 add_action('learn_press_web_hooks_processed', array($this, 'web_hook_process_idpay')); 114 add_action("learn-press/before-checkout-order-review", array($this, 'error_message')); 115 } 116 117 /** 118 * Register web hook. 119 * 120 * @return array 121 */ 122 public function register_web_hook() 123 { 124 learn_press_register_web_hook('idpay', 'learn_press_idpay'); 125 } 126 127 /** 128 * Admin payment settings. 129 * 130 * @return array 131 */ 132 public function get_settings() 133 { 134 return apply_filters('learn-press/gateway-payment/idpay/settings', 135 array( 136 array( 137 'title' => __('Enable', 'learnpress-idpay'), 138 'id' => '[enable]', 139 'default' => 'no', 140 'type' => 'yes-no' 141 ), 142 array( 143 'title' => __('sandbox', 'learnpress-idpay'), 144 'id' => '[sandbox]', 145 'default' => 'no', 146 'type' => 'yes-no' 147 ), 148 array( 149 'type' => 'textarea', 150 'title' => __('Description', 'learnpress-idpay'), 151 'default' => __('Pay with IDPay', 'learnpress-idpay'), 152 'id' => '[description]', 153 'editor' => array( 154 'textarea_rows' => 5 155 ), 156 'css' => 'height: 100px;display:block;margin-top:15px;margin-bottom:15px', 157 ), 158 array( 159 'title' => __('api_key', 'learnpress-idpay'), 160 'id' => '[api_key]', 161 'type' => 'text', 162 'css' => 'margin-bottom:15px;margin-top:15px;display:block', 163 ) 164 ) 165 ); 166 } 167 168 /** 169 * Payment form. 170 */ 171 public function get_payment_form() 172 { 173 ob_start(); 174 $template = learn_press_locate_template('form.php', learn_press_template_path() . '/addons/idpay-payment/', LP_ADDON_IDPAY_PAYMENT_TEMPLATE); 175 include $template; 176 177 return ob_get_clean(); 178 } 179 180 /** 181 * Error message 182 */ 183 public function error_message() 184 { 185 if (isset($_SESSION['idpay_error']) && intval($_SESSION['idpay_error']) === 1) { 186 $_SESSION['idpay_error'] = 0; 187 $template = learn_press_locate_template('payment-error.php', learn_press_template_path() . '/addons/idpay-payment/', LP_ADDON_IDPAY_PAYMENT_TEMPLATE); 188 include $template; 189 } 190 } 191 192 /** 193 * @return mixed 194 */ 195 public function get_icon() 196 { 197 if (empty($this->icon)) { 198 $this->icon = LP_ADDON_IDPAY_PAYMENT_URL . 'assets/images/idpay.png'; 199 } 200 201 return parent::get_icon(); 202 } 203 204 /** 205 * Check gateway available. 206 * 207 * @return bool 208 */ 209 public function idpay_available() 210 { 211 if (LP()->settings->get("{$this->id}.enable") != 'yes') { 212 return false; 213 } 214 215 return true; 216 } 217 218 /** 219 * Get form data. 220 * 221 * @return array 222 */ 223 public function get_form_data() 224 { 225 if ($this->order) { 226 $user = learn_press_get_current_user(); 227 $currency_code = learn_press_get_currency(); 228 if ($currency_code == 'IRR') { 229 $amount = $this->order->order_total / 10; 230 } else { 231 $amount = $this->order->order_total; 232 } 233 234 $this->form_data = array( 235 'amount' => $amount, 236 'currency' => strtolower(learn_press_get_currency()), 237 'token' => $this->token, 238 'description' => sprintf(__("Charge for %s", "learnpress-idpay"), $user->get_data('email')), 239 'customer' => array( 240 'name' => $user->get_data('display_name'), 241 'billing_email' => $user->get_data('email'), 242 ), 243 'errors' => isset($this->posted['form_errors']) ? $this->posted['form_errors'] : '' 244 ); 245 } 246 247 return $this->form_data; 248 } 249 250 /** 251 * Validate form fields. 252 * 253 * @return bool 254 * @throws Exception 255 * @throws string 256 */ 257 public function validate_fields() 258 { 259 $posted = learn_press_get_request('learn-press-idpay'); 260 $email = !empty($posted['email']) ? $posted['email'] : ""; 261 $mobile = !empty($posted['mobile']) ? $posted['mobile'] : ""; 262 263 $error_message = array(); 264 if (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) { 265 $error_message[] = __('Invalid email format.', 'learnpress-idpay'); 266 } 267 if (!empty($mobile) && !preg_match("/^(09)(\d{9})$/", $mobile)) { 268 $error_message[] = __('Invalid mobile format.', 'learnpress-idpay'); 269 } 270 271 if ($error = sizeof($error_message)) { 272 throw new Exception(sprintf('<div>%s</div>', join('</div><div>', $error_message)), 8000); 273 } 274 $this->posted = $posted; 275 276 return $error ? false : true; 277 } 278 279 280 /** 281 * IDPay payment process. 282 * 283 * @param $order 284 * 285 * @return array 286 * @throws string 287 */ 288 public function process_payment($order) 289 { 290 $this->order = learn_press_get_order($order); 291 $isPaymentCheckout = $this->get_checkout_payment_url(); 292 $gateway_url = $this->link; 293 294 return array( 295 'result' => $isPaymentCheckout ? 'success' : 'fail', 296 'redirect' => $isPaymentCheckout ? $gateway_url : learn_press_get_checkout_url() 297 ); 298 } 299 300 /** 301 * @return bool 302 */ 303 public function get_checkout_payment_url() 304 { 305 if ($this->get_form_data()) { 306 $order = $this->order; 307 $customer_name = $order->get_customer_name(); 308 $callback = get_site_url() . '/?' . learn_press_get_web_hook('idpay') . '=1&order_id=' . $order->get_id(); 309 $phone = !empty($this->posted['mobile']) ? $this->posted['mobile'] : ''; 310 $mail = !empty($this->posted['email']) ? $this->posted['email'] : ''; 311 $amount = $order->order_total; 312 313 if (learn_press_get_currency() != 'IRR') { 314 $note = __("Currency is not supported", 'learnpress-idpay'); 315 $payment_error = $note; 316 $payment_error .= "\n"; 317 $payment_error .= get_post_meta($order->get_id(), 'idpay_payment_error', TRUE); 318 update_post_meta($order->get_id(), __('idpay_payment_error', 'learnpress-idpay'), $payment_error); 319 learn_press_add_message($note, 'error'); 320 return false; 321 } 322 323 $data = array( 324 'order_id' => $order->get_id(), 325 'amount' => $amount, 326 'name' => $customer_name, 327 'phone' => $phone, 328 'mail' => $mail, 329 'desc' => '', 330 'callback' => $callback, 331 ); 332 333 $headers = array( 334 'Content-Type' => 'application/json', 335 'X-API-KEY' => $this->api_key, 336 'X-SANDBOX' => $this->sandbox == 'yes', 337 ); 338 339 $args = array( 340 'body' => json_encode($data), 341 'headers' => $headers, 342 'timeout' => 15, 343 ); 344 345 $response = $this->call_gateway_endpoint($this->payment_endpoint, $args); 346 //Check error 347 if (is_wp_error($response)) { 348 $payment_error = $this->other_status_messages(); 349 $payment_error .= "\n"; 350 $payment_error .= get_post_meta($order->id, 'idpay_payment_error', TRUE); 351 update_post_meta($order->id, __('idpay_payment_error', 'learnpress-idpay'), $payment_error); 352 learn_press_add_message($response->get_error_message(), 'error'); 353 354 return false; 355 } 356 $http_status = wp_remote_retrieve_response_code($response); 357 $result = wp_remote_retrieve_body($response); 358 $result = json_decode($result); 359 360 //Check http error 361 if ($http_status != 201 || empty($result) || empty($result->id) || empty($result->link)) { 362 $note = ''; 363 $note .= __('An error occurred while creating the transaction.', 'learnpress-idpay'); 364 $note .= '<br/>'; 365 $note .= sprintf(__('error status: %s', 'learnpress-idpay'), $http_status); 366 367 if (!empty($result->error_code) && !empty($result->error_message)) { 368 $note .= '<br/>'; 369 $note .= sprintf(__('error code: %s', 'learnpress-idpay'), $result->error_code); 370 $note .= '<br/>'; 371 $note .= sprintf(__('error message: %s', 'learnpress-idpay'), $result->error_message); 372 $payment_error = $result->error_message; 373 $payment_error .= "\n"; 374 $payment_error .= get_post_meta($order->id, 'idpay_payment_error', TRUE); 375 update_post_meta($order->id, __('idpay_payment_error', 'learnpress-idpay'), $payment_error); 376 learn_press_add_message($note, 'error'); 377 } 378 379 return false; 380 } 381 // Save ID of this transaction 382 update_post_meta($order->id, "IdpayTransactionId:$order->id", $result->id); 383 384 // Set remote status of the transaction to 1 as it's primary value. 385 update_post_meta($order->id, __('idpay_transaction_status', 'learnpress-idpay'), 1); 386 387 $note = sprintf(__('transaction id: %s', 'learnpress-idpay'), $result->id); 388 $this->link = $result->link; 389 return true; 390 391 } 392 393 return false; 394 } 395 396 public function web_hook_process_idpay() 397 { 398 $status = ($_SERVER['REQUEST_METHOD'] == 'POST') ? sanitize_text_field($_POST['status']) : sanitize_text_field($_GET['status']); 399 $track_id = ($_SERVER['REQUEST_METHOD'] == 'POST') ? sanitize_text_field($_POST['track_id']) : sanitize_text_field($_GET['track_id']); 400 $trans_id = ($_SERVER['REQUEST_METHOD'] == 'POST') ? sanitize_text_field($_POST['id']) : sanitize_text_field($_GET['id']); 401 $order_id = ($_SERVER['REQUEST_METHOD'] == 'POST') ? sanitize_text_field($_POST['order_id']) : sanitize_text_field($_GET['order_id']); 402 403 if (empty($trans_id) || empty($order_id) || empty($track_id)) { 404 learn_press_add_message($this->other_status_messages(), 'error'); 405 wp_redirect(esc_url(learn_press_get_page_link('checkout'))); 406 exit(); 407 } 408 409 $order = LP_Order::instance($order_id); 410 if (empty($order)) { 411 learn_press_add_message($this->other_status_messages(), 'error'); 412 wp_redirect(esc_url(learn_press_get_page_link('checkout'))); 413 exit(); 414 } 415 416 if ($order->has_status('completed')) { 417 learn_press_add_message($this->other_status_messages(), 'error'); 418 wp_redirect(esc_url(learn_press_get_page_link('checkout'))); 419 exit(); 420 } 421 422 if ($status != 10) { 423 $massage = $this->other_status_messages($status); 424 $payment_error = $massage . "\n"; 425 $payment_error .= get_post_meta($order_id, 'idpay_payment_error', TRUE); 426 update_post_meta($order_id, __('idpay_payment_error', 'learnpress-idpay'), $payment_error); 427 update_post_meta($order_id, 'idpay_transaction_status', $status); 428 $order->update_status('failed'); 429 learn_press_add_message($massage, 'error'); 430 wp_redirect(esc_url(learn_press_get_page_link('checkout'))); 431 exit(); 432 } elseif (self::isNotDoubleSpending($order->id, $order_id, $trans_id) != true) { 433 $massage = 'سوع استفاده از تراکنش (Double Spending)'; 434 $payment_error = $massage . "\n"; 435 $payment_error .= get_post_meta($order_id, 'idpay_payment_error', TRUE); 436 update_post_meta($order_id, __('idpay_payment_error', 'learnpress-idpay'), $payment_error); 437 update_post_meta($order_id, 'idpay_transaction_status', $status); 438 $order->update_status('failed'); 439 learn_press_add_message($massage, 'error'); 440 wp_redirect(esc_url(learn_press_get_page_link('checkout'))); 441 } else { 442 443 $params = array( 444 'id' => $trans_id, 445 'order_id' => $order->id); 446 447 $headers = array( 448 'Content-Type' => 'application/json', 449 'X-API-KEY' => $this->api_key, 450 'X-SANDBOX' => $this->sandbox == 'yes', 451 ); 452 453 $args = array( 454 'body' => json_encode($params), 455 'headers' => $headers, 456 'timeout' => 15, 457 ); 458 459 $response = $this->call_gateway_endpoint($this->verify_endpoint, $args); 460 //Check Error 461 if (is_wp_error($response)) { 462 $payment_error = $this->other_status_messages(); 463 $payment_error .= "\n"; 464 $payment_error .= get_post_meta($order->id, 'idpay_payment_error', TRUE); 465 update_post_meta($order->id, __('idpay_payment_error' . 'learnpress-idpay'), $payment_error); 466 learn_press_add_message($response->get_error_message(), 'error'); 467 wp_redirect(esc_url(learn_press_get_page_link('checkout'))); 468 469 exit(); 470 } 471 472 $http_status = wp_remote_retrieve_response_code($response); 473 $result = wp_remote_retrieve_body($response); 474 $result = json_decode($result); 475 476 //Check http Error 477 if ($http_status != 200) { 478 $note = ''; 479 $note .= __('An error occurred while verifying the transaction.', 'learnpress-idpay'); 480 $note .= '<br/>'; 481 $note .= sprintf(__('error status: %s', 'learnpress-idpay'), $http_status); 482 483 if (!empty($result->error_code) && !empty($result->error_message)) { 484 $note = ''; 485 $note .= __('An error occurred while creating the transaction.', 'learnpress-idpay'); 486 $note .= '<br/>'; 487 $note .= sprintf(__('error status: %s', 'learnpress-idpay'), $http_status); 488 $note .= '<br/>'; 489 $note .= sprintf(__('error message: %s', 'learnpress-idpay'), $result->error_message); 490 $payment_error = $result->error_message; 491 learn_press_add_message($note, 'error'); 492 } 493 494 $payment_error = get_post_meta($order_id, 'idpay_payment_error', TRUE); 495 update_post_meta($order_id, __('idpay_payment_error', 'learnpress-idpay'), $payment_error); 496 learn_press_add_message($note, 'error'); 497 $order->update_status('failed'); 498 wp_redirect(esc_url(learn_press_get_page_link('checkout'))); 499 500 exit(); 501 } else { 502 503 $order_id = $order->id; 504 $verify_status = empty($result->status) ? NULL : $result->status; 505 $verify_track_id = empty($result->track_id) ? NULL : $result->track_id; 506 $verify_id = empty($result->id) ? NULL : $result->id; 507 $verify_order_id = empty($result->order_id) ? NULL : $result->order_id; 508 $verify_amount = empty($result->amount) ? NULL : $result->amount; 509 $verify_card_no = empty($result->payment->card_no) ? NULL : $result->payment->card_no; 510 $verify_hashed_card_no = empty($result->payment->hashed_card_no) ? NULL : $result->payment->hashed_card_no; 511 $verify_date = empty($result->payment->date) ? NULL : $result->payment->date; 512 513 // Updates order's meta data after verifying the payment. 514 update_post_meta($order_id, __('idpay_transaction_status', 'learnpress-idpay'), $verify_status); 515 update_post_meta($order_id, __('idpay_track_id', 'learnpress-idpay'), $verify_track_id); 516 update_post_meta($order_id, __('idpay_transaction_id', 'learnpress-idpay'), $verify_id); 517 update_post_meta($order_id, __('idpay_transaction_order_id', 'learnpress-idpay'), $verify_order_id); 518 update_post_meta($order_id, __('idpay_transaction_amount', 'learnpress-idpay'), $verify_amount); 519 update_post_meta($order_id, __('idpay_payment_card_no', 'learnpress-idpay'), $verify_card_no); 520 update_post_meta($order_id, __('idpay_payment_hashed_card_no', 'learnpress-idpay'), $verify_hashed_card_no); 521 update_post_meta($order_id, __('idpay_payment_date', 'learnpress-idpay'), $verify_date); 522 $order->payment_complete($verify_track_id); 523 wp_redirect(esc_url($this->get_return_url($order))); 524 525 exit(); 526 } 527 528 } 529 } 530 531 private static function isNotDoubleSpending($reference_id, $order_id, $transaction_id) 532 { 533 $relatedTransaction = get_post_meta($reference_id, "IdpayTransactionId:$order_id", TRUE); 534 if (!empty($relatedTransaction)) { 535 return $transaction_id == $relatedTransaction; 536 } 537 return false; 538 } 539 540 /** 541 * Calls the gateway endpoints. 542 * 543 * Tries to get response from the gateway for 4 times. 544 * 545 * @param $url 546 * @param $args 547 * 548 * @return array|\WP_Error 549 */ 550 private function call_gateway_endpoint($url, $args) 551 { 552 $number_of_connection_tries = 4; 553 while ($number_of_connection_tries) { 554 $response = wp_safe_remote_post($url, $args); 555 if (is_wp_error($response)) { 556 $number_of_connection_tries--; 557 continue; 558 } else { 559 break; 560 } 561 } 562 563 return $response; 564 } 565 566 /** 567 * @param null $status 568 * @return string 569 */ 570 public function other_status_messages($status = null) 571 { 572 switch ($status) { 573 case "1": 574 $msg = __("Payment has not been made. code:", 'learnpress-idpay'); 575 break; 576 case "2": 577 $msg = __("Payment has failed. code:", 'learnpress-idpay'); 578 break; 579 case "3": 580 $msg = __("An error has occurred. code:", 'learnpress-idpay'); 581 break; 582 case "4": 583 $msg = __("Blocked. code:", 'learnpress-idpay'); 584 break; 585 case "5": 586 $msg = __("Return to payer. code:", 'learnpress-idpay'); 587 break; 588 case "6": 589 $msg = __("Systematic return. code:", 'learnpress-idpay'); 590 break; 591 case "7": 592 $msg = __("Cancel payment. code:", 'learnpress-idpay'); 593 break; 594 case "8": 595 $msg = __("It was transferred to the payment gateway. code:", 'learnpress-idpay'); 596 break; 597 case "10": 598 $msg = __("Waiting for payment confirmation. code:", 'learnpress-idpay'); 599 break; 600 case "100": 601 $msg = __("Payment has been confirmed. code:", 'learnpress-idpay'); 602 break; 603 case "101": 604 $msg = __("Payment has already been confirmed. code:", 'learnpress-idpay'); 605 break; 606 case "200": 607 $msg = __("Deposited to the recipient. code:", 'learnpress-idpay'); 608 break; 609 case "0": 610 $msg = __("Abuse of previous transactions. code:", 'learnpress-idpay'); 611 break; 612 case null: 613 $msg = __("Unexpected error. code:", 'learnpress-idpay'); 614 $status = '1000'; 615 break; 616 } 617 $msg = sprintf("$msg %s", $status); 618 619 return $msg; 620 } 621 115 622 } 116 117 /**118 * Register web hook.119 *120 * @return array121 */122 public function register_web_hook()123 {124 learn_press_register_web_hook('idpay', 'learn_press_idpay');125 }126 127 /**128 * Admin payment settings.129 *130 * @return array131 */132 public function get_settings()133 {134 return apply_filters('learn-press/gateway-payment/idpay/settings',135 array(136 array(137 'title' => __('Enable', 'learnpress-idpay'),138 'id' => '[enable]',139 'default' => 'no',140 'type' => 'yes-no'141 ),142 array(143 'title' => __('sandbox', 'learnpress-idpay'),144 'id' => '[sandbox]',145 'default' => 'yes',146 'type' => 'yes-no'147 ),148 array(149 'type' => 'textarea',150 'title' => __('Description', 'learnpress-idpay'),151 'default' => __('Pay with IDPay', 'learnpress-idpay'),152 'id' => '[description]',153 'editor' => array(154 'textarea_rows' => 5155 ),156 'css' => 'height: 100px;',157 'visibility' => array(158 'state' => 'show',159 'conditional' => array(160 array(161 'field' => '[enable]',162 'compare' => '=',163 'value' => 'yes'164 )165 )166 )167 ),168 array(169 'title' => __('api_key', 'learnpress-idpay'),170 'id' => '[api_key]',171 'type' => 'text',172 'visibility' => array(173 'state' => 'show',174 'conditional' => array(175 array(176 'field' => '[enable]',177 'compare' => '=',178 'value' => 'yes'179 )180 )181 )182 )183 )184 );185 }186 187 /**188 * Payment form.189 */190 public function get_payment_form()191 {192 ob_start();193 $template = learn_press_locate_template('form.php', learn_press_template_path() . '/addons/idpay-payment/', LP_ADDON_IDPAY_PAYMENT_TEMPLATE);194 include $template;195 196 return ob_get_clean();197 }198 199 /**200 * Error message201 */202 public function error_message()203 {204 if (isset($_SESSION['idpay_error']) && intval($_SESSION['idpay_error']) === 1) {205 $_SESSION['idpay_error'] = 0;206 $template = learn_press_locate_template('payment-error.php', learn_press_template_path() . '/addons/idpay-payment/', LP_ADDON_IDPAY_PAYMENT_TEMPLATE);207 include $template;208 }209 }210 211 /**212 * @return mixed213 */214 public function get_icon()215 {216 if (empty($this->icon)) {217 $this->icon = LP_ADDON_IDPAY_PAYMENT_URL . 'assets/images/idpay.png';218 }219 220 return parent::get_icon();221 }222 223 /**224 * Check gateway available.225 *226 * @return bool227 */228 public function idpay_available()229 {230 if (LP()->settings->get("{$this->id}.enable") != 'yes') {231 return false;232 }233 234 return true;235 }236 237 /**238 * Get form data.239 *240 * @return array241 */242 public function get_form_data()243 {244 if ($this->order) {245 $user = learn_press_get_current_user();246 $currency_code = learn_press_get_currency();247 if ($currency_code == 'IRR') {248 $amount = $this->order->order_total / 10;249 } else {250 $amount = $this->order->order_total;251 }252 253 $this->form_data = array(254 'amount' => $amount,255 'currency' => strtolower(learn_press_get_currency()),256 'token' => $this->token,257 'description' => sprintf(__("Charge for %s", "learnpress-idpay"), $user->get_data('email')),258 'customer' => array(259 'name' => $user->get_data('display_name'),260 'billing_email' => $user->get_data('email'),261 ),262 'errors' => isset($this->posted['form_errors']) ? $this->posted['form_errors'] : ''263 );264 }265 266 return $this->form_data;267 }268 269 /**270 * Validate form fields.271 *272 * @return bool273 * @throws Exception274 * @throws string275 */276 public function validate_fields()277 {278 $posted = learn_press_get_request('learn-press-idpay');279 $email = !empty($posted['email']) ? $posted['email'] : "";280 $mobile = !empty($posted['mobile']) ? $posted['mobile'] : "";281 282 $error_message = array();283 if (!empty($email) && !filter_var($email, FILTER_VALIDATE_EMAIL)) {284 $error_message[] = __('Invalid email format.', 'learnpress-idpay');285 }286 if (!empty($mobile) && !preg_match("/^(09)(\d{9})$/", $mobile)) {287 $error_message[] = __('Invalid mobile format.', 'learnpress-idpay');288 }289 290 if ($error = sizeof($error_message)) {291 throw new Exception(sprintf('<div>%s</div>', join('</div><div>', $error_message)), 8000);292 }293 $this->posted = $posted;294 295 return $error ? false : true;296 }297 298 299 /**300 * IDPay payment process.301 *302 * @param $order303 *304 * @return array305 * @throws string306 */307 public function process_payment($order)308 {309 $this->order = learn_press_get_order($order);310 $idpay = $this->get_checkout_payment_url();311 $gateway_url = $this->link;312 313 $json = array(314 'result' => $idpay ? 'success' : 'fail',315 'redirect' => $idpay ? $gateway_url : ''316 );317 318 return $json;319 }320 321 /**322 * @return bool323 */324 public function get_checkout_payment_url()325 {326 if ($this->get_form_data()) {327 328 $order = $this->order;329 330 $customer_name = $order->get_customer_name();331 $callback = get_site_url() . '/?' . learn_press_get_web_hook('idpay') . '=1&order_id=' . $order->get_id();332 333 $currency_code = learn_press_get_currency();334 if ($currency_code == 'IRR') {335 $amount = $order->order_total;336 } else {337 $note=__("Currency is not supported", 'learnpress-idpay');338 $payment_error = $note;339 $payment_error .= "\n";340 $payment_error .= get_post_meta($order->id, 'idpay_payment_error', TRUE);341 update_post_meta($order->id, __('idpay_payment_error','learnpress-idpay'), $payment_error);342 learn_press_add_message($note, 'error');343 344 return false;345 }346 347 //Set params and headers348 $data = array(349 'order_id' => $order->get_id(),350 'amount' => $amount,351 'name' => $customer_name,352 'phone' => (!empty($this->posted['mobile'])) ? $this->posted['mobile'] : "",353 'mail' => (!empty($this->posted['email'])) ? $this->posted['email'] : "",354 'desc' => 'توضیحات پرداخت کننده',355 'callback' => $callback,356 'reseller' => null,357 );358 359 $headers = array(360 'Content-Type' => 'application/json',361 'X-API-KEY' => $this->api_key,362 'X-SANDBOX' => $this->sandbox,363 );364 365 $args = array(366 'body' => json_encode($data),367 'headers' => $headers,368 'timeout' => 15,369 );370 371 $response = $this->call_gateway_endpoint($this->payment_endpoint, $args);372 //Check error373 if (is_wp_error($response)) {374 $payment_error = $this->other_status_messages();375 $payment_error .= "\n";376 $payment_error .= get_post_meta($order->id, 'idpay_payment_error', TRUE);377 update_post_meta($order->id, __('idpay_payment_error','learnpress-idpay'), $payment_error);378 learn_press_add_message($response->get_error_message(), 'error');379 380 return false;381 }382 $http_status = wp_remote_retrieve_response_code($response);383 $result = wp_remote_retrieve_body($response);384 $result = json_decode($result);385 386 //Check http error387 if ($http_status != 201 || empty($result) || empty($result->id) || empty($result->link)) {388 $note = '';389 $note .= __('An error occurred while creating the transaction.', 'learnpress-idpay');390 $note .= '<br/>';391 $note .= sprintf(__('error status: %s', 'learnpress-idpay'), $http_status);392 393 if (!empty($result->error_code) && !empty($result->error_message)) {394 $note .= '<br/>';395 $note .= sprintf(__('error code: %s', 'learnpress-idpay'), $result->error_code);396 $note .= '<br/>';397 $note .= sprintf(__('error message: %s', 'learnpress-idpay'), $result->error_message);398 $payment_error = $result->error_message;399 $payment_error .= "\n";400 $payment_error .= get_post_meta($order->id, 'idpay_payment_error', TRUE);401 update_post_meta($order->id, __('idpay_payment_error','learnpress-idpay'), $payment_error);402 learn_press_add_message($note, 'error');403 }404 405 return false;406 }407 // Save ID of this transaction408 update_post_meta($order->id, __('idpay_transaction_id','learnpress-idpay'), $result->id);409 410 // Set remote status of the transaction to 1 as it's primary value.411 update_post_meta($order->id, __('idpay_transaction_status','learnpress-idpay'), 1);412 413 $note = sprintf(__('transaction id: %s', 'learnpress-idpay'), $result->id);414 $this->link = $result->link;415 return true;416 417 }418 419 return false;420 }421 422 /**423 * Handle a web hook424 *CallBack method425 */426 public function web_hook_process_idpay()427 {428 // Check method post or get429 $method = $_SERVER['REQUEST_METHOD'];430 if ($method == 'POST') {431 $status = sanitize_text_field($_POST['status']);432 $track_id = sanitize_text_field($_POST['track_id']);433 $id = sanitize_text_field($_POST['id']);434 $order_id = sanitize_text_field($_POST['order_id']);435 }436 elseif ($method == 'GET') {437 $status = sanitize_text_field($_GET['status']);438 $track_id = sanitize_text_field($_GET['track_id']);439 $id = sanitize_text_field($_GET['id']);440 $order_id = sanitize_text_field($_GET['order_id']);441 }442 443 //Check id or order_id is empty444 if (empty($id) || empty($order_id)) {445 learn_press_add_message($this->other_status_messages(), 'error');446 wp_redirect(esc_url(learn_press_get_page_link('checkout')));447 448 exit();449 }450 451 $order = LP_Order::instance($order_id);452 //Check order is empty453 if (empty($order)) {454 learn_press_add_message($this->other_status_messages(), 'error');455 wp_redirect(esc_url(learn_press_get_page_link('checkout')));456 457 exit();458 }459 460 //Check order status461 if ($order->has_status('completed')) {462 learn_press_add_message($this->other_status_messages(), 'error');463 wp_redirect(esc_url(learn_press_get_page_link('checkout')));464 465 exit();466 }467 468 //Failed transaction469 if ($status != 10) {470 $order = LP_Order::instance($order_id);471 $massage = $this->other_status_messages($status);472 $payment_error = $massage;473 $payment_error .= "\n";474 $payment_error .= get_post_meta($order_id, 'idpay_payment_error', TRUE);475 update_post_meta($order_id, __('idpay_payment_error','learnpress-idpay'), $payment_error);476 update_post_meta($order_id, 'idpay_transaction_status', $status);477 $order->update_status('failed');478 learn_press_add_message($massage, 'error');479 wp_redirect(esc_url(learn_press_get_page_link('checkout')));480 481 exit();482 }483 484 //Set params and headers485 $params = array(486 'id' => $id,487 'order_id' => $order->id,488 );489 490 $headers = array(491 'Content-Type' => 'application/json',492 'X-API-KEY' => $this->api_key,493 'X-SANDBOX' => $this->sandbox,494 );495 496 $args = array(497 'body' => json_encode($params),498 'headers' => $headers,499 'timeout' => 15,500 );501 502 $response = $this->call_gateway_endpoint($this->verify_endpoint, $args);503 //Check Error504 if (is_wp_error($response)) {505 $payment_error = $this->other_status_messages();506 $payment_error .= "\n";507 $payment_error .= get_post_meta($order->id, 'idpay_payment_error', TRUE);508 update_post_meta($order->id, __('idpay_payment_error'.'learnpress-idpay'), $payment_error);509 learn_press_add_message($response->get_error_message(), 'error');510 wp_redirect(esc_url(learn_press_get_page_link('checkout')));511 512 exit();513 }514 515 $http_status = wp_remote_retrieve_response_code($response);516 $result = wp_remote_retrieve_body($response);517 $result = json_decode($result);518 519 //Check http Error520 if ($http_status != 200) {521 $note = '';522 $note .= __('An error occurred while verifying the transaction.', 'learnpress-idpay');523 $note .= '<br/>';524 $note .= sprintf(__('error status: %s', 'learnpress-idpay'), $http_status);525 526 if (!empty($result->error_code) && !empty($result->error_message)) {527 $note = '';528 $note .= __('An error occurred while creating the transaction.', 'learnpress-idpay');529 $note .= '<br/>';530 $note .= sprintf(__('error status: %s', 'learnpress-idpay'), $http_status);531 $note .= '<br/>';532 $note .= sprintf(__('error message: %s', 'learnpress-idpay'), $result->error_message);533 $payment_error=$result->error_message;534 learn_press_add_message($note, 'error');535 }536 537 $payment_error .= "\n";538 $payment_error .= get_post_meta($order_id, 'idpay_payment_error', TRUE);539 update_post_meta($order_id, __('idpay_payment_error','learnpress-idpay'), $payment_error);540 learn_press_add_message($note, 'error');541 $order->update_status('failed');542 wp_redirect(esc_url(learn_press_get_page_link('checkout')));543 544 exit();545 } else {546 547 //Check Double Spending548 if ($this->double_spending_occurred($order->id, $id)) {549 $note = $this->other_status_messages(0);550 $payment_error = $note;;551 $payment_error .= "\n";552 $payment_error .= get_post_meta($order_id, 'idpay_payment_error', TRUE);553 update_post_meta($order_id, __('idpay_payment_error','learnpress-idpay'), $payment_error);554 $order->update_status('failed');555 learn_press_add_message($note, 'error');556 wp_redirect(esc_url(learn_press_get_page_link('checkout')));557 558 exit();559 }560 561 $order_id = $order->id;562 $verify_status = empty($result->status) ? NULL : $result->status;563 $verify_track_id = empty($result->track_id) ? NULL : $result->track_id;564 $verify_id = empty($result->id) ? NULL : $result->id;565 $verify_order_id = empty($result->order_id) ? NULL : $result->order_id;566 $verify_amount = empty($result->amount) ? NULL : $result->amount;567 $verify_card_no = empty($result->payment->card_no) ? NULL : $result->payment->card_no;568 $verify_hashed_card_no = empty($result->payment->hashed_card_no) ? NULL : $result->payment->hashed_card_no;569 $verify_date = empty($result->payment->date) ? NULL : $result->payment->date;570 571 // Updates order's meta data after verifying the payment.572 update_post_meta($order_id, __('idpay_transaction_status', 'learnpress-idpay'), $verify_status);573 update_post_meta($order_id, __('idpay_track_id','learnpress-idpay'), $verify_track_id);574 update_post_meta($order_id, __('idpay_transaction_id','learnpress-idpay'), $verify_id);575 update_post_meta($order_id, __('idpay_transaction_order_id','learnpress-idpay'), $verify_order_id);576 update_post_meta($order_id, __('idpay_transaction_amount','learnpress-idpay'), $verify_amount);577 update_post_meta($order_id, __('idpay_payment_card_no','learnpress-idpay'), $verify_card_no);578 update_post_meta($order_id, __('idpay_payment_hashed_card_no','learnpress-idpay'), $verify_hashed_card_no);579 update_post_meta($order_id, __('idpay_payment_date','learnpress-idpay'), $verify_date);580 $order->payment_complete($verify_track_id);581 wp_redirect(esc_url($this->get_return_url($order)));582 583 exit();584 }585 586 }587 588 /**589 * @param $order_id590 * @param $remote_id591 * @return bool592 */593 private function double_spending_occurred($order_id, $remote_id)594 {595 if (get_post_meta($order_id, 'idpay_transaction_id', TRUE) != $remote_id) {596 return TRUE;597 }598 599 return FALSE;600 }601 602 /**603 * Calls the gateway endpoints.604 *605 * Tries to get response from the gateway for 4 times.606 *607 * @param $url608 * @param $args609 *610 * @return array|\WP_Error611 */612 private function call_gateway_endpoint($url, $args)613 {614 $number_of_connection_tries = 4;615 while ($number_of_connection_tries) {616 $response = wp_safe_remote_post($url, $args);617 if (is_wp_error($response)) {618 $number_of_connection_tries--;619 continue;620 } else {621 break;622 }623 }624 625 return $response;626 }627 628 /**629 * @param null $status630 * @return string631 */632 public function other_status_messages($status = null)633 {634 switch ($status) {635 case "1":636 $msg = __("Payment has not been made. code:", 'learnpress-idpay');637 break;638 case "2":639 $msg = __("Payment has failed. code:", 'learnpress-idpay');640 break;641 case "3":642 $msg = __("An error has occurred. code:", 'learnpress-idpay');643 break;644 case "4":645 $msg = __("Blocked. code:", 'learnpress-idpay');646 break;647 case "5":648 $msg = __("Return to payer. code:", 'learnpress-idpay');649 break;650 case "6":651 $msg = __("Systematic return. code:", 'learnpress-idpay');652 break;653 case "7":654 $msg = __("Cancel payment. code:", 'learnpress-idpay');655 break;656 case "8":657 $msg = __("It was transferred to the payment gateway. code:", 'learnpress-idpay');658 break;659 case "10":660 $msg = __("Waiting for payment confirmation. code:", 'learnpress-idpay');661 break;662 case "100":663 $msg = __("Payment has been confirmed. code:", 'learnpress-idpay');664 break;665 case "101":666 $msg = __("Payment has already been confirmed. code:", 'learnpress-idpay');667 break;668 case "200":669 $msg = __("Deposited to the recipient. code:", 'learnpress-idpay');670 break;671 case "0":672 $msg = __("Abuse of previous transactions. code:", 'learnpress-idpay');673 break;674 case null:675 $msg = __("Unexpected error. code:", 'learnpress-idpay');676 $status = '1000';677 break;678 }679 $msg = sprintf("$msg %s", $status);680 681 return $msg;682 }683 684 }685 623 } -
idpay-payment-learnpress/trunk/inc/load.php
r2408293 r2825657 5 5 * @author IDPay 6 6 * @package LearnPress/IDPay/Classes 7 * @version 1. 0.17 * @version 1.1.0 8 8 */ 9 9 -
idpay-payment-learnpress/trunk/readme.txt
r2408293 r2825657 1 === IDPay Payment Gateway for Learnpress === 2 Contributors: vispa, mnbp1371 3 Tags: learnpress, payment, idpay, gateway, آیدی پی 4 Stable tag: 1.0.1 5 Tested up to: 5.4 1 === IDPay Payment Gateway For LearnPress === 2 Title : IDPay Payment Gateway For LearnPress 3 Tags: learnpress, payment, idpay, gateway, آیدی پی,LearnPress,learnpress gateway,learnpress payment 4 Stable tag: 1.1.0 5 Tested up to: 6.1 6 Contributors: MimDeveloper.Tv (Mohammad-Malek), imikiani, meysamrazmi, vispa 6 7 License: GPLv2 or later 7 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html 8 9 9 [IDPay](https://idpay.ir) payment method for [Learnpress](https://wordpress.org/plugins/learnpress/).10 11 10 == Description == 12 11 13 [IDPay](https://idpay.ir) is one of the Financial Technology providers in Iran. 14 15 IDPay provides some payment services and this plugin enables the IDPay's payment gateway for Learnpress. 12 After installing and enabling this plugin, your customers can pay through IDPay gateway. 13 For doing a transaction through IDPay gateway, 14 you must have an API Key. 15 You can obtain the API Key by going to your [dashboard](https://idpay.ir/dashboard/web-services) in your 16 IDPay [account](https://idpay.ir/user). 16 17 17 18 == Installation == 18 19 19 After creating a web service on https://idpay.ir and getting an API Key, follow this instruction: 20 21 1. Activate plugin IDPay for Learnpress. 22 2. Go tho Learnpress > Settings > Payments. 20 0. After creating a web service on https://idpay.ir and getting an API Key, follow this instruction: 21 1. Activate plugin IDPay for LearnPress. 22 2. Go tho LearnPress > Settings > Payments Gateways. 23 23 3. Enable IDPay payment gateway. 24 24 4. Go to Manage. 25 25 5. Enter the API Key. 26 26 27 If you need to use this plugin in Test mode, check the "Sandbox". 28 29 Also there is a complete documentation [here](https://idpay.ir/plugins) which helps you to install the plugin step by step. 30 31 Thank you so much for using IDPay Payment Gateway. 27 * If you need to use this plugin in Test mode, check the "Sandbox". 32 28 33 29 == Changelog == 34 30 35 = 1.0.1, October 19, 2020 = 31 == 1.1.0, Nov 13, 2022 == 32 * Tested Up With Wordpress 6.1 And LearnPress 4.1.7.3.2 33 * Check Double Spending Correct 34 * Check Does Not Xss Attack Correct 35 * First Official Release 36 37 == 1.0.1, October 19, 2020 == 36 38 * Support GET method in Callback. 37 39 38 = 1.0.0, July 14, 2020=39 * Firstrelease.40 == 1.0.0, July 14, 2020 == 41 * Develope release. -
idpay-payment-learnpress/trunk/templates/form.php
r2408293 r2825657 7 7 * @author IDPay 8 8 * @package LearnPress/IDPay/Templates 9 * @version 1. 0.19 * @version 1.1.0 10 10 */ 11 11 -
idpay-payment-learnpress/trunk/templates/payment-error.php
r2408293 r2825657 7 7 * @author IDPay 8 8 * @package LearnPress/IDPay/Templates 9 * @version 1. 0.19 * @version 1.1.0 10 10 */ 11 11
Note: See TracChangeset
for help on using the changeset viewer.