• Resolved Mike Castro Demaria

    (@mikecastrodemaria)


    Problem Description:

    Every PayPal order is being processed twice, causing:

    1. Duplicate email notifications – Both customer and admin receive 2 identical order confirmation emails
    2. Double inventory deduction – Product stock quantity is decremented twice per order

    Steps to Reproduce:

    1. Customer completes a purchase using PayPal payment method
    2. PayPal transaction completes successfully
    3. Observe the following:
    • Two order confirmation emails sent to customer
    • Two order confirmation emails sent to admin
    • Product inventory reduced by 2x the ordered quantity

    Expected Behavior:

    • Single order confirmation email should be sent
    • Inventory should be decremented only once per order

    Actual Behavior:

    • Duplicate emails are sent systematically for every PayPal order
    • Stock quantity is incorrectly reduced twice

    Impact:

    • Inventory management is broken (stock appears depleted faster than actual sales)
    • Customer confusion from duplicate emails
    • Data integrity issues in order tracking

    Additional Information:

    I will provide complete system information via Pastebin in a follow-up comment including:

    • WordPress version
    • WooCommerce version
    • PayPal Payments plugin version
    • PHP version
    • Active plugins list
    • Theme information

    https://pastebin.com/EnzprbSy

    This appears to be a webhook or IPN double-processing issue where the order completion hook is triggered twice.

Viewing 5 replies - 1 through 5 (of 5 total)
  • Plugin Support Krystian Syde

    (@inpsydekrystian)

    Hello @mikecastrodemaria

    This duplicate processing issue is still under active investigation on our side. We also have a fixing package available for testing, but it comes with limitations and we can only provide it through direct support. If you want to test it, please open a ticket here: https://paypal.inpsyde.com/docs/request-support/

    Make sure to include a link to this thread so we can attach your context to the ticket immediately.

    Kind Regards,
    Krystian

    Thread Starter Mike Castro Demaria

    (@mikecastrodemaria)

    Done , but :
    We couldn’t create a request
    System Report cannot exceed 32767 characters

    I add as attachement

    Thread Starter Mike Castro Demaria

    (@mikecastrodemaria)

    I’ve found the root cause of your duplicate order processing issue. Let me explain the problem and provide solutions.

    Root Cause Analysis

    The Bug

    PayPal sends two different webhook events for the same transaction:

    1. CHECKOUT.ORDER.COMPLETED
    2. PAYMENT.CAPTURE.COMPLETED Both webhook handlers call payment_complete(), which triggers:
    • Email notifications
    • Inventory reduction
    • Order status change Race Condition Flow Initial order status: ‘on-hold’
    1. First webhook arrives (CHECKOUT.ORDER.COMPLETED)
      • CheckoutOrderCompleted.php:77 – Checks if status is ‘pending’ or ‘on-hold’ → ✓ passes
      • Calls payment_complete() → sends email #1, reduces inventory -1
    2. Second webhook arrives simultaneously (PAYMENT.CAPTURE.COMPLETED)
      • PaymentCaptureCompleted.php:98 – Checks if status is ‘on-hold’ → ✓ passes (before first webhook updates status)
      • Calls payment_complete() → sends email #2, reduces inventory -1 again
      Why Current Safeguards Fail
    3. Status checks are not atomic: Both webhooks read ‘on-hold’ status before either updates it
    4. No locking mechanism: WebhookOrchestrator.php exists but is NOT being used by the handlers
    5. No event deduplication: Webhook event IDs are stored (WebhookEventStorage.php:39) but never checked to prevent reprocessing
    6. No processing flag: No metadata flag is set before processing to indicate “order is being processed right now”

    Proposed Solutions

    I’ll give you 3 solutions from quickest fix to most comprehensive:

    Solution 1: Add Per-Order Lock (Recommended – Quick Fix)

    Modify both webhook handlers to use WebhookOrchestrator with order-specific locks:

    Files to modify:

    • modules/ppcp-webhooks/src/Handler/CheckoutOrderCompleted.php
    • modules/ppcp-webhooks/src/Handler/PaymentCaptureCompleted.php What to change:
      Add order-specific locking before calling payment_complete() to prevent concurrent processing of the same order.
    • Solution 2: Add Processing Metadata Flag (Most Reliable) Add a metadata flag (_ppcp_payment_processing) before attempting to call payment_complete(): Logic:
    1. Check if ‘_ppcp_payment_processing’ flag exists → skip if true
    2. Set ‘_ppcp_payment_processing’ = ‘true’
    3. Check order status
    4. Call payment_complete()
    5. Set ‘_ppcp_payment_completed’ = current webhook event type
    6. Remove ‘_ppcp_payment_processing’ flag
    7. Solution 3: Restrict PaymentCaptureCompleted Handler (Targeted Fix) Make PaymentCaptureCompleted only process orders that were explicitly in an authorized state (have _ppcp_paypal_authorized metadata but
      not _ppcp_paypal_captured). This prevents double-processing for standard checkout flows where authorization and capture happen atomically.

    My Recommendation

    Use Solution 2 (Metadata Flag) because it:

    • Provides the strongest guarantee against duplicates
    • Works even if webhooks arrive microseconds apart
    • Tracks which webhook actually processed the payment
    • Survives server restarts (unlike transient-based locks)
    • Provides audit trail for troubleshooting

    I’m scared of using this plugin anymore, too much problems in the latests months… and this problem during Black Friday promotion week!

    Plugin Support Krystian Syde

    (@inpsydekrystian)

    Hello @antoniogallo

    We released a fixing package yesterday that addresses the recent problems, and in most cases applying this update resolves the situation.

    Please open a ticket here: https://paypal.inpsyde.com/docs/request-support/

    Kind Regards,
    Krystian

Viewing 5 replies - 1 through 5 (of 5 total)

The topic ‘PayPal orders trigger duplicate emails and double inventory deduction’ is closed to new replies.