支付网关未触发 woocommerce_payment_complete 和 woocommerce_after_checkout_validation 挂钩

Posted

技术标签:

【中文标题】支付网关未触发 woocommerce_payment_complete 和 woocommerce_after_checkout_validation 挂钩【英文标题】:Payment gateways not triggering woocommerce_payment_complete and woocommerce_after_checkout_validation hooks 【发布时间】:2021-06-13 00:32:05 【问题描述】:

我使用 woocommerce 挂钩 woocommerce_after_checkout_validation 和 woocommerce_payment_complete 对合作伙伴网站进行 api 调用。这些调用返回数据有效的确认,然后在付款完成时实际发送数据以创建一个数字,然后我们将其保存在订单元中。然后,我们还使用 woocommerce_before_thankyou 挂钩来显示合同编号以及如何使用它的说明。

这在使用 Stripe 结账时非常有效,但在使用 Paypal 或 Splitit 时,这两种方式都会将客户带离现场进行支付流程,然后再将他带回来,这些钩子都不会被触发。合作伙伴没有收到验证电话,也没有收到 payment_complete 电话,并且 before_thankyou 文本也没有触发。是否有解决方法来确保钩子总是触发或者可能更合适的不同钩子,这里是代码:

add_action('woocommerce_after_checkout_validation', 'apiqovercall_verif');

// handle the ajax request
function apiqovercall_verif() 
    $insurance_ids  = array(24027,24031,24034,24035,24033,24032);
    $ebike_ids      = array(17386,17385,17382,17378,17375,17372,17370,17369,17364,16132,16130,4561,4550,3490,2376);

    $fields = [
      'billing_first_name'                       => '',
      'billing_last_name'     => '',
      'billing_email'                => '',
      'billing_phone'    => '',
      'insurance-birthdate'    => '',
      'gender-selection'    => '',
        'billing_address_1'    => '',
        'billing_address_2'    => '',
        'billing_postcode'    => '',
        'billing_city'    => ''  
    ];
    
    foreach( $fields as $field_name => $value ) 
      if( !empty( $_POST[ $field_name ] ) ) 
        $fields[ $field_name ] = sanitize_text_field( $_POST[ $field_name ] );
       
    
     
      foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) 
            if ( in_array( $cart_item['product_id'],  $ebike_ids ) ) 
                $_product_id = $cart_item['product_id'];
            
        
     $_product =  wc_get_product( $_product_id );
$billingcountry = WC()->customer->get_billing_country();
$cur_lang = pll_current_language();

$data_qover_verif =  array(
      "refs"        =>  array(
            "country"         => $billingcountry,
            "product"        => "BIKE"
      ),
      "settings"        =>  array(
            "language"         => $cur_lang
      ),
      "policyholder" =>  array(
             "firstName"        => $fields[ 'billing_first_name'] ,
             "lastName"     => $fields[ 'billing_last_name'],
             "email"        => $fields[ 'billing_email'],
             "phone"        => $fields[ 'billing_phone'],
             "birthdate"        => $fields[ 'insurance-birthdate'],
             "gender"       => $fields[ 'gender-selection' ],
             "address"        =>  array(
                     "country"      => $billingcountry,
                     "zip"      => $fields[ 'billing_postcode'],
                     "city"     => $fields[ 'billing_city'],
                     "street"       => $fields[ 'billing_address_1'],
                     "number"       => ' ',
                     "box"      => "box"),
          "entityType"      => "ENTITY_TYPE_PERSON"

      ),
      "risk"         => array(
            
             "model"         => $_product -> get_title(),
             "originalValue"         =>  $_product -> get_price() * 100,
      ),
    );

        $call_verif = callAPI('POST', 'https://dojo-production-bike-api.production.cluster.qover.io/v1/ancillary/validate', json_encode($data_qover_verif));
        $response_verif = json_decode($call_verif, true);
        
        if ($response_verif["status"] != "STATUS_OPEN" ) 
            wc_add_notice(pll__('There was an error'),'error')  ;
         else 
            WC()->session->set('data_qover', $data_qover_verif);
            WC()->session->set('qover_created', "1");

        
    



add_action( 'woocommerce_payment_complete', 'apiqovercall_create' );
function apiqovercall_create( $order_id ) 
        $qover_present = WC()->session->get('qover_created');
        if ($qover_present === "1") 
        $data_qover_creation = WC()->session->get('data_qover');
        $call_create = callAPI('POST', 'https://dojo-production-bike-api.production.cluster.qover.io/v1/ancillary/', json_encode($data_qover_creation));
        $response_create = json_decode($call_create, true);
        update_post_meta( $order_id, 'contract', $response_create);
        WC()->session->__unset('data_qover');
        WC()->session->__unset('qover_created');
        
    


