如何从 WordPress 自定义网关中的 process_ payment 函数进行重定向?

Mar*_*son 0 php wordpress post payment-gateway woocommerce

我正在尝试开发一个自定义网关,我需要获取订单信息,例如价值、信用卡号、卡所有者姓名、地址等。获取这些信息后,我将使用 Centinel 3D Secure 提供的 API 发送请求。如果成功,他们将返回信用卡银行的网址以及我要发布到银行网址的一些其他信息。

然后,银行将使用表单将数据发布到我的回调 URL。然而我似乎无法让它工作。这是我的代码示例:

function process_payment( $order_id ) {
            global $woocommerce;
            //code to get data using API
            if( (strcasecmp('Y', $_SESSION['Centinel_Enrolled']) == 0){

                 echo '<form action="'.$_SESSION["ACSUrl"].'"" method="post">
                  <input type=hidden name="PaReq" value="'.$_SESSION["RandomValue"].'"/>
                  <input type=hidden name="TermUrl" value="'$myWPCallbackUrl.'?>"/>
                  <input type=hidden name="MD" value="Data"/>
                  <input type="submit" value="Submit" id="submit_centinel_payment_form"/> 
                  <script type="text/javascript">
                  jQuery(function(){ 
                     jQuery("#submit_centinel_payment_form").click();});
                  </script>                 
                  </form>     



            }
Run Code Online (Sandbox Code Playgroud)

这不会重定向到服务器。有谁知道为什么这不起作用?

小智 5

这是一个老问题,但对于现在遇到同样问题的所有人来说,我希望我的回答能有所帮助。我遇到了完全相同的问题,这就是我解决它的方法。

我不太了解导致process_payment( $ order_id )这种行为的函数后台发生了什么,但是您不能通过 php echo 或通过 javascript 从函数重定向,而只能通过函数 return 语句重定向,如下例所示:

function process_payment( $order_id ) {
    global $woocommerce;
    $order = new WC_Order( $order_id );

    // Mark as on-hold (we're awaiting the cheque)
    $order->update_status('on-hold', __( 'Awaiting cheque payment', 'woocommerce' ));

    // Reduce stock levels
    $order->reduce_order_stock();

    // Remove cart
    $woocommerce->cart->empty_cart();

    // Return thank you redirect
    return array(
        'result' => 'success',
        'redirect' => $this->get_return_url( $order )
    );
}
Run Code Online (Sandbox Code Playgroud)

(示例粘贴自Wocommerce Payment Gateway API

因此,对于您的具体问题,我会将您的表单放在单独的文件 secure_form.php 中。所有需要的数据都可以通过 get 参数访问:

<!DOCTYPE html>
<html>
<head>
    <title>3D Secure Verification</title>
    <script language="Javascript">
        function OnLoadEvent() { document.form.submit(); }
    </script>
</head>
<body OnLoad="OnLoadEvent();">
    Invoking 3-D secure form, please wait ...
    <form name="form" action="<?php echo rawurldecode( $_GET[ 'acs_url' ] ); ?>" method="post">
    <input type="hidden" name="PaReq" value="<?php echo rawurldecode( $_GET[ 'pareq' ] ); ?>">
    <input type="hidden" name="TermUrl" value="<?php echo rawurldecode( $_GET[ 'term_url' ] ); ?>">
    <input type="hidden" name="MD" value="<?php echo rawurldecode( $_GET[ 'authencity_token' ] ); ?>">
    <noscript>
        <p>Please click</p><input id="to-asc-button" type="submit">
    </noscript>
    </form>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

然后,在您的process_payment( $ order_id )函数中设置变量,并调用您的表单(不要忘记传递 get 参数):

function process_payment( $order_id ) {
    global $woocommerce;
    //code to get data using API
    if( (strcasecmp('Y', $_SESSION['Centinel_Enrolled']) == 0){
        // Set variables and redirect to 3DS check form
        $acs_url          = rawurlencode( $_SESSION["ACSUrl"] );
        $pareq            = rawurlencode( $_SESSION["RandomValue"] );
        $authencity_token = rawurlencode( 'Data' );
        $term_url         = rawurlencode( $myWPCallbackUrl );
        $url              = path_to_secure_form.php . "?acs_url=$acs_url&pareq=$pareq&authencity_token=$authencity_token&term_url=$term_url";

        return [
            'result'   => 'success',
            'redirect' => $url
        ];         
    }
}
Run Code Online (Sandbox Code Playgroud)