如何从 wordpress 中自定义网关中的process_payment功能进行重定向


How can I do a redirect from the process_payment function in a custom gateway in wordpress?

我正在尝试开发一个自定义网关,我需要在其中获取订单信息,例如价值,信用卡号,持卡人姓名,地址等。得到这个后,我将使用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>     

            }

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

这是一个古老的问题,但对于现在所有在同一个问题上挣扎的人来说,我希望我的答案会有所帮助。我遇到了完全相同的问题,这就是我解决它的方式。

我不知道process_payment( $ order_id )函数后台发生了什么导致这种行为,但你不能通过 php echo 重定向函数,也不能通过 javascript,而只能通过函数返回语句,如下例所示:

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 )
    );
}

(示例粘贴自 WoCommerce 支付网关 API)

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

<!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>

然后,在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
        ];         
    }
}

使用pur JavaScript可以实现这个目标。而不是使用此代码

<script type="text/javascript">
    jQuery(function(){ 
    jQuery("#submit_centinel_payment_form").click();});
</script> 

您可以使用此代码

<script type="text/javascript">
    document.getElementById('paymentForm').submit(); // SUBMIT FORM
</script>

前提是您在表单中添加了 ID。您的表单中也有语法错误,我建议在表单元素之外取出 javascript 代码。你终于可以拥有这段代码了

echo '<form action="'.$_SESSION["ACSUrl"].'" method="post" id="paymentForm">
                  <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"/> 
                  </form>
<script type="text/javascript">
        document.getElementById("paymentForm").submit(); // SUBMIT FORM
    </script>
';