Webhooks -- Overview
Webhooks allow your application to receive real-time notifications about events on the Owem Pay platform. When an event occurs, Owem Pay sends an HTTP POST to the registered URL.
How It Works
- Register a webhook URL in your account
- When an event occurs (e.g., PIX received), Owem Pay sends an HTTP POST to your URL
- Your application processes the notification and responds with a
2xxstatus (200, 201, or 204)
Available Events
| Event | Description |
|---|---|
pix.charge.created | QR code generated |
pix.charge.paid | PIX received and settled |
pix.charge.expired | QR code expired (24h) |
pix.payout.processing | PIX sent, awaiting confirmation |
pix.payout.confirmed | PIX sent and confirmed |
pix.payout.failed | PIX sent rejected |
pix.payout.returned | PIX sent returned |
pix.refund.requested | MED received, funds blocked |
pix.refund.completed | MED finalized |
pix.return.received | PIX return received (credit) |
webhook.test | Manual test |
Security
Each notification includes security headers for validation:
| Header | Description |
|---|---|
X-Owem-Signature | HMAC-SHA256 signature of the payload |
X-Owem-Timestamp | Unix timestamp in seconds of the delivery |
X-Owem-Event-Id | Unique event ID (for deduplication) |
X-Owem-Event-Type | Event type (e.g., pix.charge.paid) |
SHA256 for webhooks vs SHA512 for the API
The API uses HMAC-SHA512 to authenticate requests that you send. Webhooks sent by Owem Pay use HMAC-SHA256 in the X-Owem-Signature header. These are different algorithms -- each in its own context.
Validating the Signature
Validate the signature to ensure the notification was sent by Owem Pay:
const crypto = require('crypto');
function validateWebhook(payload, timestamp, signature, secret) {
// timestamp is unix seconds (e.g., 1712160000)
const message = `${timestamp}.${payload}`;
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(message)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}Always validate
Never process a webhook without validating the signature. This protects against forged requests.
Retry Policy
If your URL returns a non-2xx status, Owem Pay performs automatic retries:
| Attempt | Interval |
|---|---|
| 1st | Immediate |
| 2nd | 1 minute |
| 3rd | 5 minutes |
| 4th | 30 minutes |
| 5th | 2 hours |
After 5 unsuccessful attempts, the event is marked as failed and will not be automatically resent.
Idempotency
Your application must be idempotent: if it receives the same event more than once (identified by X-Owem-Event-Id), it should process it without duplicating effects.
External ID in Webhooks
When a transaction was created with an external_id, this field is included in the webhook payload within the data object. Use it to correlate the event with the order in your system without needing an additional API query.
Endpoint Requirements
- The URL must use HTTPS (unless
allow_insecure: trueis set during registration) - Must respond with a
2xxstatus within 5 seconds - The response body is ignored
Next Steps
- Register Webhook -- create, list, and remove webhooks
- Event Payloads -- examples of each event type