当前位置: 首页 > 知识库问答 >
问题:

使用基于自定义WooCommerce表单的网关处理付款后收到的数据

张鸿宝
2023-03-14

我试图在我的WooCommerce网站中添加一个自定义支付网关。流程会是这样的:

  1. 用户单击“下订单”按钮后,他将被重定向到我的支付处理器的托管支付页面(HPP)。为了实现这一点,我必须通过隐藏表单发送一些数据(如商户id、散列、订单金额等),支付处理器需要将其重定向到HPP
  2. 在HPP中,有一个表单,用户可以在其中介绍其卡数据
  3. 如果一切正常,用户将被重定向到感谢页面,否则他将被重定向到失败页面,或者显示错误消息,我不在乎

这就是我到目前为止所实现的:当用户点击“下单”时,一个状态为“暂停”的新订单被创建,他被重定向到一个名为“prueba.php”的页面。此页面仅包含隐藏表单,其中包含支付处理器将用户重定向到其网关所需的数据。一旦页面被加载,这个表单就会自动提交(我觉得这不是最安全的做法,因为如果你打开元素检查器,你可以看到隐藏的输入及其值,但是我不知道还有什么更好的方法来实现这一点工作)。这是我在插件的主文件:

add_action( 'plugins_loaded', 'custom_init_gateway_class' );
function custom_init_gateway_class() {

    class WC_My_Gateway extends WC_Payment_Gateway {
        /**
         * Constructor
         */
        public function __construct() {
            $this->id = 'mygateway';
            $this->has_fields = true;
            $this->method_title = 'My Gateway';
            $this->method_description = 'Description of payment gateway'; 
            $this->supports = array(
                'products'
            );

            // Method 
            $this->init_form_fields();
            $this->init_settings();
            $this->title = $this->get_option( 'title' );
            $this->description = $this->get_option( 'description' );
            $this->enabled = $this->get_option( 'enabled' );

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

        /**
         * Plugin options
         */
        public function init_form_fields(){
            $this->form_fields = array(
                'enabled' => array(
                    'title' => __( 'Enable/Disable', 'woocommerce' ),
                    'type' => 'checkbox',
                    'label' => __( 'Enable Card Payment', 'woocommerce' ),
                    'default' => 'yes'
                ),
                'title' => array(
                    'title' => __( 'Title', 'woocommerce' ),
                    'type' => 'text',
                    'description' => __( 'This controls the title which the user sees during checkout.', 'woocommerce' ),
                    'default' => __( 'Credit Payment', 'woocommerce' ),
                    'desc_tip'      => true,
                ),
                'description' => array(
                    'title' => __( 'Customer Message', 'woocommerce' ),
                    'type' => 'textarea',
                    'default' => ''
                )
            );

        }

        /*
         * Processing the payments
         */
        public function process_payment( $order_id ) {
            global $woocommerce;
            $order = new WC_Order( $order_id );

            $order->update_status('on-hold', __( 'Awaiting card payment', 'woocommerce' ));

            return array(
                'result' => 'success',
                'redirect' => 'https://mydomain.example/prueba.php?price='.$order->get_total().'&currency='.$order->get_currency().'&order_id='.$order->get_id()
            );

        }

    }

}

function custom_add_gateway_class( $methods ) {
    $methods[] = 'WC_My_Gateway'; 
    return $methods;
}
add_filter( 'woocommerce_payment_gateways', 'custom_add_gateway_class' );

“prueba.php”中的隐藏形式。在输入“商户响应URL”中,我必须指定在支付完成后,我希望支付处理器将数据发送到哪个URL:

<form method="POST" action="https://paymentprocessorgateway.example" name="respuesta" style="display: none;">
        <input type="hidden" name="TIMESTAMP" value="<?php echo $timestamp; ?>">
        <input type="hidden" name="MERCHANT_ID" value="12345">
        <input type="hidden" name="AMOUNT" value="<?php echo $Amount; ?>">
        <input type="hidden" name="CURRENCY" value="<?php echo $Currency; ?>">
        <input type="hidden" name="SIGNATURE" value="<?php echo $hash; ?>">
        <input type="hidden" name="COMMENT1" value="<?php echo $order_id; ?>">
        <input type="hidden" name="MERCHANT_RESPONSE_URL" value="https://mydomain.example/response.php">
        <input type="submit" value="Click here to buy">
    </form>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript">
        function sendForm() {   
            $("form").submit();  
        }
        sendForm();
    </script>

发送此表单后,用户将被重定向到支付处理器网关,在那里他可以写入和发送卡数据,然后处理器将一些POST数据发送到“response.php”。在本页中,我将从支付处理器接收的哈希值与我自己生成的哈希值(与从支付处理器接收的一些其他POST值)进行比较。

我想实现的是将用户重定向到感谢页面,如果一切正常,则将订单状态更改为“已完成”,如果不正常,则显示错误消息。此外,我希望在此处创建订单(如果付款正确),当客户点击“下订单”按钮时就不会了(我想知道订单的id,我可以在任何需要的地方更改订单的状态,或者我可以在任何地方创建新订单,但我肯定是做错了,因为我不太清楚woocommerce和OOP PHP是如何工作的)。我试着在“response.php”中写这篇文章,但处理器的网关抛出一个错误,表示交易进行得很顺利,但无法连接到MERCHANT_response_url中指定的url:

//Generating the hash with data received from processor
$respuesta = $_POST['TIMESTAMP'].".".$_POST['MERCHANT_ID'].".".$_POST['ORDER_ID'].".".$_POST['RESULT'];
$my_hash = sha1(sha1($respuesta);

global $woocommerce;
$order = wc_get_order( $order_id );

    if ($my_hash != $_POST['HASH']) { //$_POST['HASH'] is the hash sent by the processor.
            wc_add_notice(  'Please try again.', 'error' );
            return;
         } else {
            $order->payment_complete();

            $woocommerce->cart->empty_cart();

            return array(
                'result' => 'success',
                'redirect' => $this->get_return_url( $order )
            );
        }

如果我删除与woocommerce相关的变量并使用类似的方法查看其是否工作,则会正确打印警报:

if ($my_hash != $_POST['HASH']) {
    echo '<script>alert("Wrong transaction");</script>';
} else {
    echo '<script>alert("Correct transaction");</script>';
}

好像我不能在那里使用与商业相关的变量。我想我必须把这个挂在某个钩子或什么东西上,但我不知道是哪个或在哪里,我有一种感觉,在这过程中我犯了很多错误。如果有人能告诉我如何处理支付处理器的响应,并将其与Woocommerce流集成,我将万分感激。

共有1个答案

王长卿
2023-03-14

首先如果你应该提交一个隐藏的表单,我不会担心安全性,当涉及到隐藏或不隐藏的方面。不管怎样,客户端的任何东西都可以被查看/篡改,所以这不是应该采取安全措施的地方。

您的最后一块代码提到了$old\u hash,但它是空的?至少,您的代码块没有设置它。你说这个代码的哪一部分不起作用?您是否尝试登录到某个类似于错误日志的内容,以查看是否调用了它?(如错误日志(“消息”)

您提到HPP会将散列返回到您选择的页面,所以我要说的是响应。php可能是用户付费后发送的页面。

(另外,对我来说,差不多是睡觉时间了,所以如果我停止回应,请道歉。)

 类似资料:
  • 通常在WooCommerce中,一旦付款完成,提交的订单将重定向到。 是否可以将客户重定向到特定付款方式的自定义页面? 例如:

  • 问题内容: 通常,wooCommerce应该自动完成虚拟产品的订单。但是事实并非如此,这是一个实际的问题,即使是BUG之类的。 因此,在这一点上,您可以找到一些有用的东西(但不是很方便): 1)一段代码 (您可以在wooCommerce文档中找到): 但是此代码段不适用于 BACS , 货到付款 和 支票* 付款方式。Paypal和信用卡网关的付款方式都可以。 BACS 是直接银行转帐付款方式 还

  • 我用woocommerce做了一个简单的网店,有三种付款方式。理想情况下,可通过直接银行转账和开户。订单ID是根据付款方式创建的。例如,如果使用iDEAL付款,订单id将变为ID190100;如果以账户付款,订单id将变为RK190100。我从BeRocket的插件“WooCommerce的顺序订单号”中得到了这一点,但这些都是在付款完成之前创建的。订单ID必须在付款后才能最终确定。现在,尚未付款

  • 我在这个相关的答案中找到了对我的问题的部分和可行的答案: send-an-email-notification-when-order-status-changhe-fron-pendig-to-cancelled 我正在考虑使用提供的解决方案,但想看看我是否可以更改电子邮件通知,明确地说,“未决付款订单现在取消”,所以它不同于常规取消的订单。 我该怎么做?

  • 在使用插件管理自定义订单字段的WooCommerce中,我在WooCommerce管理订单列表中添加了一个自定义字段“回扣状态”,其中有3个值“无回扣”、“未付款”和“已付款”。 我还将其显示在查看订单屏幕上,如下面的屏幕截图所示: 现在我想批量更新所选订单的折扣状态,就像wooCommerce允许批量更改订单状态一样。 基于“在Woocommerce中处理管理员订单列表上的自定义批量操作”回答线

  • 我们正在使用安全令牌方法处理信用卡付款与贝宝托管页面。我们通过提供所需的信息来生成安全令牌 我们得到的成功结果如下: 然后我们将此发送回贝宝,在那里用户可以选择用信用卡和/或贝宝支付。 当有人用信用卡支付时,一切都很好,当有人选择用“贝宝”支付时,它会要求用户提供贝宝凭证,一旦提供,它会显示另一个屏幕来接受收费。一旦用户接受,我们会得到以下错误消息: 我从PayPal的人那里得到的帮助说:“看着日

  • 问题内容: 我开始工作,并和奇迹是否可以定制响应期待。当前对DataTables插件的期望是这样的: 在服务器端,API由 服务器的响应是: 因此,有没有一种方法可以调整Datatables插件以接受/映射此响应,或者我必须找到一种将期望的字段添加到api的方法? 到目前为止,我已经做到了: 任何帮助将不胜感激。 提前致谢 :) 问题答案: 您可以将函数传递给DataTables 选项,这将使您完

  • 我正在使用亚美尼亚银行API与woocommerce作为额外的支付方式。当我下订单时,它会给我运行时错误。我正在附加图像或我收到的错误和我正在使用的代码。 如果有人能帮我就告诉我。