Handling Webhooks
While the Submit endpoint creates the order, the payment process might still be ongoing (e.g., if the user is paying with Multibanco).
To handle these asynchronous updates, you must implement a Webhook Receiver. Simpler will notify your system whenever an important event occurs, such as a successful payment or a cancellation.
- The full list of event types and their payloads lives in the Webhook Event Catalog.
- The retry schedule, delivery guarantees, and dead-letter behavior are documented in Retries & Timeouts.
- The FAQ answers common questions about webhook handling.
Let's implement a simple webhook receiver that listens for the ORDER_UPDATED event to finalize the order status.
class SimplerWebhookController extends AbstractController {
public function receiveWebhook(Request $request): Response {
// 1. Verify the Security Signature
// Always validate that the request actually came from Simpler
$signature = $request->headers->get('X-Simpler-CRC');
$payload = $request->getContent();
$mySecret = 'YOUR_APP_SECRET';
if (hash_hmac('sha1', $payload, $mySecret) !== $signature) {
return new Response('Invalid Signature', 401);
}
// 2. Parse the Event
$event = json_decode($payload, true);
// 3. Handle specific event types
if ($event['type'] === 'ORDER_UPDATED') {
$data = $event['data'];
// Find the order in your system using the Simpler Order ID or your internal ID
$order = CheckoutService::getOrder($data['order_id']);
if ($data['status'] === 'PAYMENT_SUCCESS') {
// Mark order as Paid / Processing
$order->setStatus('processing');
$order->setTransactionId($data['transaction_id']);
$order->save();
}
}
// 4. Acknowledge receipt
// Return 200 OK (or 202 Accepted) immediately so Simpler knows you received it.
return new Response('Webhook Received', 200);
}
}
Webhooks require your server to respond quickly (usually within seconds). If you need to perform heavy tasks like generating PDF invoices or sending emails, we recommend returning 202 Accepted immediately and processing the logic in a background queue.
Webhook delivery is at-least-once: Simpler retries on any non-2xx response, so your handler may receive the same event more than once. Each request carries an Idempotency-Key HTTP header — dedupe on that key to avoid applying the same state transition twice.
Once your webhook endpoint is live and publicly accessible, share the full URL with our Integrations Support team so we can register it against your account.