Plugin Directory

Changeset 3010003

Timestamp:
12/14/2023 12:27:18 PM (8 months ago)
Author:
monobank
Message:

Added version 2.1.0

Location:
monopay
Files:
13 added
5 deleted
5 edited
8 copied

Legend:

Unmodified
Added
Removed
  • monopay/tags/2.1.0/README.txt

    r3006277 r3010003  
    44Tags: mono, cashier, payments, routing
    55Requires at least: 6.2
    6 Tested up to: 6.3.1
    7 Stable tag: 2.0.4
     6Tested up to: 6.
     7Stable tag: 2.
    88Requires PHP: 7.4
    99License: GPLv2 or later
     
    130130= 2.0.4 =
    131131- added thankyou page redirect.
     132
     133
     134
     135
  • monopay/tags/2.1.0/includes/class-wc-mono-gateway.php

    r3006277 r3010003  
    33use MonoGateway\Api;
    44use MonoGateway\Order;
     5
     6
     7
     8
     9
    510
    611const ORDER_STATUS_COMPLETED = 'completed';
     
    5055        $this->redirect = $this->get_option('redirect');
    5156
     57
     58
     59
    5260        add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);
    5361        add_action('woocommerce_api_mono_gateway', [$this, 'webhook']);
     
    5563
    5664        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']);
    5867        add_action('woocommerce_api_mono_refresh', [$this, 'admin_refresh_invoice_status']);
    5968        add_action('woocommerce_thankyou', [$this, 'post_payment_request']);
     
    123132        }
    124133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
    125144
    126145        $monoOrder = new Order();
     
    134153            $monoOrder->setRedirectUrl(home_url() . $this->redirect);
    135154        } 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);
    138155            $monoOrder->setRedirectUrl($order->get_checkout_order_received_url());
    139156        }
     
    146163        $currencyCode = get_woocommerce_currency();
    147164        $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);
    150167        try {
    151168            $invoice = $this->mono_api->create($paymentType, $ccy);
     
    230247            return;
    231248        }
    232         $meta = $order->get_meta_data();
     249        $meta = );
    233250        $ccy = $this->get_from_meta($meta, "_ccy");
    234251        if ($ccy == null) {
    235252            $ccy = self::CURRENCY_CODE[get_woocommerce_currency()];
    236             update_post_meta($order_id, '_ccy', $ccy);
     253            _meta($order_id, '_ccy', $ccy);
    237254        }
    238255        if ($ccy == CURRENCY_UAH) {
     
    298315
    299316    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        }
    301321        $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0;
    302322        if (!$order_id || !current_user_can('manage_woocommerce')) {
     
    310330            return;
    311331        }
    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
    319344        $this->refresh_status($order);
    320         update_post_meta($order_id, '_status_refreshed', time());
     345        );
    321346
    322347        wp_send_json_success('Status refreshed successfully');
     
    346371                        );
    347372                    }
    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);
    352377                    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));
    354379                    }
    355380                    global $woocommerce;
    356                     if ($woocommerce->cart) {
     381                    if ($woocommerce->cart) {
    357382                        $woocommerce->cart->empty_cart();
    358383                    }
     
    364389                    $order->update_status(ORDER_STATUS_ON_HOLD);
    365390
    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);
    368393                    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));
    370395                    }
    371396                    global $woocommerce;
    372                     if ($woocommerce->cart) {
     397                    if ($woocommerce->cart) {
    373398                        $woocommerce->cart->empty_cart();
    374399                    }
     
    383408                    $payment_amount_uah = get_post_meta($order->get_id(), '_payment_amount', true) ?? 0;
    384409                    $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                    }
    390418                }
    391419                break;
     
    411439
    412440    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        }
    417448        $order = wc_get_order($order_id);
    418449        if (!$order) {
     
    423454            __('Monopay payment status refresh', 'womono'),
    424455            [$this, 'add_refresh_invoice_status_button'],
    425             'shop_order',
     456            '',
    426457            'side',
    427458            'high'
     
    429460        $order_status = $order->get_status();
    430461
    431         if ($order_status != ORDER_STATUS_COMPLETED && $order_status != ORDER_STATUS_ON_HOLD) {
     462        if ($order_status != ORDER_STATUS_ON_HOLD) {
    432463//            we can finalize or cancel invoice only if it's paid
    433464            return;
    434465        }
    435         $meta = $order->get_meta_data();
     466        $meta = );
    436467        $payment_type = $this->get_from_meta($meta, '_payment_type');
    437468        if ($payment_type != 'hold') {
     
    453484            __('Hold Settings', 'womono'),
    454485            [$this, 'add_hold_functionality_buttons'],
    455             'shop_order',
     486            '',
    456487            'side',
    457488            'high'
     
    465496            return;
    466497        }
    467         $refreshed_timestamp = $order->get_meta('_status_refreshed');
    468         $disabled = '';
    469         if ($refreshed_timestamp && (time() - $refreshed_timestamp) < REFRESH_REQUEST_INTERVAL) {
    470             $disabled = 'disabled';
    471         }
    472498        $url = home_url() . '/?wc-api=mono_refresh';
    473499
    474500        // Nonce for security
    475501        $ajax_nonce = wp_create_nonce('monopay_refresh_nonce');
     502
    476503        echo <<<END
    477504        <a class="button button-primary" onclick="jQuery.ajax({
     
    481508                    'order_id': $post->ID,
    482509                    'nonce': '$ajax_nonce',
     510
    483511                },
    484512                success: function(response) {
    485513                    window.location.reload();
    486514                },
    487             })" $disabled>$refresh_text</a>
     515            })">$refresh_text</a>
    488516END;
    489517    }
     
    500528            return;
    501529        }
    502 //        $this->refresh_status($order->get_transaction_id(), $order);
    503         $meta = $order->get_meta_data();
     530        $meta = get_post_meta($post->ID, '', true);
    504531        $amounts = $this->get_amounts($meta, $order);
    505532
     
    509536        $cancel_text = __('Cancel', 'womono');
    510537        $payment_amount = sprintf('%.2f', $amounts['payment_amount'] / 100);
     538
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
    511549        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>
    530550            <div id="hold_span_actions" class="text-left">
    531551                <a class="button button-primary"
     
    535555                </a>
    536556               
    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>
    540571            </div>
    541572            <div id="hold_form_container" style="display: none;">
     
    556587                            onclick="document.getElementById('hold_span_actions').style.display='block';document.getElementById('hold_form_container').style.display='none';">
    557588                        $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>
    563606                </div>
    564607            </div>
     
    566609    }
    567610
    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        }
    571621        if (!$order_id) {
    572622            return;
    573623        }
    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
    577635        $order = wc_get_order($order_id);
    578636        if (!$order) {
    579637            return;
    580638        }
     639
     640
     641
     642
    581643        $invoice_id = $order->get_transaction_id();
    582644
    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());
    600654            }
    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']);
    617657            }
     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
    618713        }
    619714    }
     
    669764
    670765    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            }
    673770        }
    674771        return null;
     
    698795                $payment_amount_refunded = 0;
    699796                $payment_amount_final = 0;
    700                 update_post_meta($order_id, '_payment_type', 'hold');
     797                _meta($order_id, '_payment_type', 'hold');
    701798                break;
    702799            case 'reversed':
     
    714811                return [];
    715812        }
    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);
    719816
    720817        return [
     
    746843        }
    747844    }
     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
    748870}
  • monopay/tags/2.1.0/languages/womono-uk.po

    r3006277 r3010003  
    118118msgid "Payment failed"
    119119msgstr "Оплату не здійснено. Зверніться до продавця"
     120
     121
     122
  • monopay/tags/2.1.0/monopay.php

    r3006277 r3010003  
    66 * Plugin URI: https://wordpress.org/plugins/monopay/#description
    77 * 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.4
     8 * Version: 2.
    99 */
    1010
     
    2222
    2323add_filter('woocommerce_payment_gateways', 'add_mono_gateway_class');
     24
     25
    2426
    2527
     
    6163}
    6264
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
    6377function loadMonoLibrary() {
    6478    require_once MONOGATEWAY_DIR . 'includes/classes/Api.php';
    6579    require_once MONOGATEWAY_DIR . 'includes/classes/Order.php';
    6680}
     81
     82
     83
     84
     85
     86
     87
     88
  • monopay/trunk/README.txt

    r3006277 r3010003  
    44Tags: mono, cashier, payments, routing
    55Requires at least: 6.2
    6 Tested up to: 6.3.1
    7 Stable tag: 2.0.4
     6Tested up to: 6.
     7Stable tag: 2.
    88Requires PHP: 7.4
    99License: GPLv2 or later
     
    130130= 2.0.4 =
    131131- added thankyou page redirect.
     132
     133
     134
     135
  • monopay/trunk/includes/class-wc-mono-gateway.php

    r3006277 r3010003  
    33use MonoGateway\Api;
    44use MonoGateway\Order;
     5
     6
     7
     8
     9
    510
    611const ORDER_STATUS_COMPLETED = 'completed';
     
    5055        $this->redirect = $this->get_option('redirect');
    5156
     57
     58
     59
    5260        add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);
    5361        add_action('woocommerce_api_mono_gateway', [$this, 'webhook']);
     
    5563
    5664        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']);
    5867        add_action('woocommerce_api_mono_refresh', [$this, 'admin_refresh_invoice_status']);
    5968        add_action('woocommerce_thankyou', [$this, 'post_payment_request']);
     
    123132        }
    124133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
    125144
    126145        $monoOrder = new Order();
     
    134153            $monoOrder->setRedirectUrl(home_url() . $this->redirect);
    135154        } 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);
    138155            $monoOrder->setRedirectUrl($order->get_checkout_order_received_url());
    139156        }
     
    146163        $currencyCode = get_woocommerce_currency();
    147164        $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);
    150167        try {
    151168            $invoice = $this->mono_api->create($paymentType, $ccy);
     
    230247            return;
    231248        }
    232         $meta = $order->get_meta_data();
     249        $meta = );
    233250        $ccy = $this->get_from_meta($meta, "_ccy");
    234251        if ($ccy == null) {
    235252            $ccy = self::CURRENCY_CODE[get_woocommerce_currency()];
    236             update_post_meta($order_id, '_ccy', $ccy);
     253            _meta($order_id, '_ccy', $ccy);
    237254        }
    238255        if ($ccy == CURRENCY_UAH) {
     
    298315
    299316    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        }
    301321        $order_id = isset($_POST['order_id']) ? intval($_POST['order_id']) : 0;
    302322        if (!$order_id || !current_user_can('manage_woocommerce')) {
     
    310330            return;
    311331        }
    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
    319344        $this->refresh_status($order);
    320         update_post_meta($order_id, '_status_refreshed', time());
     345        );
    321346
    322347        wp_send_json_success('Status refreshed successfully');
     
    346371                        );
    347372                    }
    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);
    352377                    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));
    354379                    }
    355380                    global $woocommerce;
    356                     if ($woocommerce->cart) {
     381                    if ($woocommerce->cart) {
    357382                        $woocommerce->cart->empty_cart();
    358383                    }
     
    364389                    $order->update_status(ORDER_STATUS_ON_HOLD);
    365390
    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);
    368393                    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));
    370395                    }
    371396                    global $woocommerce;
    372                     if ($woocommerce->cart) {
     397                    if ($woocommerce->cart) {
    373398                        $woocommerce->cart->empty_cart();
    374399                    }
     
    383408                    $payment_amount_uah = get_post_meta($order->get_id(), '_payment_amount', true) ?? 0;
    384409                    $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                    }
    390418                }
    391419                break;
     
    411439
    412440    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        }
    417448        $order = wc_get_order($order_id);
    418449        if (!$order) {
     
    423454            __('Monopay payment status refresh', 'womono'),
    424455            [$this, 'add_refresh_invoice_status_button'],
    425             'shop_order',
     456            '',
    426457            'side',
    427458            'high'
     
    429460        $order_status = $order->get_status();
    430461
    431         if ($order_status != ORDER_STATUS_COMPLETED && $order_status != ORDER_STATUS_ON_HOLD) {
     462        if ($order_status != ORDER_STATUS_ON_HOLD) {
    432463//            we can finalize or cancel invoice only if it's paid
    433464            return;
    434465        }
    435         $meta = $order->get_meta_data();
     466        $meta = );
    436467        $payment_type = $this->get_from_meta($meta, '_payment_type');
    437468        if ($payment_type != 'hold') {
     
    453484            __('Hold Settings', 'womono'),
    454485            [$this, 'add_hold_functionality_buttons'],
    455             'shop_order',
     486            '',
    456487            'side',
    457488            'high'
     
    465496            return;
    466497        }
    467         $refreshed_timestamp = $order->get_meta('_status_refreshed');
    468         $disabled = '';
    469         if ($refreshed_timestamp && (time() - $refreshed_timestamp) < REFRESH_REQUEST_INTERVAL) {
    470             $disabled = 'disabled';
    471         }
    472498        $url = home_url() . '/?wc-api=mono_refresh';
    473499
    474500        // Nonce for security
    475501        $ajax_nonce = wp_create_nonce('monopay_refresh_nonce');
     502
    476503        echo <<<END
    477504        <a class="button button-primary" onclick="jQuery.ajax({
     
    481508                    'order_id': $post->ID,
    482509                    'nonce': '$ajax_nonce',
     510
    483511                },
    484512                success: function(response) {
    485513                    window.location.reload();
    486514                },
    487             })" $disabled>$refresh_text</a>
     515            })">$refresh_text</a>
    488516END;
    489517    }
     
    500528            return;
    501529        }
    502 //        $this->refresh_status($order->get_transaction_id(), $order);
    503         $meta = $order->get_meta_data();
     530        $meta = get_post_meta($post->ID, '', true);
    504531        $amounts = $this->get_amounts($meta, $order);
    505532
     
    509536        $cancel_text = __('Cancel', 'womono');
    510537        $payment_amount = sprintf('%.2f', $amounts['payment_amount'] / 100);
     538
     539
     540
     541
     542
     543
     544
     545
     546
     547
     548
    511549        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>
    530550            <div id="hold_span_actions" class="text-left">
    531551                <a class="button button-primary"
     
    535555                </a>
    536556               
    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>
    540571            </div>
    541572            <div id="hold_form_container" style="display: none;">
     
    556587                            onclick="document.getElementById('hold_span_actions').style.display='block';document.getElementById('hold_form_container').style.display='none';">
    557588                        $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>
    563606                </div>
    564607            </div>
     
    566609    }
    567610
    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        }
    571621        if (!$order_id) {
    572622            return;
    573623        }
    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
    577635        $order = wc_get_order($order_id);
    578636        if (!$order) {
    579637            return;
    580638        }
     639
     640
     641
     642
    581643        $invoice_id = $order->get_transaction_id();
    582644
    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());
    600654            }
    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']);
    617657            }
     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
    618713        }
    619714    }
     
    669764
    670765    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            }
    673770        }
    674771        return null;
     
    698795                $payment_amount_refunded = 0;
    699796                $payment_amount_final = 0;
    700                 update_post_meta($order_id, '_payment_type', 'hold');
     797                _meta($order_id, '_payment_type', 'hold');
    701798                break;
    702799            case 'reversed':
     
    714811                return [];
    715812        }
    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);
    719816
    720817        return [
     
    746843        }
    747844    }
     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
    748870}
  • monopay/trunk/languages/womono-uk.po

    r3006277 r3010003  
    118118msgid "Payment failed"
    119119msgstr "Оплату не здійснено. Зверніться до продавця"
     120
     121
     122
  • monopay/trunk/monopay.php

    r3006277 r3010003  
    66 * Plugin URI: https://wordpress.org/plugins/monopay/#description
    77 * 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.4
     8 * Version: 2.
    99 */
    1010
     
    2222
    2323add_filter('woocommerce_payment_gateways', 'add_mono_gateway_class');
     24
     25
    2426
    2527
     
    6163}
    6264
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
    6377function loadMonoLibrary() {
    6478    require_once MONOGATEWAY_DIR . 'includes/classes/Api.php';
    6579    require_once MONOGATEWAY_DIR . 'includes/classes/Order.php';
    6680}
     81
     82
     83
     84
     85
     86
     87
     88
Note: See TracChangeset for help on using the changeset viewer.