Appearance
Webhooks allow your application to receive real-time notifications about events that occur in Pocketbook. Instead of polling for changes, webhooks push event data to your specified endpoint when events occur.
Overview
Pocketbook webhooks deliver event notifications via HTTP POST requests to your configured endpoint URLs. This enables you to:
- React to events in real-time
- Automate workflows based on Pocketbook events
- Synchronize data with external systems
- Trigger business logic in your application
Webhook Events
Pocketbook supports the following webhook event types:
User Events
user.created- New user account createduser.updated- User account information updateduser.deleted- User account deleteduser.verified- User email or identity verified
Transaction Events
transaction.created- New transaction recordedtransaction.updated- Transaction details updatedtransaction.completed- Transaction successfully completedtransaction.failed- Transaction failed or was rejected
Payment Events
payment.succeeded- Payment successfully processedpayment.failed- Payment processing failedpayment.refunded- Payment was refunded
Subscription Events
subscription.created- New subscription startedsubscription.updated- Subscription details changedsubscription.cancelled- Subscription cancelledsubscription.renewed- Subscription auto-renewed
Document Events
document.uploaded- New document uploadeddocument.processed- Document processing completeddocument.verified- Document verification completed
Managing Webhooks
Create Webhook Endpoint
http
POST /api/v1/webhooksRequest Body:
json
{
"url": "https://your-app.com/webhooks/pocketbook",
"events": ["transaction.created", "payment.succeeded"],
"description": "Production webhook endpoint",
"secret": "your_webhook_secret_key"
}Parameters:
url(string, required): HTTPS endpoint to receive webhook eventsevents(array, required): List of event types to subscribe todescription(string, optional): Description for your referencesecret(string, optional): Secret key for signature validation
Example Request:
bash
curl -X POST "https://api.pocketbook.studio/api/v1/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/pocketbook",
"events": ["transaction.created", "payment.succeeded"],
"description": "Production webhook"
}'Example Response:
json
{
"id": "webhook_abc123",
"url": "https://your-app.com/webhooks/pocketbook",
"events": ["transaction.created", "payment.succeeded"],
"status": "active",
"secret": "whsec_xyz789...",
"created_at": "2024-01-15T10:30:00Z"
}List Webhooks
http
GET /api/v1/webhooksExample Request:
bash
curl -X GET "https://api.pocketbook.studio/api/v1/webhooks" \
-H "Authorization: Bearer YOUR_API_KEY"Get Webhook Details
http
GET /api/v1/webhooks/{webhook_id}Update Webhook
http
PATCH /api/v1/webhooks/{webhook_id}Request Body:
json
{
"events": ["transaction.created", "transaction.completed", "payment.succeeded"],
"status": "active"
}Delete Webhook
http
DELETE /api/v1/webhooks/{webhook_id}Webhook Payload Structure
All webhook events follow this standard structure:
json
{
"id": "evt_abc123xyz",
"type": "transaction.created",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"object": {
"id": "txn_123456",
"amount": 5000,
"currency": "USD",
"status": "completed",
"user_id": "user_789",
"created_at": "2024-01-15T10:29:55Z"
}
},
"api_version": "2024-01"
}Fields:
id: Unique event identifiertype: Event type (e.g.,transaction.created)created_at: ISO 8601 timestamp when event occurreddata.object: The resource object related to the eventapi_version: API version used for the event
Example Event Payloads
Transaction Created
json
{
"id": "evt_tx_created_123",
"type": "transaction.created",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"object": {
"id": "txn_123456",
"type": "payment",
"amount": 5000,
"currency": "USD",
"status": "pending",
"user_id": "user_789",
"description": "Monthly subscription payment",
"metadata": {
"plan": "premium",
"billing_period": "2024-01"
}
}
}
}Payment Succeeded
json
{
"id": "evt_pay_success_456",
"type": "payment.succeeded",
"created_at": "2024-01-15T10:30:05Z",
"data": {
"object": {
"id": "pay_abc123",
"transaction_id": "txn_123456",
"amount": 5000,
"currency": "USD",
"payment_method": "card",
"status": "succeeded",
"receipt_url": "https://pocketbook.studio/receipts/pay_abc123"
}
}
}User Verified
json
{
"id": "evt_user_verified_789",
"type": "user.verified",
"created_at": "2024-01-15T11:00:00Z",
"data": {
"object": {
"id": "user_789",
"email": "user@example.com",
"verification_type": "email",
"verified_at": "2024-01-15T11:00:00Z"
}
}
}Webhook Security
Signature Verification
Pocketbook signs all webhook requests with HMAC-SHA256. Verify signatures to ensure requests are authentic.
Signature Header:
X-Pocketbook-Signature: t=1234567890,v1=abc123def456...Verification Steps:
- Extract timestamp and signature from header
- Construct signed payload:
{timestamp}.{request_body} - Compute HMAC-SHA256 hash using your webhook secret
- Compare computed hash with signature from header
Example (Node.js):
javascript
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const parts = signature.split(',');
const timestamp = parts.find(p => p.startsWith('t=')).split('=')[1];
const receivedSignature = parts.find(p => p.startsWith('v1=')).split('=')[1];
// Construct signed payload
const signedPayload = `${timestamp}.${payload}`;
// Compute HMAC
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
// Compare signatures
return crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(receivedSignature)
);
}Example (Python):
python
import hmac
import hashlib
def verify_webhook_signature(payload, signature, secret):
parts = dict(part.split('=') for part in signature.split(','))
timestamp = parts['t']
received_signature = parts['v1']
# Construct signed payload
signed_payload = f"{timestamp}.{payload}"
# Compute HMAC
expected_signature = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
# Compare signatures
return hmac.compare_digest(expected_signature, received_signature)Timestamp Validation
Always verify the timestamp to prevent replay attacks:
javascript
const MAX_TIMESTAMP_AGE = 5 * 60; // 5 minutes
function isTimestampValid(timestamp) {
const now = Math.floor(Date.now() / 1000);
return Math.abs(now - timestamp) < MAX_TIMESTAMP_AGE;
}HTTPS Requirement
All webhook endpoints must use HTTPS. HTTP endpoints will be rejected.
Implementing a Webhook Endpoint
Best Practices
- Respond Quickly: Return 200 OK as fast as possible
- Process Asynchronously: Queue events for background processing
- Verify Signatures: Always validate webhook signatures
- Handle Duplicates: Events may be delivered multiple times
- Log Everything: Keep detailed logs for debugging
Example Implementation (Express.js)
javascript
const express = require('express');
const app = express();
app.post('/webhooks/pocketbook',
express.raw({ type: 'application/json' }),
async (req, res) => {
const signature = req.headers['x-pocketbook-signature'];
const payload = req.body;
// Verify signature
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Respond immediately
res.status(200).send('OK');
// Process event asynchronously
const event = JSON.parse(payload);
processWebhookEvent(event).catch(console.error);
}
);
async function processWebhookEvent(event) {
switch (event.type) {
case 'transaction.created':
await handleTransactionCreated(event.data.object);
break;
case 'payment.succeeded':
await handlePaymentSucceeded(event.data.object);
break;
// Handle other event types...
}
}Webhook Delivery
Retry Policy
If your endpoint returns a non-2xx response, Pocketbook will retry the webhook:
- Initial retry: After 1 minute
- Second retry: After 5 minutes
- Third retry: After 15 minutes
- Fourth retry: After 1 hour
- Final retry: After 6 hours
After 5 failed attempts, the webhook will be marked as failed.
Timeout
Webhook requests timeout after 30 seconds. Ensure your endpoint responds within this time.
Monitoring
Monitor webhook deliveries in your Pocketbook dashboard:
- View delivery status for each event
- See retry attempts and failures
- Access webhook logs and error messages
Testing Webhooks
Test Mode
Create test webhooks to receive events from test mode transactions:
bash
curl -X POST "https://api.pocketbook.studio/api/v1/webhooks" \
-H "Authorization: Bearer YOUR_TEST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-dev-app.com/webhooks",
"events": ["transaction.created"]
}'Local Testing
Use tools like ngrok to test webhooks locally:
bash
# Start ngrok tunnel
ngrok http 3000
# Use the ngrok URL as your webhook endpoint
https://abc123.ngrok.io/webhooks/pocketbookManual Trigger
Trigger test webhooks from the Pocketbook dashboard to verify your endpoint implementation.
Webhook Events Reference
For detailed information about each webhook event and its payload structure, see the Events Reference documentation.
Troubleshooting
Common Issues
Signature Verification Fails
- Ensure you're using the raw request body
- Check that your webhook secret is correct
- Verify timestamp is within acceptable range
Webhooks Not Received
- Verify endpoint is HTTPS
- Check firewall settings
- Ensure endpoint returns 200 OK quickly
Duplicate Events
- Implement idempotency using event IDs
- Check retry logic isn't triggering unnecessarily
For more help, see Error Handling or contact support.
