• Resolved MDC2957

    (@mdc2957)


    I have a Make.com scenario set up to enroll customers into courses in a separate online course platform, and it’s triggered by the Order Created webhook and it works great. That is until, I receive an order that hasn’t been paid for yet, e.g. Payment by check/money order, BTCPay Server (bitcoin) On these orders, when someone checks out, the order gets created, but with status Pending Payment. Nevertheless, the webhook still gets triggered because an order is created even though payment hasn’t been received. Is there a solution for this issue? I’m not a coder, but is it possible to have a “Payment Received” webhook added to WooCommerce somehow? Thanks for any suggestions.

Viewing 10 replies - 1 through 10 (of 10 total)
  • Plugin Support ckadenge (woo-hc)

    (@ckadenge)

    Hi there @mdc2957,

    Thanks for reaching out.

    I understand you’re having an issue with orders being created and triggering the webhook before payment has been received.

    In WooCommerce, the ‘Order Created’ webhook is triggered as soon as an order is created, regardless of the payment status.

    If I understand you correctly, you would like to have the webhook triggered only if payment has been made, is that correct?

    In that case, you’ll need to edit the webhooks to fit your description. We have a detailed guide on how to edit your webhooks here.

    Let us know if you still need further assistance.

    Thread Starter MDC2957

    (@mdc2957)

    editing a web hook only allows you to change the topic URL etc. There’s nothing there about payment received?

    Plugin Support Shameem R. a11n

    (@shameemreza)

    Hi @mdc2957

    Did you use the “Order Updated” webhook? This webhook is triggered when the order status changes, including when it moves from “Pending Payment” to “Processing” (which typically happens after payment is received).

    Try it, and let me know how that goes. Looking forward to hearing from you soon.

    Thread Starter MDC2957

    (@mdc2957)

    Order Updated will not work as it would result it too many activations. I did some more googling and found this:

    https://gist.github.com/onetarek/6652c0ceb04c81918b78dca5e495c49a

    This could work, except I think it only goes for orders in the completed status. Problem is I might receive orders that contain both shipped and virtual products, so those will go to processing status. Obviously, the customer will have to wait for his shipped items to ship before the order can be completed, but he paid, so he should get access to the virtual product (handled by the Make automation).

    So I guess what I need is the ability to send the webhook when payment is received, whether that’s completed or processing status. But then again, I don’t want the webhook to get sent twice on the same order, i.e. once for processing and once for completed. So maybe I should just not worry about the rare case where virtual and shipped are purchased together, and handle it manually when it arises?

    Plugin Support Shameem R. a11n

    (@shameemreza)

    Hi @mdc2957

    The code snippet you found could indeed be a good starting point. It’s indeed set for “completed” orders, but it could also be tweaked to include “processing” status. However, as you rightly pointed out, this could result in the webhook being triggered twice for the same order.

    To avoid this, you might consider creating a custom webhook that only triggers when an order changes to either “completed” or “processing” status for the first time. This would require some custom coding, and while I understand you’re not a coder, there are WooCommerce experts available who could help with this.

    As for orders containing shipped and virtual products, handling these manually when they arise could be a feasible workaround, especially if these cases are rare.

    For reference, this particular forum is meant for general support with the core functionality of WooCommerce itself. For development and custom coding questions, it’s best to ask for insight related to those on either the WooCommerce Advanced Facebook group or the WooCommerce Community Slack. Many of our developers hang out there and will be able to offer insights into your question.

    I wish I could help more, but hopefully, this gets you going in the right direction to get some further insight/information.

    Thread Starter MDC2957

    (@mdc2957)

    Can you tell me from looking at the code in that custom order completed webhook that I linked to if it delivers the same payload as the built in core “order created” webhook? If it does, then I can just swap them.

    Plugin Support ckadenge (woo-hc)

    (@ckadenge)

    Hi there @mdc2957,

    Thanks for getting back to us.

    Can you tell me from looking at the code in that custom order completed webhook that I linked to if it delivers the same payload as the built in core “order created” webhook? If it does, then I can just swap them.

    Helping out with custom coding of this nature is outside the scope of support , although I would recommend the following:

    1. Running the exact question you’re asking, along with the code provided, through an AI platform like ChatGPT for recommendations/changes to your code;
    2. Checking whether there are existing plugins in the WordPress plugin repository that might be doing that already.
    3. Joining our WooCommerce Slack community (it does have a developer channel where you can ask coding questions): https://woo.com/community-slack/

    Hope it helps!

    Thread Starter MDC2957

    (@mdc2957)

    I asked chatgpt and it said this:

    To determine if the custom WooCommerce webhook creates the same payload as the built-in “order created” webhook, we need to compare the payload structures and data they send.

    Here’s the built-in “order created” webhook payload structure:

    {
      "id": 123,
      "parent_id": 0,
      "status": "processing",
      "order_key": "wc_order_1234567890abcdef",
      "number": "123",
      "currency": "USD",
      "version": "5.1.0",
      "prices_include_tax": false,
      "date_created": "2021-04-06T13:17:50",
      "date_created_gmt": "2021-04-06T17:17:50",
      "date_modified": "2021-04-06T13:17:50",
      "date_modified_gmt": "2021-04-06T17:17:50",
      "discount_total": "0.00",
      "discount_tax": "0.00",
      "shipping_total": "10.00",
      "shipping_tax": "0.00",
      "cart_tax": "0.00",
      "total": "60.00",
      "total_tax": "0.00",
      "customer_id": 2,
      "order_currency": "USD",
      "meta_data": [],
      "line_items": [],
      "tax_lines": [],
      "shipping_lines": [],
      "fee_lines": [],
      "coupon_lines": [],
      "refunds": [],
      "payment_method": "bacs",
      "payment_method_title": "Direct Bank Transfer",
      "transaction_id": "",
      "customer_ip_address": "127.0.0.1",
      "customer_user_agent": "Mozilla/5.0",
      "created_via": "checkout",
      "customer_note": "",
      "date_completed": null,
      "date_paid": null,
      "cart_hash": "",
      "number": "123",
      "meta_data": [],
      "_links": {
        "self": [],
        "collection": []
      }
    }

    Now let’s look at the custom webhook code from the provided link:

    <?php
    add_action( 'woocommerce_thankyou', 'custom_order_created_webhook', 10, 1 );
    function custom_order_created_webhook( $order_id ) {
        $order = wc_get_order( $order_id );
    
        $webhook_payload = array(
            'id' => $order->get_id(),
            'parent_id' => $order->get_parent_id(),
            'status' => $order->get_status(),
            'order_key' => $order->get_order_key(),
            'currency' => $order->get_currency(),
            'version' => $order->get_version(),
            'prices_include_tax' => $order->get_prices_include_tax(),
            'date_created' => $order->get_date_created()->date('Y-m-d\TH:i:s'),
            'date_created_gmt' => $order->get_date_created()->date('Y-m-d\TH:i:s\Z'),
            'date_modified' => $order->get_date_modified()->date('Y-m-d\TH:i:s'),
            'date_modified_gmt' => $order->get_date_modified()->date('Y-m-d\TH:i:s\Z'),
            'discount_total' => $order->get_discount_total(),
            'discount_tax' => $order->get_discount_tax(),
            'shipping_total' => $order->get_shipping_total(),
            'shipping_tax' => $order->get_shipping_tax(),
            'cart_tax' => $order->get_cart_tax(),
            'total' => $order->get_total(),
            'total_tax' => $order->get_total_tax(),
            'customer_id' => $order->get_customer_id(),
            'order_currency' => $order->get_currency(),
            'payment_method' => $order->get_payment_method(),
            'payment_method_title' => $order->get_payment_method_title(),
            'transaction_id' => $order->get_transaction_id(),
            'customer_ip_address' => $order->get_customer_ip_address(),
            'customer_user_agent' => $order->get_customer_user_agent(),
            'created_via' => $order->get_created_via(),
            'customer_note' => $order->get_customer_note(),
            'date_completed' => $order->get_date_completed() ? $order->get_date_completed()->date('Y-m-d\TH:i:s') : null,
            'date_paid' => $order->get_date_paid() ? $order->get_date_paid()->date('Y-m-d\TH:i:s') : null,
            'cart_hash' => $order->get_cart_hash(),
            'line_items' => array(),
            'tax_lines' => array(),
            'shipping_lines' => array(),
            'fee_lines' => array(),
            'coupon_lines' => array(),
            'refunds' => array()
        );
    
        $webhook_url = 'https://example.com/webhook';
        $response = wp_remote_post( $webhook_url, array(
            'method' => 'POST',
            'body' => json_encode( $webhook_payload ),
            'headers' => array(
                'Content-Type' => 'application/json'
            )
        ));
    }
    ?>

    The custom webhook payload is constructed using data from the WooCommerce order object, similar to the built-in webhook. However, a few differences exist:

    1. Field Differences:
    • The custom webhook includes ‘number’ within ‘webhook_payload’.
    • The built-in webhook includes ‘_links’ which is missing from the custom webhook.
    1. Data Formatting:
    • Dates in the custom webhook are formatted explicitly using the date('Y-m-d\TH:i:s') format, ensuring proper datetime formatting.
    1. Empty Arrays:
    • ‘meta_data’ in the built-in webhook is an empty array, but the custom webhook does not include it in ‘webhook_payload’.
    • ‘line_items’, ‘tax_lines’, ‘shipping_lines’, ‘fee_lines’, ‘coupon_lines’, and ‘refunds’ are included as empty arrays in the custom webhook. In contrast, these fields are included as empty arrays in the built-in webhook if there is no data.

    To summarize, while the custom webhook is similar in structure to the built-in “order created” webhook, there are slight differences in fields and data formatting. Specifically, the custom webhook is missing the ‘_links’ field and includes the ‘number’ field twice. Other fields such as ‘meta_data’ and arrays like ‘line_items’, ‘tax_lines’, etc., are included but empty.

    For complete parity, you would need to ensure all fields match exactly, including the ‘_links’ field and ensure no duplicate fields are present.

    Plugin Support Zubair Zahid (woo-hc)

    (@doublezed2)

    Hello MDC2957?

    Thank you for your reply.

    Please note that the ChatGPT code might not work out of the box and may need some customization.
    At this point, I suggest consulting a local web developer or finding one at Codeable.io or WooExperts.

    Let me know if you still have any questions. ??

    Best regards.

    Plugin Support Shameem R. a11n

    (@shameemreza)

    Hi @mdc2957

    We’ve not heard back from you in a while, so I’m marking this thread as resolved. Hopefully, you were able to find a solution to your problem!

    If you have further questions, please feel free to open a new topic.

    Thanks!

Viewing 10 replies - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.