Webhook Configuration
Learn how to configure webhooks for your OrcaRail API keys to receive real-time payment notifications.
Overview
Webhooks in OrcaRail are configured at the API key level. Each API key can have its own webhook URL, allowing you to:
- Send different events to different endpoints
- Use separate webhooks for different environments (development, staging, production)
- Test webhooks independently for each API key
Setting Up Webhooks
Step 1: Create or Update an API Key
Webhooks are configured when creating or updating an API key. You can set a webhookUrl parameter:
Creating an API Key with Webhook URL
POST /api/v1/organizations/:organizationId/api-keys
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json
Replace :organizationId with the organization you want to manage. You can find it in Dashboard → Organization Settings, or by calling your organizations list endpoint and copying the id of the organization you want to use. The bearer token must belong to a user/session that can manage that same organization.
Request Body:
{
"name": "Production API Key",
"webhookUrl": "https://api.example.com/webhooks/orcarail"
}
Response:
{
"apiKey": {
"id": 1,
"name": "Production API Key",
"keyPrefix": "ak_live_",
"status": "active",
"webhookUrl": "https://api.example.com/webhooks/orcarail",
"createdAt": "2024-01-01T00:00:00.000Z"
},
"key": "ak_live_abc123def456",
"secret": "sk_live_xyz789uvw012"
}
Updating an API Key's Webhook URL
You can update the webhook URL for an existing API key:
PATCH /api/v1/api-keys/:id
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json
Request Body:
{
"webhookUrl": "https://api.example.com/webhooks/orcarail"
}
Response:
{
"id": 1,
"name": "Production API Key",
"keyPrefix": "ak_live_",
"status": "active",
"webhookUrl": "https://api.example.com/webhooks/orcarail",
"updatedAt": "2024-01-01T12:00:00.000Z"
}
Step 2: Webhook URL Requirements
Your webhook URL must meet these requirements:
- HTTPS - Required in production (HTTP allowed for local development)
- Publicly accessible - OrcaRail must be able to reach it from the internet
- Valid HTTP endpoint - Must accept POST requests
- Fast response - Should return
200 OKwithin 10 seconds (timeout is 10 seconds)
Step 3: Remove Webhook URL
To stop receiving webhooks for an API key, set webhookUrl to null:
PATCH /api/v1/api-keys/:id
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json
Request Body:
{
"webhookUrl": null
}
Code Examples
JavaScript/TypeScript
// Create API key with webhook URL
const response = await fetch(
'https://api.orcarail.com/api/v1/organizations/org_123/api-keys',
{
method: 'POST',
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Production API Key',
webhookUrl: 'https://api.example.com/webhooks/orcarail',
}),
}
)
const { apiKey, key, secret } = await response.json()
console.log('API Key created:', key)
console.log('Webhook URL:', apiKey.webhookUrl)
// Update webhook URL
const updateResponse = await fetch(
`https://api.orcarail.com/api/v1/api-keys/${apiKey.id}`,
{
method: 'PATCH',
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
webhookUrl: 'https://api.example.com/webhooks/orcarail-v2',
}),
}
)
Python
import requests
# Create API key with webhook URL
response = requests.post(
'https://api.orcarail.com/api/v1/organizations/org_123/api-keys',
headers={
'Authorization': f'Bearer {jwt_token}',
'Content-Type': 'application/json',
},
json={
'name': 'Production API Key',
'webhookUrl': 'https://api.example.com/webhooks/orcarail',
},
)
data = response.json()
api_key = data['apiKey']
print(f"API Key created: {data['key']}")
print(f"Webhook URL: {api_key['webhookUrl']}")
# Update webhook URL
update_response = requests.patch(
f"https://api.orcarail.com/api/v1/api-keys/{api_key['id']}",
headers={
'Authorization': f'Bearer {jwt_token}',
'Content-Type': 'application/json',
},
json={
'webhookUrl': 'https://api.example.com/webhooks/orcarail-v2',
},
)
cURL
# Create API key with webhook URL
curl -X POST https://api.orcarail.com/api/v1/organizations/org_123/api-keys \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Production API Key",
"webhookUrl": "https://api.example.com/webhooks/orcarail"
}'
# Update webhook URL
curl -X PATCH https://api.orcarail.com/api/v1/api-keys/1 \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"webhookUrl": "https://api.example.com/webhooks/orcarail-v2"
}'
Testing Your Webhook Configuration
Using the Test Webhook Endpoint
OrcaRail provides endpoints to test your webhook configuration:
Send Test Webhook
Sends a test payment_intent.completed event to your configured webhook URL:
POST /api/v1/webhooks/test/:apiKeyId
Authorization: Bearer YOUR_JWT_TOKEN
Response:
{
"success": true
}
Example:
const response = await fetch(
'https://api.orcarail.com/api/v1/webhooks/test/1',
{
method: 'POST',
headers: {
Authorization: `Bearer ${jwtToken}`,
},
}
)
const result = await response.json()
console.log('Test webhook sent:', result.success)
Send Custom Webhook
Send a custom payload to test your webhook handler:
POST /api/v1/webhooks/test/:apiKeyId/custom
Authorization: Bearer YOUR_JWT_TOKEN
Content-Type: application/json
Request Body:
{
"payload": {
"type": "payment_intent.completed",
"data": {
"object": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"amount": "100.00",
"currency": "usd",
"status": "succeeded"
}
}
}
}
Response:
{
"success": true
}
Viewing Webhook Logs
Check the delivery status of your webhooks:
GET /api/v1/webhooks/logs?limit=50&offset=0
Authorization: Bearer YOUR_JWT_TOKEN
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | number | 50 | Number of logs to return |
offset | number | 0 | Number of logs to skip |
Response:
{
"logs": [
{
"id": 1,
"apiKeyId": 1,
"event": "payment_intent.completed",
"url": "https://api.example.com/webhooks/orcarail",
"statusCode": 200,
"success": true,
"attemptNumber": 1,
"createdAt": "2024-01-01T00:00:00.000Z"
}
],
"total": 1
}
Example:
const response = await fetch(
'https://api.orcarail.com/api/v1/webhooks/logs?limit=10&offset=0',
{
headers: {
Authorization: `Bearer ${jwtToken}`,
},
}
)
const { logs, total } = await response.json()
console.log(`Found ${total} webhook logs`)
logs.forEach((log) => {
console.log(`${log.event}: ${log.success ? 'Success' : 'Failed'}`)
})
Best Practices
1. Use Different Webhooks for Different Environments
Create separate API keys with different webhook URLs for each environment:
// Development
{
name: "Development API Key",
webhookUrl: "https://dev.example.com/webhooks/orcarail"
}
// Staging
{
name: "Staging API Key",
webhookUrl: "https://staging.example.com/webhooks/orcarail"
}
// Production
{
name: "Production API Key",
webhookUrl: "https://api.example.com/webhooks/orcarail"
}
2. Test Before Production
Always test your webhook endpoint before using it in production:
- Use the test webhook endpoint to verify your handler works
- Check webhook logs to ensure successful delivery
- Verify signature validation is working correctly
3. Monitor Webhook Delivery
Regularly check webhook logs to ensure:
- Webhooks are being delivered successfully
- Response times are acceptable
- No errors are occurring
4. Handle Webhook Failures
OrcaRail will retry failed webhooks automatically:
- Maximum attempts: 3 attempts (1 initial + 2 retries)
- Backoff strategy: Exponential backoff starting at 2 seconds
- Timeout: 10 seconds per request
Ensure your webhook endpoint can handle retries gracefully (make handlers idempotent).
5. Use ngrok for Local Development
For local development, use ngrok to expose your local server:
# Install ngrok
npm install -g ngrok
# Expose local server
ngrok http 3000
Then configure your webhook URL to the ngrok URL:
https://abc123.ngrok.io/webhooks/orcarail
Troubleshooting
Webhook Not Receiving Events
- Check API Key Status - Ensure your API key is active
- Verify Webhook URL - Confirm the URL is correctly configured
- Check Webhook Logs - Review logs for delivery errors
- Test Webhook - Use the test endpoint to verify connectivity
Webhook Returns 404
- Verify your webhook endpoint exists and accepts POST requests
- Check that the URL path is correct
- Ensure your server is running and accessible
Webhook Returns 500
- Check your server logs for errors
- Verify your webhook handler doesn't throw exceptions
- Ensure you're returning
200 OKeven if processing fails
Signature Verification Fails
- Verify you're using the correct secret (from the API key)
- Ensure you're computing the signature correctly
- Check that you're using the raw request body (not parsed JSON)
Next Steps
- Webhook Overview - Learn webhook basics
- Webhook Events - Understand available events
- Webhook Signatures - Secure your webhooks
- API Keys Guide - Manage your API keys