Search code examples
paypalpaypal-sandboxpaypal-rest-sdk

Passing Internal Order ID Between Webhooks (CHECKOUT.ORDER.APPROVED & PAYMENT.CAPTURE.COMPLETED)


I'm trying to figure out the best way to pass an internal order ID between different webhook events, specifically from CHECKOUT.ORDER.APPROVED to PAYMENT.CAPTURE.COMPLETED. Here's what I've tried so far:

  1. Using reference_id: I included the internal order ID in the reference_id field during the checkout order approval phase. This ID gets returned in the CHECKOUT.ORDER.APPROVED webhook, which is great. However, it doesn't appear in the PAYMENT.CAPTURE.COMPLETED webhook, as there's no reference_id field available in the payload of the latter.

  2. Database storage: One workaround I considered is storing the reference_id from the first webhook in a database. Then just use field supplementary_data.related_ids.order_id from PAYMENT.CAPTURE.COMPLETED . But there is one important question: Will CHECKOUT.ORDER.APPROVED always be send first to my API ?

  3. API call: Another method I thought of is making an API call to checkout/orders/:orderId to fetch the reference_id. However, this feels like an overly complicated step just to retrieve the order number.

Is there a simpler or more efficient method to maintain the continuity of the internal order ID across these webhook events? I'm looking for any advice or best practices that might help streamline this process.


Solution

  • The only purpose of the reference_id field is to tell apart multiple purchase_units (for if doing later patch operations). It has no other purpose, so if you only have a single purchase_unit leave it blank for default.

    The value you are looking for for reconciliation is either invoice_id or custom_id:

    • invoice_id is indexed, searchable in the paypal.com interface, by default will prevent duplicate transactions with the same id from completing and is visible to the payer. Essentially it is best used for the business's own order id if unique (beware of the duplicates blocked issue)
    • custom_id is not visible to the payer and is not indexed.