Webhooks
WPReturns sends return events through WooCommerce’s own webhooks with two topics: Return request created (return_request.created) and Return request updated (return_request.updated). You add them in WooCommerce > Settings > Advanced > Webhooks like any other webhook. WooCommerce handles delivery, signing, retries and the delivery log.
Available in: Pro.
Topics
Section titled “Topics”| Topic | Name in WooCommerce | Fires when |
|---|---|---|
return_request.created | Return request created | A request is saved, from any source: My Account, the guest portal, the withdrawal form, the admin screen or the REST API |
return_request.updated | Return request updated | A request changes status, or a resolution is carried out |
Resolving a request triggers the updated topic for the resolution and again for the move to Completed. Build the receiving app to handle the same request more than once. Read status and date_updated to decide what changed.
Add a webhook
Section titled “Add a webhook”- Go to WooCommerce > Settings > Advanced > Webhooks and select Add webhook.
- Enter a Name such as “Returns to helpdesk”.
- Set Status to Active.
- Pick Return request created or Return request updated under Topic.
- Enter the Delivery URL of the receiving app.
- Enter a Secret or keep the generated one.
- Select Save webhook.
Add a second webhook for the other topic if you need both.
Payload
Section titled “Payload”The body is the same request object the REST API returns.
{ "id": 1042, "number": "RMA-01042", "order_id": 1042, "customer_id": 17, "customer_email": "jane.cooper@example.com", "customer_name": "Jane Cooper", "type": "return", "status": "approved", "status_label": "Approved", "resolution": "store_credit", "customer_note": "The shirt is too small.", "items_total": 49, "restocking_fee": 0, "shipping_fee": 0, "credit_bonus": 4.9, "resolution_total": 53.9, "refunded_total": 0, "coupon_code": "", "exchange_order_id": 0, "tracking_number": "", "carrier": "", "assigned_to": 0, "risk_score": 15, "risk_flags": ["quick_return"], "source": "portal", "returnless": false, "date_created": "2026-11-02T10:15:00+00:00", "date_updated": "2026-11-03T09:02:00+00:00", "date_closed": null, "items": [ { "id": 2210, "order_item_id": 3381, "product_id": 512, "variation_id": 515, "name": "Linen shirt - M", "qty": 1, "line_total": 49, "reason": "wrong-size", "condition": "unopened", "exchange_product_id": 0, "restocked": 0 } ]}See REST API for what each field means.
Verify the signature
Section titled “Verify the signature”WooCommerce signs each delivery. The X-WC-Webhook-Signature header holds a base64 HMAC-SHA256 of the raw body, keyed with the webhook secret. Other headers name the topic (X-WC-Webhook-Topic), the resource and the delivery ID.
<?php$secret = 'your-webhook-secret';$body = file_get_contents( 'php://input' );$signature = isset( $_SERVER['HTTP_X_WC_WEBHOOK_SIGNATURE'] ) ? $_SERVER['HTTP_X_WC_WEBHOOK_SIGNATURE'] : '';$expected = base64_encode( hash_hmac( 'sha256', $body, $secret, true ) );
if ( ! hash_equals( $expected, $signature ) ) { http_response_code( 401 ); exit;}
$request = json_decode( $body, true );// Use $request['number'], $request['status'] and the rest here.Delivery and retries
Section titled “Delivery and retries”WooCommerce queues deliveries through Action Scheduler, and each webhook’s edit screen shows recent deliveries with the response code. WooCommerce turns a webhook off after too many failed deliveries in a row. Check its Status if deliveries stop.
To react inside WordPress instead of over HTTP, use the actions in the Hooks reference.