DOCS

v1.3.28
 // Pro v1.2.20

 · Latest

Docs/API Reference/Webhooks API

Webhooks API

The Webhooks API enables Order Daemon to receive and process events from external services: payment gateways, automation platforms, and third-party integrations.

Base URL: /wp-json/odcm/v1/webhooks/

Authentication: Webhook endpoints use service-specific authentication (signatures, shared secrets) rather than WordPress authentication.

Gateway webhook endpoint

POST /webhooks/{gateway}

Receive webhook events from supported gateways and services.

Supported gateways:

  • stripe – Stripe payment events (comprehensive coverage)
  • paypal – PayPal IPN and webhook events (full lifecycle)
  • generic – Flexible adapter for any other service

Webhook URL format: https://yoursite.com/wp-json/odcm/v1/webhooks/{gateway}

Named connection variant: POST /webhooks/generic/{connection} – use this to distinguish multiple generic integrations by a stable connection name (e.g. zapier, make).

Note: All webhook POST endpoints always return HTTP 200, even on processing errors. This is intentional – returning non-200 would cause most gateways to retry delivery. Check the success field in the response body to determine outcome.

Response (success): {success: true, message: "Processed N event(s)", events_processed: N, process_id: "...", execution_time: "...ms"}

Response (error): {success: false, message: "...", process_id: "..."} – HTTP 200

Gateway discovery and management

GET /webhooks/gateways

Get comprehensive information about all available webhook gateways.

Authentication: Requires manage_woocommerce.

Response includes: gateway name and display info, available event types, webhook and test URLs, adapter status and capabilities.

GET /webhooks/test/{gateway}/events

Get available test event types for a specific gateway.

Authentication: Requires manage_woocommerce.

GET /webhooks/health

Public health check – no authentication required.

Response: {status: "healthy", timestamp, version, endpoints: {paypal, stripe, generic}, adapters: [...]}

POST /webhooks/test/{gateway}

Test a webhook endpoint with sample data.

Parameters:

  • gateway (string, required) – gateway identifier
  • event_type (string, optional) – specific event type (default: payment_completed)

Response includes: test success status, test ID for tracking, processing results, performance metrics, test recommendations.

Webhook security

Signature verification

  • StripeStripe-Signature header with HMAC-SHA256
  • PayPal – Certificate verification via PayPal-Transmission-Sig, PayPal-Cert-Id, etc.
  • Generic – HMAC-SHA256 shared secrets via a configurable header (connection setting hmac_header, defaulting to x-signature). If no connection is configured the endpoint operates in permissive mode – all requests pass.

Event processing flow

  1. Receive – verify signature, parse and validate payload, extract order reference.
  2. Map to universal event – convert gateway-specific data to standard format, enrich with WooCommerce order context.
  3. Trigger rule evaluation – find applicable rules, evaluate conditions, execute matching actions.
  4. Record audit trail – log webhook reception, rule evaluations, and outcomes.

Gateway-specific features

Stripe

The adapter normalizes raw Stripe webhook events to internal event type IDs. These IDs are what getSupportedEventTypes() returns and what the EventTypeCondition component matches against. The UniversalEvent.eventType property uses the hierarchical format payment.stripe.{original_event_type}.

52 event types are supported:

CategoryEvent type IDs
Payment Intentpayment_intent_created, payment_intent_succeeded, payment_intent_payment_failed, payment_intent_canceled, payment_intent_requires_action, payment_intent_processing
Chargecharge_succeeded, charge_failed, charge_pending, charge_captured, charge_updated, charge_refunded
Disputecharge_dispute_created, charge_dispute_updated, charge_dispute_closed, charge_dispute_funds_withdrawn, charge_dispute_funds_reinstated
Refundrefund_created, refund_updated, refund_failed
Subscriptioncustomer_subscription_created, customer_subscription_updated, customer_subscription_deleted, customer_subscription_trial_will_end, customer_subscription_paused, customer_subscription_resumed
Invoiceinvoice_created, invoice_finalized, invoice_payment_succeeded, invoice_payment_failed, invoice_payment_action_required, invoice_upcoming, invoice_voided
Customercustomer_created, customer_updated, customer_deleted, customer_source_created, customer_source_updated, customer_source_deleted
Payoutpayout_created, payout_updated, payout_paid, payout_failed, payout_canceled
Setup Intentsetup_intent_created, setup_intent_succeeded, setup_intent_setup_failed, setup_intent_canceled
Price / Productprice_created, price_updated, product_created, product_updated

Features: automatic order lookup by Stripe ID or metadata, subscription lifecycle management, dispute and refund handling.

