Changeset 3010003
- Timestamp:
- 12/14/2023 12:27:18 PM (8 months ago)
- Location:
- monopay
- Files:
-
- 13 added
- 5 deleted
- 5 edited
- 8 copied
Legend:
- Unmodified
- Added
- Removed
-
monopay/tags/2.1.0/README.txt
r3006277 r3010003 4 4 Tags: mono, cashier, payments, routing 5 5 Requires at least: 6.2 6 Tested up to: 6. 3.17 Stable tag: 2. 0.46 Tested up to: 6. 7 Stable tag: 2. 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 130 130 = 2.0.4 = 131 131 - added thankyou page redirect. 132 133 134 135 -
monopay/tags/2.1.0/includes/class-wc-mono-gateway.php
r3006277 r3010003 3 3 use MonoGateway\Api; 4 4 use MonoGateway\Order; 5 6 7 8 9 5 10 6 11 const ORDER_STATUS_COMPLETED = 'completed'; … … 50 55 $this->redirect = $this->get_option('redirect'); 51 56 57 58 59 52 60 add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']); 53 61 add_action('woocommerce_api_mono_gateway', [$this, 'webhook']); … … 55 63 56 64 add_action('add_meta_boxes', [$this, 'add_meta_boxes']); 57 add_action('save_post_shop_order', [$this, 'finalize_or_cancel_hold']); 65 add_action('woocommerce_api_mono_finalize_hold', [$this, 'admin_finalize_hold']); 66 add_action('woocommerce_api_mono_cancel_hold', [$this, 'admin_cancel_hold']); 58 67 add_action('woocommerce_api_mono_refresh', [$this, 'admin_refresh_invoice_status']); 59 68 add_action('woocommerce_thankyou', [$this, 'post_payment_request']); … … 123 132 } 124 133 134 135 136 137 138 139 140 141 142 143 125 144 126 145 $monoOrder = new Order(); … … 134 153 $monoOrder->setRedirectUrl(home_url() . $this->redirect); 135 154 } else { 136 // $custom_afterpayment_redirect = add_query_arg('mono_payment_result', '1', home_url('/'));137 // $custom_afterpayment_redirect = add_query_arg('order_id', $order_id, $custom_afterpayment_redirect);138 155 $monoOrder->setRedirectUrl($order->get_checkout_order_received_url()); 139 156 } … … 146 163 $currencyCode = get_woocommerce_currency(); 147 164 $ccy = key_exists($currencyCode, self::CURRENCY_CODE) ? self::CURRENCY_CODE[$currencyCode] : CURRENCY_UAH; 148 update_post_meta($order_id, '_payment_type', $paymentType);149 update_post_meta($order_id, '_ccy', $ccy);165 _meta($order_id, '_payment_type', $paymentType); 166 _meta($order_id, '_ccy', $ccy); 150 167 try { 151 168 $invoice = $this->mono_api->create($paymentType, $ccy); … … 230 247 return; 231 248 } 232 $meta = $order->get_meta_data();249 $meta = ); 233 250 $ccy = $this->get_from_meta($meta, "_ccy"); 234 251 if ($ccy == null) { 235 252 $ccy = self::CURRENCY_CODE[get_woocommerce_currency()]; 236 update_post_meta($order_id, '_ccy', $ccy);253 _meta($order_id, '_ccy', $ccy); 237 254 } 238 255 if ($ccy == CURRENCY_UAH) { … … 298 315 299 316 public function admin_refresh_invoice_status() { 300 check_ajax_referer('monopay_refresh_nonce', 'nonce'); 317 $ok = $this->validate_nonces('monopay_refresh_nonce'); 318 if (!$ok) { 319 return; 320 } 301 321 $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0; 302 322 if (!$order_id || !current_user_can('manage_woocommerce')) { … … 310 330 return; 311 331 } 312 $refreshed_timestamp = $order->get_meta('_status_refreshed'); 313 if ($refreshed_timestamp && (time() - $refreshed_timestamp) < REFRESH_REQUEST_INTERVAL) { 314 wp_send_json_error('Too many requests', 429); 315 return; 316 } 317 318 $invoice_id = $order->get_transaction_id(); 332 333 334 // Define a unique transient key for this order. 335 $transient_key = 'refresh_order_' . $order_id; 336 337 // this function might get called multiple times so we escape excessive fincalization or cancellation attempts 338 // Check if this function has already been called for this order. 339 if (get_transient($transient_key)) { 340 // If yes, return early. 341 return; 342 } 343 319 344 $this->refresh_status($order); 320 update_post_meta($order_id, '_status_refreshed', time());345 ); 321 346 322 347 wp_send_json_success('Status refreshed successfully'); … … 346 371 ); 347 372 } 348 update_post_meta($order_id, '_payment_amount', $invoice_final_amount);349 update_post_meta($order_id, '_payment_amount_refunded', 0);350 update_post_meta($order_id, '_payment_amount_final', $invoice_final_amount);351 $ccy = $order->get_meta('_ccy', true);373 _meta($order_id, '_payment_amount', $invoice_final_amount); 374 _meta($order_id, '_payment_amount_refunded', 0); 375 _meta($order_id, '_payment_amount_final', $invoice_final_amount); 376 $ccy = '_ccy', true); 352 377 if ($ccy && $ccy != CURRENCY_UAH) { 353 update_post_meta($order_id, '_rate', $invoice_final_amount / (int)($order->get_total() * 100 + 0.5));378 _meta($order_id, '_rate', $invoice_final_amount / (int)($order->get_total() * 100 + 0.5)); 354 379 } 355 380 global $woocommerce; 356 if ($woocommerce->cart ) {381 if ($woocommerce->cart) { 357 382 $woocommerce->cart->empty_cart(); 358 383 } … … 364 389 $order->update_status(ORDER_STATUS_ON_HOLD); 365 390 366 update_post_meta($order_id, '_payment_amount', $invoice_amount);367 $ccy = $order->get_meta('_ccy', true);391 _meta($order_id, '_payment_amount', $invoice_amount); 392 $ccy = '_ccy', true); 368 393 if ($ccy && $ccy != CURRENCY_UAH) { 369 update_post_meta($order_id, '_rate', $invoice_amount / (int)($order->get_total() * 100 + 0.5));394 _meta($order_id, '_rate', $invoice_amount / (int)($order->get_total() * 100 + 0.5)); 370 395 } 371 396 global $woocommerce; 372 if ($woocommerce->cart ) {397 if ($woocommerce->cart) { 373 398 $woocommerce->cart->empty_cart(); 374 399 } … … 383 408 $payment_amount_uah = get_post_meta($order->get_id(), '_payment_amount', true) ?? 0; 384 409 $old_payment_amount_final_uah = get_post_meta($order->get_id(), '_payment_amount_final', true) ?? 0; 385 update_post_meta($order_id, '_payment_amount_refunded', $payment_amount_uah - $invoice_final_amount); 386 update_post_meta($order_id, '_payment_amount_final', $invoice_final_amount); 387 $order->add_order_note( 388 sprintf(__('Refunded %1$s UAH', 'womono'), sprintf('%.2f', ((int)($old_payment_amount_final_uah) - $invoice_final_amount) / 100)) 389 ); 410 $this->update_meta($order_id, '_payment_amount_refunded', $payment_amount_uah - $invoice_final_amount); 411 $this->update_meta($order_id, '_payment_amount_final', $invoice_final_amount); 412 $refunded_amount = (int)($old_payment_amount_final_uah) - $invoice_final_amount; 413 if ($refunded_amount != 0) { 414 $order->add_order_note( 415 sprintf(__('Refunded %1$s UAH', 'womono'), sprintf('%.2f', ($refunded_amount / 100))) 416 ); 417 } 390 418 } 391 419 break; … … 411 439 412 440 function add_meta_boxes() { 413 if (!isset($_GET['post'])) { 414 return; 415 } 416 $order_id = intval($_GET['post']); 441 if (isset($_GET['post'])) { 442 $order_id = intval($_GET['post']); 443 } else if (isset($_GET['id'])) { 444 $order_id = intval($_GET['id']); 445 } else { 446 return; 447 } 417 448 $order = wc_get_order($order_id); 418 449 if (!$order) { … … 423 454 __('Monopay payment status refresh', 'womono'), 424 455 [$this, 'add_refresh_invoice_status_button'], 425 ' shop_order',456 '', 426 457 'side', 427 458 'high' … … 429 460 $order_status = $order->get_status(); 430 461 431 if ($order_status != ORDER_STATUS_ COMPLETED && $order_status != ORDER_STATUS_ON_HOLD) {462 if ($order_status != ORDER_STATUS_ON_HOLD) { 432 463 // we can finalize or cancel invoice only if it's paid 433 464 return; 434 465 } 435 $meta = $order->get_meta_data();466 $meta = ); 436 467 $payment_type = $this->get_from_meta($meta, '_payment_type'); 437 468 if ($payment_type != 'hold') { … … 453 484 __('Hold Settings', 'womono'), 454 485 [$this, 'add_hold_functionality_buttons'], 455 ' shop_order',486 '', 456 487 'side', 457 488 'high' … … 465 496 return; 466 497 } 467 $refreshed_timestamp = $order->get_meta('_status_refreshed');468 $disabled = '';469 if ($refreshed_timestamp && (time() - $refreshed_timestamp) < REFRESH_REQUEST_INTERVAL) {470 $disabled = 'disabled';471 }472 498 $url = home_url() . '/?wc-api=mono_refresh'; 473 499 474 500 // Nonce for security 475 501 $ajax_nonce = wp_create_nonce('monopay_refresh_nonce'); 502 476 503 echo <<<END 477 504 <a class="button button-primary" onclick="jQuery.ajax({ … … 481 508 'order_id': $post->ID, 482 509 'nonce': '$ajax_nonce', 510 483 511 }, 484 512 success: function(response) { 485 513 window.location.reload(); 486 514 }, 487 })" $disabled>$refresh_text</a>515 })">$refresh_text</a> 488 516 END; 489 517 } … … 500 528 return; 501 529 } 502 // $this->refresh_status($order->get_transaction_id(), $order); 503 $meta = $order->get_meta_data(); 530 $meta = get_post_meta($post->ID, '', true); 504 531 $amounts = $this->get_amounts($meta, $order); 505 532 … … 509 536 $cancel_text = __('Cancel', 'womono'); 510 537 $payment_amount = sprintf('%.2f', $amounts['payment_amount'] / 100); 538 539 540 541 542 543 544 545 546 547 548 511 549 echo <<<END 512 <script>513 document.addEventListener('DOMContentLoaded', function() {514 var cancelBtn = document.getElementById('mono_cancel');515 var finalizeBtn = document.getElementById('finalize_hold');516 517 cancelBtn.addEventListener('click', function(event) {518 if (!confirm("$cancel_hold_text")) {519 event.preventDefault();520 }521 });522 523 finalizeBtn.addEventListener('click', function(event) {524 if (!confirm("$finalize_text")) {525 event.preventDefault();526 }527 });528 });529 </script>530 550 <div id="hold_span_actions" class="text-left"> 531 551 <a class="button button-primary" … … 535 555 </a> 536 556 537 <button type="submit" name="cancel_hold_action" id="mono_cancel" 538 class="button button-danger" value="cancel_hold">$cancel_hold_text 539 </button> 557 <a class="button button-danger" onclick="if (confirm('$cancel_hold_text')) { 558 jQuery.ajax({ 559 url: '$cancel_hold_url', 560 type: 'POST', 561 data: { 562 'order_id': $post->ID, 563 'nonce': '$cancel_hold_nonce', 564 'sec_nonce': '$cancel_hold_sec_nonce', 565 }, 566 success: function (response) { 567 window.location.reload(); 568 }, 569 }) 570 }">$cancel_hold_text</a> 540 571 </div> 541 572 <div id="hold_form_container" style="display: none;"> … … 556 587 onclick="document.getElementById('hold_span_actions').style.display='block';document.getElementById('hold_form_container').style.display='none';"> 557 588 $cancel_text 558 </button> 559 560 <button type="submit" name="finalize_hold_action" id="finalize_hold" 561 class="button button-primary" value="finalize">$finalize_text 562 </button> 589 </button> 590 591 <a class="button button-primary" onclick="if (confirm('$finalize_text')) { 592 jQuery.ajax({ 593 url: '$finalize_hold_url', 594 type: 'POST', 595 data: { 596 'order_id': $post->ID, 597 'nonce': '$finalize_hold_nonce', 598 'sec_nonce': '$finalize_sec_nonce', 599 'finalization_amount': document.getElementById('mono_amount').value, 600 }, 601 success: function (response) { 602 window.location.reload(); 603 }, 604 }) 605 }">$finalize_text</a> 563 606 </div> 564 607 </div> … … 566 609 } 567 610 568 function finalize_or_cancel_hold($order_id) { 569 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) 570 return; 611 function admin_finalize_hold() { 612 $ok = $this->validate_nonces('monopay_finalize_hold_nonce'); 613 if (!$ok) { 614 return; 615 } 616 $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0; 617 if (!$order_id || !current_user_can('manage_woocommerce')) { 618 wp_send_json_error('Invalid request', 400); 619 return; 620 } 571 621 if (!$order_id) { 572 622 return; 573 623 } 574 if (!isset($_POST['finalize_hold_action']) && !isset($_POST['cancel_hold_action']) && !isset($_POST['monopay_refresh_action'])) { 575 return; 576 } 624 // Define a unique transient key for this order. 625 $transient_key = 'finalize_or_cancel_hold_' . $order_id; 626 627 // this function might get called multiple times so we escape excessive fincalization or cancellation attempts 628 // Check if this function has already been called for this order. 629 if (get_transient($transient_key)) { 630 // If yes, return early. 631 return; 632 } 633 set_transient($transient_key, true, 180); 634 577 635 $order = wc_get_order($order_id); 578 636 if (!$order) { 579 637 return; 580 638 } 639 640 641 642 581 643 $invoice_id = $order->get_transaction_id(); 582 644 583 if (isset($_POST['finalize_hold_action']) && 'finalize' === $_POST['finalize_hold_action']) { 584 $finalization_amount = floatval($_POST['finalization_amount']); 585 try { 586 $result = $this->mono_api->finalizeHold([ 587 "invoiceId" => $invoice_id, 588 "amount" => (int)($finalization_amount * 100 + 0.5), 589 ]); 590 591 if (is_wp_error($result)) { 592 return new WP_Error('error', $result->get_error_message()); 593 } 594 if (key_exists('errText', $result)) { 595 $order->add_order_note(__('Failed to finalize invoice: ', 'womono') . $result['errText']); 596 } 597 } catch (\Exception $e) { 598 $order->add_order_note(__('Hold cancellation error: ', 'womono') . $e->getMessage()); 599 return; 645 $finalization_amount = floatval($_POST['finalization_amount']); 646 try { 647 $result = $this->mono_api->finalizeHold([ 648 "invoiceId" => $invoice_id, 649 "amount" => (int)($finalization_amount * 100 + 0.5), 650 ]); 651 652 if (is_wp_error($result)) { 653 return new WP_Error('error', $result->get_error_message()); 600 654 } 601 } else if (isset($_POST['cancel_hold_action']) && 'cancel_hold' === $_POST['cancel_hold_action']) { 602 try { 603 $result = $this->mono_api->cancel([ 604 "invoiceId" => $invoice_id, 605 "extRef" => (string)$order_id, 606 ]); 607 608 if (is_wp_error($result)) { 609 return new WP_Error('error', $result->get_error_message()); 610 } 611 if (key_exists('errText', $result)) { 612 $order->add_order_note(__('Hold cancellation error: ', 'womono') . $result['errText']); 613 } 614 } catch (\Exception $e) { 615 $order->add_order_note(__('Hold cancellation error: ', 'womono') . $e->getMessage()); 616 return; 655 if (key_exists('errText', $result)) { 656 $order->add_order_note(__('Failed to finalize invoice: ', 'womono') . $result['errText']); 617 657 } 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 618 713 } 619 714 } … … 669 764 670 765 function get_from_meta($meta, $key) { 671 foreach ($meta as $item) { 672 if ($item->key == $key) return $item->value; 766 foreach ($meta as $item_key => $item_value) { 767 if ($item_key == $key && !empty($item_value)) { 768 return $item_value[0]; 769 } 673 770 } 674 771 return null; … … 698 795 $payment_amount_refunded = 0; 699 796 $payment_amount_final = 0; 700 update_post_meta($order_id, '_payment_type', 'hold');797 _meta($order_id, '_payment_type', 'hold'); 701 798 break; 702 799 case 'reversed': … … 714 811 return []; 715 812 } 716 update_post_meta($order_id, '_payment_amount', $payment_amount);717 update_post_meta($order_id, '_payment_amount_refunded', $payment_amount_refunded);718 update_post_meta($order_id, '_payment_amount_final', $payment_amount_final);813 _meta($order_id, '_payment_amount', $payment_amount); 814 _meta($order_id, '_payment_amount_refunded', $payment_amount_refunded); 815 _meta($order_id, '_payment_amount_final', $payment_amount_final); 719 816 720 817 return [ … … 746 843 } 747 844 } 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 748 870 } -
monopay/tags/2.1.0/languages/womono-uk.po
r3006277 r3010003 118 118 msgid "Payment failed" 119 119 msgstr "Оплату не здійснено. Зверніться до продавця" 120 121 122 -
monopay/tags/2.1.0/monopay.php
r3006277 r3010003 6 6 * Plugin URI: https://wordpress.org/plugins/monopay/#description 7 7 * Description: The Monopay WooCommerce Api plugin enables you to easily accept payments through your Woocommerce store. <a href="https://www.monobank.ua/">https://www.monobank.ua/</a> 8 * Version: 2. 0.48 * Version: 2. 9 9 */ 10 10 … … 22 22 23 23 add_filter('woocommerce_payment_gateways', 'add_mono_gateway_class'); 24 25 24 26 25 27 … … 61 63 } 62 64 65 66 67 68 69 70 71 72 73 74 75 76 63 77 function loadMonoLibrary() { 64 78 require_once MONOGATEWAY_DIR . 'includes/classes/Api.php'; 65 79 require_once MONOGATEWAY_DIR . 'includes/classes/Order.php'; 66 80 } 81 82 83 84 85 86 87 88 -
monopay/trunk/README.txt
r3006277 r3010003 4 4 Tags: mono, cashier, payments, routing 5 5 Requires at least: 6.2 6 Tested up to: 6. 3.17 Stable tag: 2. 0.46 Tested up to: 6. 7 Stable tag: 2. 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 130 130 = 2.0.4 = 131 131 - added thankyou page redirect. 132 133 134 135 -
monopay/trunk/includes/class-wc-mono-gateway.php
r3006277 r3010003 3 3 use MonoGateway\Api; 4 4 use MonoGateway\Order; 5 6 7 8 9 5 10 6 11 const ORDER_STATUS_COMPLETED = 'completed'; … … 50 55 $this->redirect = $this->get_option('redirect'); 51 56 57 58 59 52 60 add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']); 53 61 add_action('woocommerce_api_mono_gateway', [$this, 'webhook']); … … 55 63 56 64 add_action('add_meta_boxes', [$this, 'add_meta_boxes']); 57 add_action('save_post_shop_order', [$this, 'finalize_or_cancel_hold']); 65 add_action('woocommerce_api_mono_finalize_hold', [$this, 'admin_finalize_hold']); 66 add_action('woocommerce_api_mono_cancel_hold', [$this, 'admin_cancel_hold']); 58 67 add_action('woocommerce_api_mono_refresh', [$this, 'admin_refresh_invoice_status']); 59 68 add_action('woocommerce_thankyou', [$this, 'post_payment_request']); … … 123 132 } 124 133 134 135 136 137 138 139 140 141 142 143 125 144 126 145 $monoOrder = new Order(); … … 134 153 $monoOrder->setRedirectUrl(home_url() . $this->redirect); 135 154 } else { 136 // $custom_afterpayment_redirect = add_query_arg('mono_payment_result', '1', home_url('/'));137 // $custom_afterpayment_redirect = add_query_arg('order_id', $order_id, $custom_afterpayment_redirect);138 155 $monoOrder->setRedirectUrl($order->get_checkout_order_received_url()); 139 156 } … … 146 163 $currencyCode = get_woocommerce_currency(); 147 164 $ccy = key_exists($currencyCode, self::CURRENCY_CODE) ? self::CURRENCY_CODE[$currencyCode] : CURRENCY_UAH; 148 update_post_meta($order_id, '_payment_type', $paymentType);149 update_post_meta($order_id, '_ccy', $ccy);165 _meta($order_id, '_payment_type', $paymentType); 166 _meta($order_id, '_ccy', $ccy); 150 167 try { 151 168 $invoice = $this->mono_api->create($paymentType, $ccy); … … 230 247 return; 231 248 } 232 $meta = $order->get_meta_data();249 $meta = ); 233 250 $ccy = $this->get_from_meta($meta, "_ccy"); 234 251 if ($ccy == null) { 235 252 $ccy = self::CURRENCY_CODE[get_woocommerce_currency()]; 236 update_post_meta($order_id, '_ccy', $ccy);253 _meta($order_id, '_ccy', $ccy); 237 254 } 238 255 if ($ccy == CURRENCY_UAH) { … … 298 315 299 316 public function admin_refresh_invoice_status() { 300 check_ajax_referer('monopay_refresh_nonce', 'nonce'); 317 $ok = $this->validate_nonces('monopay_refresh_nonce'); 318 if (!$ok) { 319 return; 320 } 301 321 $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0; 302 322 if (!$order_id || !current_user_can('manage_woocommerce')) { … … 310 330 return; 311 331 } 312 $refreshed_timestamp = $order->get_meta('_status_refreshed'); 313 if ($refreshed_timestamp && (time() - $refreshed_timestamp) < REFRESH_REQUEST_INTERVAL) { 314 wp_send_json_error('Too many requests', 429); 315 return; 316 } 317 318 $invoice_id = $order->get_transaction_id(); 332 333 334 // Define a unique transient key for this order. 335 $transient_key = 'refresh_order_' . $order_id; 336 337 // this function might get called multiple times so we escape excessive fincalization or cancellation attempts 338 // Check if this function has already been called for this order. 339 if (get_transient($transient_key)) { 340 // If yes, return early. 341 return; 342 } 343 319 344 $this->refresh_status($order); 320 update_post_meta($order_id, '_status_refreshed', time());345 ); 321 346 322 347 wp_send_json_success('Status refreshed successfully'); … … 346 371 ); 347 372 } 348 update_post_meta($order_id, '_payment_amount', $invoice_final_amount);349 update_post_meta($order_id, '_payment_amount_refunded', 0);350 update_post_meta($order_id, '_payment_amount_final', $invoice_final_amount);351 $ccy = $order->get_meta('_ccy', true);373 _meta($order_id, '_payment_amount', $invoice_final_amount); 374 _meta($order_id, '_payment_amount_refunded', 0); 375 _meta($order_id, '_payment_amount_final', $invoice_final_amount); 376 $ccy = '_ccy', true); 352 377 if ($ccy && $ccy != CURRENCY_UAH) { 353 update_post_meta($order_id, '_rate', $invoice_final_amount / (int)($order->get_total() * 100 + 0.5));378 _meta($order_id, '_rate', $invoice_final_amount / (int)($order->get_total() * 100 + 0.5)); 354 379 } 355 380 global $woocommerce; 356 if ($woocommerce->cart ) {381 if ($woocommerce->cart) { 357 382 $woocommerce->cart->empty_cart(); 358 383 } … … 364 389 $order->update_status(ORDER_STATUS_ON_HOLD); 365 390 366 update_post_meta($order_id, '_payment_amount', $invoice_amount);367 $ccy = $order->get_meta('_ccy', true);391 _meta($order_id, '_payment_amount', $invoice_amount); 392 $ccy = '_ccy', true); 368 393 if ($ccy && $ccy != CURRENCY_UAH) { 369 update_post_meta($order_id, '_rate', $invoice_amount / (int)($order->get_total() * 100 + 0.5));394 _meta($order_id, '_rate', $invoice_amount / (int)($order->get_total() * 100 + 0.5)); 370 395 } 371 396 global $woocommerce; 372 if ($woocommerce->cart ) {397 if ($woocommerce->cart) { 373 398 $woocommerce->cart->empty_cart(); 374 399 } … … 383 408 $payment_amount_uah = get_post_meta($order->get_id(), '_payment_amount', true) ?? 0; 384 409 $old_payment_amount_final_uah = get_post_meta($order->get_id(), '_payment_amount_final', true) ?? 0; 385 update_post_meta($order_id, '_payment_amount_refunded', $payment_amount_uah - $invoice_final_amount); 386 update_post_meta($order_id, '_payment_amount_final', $invoice_final_amount); 387 $order->add_order_note( 388 sprintf(__('Refunded %1$s UAH', 'womono'), sprintf('%.2f', ((int)($old_payment_amount_final_uah) - $invoice_final_amount) / 100)) 389 ); 410 $this->update_meta($order_id, '_payment_amount_refunded', $payment_amount_uah - $invoice_final_amount); 411 $this->update_meta($order_id, '_payment_amount_final', $invoice_final_amount); 412 $refunded_amount = (int)($old_payment_amount_final_uah) - $invoice_final_amount; 413 if ($refunded_amount != 0) { 414 $order->add_order_note( 415 sprintf(__('Refunded %1$s UAH', 'womono'), sprintf('%.2f', ($refunded_amount / 100))) 416 ); 417 } 390 418 } 391 419 break; … … 411 439 412 440 function add_meta_boxes() { 413 if (!isset($_GET['post'])) { 414 return; 415 } 416 $order_id = intval($_GET['post']); 441 if (isset($_GET['post'])) { 442 $order_id = intval($_GET['post']); 443 } else if (isset($_GET['id'])) { 444 $order_id = intval($_GET['id']); 445 } else { 446 return; 447 } 417 448 $order = wc_get_order($order_id); 418 449 if (!$order) { … … 423 454 __('Monopay payment status refresh', 'womono'), 424 455 [$this, 'add_refresh_invoice_status_button'], 425 ' shop_order',456 '', 426 457 'side', 427 458 'high' … … 429 460 $order_status = $order->get_status(); 430 461 431 if ($order_status != ORDER_STATUS_ COMPLETED && $order_status != ORDER_STATUS_ON_HOLD) {462 if ($order_status != ORDER_STATUS_ON_HOLD) { 432 463 // we can finalize or cancel invoice only if it's paid 433 464 return; 434 465 } 435 $meta = $order->get_meta_data();466 $meta = ); 436 467 $payment_type = $this->get_from_meta($meta, '_payment_type'); 437 468 if ($payment_type != 'hold') { … … 453 484 __('Hold Settings', 'womono'), 454 485 [$this, 'add_hold_functionality_buttons'], 455 ' shop_order',486 '', 456 487 'side', 457 488 'high' … … 465 496 return; 466 497 } 467 $refreshed_timestamp = $order->get_meta('_status_refreshed');468 $disabled = '';469 if ($refreshed_timestamp && (time() - $refreshed_timestamp) < REFRESH_REQUEST_INTERVAL) {470 $disabled = 'disabled';471 }472 498 $url = home_url() . '/?wc-api=mono_refresh'; 473 499 474 500 // Nonce for security 475 501 $ajax_nonce = wp_create_nonce('monopay_refresh_nonce'); 502 476 503 echo <<<END 477 504 <a class="button button-primary" onclick="jQuery.ajax({ … … 481 508 'order_id': $post->ID, 482 509 'nonce': '$ajax_nonce', 510 483 511 }, 484 512 success: function(response) { 485 513 window.location.reload(); 486 514 }, 487 })" $disabled>$refresh_text</a>515 })">$refresh_text</a> 488 516 END; 489 517 } … … 500 528 return; 501 529 } 502 // $this->refresh_status($order->get_transaction_id(), $order); 503 $meta = $order->get_meta_data(); 530 $meta = get_post_meta($post->ID, '', true); 504 531 $amounts = $this->get_amounts($meta, $order); 505 532 … … 509 536 $cancel_text = __('Cancel', 'womono'); 510 537 $payment_amount = sprintf('%.2f', $amounts['payment_amount'] / 100); 538 539 540 541 542 543 544 545 546 547 548 511 549 echo <<<END 512 <script>513 document.addEventListener('DOMContentLoaded', function() {514 var cancelBtn = document.getElementById('mono_cancel');515 var finalizeBtn = document.getElementById('finalize_hold');516 517 cancelBtn.addEventListener('click', function(event) {518 if (!confirm("$cancel_hold_text")) {519 event.preventDefault();520 }521 });522 523 finalizeBtn.addEventListener('click', function(event) {524 if (!confirm("$finalize_text")) {525 event.preventDefault();526 }527 });528 });529 </script>530 550 <div id="hold_span_actions" class="text-left"> 531 551 <a class="button button-primary" … … 535 555 </a> 536 556 537 <button type="submit" name="cancel_hold_action" id="mono_cancel" 538 class="button button-danger" value="cancel_hold">$cancel_hold_text 539 </button> 557 <a class="button button-danger" onclick="if (confirm('$cancel_hold_text')) { 558 jQuery.ajax({ 559 url: '$cancel_hold_url', 560 type: 'POST', 561 data: { 562 'order_id': $post->ID, 563 'nonce': '$cancel_hold_nonce', 564 'sec_nonce': '$cancel_hold_sec_nonce', 565 }, 566 success: function (response) { 567 window.location.reload(); 568 }, 569 }) 570 }">$cancel_hold_text</a> 540 571 </div> 541 572 <div id="hold_form_container" style="display: none;"> … … 556 587 onclick="document.getElementById('hold_span_actions').style.display='block';document.getElementById('hold_form_container').style.display='none';"> 557 588 $cancel_text 558 </button> 559 560 <button type="submit" name="finalize_hold_action" id="finalize_hold" 561 class="button button-primary" value="finalize">$finalize_text 562 </button> 589 </button> 590 591 <a class="button button-primary" onclick="if (confirm('$finalize_text')) { 592 jQuery.ajax({ 593 url: '$finalize_hold_url', 594 type: 'POST', 595 data: { 596 'order_id': $post->ID, 597 'nonce': '$finalize_hold_nonce', 598 'sec_nonce': '$finalize_sec_nonce', 599 'finalization_amount': document.getElementById('mono_amount').value, 600 }, 601 success: function (response) { 602 window.location.reload(); 603 }, 604 }) 605 }">$finalize_text</a> 563 606 </div> 564 607 </div> … … 566 609 } 567 610 568 function finalize_or_cancel_hold($order_id) { 569 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) 570 return; 611 function admin_finalize_hold() { 612 $ok = $this->validate_nonces('monopay_finalize_hold_nonce'); 613 if (!$ok) { 614 return; 615 } 616 $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0; 617 if (!$order_id || !current_user_can('manage_woocommerce')) { 618 wp_send_json_error('Invalid request', 400); 619 return; 620 } 571 621 if (!$order_id) { 572 622 return; 573 623 } 574 if (!isset($_POST['finalize_hold_action']) && !isset($_POST['cancel_hold_action']) && !isset($_POST['monopay_refresh_action'])) { 575 return; 576 } 624 // Define a unique transient key for this order. 625 $transient_key = 'finalize_or_cancel_hold_' . $order_id; 626 627 // this function might get called multiple times so we escape excessive fincalization or cancellation attempts 628 // Check if this function has already been called for this order. 629 if (get_transient($transient_key)) { 630 // If yes, return early. 631 return; 632 } 633 set_transient($transient_key, true, 180); 634 577 635 $order = wc_get_order($order_id); 578 636 if (!$order) { 579 637 return; 580 638 } 639 640 641 642 581 643 $invoice_id = $order->get_transaction_id(); 582 644 583 if (isset($_POST['finalize_hold_action']) && 'finalize' === $_POST['finalize_hold_action']) { 584 $finalization_amount = floatval($_POST['finalization_amount']); 585 try { 586 $result = $this->mono_api->finalizeHold([ 587 "invoiceId" => $invoice_id, 588 "amount" => (int)($finalization_amount * 100 + 0.5), 589 ]); 590 591 if (is_wp_error($result)) { 592 return new WP_Error('error', $result->get_error_message()); 593 } 594 if (key_exists('errText', $result)) { 595 $order->add_order_note(__('Failed to finalize invoice: ', 'womono') . $result['errText']); 596 } 597 } catch (\Exception $e) { 598 $order->add_order_note(__('Hold cancellation error: ', 'womono') . $e->getMessage()); 599 return; 645 $finalization_amount = floatval($_POST['finalization_amount']); 646 try { 647 $result = $this->mono_api->finalizeHold([ 648 "invoiceId" => $invoice_id, 649 "amount" => (int)($finalization_amount * 100 + 0.5), 650 ]); 651 652 if (is_wp_error($result)) { 653 return new WP_Error('error', $result->get_error_message()); 600 654 } 601 } else if (isset($_POST['cancel_hold_action']) && 'cancel_hold' === $_POST['cancel_hold_action']) { 602 try { 603 $result = $this->mono_api->cancel([ 604 "invoiceId" => $invoice_id, 605 "extRef" => (string)$order_id, 606 ]); 607 608 if (is_wp_error($result)) { 609 return new WP_Error('error', $result->get_error_message()); 610 } 611 if (key_exists('errText', $result)) { 612 $order->add_order_note(__('Hold cancellation error: ', 'womono') . $result['errText']); 613 } 614 } catch (\Exception $e) { 615 $order->add_order_note(__('Hold cancellation error: ', 'womono') . $e->getMessage()); 616 return; 655 if (key_exists('errText', $result)) { 656 $order->add_order_note(__('Failed to finalize invoice: ', 'womono') . $result['errText']); 617 657 } 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 618 713 } 619 714 } … … 669 764 670 765 function get_from_meta($meta, $key) { 671 foreach ($meta as $item) { 672 if ($item->key == $key) return $item->value; 766 foreach ($meta as $item_key => $item_value) { 767 if ($item_key == $key && !empty($item_value)) { 768 return $item_value[0]; 769 } 673 770 } 674 771 return null; … … 698 795 $payment_amount_refunded = 0; 699 796 $payment_amount_final = 0; 700 update_post_meta($order_id, '_payment_type', 'hold');797 _meta($order_id, '_payment_type', 'hold'); 701 798 break; 702 799 case 'reversed': … … 714 811 return []; 715 812 } 716 update_post_meta($order_id, '_payment_amount', $payment_amount);717 update_post_meta($order_id, '_payment_amount_refunded', $payment_amount_refunded);718 update_post_meta($order_id, '_payment_amount_final', $payment_amount_final);813 _meta($order_id, '_payment_amount', $payment_amount); 814 _meta($order_id, '_payment_amount_refunded', $payment_amount_refunded); 815 _meta($order_id, '_payment_amount_final', $payment_amount_final); 719 816 720 817 return [ … … 746 843 } 747 844 } 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 748 870 } -
monopay/trunk/languages/womono-uk.po
r3006277 r3010003 118 118 msgid "Payment failed" 119 119 msgstr "Оплату не здійснено. Зверніться до продавця" 120 121 122 -
monopay/trunk/monopay.php
r3006277 r3010003 6 6 * Plugin URI: https://wordpress.org/plugins/monopay/#description 7 7 * Description: The Monopay WooCommerce Api plugin enables you to easily accept payments through your Woocommerce store. <a href="https://www.monobank.ua/">https://www.monobank.ua/</a> 8 * Version: 2. 0.48 * Version: 2. 9 9 */ 10 10 … … 22 22 23 23 add_filter('woocommerce_payment_gateways', 'add_mono_gateway_class'); 24 25 24 26 25 27 … … 61 63 } 62 64 65 66 67 68 69 70 71 72 73 74 75 76 63 77 function loadMonoLibrary() { 64 78 require_once MONOGATEWAY_DIR . 'includes/classes/Api.php'; 65 79 require_once MONOGATEWAY_DIR . 'includes/classes/Order.php'; 66 80 } 81 82 83 84 85 86 87 88
Note: See TracChangeset
for help on using the changeset viewer.