Simple Points and Rewards

How can we help?

Search the documentation or ask the AI agent anything about the plugin.

Send webhooks to other services (Pro)

Simple Points and RewardsUpdated October 27, 2026

Webhooks send a notification to another service as soon as something happens in your rewards program, such as a customer earning points or claiming a reward. Set them up at Points & Rewards › API, Webhooks & AI › Webhooks. Webhooks need Pro, and the REST API must be switched on.

Add a webhook

  1. Make sure the REST API is switched on. See Set up the REST API and API keys.
  2. Open the Webhooks tab and click Add webhook.
  3. Enter a Name, such as “Slack notifications”.
  4. Enter the Delivery URL. It must use HTTPS and be reachable from the internet. Private and local addresses are refused.
  5. Tick the Events to send, or tick All events.
  6. Click Add webhook.
The Add webhook form with a name, a delivery URL and three events ticked

You cannot change the delivery URL later. If it changes, add a new webhook and delete the old one.

The webhook then appears in the list with its secret. Copy the secret into the receiving service so it can check each delivery. Administrators see the full secret. Shop managers see only the last 4 characters.

The webhooks list with one active webhook, its events and a masked secret

Events you can send

EventWhen it is sent
points.addedA customer earned points or was given points
points.removedPoints were taken from a customer: spent, refunded, expired or removed by an admin
customer.level_changedA customer moved to a new level
reward.claimedA customer claimed a reward with their points
referral.rewardedA referred friend placed an order and the referrer was rewarded
referral.reversedA referral reward was taken back because the order was refunded, cancelled or failed
points.pendingPoints were held back by the points delay, to be released later
points.expiredA customer’s points expired after a period of inactivity
guest.points_addedA guest customer, without an account, earned points for an order

What each delivery contains

Each delivery is a JSON body with these fields:

  • id: a unique ID for the delivery. It stays the same on every retry, so use it to skip duplicates.
  • event: the event name, such as points.added.
  • created: when the event happened, in UTC.
  • site: your store’s home URL.
  • data: the details of the event. Most events include a customer object with the customer’s ID, email address, display name, balance, lifetime points and level.

Each delivery also has these headers: X-SPAR-Event (the event name), X-SPAR-Delivery (the delivery ID) and X-SPAR-Signature.

Check the signature

The X-SPAR-Signature header looks like t=1793030000,v1=5d41.... The v1 value is an HMAC-SHA256 hash of the timestamp, a full stop and the raw request body, using the webhook secret as the key. This PHP example checks it:

$secret  = 'whsec_your_webhook_secret';
$body    = file_get_contents( 'php://input' );
$header  = $_SERVER['HTTP_X_SPAR_SIGNATURE'] ?? '';

parse_str( str_replace( ',', '&', $header ), $parts );
$timestamp = $parts['t'] ?? '';
$expected  = hash_hmac( 'sha256', $timestamp . '.' . $body, $secret );

if ( ! hash_equals( $expected, $parts['v1'] ?? '' ) || abs( time() - (int) $timestamp ) > 300 ) {
	http_response_code( 401 );
	exit;
}

$event = json_decode( $body, true );
http_response_code( 200 );

Retries and automatic switch-off

A delivery succeeds when the receiving service replies with a 2xx status within 8 seconds. Redirects are not followed. A failed delivery is tried up to 5 times in total, waiting about 1, 4, 16 and 64 minutes between attempts.

After 25 failures in a row, where the first of them was at least a day ago, the webhook is switched off. Click Enable to switch it on again. This also resets the failure count.

The list shows the time of the last delivery and the number of failures. Hover over the failure count to see the last error. There is no full delivery log.

Test a webhook

Click Test to send a ping event straight away. A notice shows the HTTP status the service returned. Tests work even while the REST API is off, and they do not count as failures.

Related

Was this article helpful?