add_action( 'woocommerce_before_thankyou', 'display_qover_contract' );
function display_qover_contract( $order_id ) 
    $contract_id = get_post_meta($order_id, 'contract', true);
    if ( ! empty( $contract_id ) ) 
        $contract_message = pll__('<div class="qover_notice">Your contract has been created successfully.  Your contract id is: ') . $contract_id['contractId'] . "</div>";
    echo $contract_message;
    

【问题讨论】:

您的订单是否只包含一种产品? callAPI() 函数的第二个参数是“url”,它没有按原样设置和写入会产生语法错误。你能修复/更新你的代码吗?如果您删除了“重要”部分,请发布它们。一般来说,您可以通过使用woocommerce_payment_complete 钩子激活的单个函数来解决问题(然后您可以通过从创建的订单对象中获取客户和产品数据来将apiqovercall_verif 函数集成到apiqovercall_create 中)。另请参阅answer。 感谢您的帮助!我已经更新了 URL,我删除了它,因为 API 调用运行良好,但现在它已被编辑。钩子本身似乎根本没有被触发。另外,我在 apiqovercall_verif 和 apiqovercall_create 之间以这种方式拆分的原因是,如果未通过 API 验证,验证部分需要由客户在结帐时更新,因此必须在付款前进行,而创建部分只能发生收到并确认付款后。 我添加了以下过滤器: add_filter( 'woocommerce_valid_order_statuses_for_payment_complete', 'add_woocommerce_valid_order_statuses_for_payment_complete', 10, 2 );函数 add_woocommerce_valid_order_statuses_for_payment_complete( $statuses, $order ) $statuses[] = 'processing';返回$状态;但是仍然遇到同样的问题,使用 paypal 结帐或拆分时,payment_complete 挂钩不会触发。 【参考方案1】:

woocommerce_after_checkout_validation 钩子在订单确认按钮被按下后被激活。因此,无论选择哪种付款方式,它里面的功能每次肯定都会被激活。作为第一步,检查 API 调用是否在此处正确完成。

那么,由于woocommerce_payment_complete钩子仅针对某些订单状态激活,请参阅此answer了解更多信息,您可以将钩子替换为woocommerce_pre_payment_complete

当然要确保问题与 API 调用无关 一种或两种功能。

要进行测试,请尝试在$qover_present = WC()-&gt;session-&gt;get('qover_created'); 之前使用您选择的值更新contract 订单元数据。这样您就可以知道钩子是否会被触发以及问题是否出在 API 调用中。

最后还要检查WC()-&gt;session-&gt;get('qover_created'); 是否包含您期望的数据。

【讨论】:

您好文森佐,谢谢!问题似乎与使用会话和丢失数据有关。我现在正在做的是在验证中使用会话,然后在 checkout_order_processed 中获取该数据,将其按顺序保存为元,然后在 payment_complete 中获取此元。现在在这种情况下创建了合同。但是,在thankyou 之前的钩子 $contract_id 似乎是未定义的。会不会是 before_thank you 在 payment_complete 之前触发了,我该如何解决这个问题? woocommerce_before_thankyou 钩子在使用 PayPal 付款之后加载到感谢页面中(除非用户在重定向之前关闭页面)。您可以在 Wordpress wp_postmeta 表中检查该订单是否包含该特定订单 ID 的 contract 帖子元数据。 我只是做了多次检查,并且在我使用get_post_meta进行全过程检查时按顺序创建并注册了合同。但是,当我将合同 ID 打印到控制台时(也可以通过 before_thankyou 钩子中订单的 get_post_meta 获取它,我得到的只是 1...不确定这是由于什么。再次感谢您的帮助!

以上是关于支付网关未触发 woocommerce_payment_complete 和 woocommerce_after_checkout_validation 挂钩的主要内容,如果未能解决你的问题,请参考以下文章

支付网关未触发 woocommerce_payment_complete 和 woocommerce_after_checkout_validation 挂钩

在 Azure 上部署 Stripe 支付网关

使用Android Deep Link的UPI支付网关

生成订单30分钟未支付,则自动取消,该怎么实现?

面试官:生成订单 30 分钟未支付,则自动取消,该怎么实现?

GraphQL 网关`预检请求未通过访问控制检查`