如何在 woocommerce 支付网关 class 的 payment_fields() 中获取订单 ID

How to Get Order ID in payment_fields() in woocommerce Payment gateway class

我正在为 woocommerce 开发自定义支付网关,支付网关需要在处理支付之前进行注册调用,然后需要提交表单以重定向到网关的支付页面,用户将在其中放置他的卡详细信息。

需要使用表单提交进行重定向,因为必须传递交易 ID 和 URL 我正在注册调用:

下面是我的支付网关的实际流程:

1- 注册调用(必须传递 orderID、Amount、ReturnURL) 我在 payment_fields() 函数中执行此操作,而不是将 return 值置于隐藏形式。 2- 重定向调用(必须以一种形式传递 TransactionID、PortalURL,其中 PortalURL 是我的表单操作,而 TransactionID 是一个隐藏字段)

这是我的支付网关class:

<?php

    class WC_Etisalat_Payment_Gateway extends WC_Payment_Gateway {

        public function __construct(){

            $this->id = 'epg';
            $this->icon = '';
            $this->has_fields = false;
            $this->method_title = 'Etisalat Payment Gateway';
            $this->method_description = 'Pay with your UAE Credit, Debit or Prepaid cards.';
            $this->supports           = array(
                'products',
                'refunds',
            );

            $this->init_form_fields();
            $this->init_settings();

            $this->enabled = $this->get_option('enabled');
            $this->title = $this->get_option('title');
            $this->description = $this->get_option('description');

            add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );

            add_action( 'admin_notices', array( $this,  'do_ssl_check' ) );

        }

        public function do_ssl_check() {
            if( $this->enabled == "yes" ) {
                if( get_option( 'woocommerce_force_ssl_checkout' ) == "no" ) {
                    echo "<div class=\"error\"><p>". sprintf( __( "<strong>%s</strong> is enabled and WooCommerce is not forcing the SSL certificate on your checkout page. Please ensure that you have a valid SSL certificate and that you are <a href=\"%s\">forcing the checkout pages to be secured.</a>" ), $this->method_title, admin_url( 'admin.php?page=wc-settings&tab=checkout' ) ) ."</p></div>";
                }
            }
        }

        public function init_form_fields() {
            $this->form_fields = array(
                'enabled' => array(
                    'title'   => 'Enable/Disable',
                    'type'    => 'checkbox',
                    'label'   => 'Enable Etisalat Payment Gateway',
                    'default' => ''
                ),
                'title' => array(
                    'title'       => 'Title',
                    'type'        => 'text',
                    'description' => 'This controls the title for the payment method the customer sees during checkout.',
                    'default'     => 'Etisalat Payment Gateway'
                ),
                'description' => array(
                    'title'       => 'Description',
                    'type'        => 'textarea',
                    'description' => 'Payment method description that the customer will see on your checkout.',
                    'default'     => 'Pay with your UAE Credit, Debit or Prepaid cards.'
                ),
                'epg_merchant_id' => array(
                    'title'     => 'EPG Merchant ID',
                    'type'      => 'text'
                ),
                'epg_merchant_password' => array(
                    'title'     => 'EPG Password',
                    'type'      => 'password'
                )
            );
        }

        public function admin_options() {
            ?>

            <h2>Etisalat Payment Gateway</h2>

            <table class="form-table">

                <?php $this->generate_settings_html(); ?>

            </table>

            <?php
        }

        public function init_epg_register( $order_id, $amount, $return_url ) {

            $cert = plugin_dir_path( __FILE__ )."cert.pem";

            $opts = array(
                'ssl' => array(
                    'verify_peer'       => false,
                    'verify_peer_name'  => false,
                )
            );
            $options = array(
                'trace'         => 1,
                'keep_alive'    => true,
                'exceptions'    => 0,
                'local_cert'    => $cert,
                'passphrase'    => $this->get_option('epg_merchant_password'),
                'stream_context' => stream_context_create($opts),
                'cache_wsdl'    => WSDL_CACHE_NONE
            );
            $client = new SoapClient("https://demo-ipg.comtrust.ae:2443/MerchantAPI.svc?singleWsdl", $options);

            $params = array(
                'Register' => '',
                'request' => array(
                    'Customer'      => $this->get_option('epg_merchant_id'),
                    'Language'      => 'en',
                    'version'       => 2,
                    'Amount'        => $amount,
                    'Currency'      => 'USD',
                    'OrderID'       => $order_id,
                    'OrderInfo'     => $order_id,
                    'OrderName'     => $order_id,
                    'ReturnPath'    => $return_url,
                    'TransactionHint' => 'VCC:Y'
                )
            );

            $result = $client->Register($params);

            $response = json_encode( $result );

            $decode_data = json_decode($response);
            $reg_result = $decode_data->RegisterResult;

            return $reg_result;

        }

        public function process_payment( $order_id ) {

            global $woocommerce;

            $order = wc_get_order( $order_id );

            $order->update_status( 'on-hold', __( 'Awaiting offline payment', 'wc-gateway-offline' ) );

            $order->reduce_order_stock();

            $woocommerce->cart->empty_cart();

            return array(
                'result'    => 'success'
            );

        }

        public function payment_fields(){

            global $woocommerce;

            $order_id = $woocommerce->session->order_awaiting_payment;

            $order = wc_get_order( $order_id );

            $register = $this->init_epg_register( $order_id, $woocommerce->cart->total, $this->get_return_url( $order ) );

            $environment_url = $register->PaymentPortal;

            $transaction_id = $register->TransactionID;

            if ( $description = $this->get_description() ) {
                echo wpautop( wptexturize( $description ) );
            }

            ?>
            <form id="epg_payment_call" action="<?php echo esc_url( $environment_url ); ?>" method="post">
                <!--<input type='hidden' name='Price' value='<?php echo esc_attr( $woocommerce->cart->total ); ?>'/>
                <input type='hidden' name='ReturnURL' value='<?php echo esc_attr( $this->get_return_url( $order ) ); ?>'/>-->
                <input type='hidden' name='TransactionID' value='<?php echo esc_attr( $transaction_id ); ?>'/>
                <input type="submit" value="Place Order">
            </form>
            <?php
        }

    }

