Webhooks
YouCan Pay uses webhooks to notify your application when an event happens in your account. Webhooks are useful for handling reactions to asynchronous events on your backend, such as successful payments, failed payments, successful refunds, and many other real time events.
A webhook enables YouCan Pay to push real-time notifications to your application by delivering JSON payloads over HTTPS.
These notifications can be used to map YouCan Pay events to suitable reactions on your backend. For example, every time you receive a notification of a paid transaction, you can programmatically mark an order as paid in your backend and update its information to match the transaction's.
You can start receiving webhook notifications by following these steps:
- Create a public webhook endpoint on your server.
- Handle requests from YouCan Pay by parsing each event object and returning 2xx response status codes.
- Deploy your webhook endpoint so it's a publicly accessible HTTPS URL.
- Register your publicly accessible HTTPS URL, either in the YouCan Pay webhook settings dashboard or through the API with Create a Webhook.
Managing Webhooks
Webhooks can be listed, created, updated and deleted through the API:
| Endpoint | Description |
|---|---|
GET /api/v2/webhooks | List the webhooks on your account. |
POST /api/v2/webhooks | Register a new webhook. |
PUT /api/v2/webhooks/{id} | Change a webhook's URL or subscribed events. |
DELETE /api/v2/webhooks/{id} | Delete a webhook. |
Every delivery attempt is recorded. Use Webhook History to see what was sent, how your endpoint answered, and whether a retry is pending.
Verifying Notifications
Each notification carries an X-YOUCANPAY-SIGNATURE header holding an HMAC-SHA256 hex digest of the raw request body, keyed with your private key.
Recompute it and compare with a constant-time comparison before trusting the payload:
$expected = hash_hmac('sha256', $request->getContent(), $privateKey);
if (!hash_equals($expected, $request->header('X-YOUCANPAY-SIGNATURE'))) {
abort(403);
}Sign against the raw body exactly as received. Decoding and re-encoding the JSON changes the bytes and the digest will not match.
Event Objects
Every time an event is triggered in our system, all of your configured webhooks are automatically notified with a JSON payload of the corresponding event.
Attributes
| Parameter | Type | Description |
|---|---|---|
id | string | The object's unique identifier. |
event_name | string | The event type following the pattern of "event_resource.event_action". |
sandbox | boolean | Whether the event was triggered in a sandbox environment or not. |
payload | object | An object containing sub-objects pertaining to the event's resource. |
Webhook Event Object
{
"id": "f9dc2ad2-a2ac-4608-878c-066f5ceb2ab3",
"event_name": "transaction.paid",
"sandbox": false,
"payload": {
"token": {
"id": "31b72661-e51f-4cb3-8aec-d990aec3ae63"
},
"customer": {
"id": "e85efd21-7a28-4cfa-9d43-b64355db1292",
"city": null,
"name": null,
"email": null,
"phone": null,
"state": null,
"address": null,
"zip_code": null,
"country_code": null
},
"metadata": {
"type": "checkout",
"cart.id": "uuid"
},
"transaction": {
"id": "5d47a625-4e1e-4505-94e0-8328a371fe67",
"amount": "500",
"status": 1,
"currency": "MAD",
"order_id": "12",
"created_at": "2022-05-13T10:36:08.000000Z",
"base_amount": null,
"base_currency": null
},
"payment_method": {
"id": 1,
"card": {
"id": "2c546131-e228-44e0-8fb4-733d6dd9daa7",
"brand": "VISA",
"fingerprint": "1f3decbcf2fb9a2e50e8a64ec5b2c83e",
"last_digits": "1881",
"country_code": "MA",
"is_3d_secure": false
},
"name": "credit_card"
}
}
}