Payment Issues

This page covers problems related to WooCommerce order processing, Stripe webhook integration, and automatic license provisioning during payment flows.

WooCommerce Not Creating Licenses

Symptom

A WooCommerce order completes successfully but no license is created in LicenceForge.

Possible Causes

  1. Price tier not linked to WooCommerce product. The wc_product_id field on the LicenceForge price tier is not set, or it does not match the WooCommerce product ID in the order.
  2. Order status not triggering license creation. LicenceForge creates licenses when an order reaches completed or processing status. If the order is stuck in pending or on-hold, no license is generated.
  3. Product is inactive. If the LicenceForge product has is_active = 0, license creation is skipped even when the WooCommerce order is valid.

Solutions

  1. Verify the price tier mapping:
    • Navigate to LicenceForge > Products > [Product] > Price Tiers.
    • Confirm the wc_product_id matches the WooCommerce product (or variation) ID.
    • You can find the WooCommerce product ID in the URL when editing the product: post.php?post=123&action=edit.
  2. Check the order status in WooCommerce > Orders. If the order is stuck, manually transition it to completed or investigate the payment gateway configuration.
  3. Ensure the LicenceForge product is active: navigate to LicenceForge > Products and verify the status column shows Active.

Tip

Check the wplf_audit_log table for entries with action license_create around the order time. If no entry exists, the WooCommerce hook did not fire or was intercepted by another plugin.

Stripe Webhooks Failing

Symptom

The Stripe dashboard shows webhook delivery failures (HTTP 400 or 500 responses) for events sent to your LicenceForge endpoint.

Possible Causes

  1. Wrong webhook URL. The URL configured in Stripe does not match the LicenceForge webhook endpoint.
  2. Incorrect webhook secret. The stripe_webhook_secret stored in LicenceForge does not match the signing secret from the Stripe dashboard.
  3. Signature verification failure. The payload signature cannot be verified, typically due to a secret mismatch or payload modification by a proxy or firewall.
  4. Timestamp tolerance exceeded. Stripe rejects webhooks if the timestamp in the signature header is more than 5 minutes old, which can happen with significant server time drift.

Solutions

  1. Verify the webhook URL in your Stripe dashboard is exactly:
    https://your-site.com/wp-json/wplf/v1/webhooks/stripe

    Replace your-site.com with your actual domain. The path must match precisely.

  2. Compare the webhook signing secret:
    • In Stripe: Developers > Webhooks > [Endpoint] > Signing secret (starts with whsec_).
    • In LicenceForge: Settings > Stripe, the stripe_webhook_secret field.

    These values must be identical.

  3. Ensure no proxy, CDN, or security plugin is modifying the raw request body before it reaches WordPress. Stripe signature verification requires the exact original payload.
  4. Synchronise the server clock with NTP to prevent timestamp tolerance failures:
    sudo ntpdate pool.ntp.org

Duplicate Licenses Created

Symptom

Multiple licenses are created for a single order or payment event.

Explanation

This should not occur under normal conditions. LicenceForge uses a MySQL GET_LOCK() during license creation and performs an idempotent check against the webhook event ID. The wplf_webhook_events table enforces a UNIQUE constraint on event_id, preventing the same event from being processed twice.

Diagnostic Steps

  1. Check the wplf_webhook_events table for duplicate event_id values:
    SELECT event_id, COUNT(*) as cnt
    FROM wplf_webhook_events
    GROUP BY event_id
    HAVING cnt > 1;

    If this query returns results, the UNIQUE constraint may have been removed or the table schema is corrupted. Re-run the LicenceForge database migration by deactivating and reactivating the plugin.

  2. Check the audit log for multiple license_create entries with the same order reference.
  3. If duplicates were created by both Stripe webhooks and WooCommerce order hooks, ensure you are not running both integrations for the same payment flow. Use one or the other.

Subscription Renewal Not Extending License

Symptom

A customer's subscription renews successfully in Stripe, but their license expiration date is not extended in LicenceForge.

Cause

The invoice.payment_succeeded event is not configured in the Stripe webhook settings. LicenceForge listens for this specific event to detect subscription renewals and extend license expiry dates.

Solution

  1. Navigate to Stripe Dashboard > Developers > Webhooks > [Your Endpoint].
  2. Click Update details or Select events.
  3. Ensure the following events are enabled:
    • checkout.session.completed — initial purchase
    • invoice.payment_succeeded — subscription renewal
    • customer.subscription.deleted — subscription cancellation
  4. Save the webhook configuration and test with a renewal event using the Stripe CLI:
    stripe trigger invoice.payment_succeeded

Note

For a complete guide to Stripe webhook configuration, see Stripe Webhooks.

Related Pages