现在我的问题是,我需要 OrderID、OrderTotal 和 payment_fields() 函数中的 get_return_url()。

我已经使用了以下所有方法,但 none 对我有用。

global $wp;
    $order_id = $wp->query_vars['order-pay'];
    $order = new WC_Order( $order_id );

不工作:

get_query_var('order-pay');

不工作:

global $woocommerce, $post;
$order = new WC_Order($post->ID);

谁能帮我解决这个问题。因为我被困在这里。阅读 woocommerce 的所有文档并在堆栈溢出上搜索了很多但 none 对我有用。

我正在使用最新版本的 WooCommerce 和 WP。

我一直在寻找类似的东西,但恐怕你找不到,这是 process_checkout 方法的生命周期:

https://docs.woocommerce.com/wc-apidocs/source-class-WC_Checkout.html#895

正如您在第 928 行看到的那样

$order_id = $this->create_order( $posted_data ); 

订单是在您即将付款时创建的,之前无法获取。

您无法像前面提到的 post 那样获得 $order_id,但您可以通过执行以下操作在 payment_fields() 函数中检索货币和购物车的价值以下:

$currency = get_woocommerce_currency();
$value = max( 0, apply_filters( 'woocommerce_calculated_total', round( WC()->cart->cart_contents_total + WC()->cart->fee_total + WC()->cart->tax_total, WC()->cart->dp ), WC()->cart ) );

希望对您有所帮助

我用下面的代码实现了它。

global $woocommerce;
$ordID = $woocommerce->session->order_awaiting_payment;