Note: The EventTypeCondition rule component Pro uses a separate generic vocabulary (payment_completed, subscription_cancelled, etc.) mapped from WooCommerce hooks – not the adapter-specific IDs listed above. The adapter event type IDs are used for adapter capability declaration (getSupportedEventTypes()) and appear in the UniversalEvent.eventType field as payment.stripe.{original_event_type}.

PayPal

The adapter handles both IPN (form-encoded) and webhook (JSON) formats. Event type IDs follow the same normalized format. The UniversalEvent.eventType uses payment.paypal.{original_event_type}.

38 event types are supported:

CategoryEvent type IDs
Paymentpayment_created, payment_completed, payment_denied, payment_pending, payment_failed, payment_refunded, payment_reversed, payment_voided
Subscriptionsubscription_created, subscription_approved, subscription_cancelled, subscription_suspended, subscription_reactivated, subscription_completed, subscription_expired
Recurringrecurring_payment, recurring_payment_profile_created, recurring_payment_failed, recurring_payment_skipped, recurring_payment_suspended, recurring_payment_cancelled
Renewalrenewal_payment_processing, renewal_payment_completed, renewal_payment_failed, renewal_payment_pending
Trialtrial_started, trial_ended
Disputedispute_opened, dispute_resolved, dispute_won, dispute_lost
Express Checkoutexpress_checkout_created, express_checkout_completed
Mass Paymentmass_payment_completed, mass_payment_failed
Authorizationauthorization_created, authorization_voided, authorization_expired

Features: both IPN (form-encoded) and webhook (JSON) formats, automatic order lookup by transaction ID, PayPal certificate verification.

Generic adapter

The generic adapter accepts any JSON payload and normalizes it to a UniversalEvent. It is designed for services without a dedicated adapter (Zapier, Make, custom webhooks).

12 built-in event types are recognized:

CategoryEvent type IDs
Paymentpayment_completed, payment_failed, payment_pending, payment_refunded, payment_cancelled
Orderorder_updated, order_completed, order_cancelled
Subscriptionsubscription_created, subscription_cancelled, subscription_renewed
Customcustom_event – fallback for unrecognized types

Any string not in this list is passed through as-is and stored in the audit log – you are not limited to these values.

Features: flexible field mapping, automatic extraction of order IDs and transaction IDs, configurable HMAC authentication, nested payload support.

Custom gateway integration

Extend AbstractGatewayAdapter and register via the odcm_register_gateway_adapters hook:

class CustomGatewayAdapter extends OrderDaemonCompletionManagerCoreEventsAdaptersAbstractGatewayAdapter {

    public function __construct() {
        parent::__construct('custom_gateway');
    }

    public function getSupportedEventTypes(): array {
        return ['payment_completed', 'payment_failed'];
    }

    public function canHandle(array $input): bool {
        return isset($input['payload']['custom_gateway_event']);
    }

    public function validateAuthenticity(array $input): bool {
        $signature = $input['headers']['x-custom-signature'] ?? '';
        $secret    = get_option('custom_gateway_secret', '');
        $expected  = hash_hmac('sha256', json_encode($input['payload']), $secret);
        return hash_equals($expected, $signature);
    }

    public function normalize(array $input): array {
        $payload = $input['payload'] ?? [];

        $event = new OrderDaemonCompletionManagerCoreEventsUniversalEvent([
            'eventType'         => $this->mapEventType($payload['event']),
            'sourceGateway'     => 'custom_gateway',
            'primaryObjectType' => 'order',
            'primaryObjectID'   => $payload['order_id'] ?? null,
            'transactionID'     => $payload['transaction_id'] ?? null,
            'amount'            => $payload['amount'] ?? null,
            'currency'          => $payload['currency'] ?? 'USD',
            'rawData'           => $payload,
        ]);

        return [$event];
    }

    public function computeIdempotencyKey(array $input): string {
        $payload = $input['payload'] ?? [];
        return 'custom_gateway_' . ($payload['transaction_id'] ?? md5(json_encode($payload)));
    }

    protected function extractTransactionId(array $payload): ?string {
        return $payload['transaction_id'] ?? null;
    }

    protected function extractGatewaySpecificMetadata(array $input): array {
        return ['event_type' => $input['payload']['event'] ?? null];
    }

    protected function mapEventType(string $event): string {
        return [
            'payment.success' => 'payment_completed',
            'payment.failure' => 'payment_failed',
        ][$event] ?? 'custom_event';
    }
}

add_action('odcm_register_gateway_adapters', function ($router) {
    $router->registerAdapter(new CustomGatewayAdapter());
});

See Creating custom rule components and Hooks and filters reference for full adapter documentation.