1

I use the the woocommerce hooks woocommerce_after_checkout_validation and woocommerce_payment_complete to do api calls to a partner site. These calls return a confirmation that the data is valid and then actually send the data on payment complete to create a number which we then save in the order meta. We then also use the woocommerce_before_thankyou hook to display the contract number and instructions on how to use it.

This works perfectly when using Stripe to checkout but when using Paypal or Splitit, both of which take the customer off-site to conduct the payment process and then bring him back, none of these hooks are triggered. the partner does not receive the verification call nor payment_complete call and the before_thankyou text does not fire either. Is there a work around to make sure that the hooks always trigger or maybe different hooks that are more appropriate, here is the code:

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;
    }
}
elt93
  • 11
  • 4
  • Do your orders contain only one product? Also the second parameter of the callAPI() function is "url", it is not set and written as is would generate a syntax error. Could you fix/update your code? If you have removed "important" parts, post them. In general, you could solve the problem by using a single function activated by the `woocommerce_payment_complete` hook (then you can integrate the `apiqovercall_verif` function in `apiqovercall_create` by obtaining the customer and product data from the created order object). See also this [answer](https://stackoverflow.com/a/66538110/10447197). – Vincenzo Di Gaetano Mar 15 '21 at 20:28
  • Thank you for your help! I have updated the URL, I removed it as the API call works perfectly, but it is edited now. The hook itself seems to not be triggered at all. Also the reason why I split it this way between apiqovercall_verif and apiqovercall_create is because the verif part, if not validated via the API, need to be update by the customer at checkout so it has to occur before payment, whereas the create part can only occur once payment has been received and confirmed. – elt93 Mar 15 '21 at 20:41
  • I have added the following filter: add_filter( 'woocommerce_valid_order_statuses_for_payment_complete', 'add_woocommerce_valid_order_statuses_for_payment_complete', 10, 2 ); function add_woocommerce_valid_order_statuses_for_payment_complete( $statuses, $order ) { $statuses[] = 'processing'; return $statuses; } But still get the same issue, the payment_complete hook doesn't trigger when using paypal to check out or splitit. – elt93 Mar 15 '21 at 21:31

1 Answers1

0

The woocommerce_after_checkout_validation hook is activated after the order confirm button is pressed. So the function inside it is certainly activated every time regardless of the payment method selected. As a first step check that the API call is done correctly here.

Then, since the woocommerce_payment_complete hook only activates for some order status, see this answer for more information, you can replace the hook with woocommerce_pre_payment_complete.

Make sure of course that the problem is not related to API calls in one or both functions.

To test, try updating the contract order meta with a value of your choice before $qover_present = WC()->session->get('qover_created');. This way you will know if the hook will be triggered or not and if the problem is in the API call.

Finally also check that WC()->session->get('qover_created'); contains the data you expect.

Vincenzo Di Gaetano
  • 3,892
  • 3
  • 13
  • 32
  • Hi Vincenzo, thank you! The issue seemed to be with using sessions and the data being lost. What I am doing now is using session in the validation, then getting that data in checkout_order_processed, saving it in the order as a meta and then getting this meta in payment_complete. The contracts are now created in this case. However, in the before thankyou hook $contract_id seems to be undefined. Could it be that before_thank you is triggered before payment_complete and how could I go around this? – elt93 Mar 17 '21 at 14:41
  • The `woocommerce_before_thankyou` hook is loaded in the thankyou page then after the payment has been made with PayPal (unless the user closes the page before redirecting). You can check if the order contains the **contract** post meta in Wordpress `wp_postmeta` table for that specific order id. – Vincenzo Di Gaetano Mar 17 '21 at 19:32
  • I just did multiple checks, and the contract is created and registered in the order when I check after the whole process using get_post_meta. However when I print the contract id to the console (also by getting it from the get_post_meta of the order in the before_thankyou hook, all I get is a 1... Not sure what this is due to. Thanks again for your help! – elt93 Mar 18 '21 at 12:09