Skip to content

Webhooks

Receive real-time order status updates from SparkCRM via webhooks.

Navigation: Spark CRM > Webhooks

Webhooks enable real-time communication from SparkCRM back to your WooCommerce store. When an order status changes in SparkCRM, a webhook event is sent to your WordPress site to update the corresponding WooCommerce order.


Webhook Endpoint

Your site’s webhook URL is displayed on the Spark CRM > Webhooks page:

https://yourstore.com/wp-json/spark/v1/webhook

Copy this URL and configure it as a webhook endpoint in your SparkCRM account under Settings > Webhooks.


Webhook Secret

The plugin generates a secret on the Webhooks settings page, where you can also regenerate it. Despite its name it is used as the Basic Authentication password for the Spark CRM webhook - see the note below.

To configure in SparkCRM:

  1. Copy the Webhook Secret and the Webhook URL from the plugin’s Webhooks page
  2. In SparkCRM, go to Settings > Webhooks and click Add Webhook
  3. Paste the plugin’s Webhook URL into Endpoint URL
  4. Set Authentication to Basic Authentication and paste the Webhook Secret into the password field
  5. Under Events, select the triggers you want to send
  6. Add the JSON Payload Parameters the plugin expects for that event (see below)
  7. Tick Active and save

Use Basic Authentication, not the signature. Spark CRM signs every delivery with HMAC-SHA256 and sends the digest in X-Webhook-Signature (raw lowercase hex, no sha256= prefix), alongside a delivery id in X-Webhook-ID. This plugin version reads a differently named header, X-Spark-Signature, so it cannot verify Spark CRM’s signature. Because the plugin generates a webhook secret when it is activated, it rejects any request that arrives without X-Spark-Signature — so a webhook configured for signature verification returns 401 on every delivery. Basic Authentication is the path the plugin actually supports, and is what its own setup card instructs.


Supported Events

Two names matter here, and they are not the same:

  • The trigger you select under Events in Spark CRM. These are snake_case (order_complete, refund_created) and never dot-separated.
  • The event_type value the plugin dispatches on. These are dot-separated (order.approved), and the plugin acts on nothing else — any other value returns Event type not handled and the order is untouched.

The plugin does not translate between them. You bridge the two by adding a JSON Payload Parameter named event_type whose value is the dotted string, and nesting the order fields under a data object — the plugin reads its fields from body.data, not from the flat payload Spark CRM sends by default.

Select this trigger Set event_type to WooCommerce action
order_complete order.approved Order status set to Processing
order_declined order.declined Order status set to Failed
refund_created order.refunded WooCommerce refund created
order_canceled order.cancelled Order cancelled, stock restored
fulfillment_created or tracking_updated order.shipped Order set to Completed; tracking number, tracking URL and carrier stored as order meta
delivered order.delivered Delivery recorded in order meta (_spark_delivered_date) plus an order note
subscription_created subscription.created Subscription data stored in order meta
subscription_canceled subscription.cancelled Subscription status updated

Note the spelling difference across the boundary: the Spark CRM triggers use the American single-l canceled, while the plugin’s event_type values use cancelled.

Notes on these events:

  • Subscription rebills emit subscription_rebill_complete rather than order_complete, and rebill declines deliberately emit subscription_rebill_declined instead of order_declined. Use transaction_approved if you need per-transaction granularity.
  • A queued order_declined delivery is skipped if the order is no longer declined when it is sent, and a queued subscription_canceled delivery is skipped if the subscription is no longer cancelled.
  • refund_created carries refund_amount, refund_currency, refund_is_partial, refund_transaction_number, refunded_transaction_number and refunded_products[], which is what the plugin needs to mirror a partial refund.
  • All fulfillment events share the same payload shape (fulfillment_number, tracking_number, carrier, status, shipping_method); tracking_number is populated once tracking exists, so fulfillment_created may carry an empty one.
  • delivered requires Enhanced Shipping Notifications on your team before it can be selected. Its payload is fulfillment-scoped (fulfillment_number, tracking_number, carrier, status) and the delivery time comes from the payload’s timestamp field. The plugin looks for a delivered_at field, so map one in your payload parameters if you want the real delivery date recorded rather than the time the webhook arrived.
  • subscription_created payload fields include subscription_number, status, amount, currency, billing_interval, next_billing_at, trial_days, trial_ends_at and products[]. Note that order_id holds an order number for the customer’s most recent order, which is not guaranteed to be the order that created the subscription — match on subscription_number instead.

Order Matching

Webhooks match SparkCRM orders to WooCommerce orders using the _spark_order_number meta key, which is stored when an order is first synced to SparkCRM.


Testing

A test endpoint is available to verify your webhook configuration:

GET https://yourstore.com/wp-json/spark/v1/webhook/test

This returns a success response without processing any data.


Troubleshooting

Webhooks Not Arriving

  • Verify the endpoint URL is correct in SparkCRM
  • Check that your site is accessible from the internet (not localhost)
  • Ensure no firewall or security plugin is blocking the REST API endpoint
  • Test the endpoint manually using the test URL above

Every Delivery Returns 401

This is what happens when the webhook is configured for signature verification. The plugin verifies X-Spark-Signature, which Spark CRM never sends — it sends X-Webhook-Signature — and because the plugin generates a secret when it is activated, it refuses any request that arrives without its own header.

  • Set Authentication to Basic Authentication on the Spark CRM webhook and use the plugin’s Webhook Secret as the password
  • Do not use the plugin secret as a signing secret; the two schemes are not interoperable in this plugin version
  • Check that no proxy or CDN is stripping the Authorization header

Deliveries Return 200 but Nothing Changes

The plugin answers Event type not handled and returns 200 when it does not recognise the event_type value. Add a JSON Payload Parameter named event_type set to the dotted value for that trigger (see Supported Events), and nest the order fields under a data object.

Order Not Updating

  • Confirm the order was originally synced from this WooCommerce site
  • Check that the _spark_order_number meta exists on the WooCommerce order
  • Enable debug mode to see detailed webhook processing logs
Navigation

Type to search…

↑↓ navigate↵ selectEsc close