Webhooks
Create and manage webhook endpoints.
Webhooks API
The Webhooks API allows you to create, manage, and test webhook endpoints that receive event notifications from Shika Creators.
The Webhook Endpoint Object
{
"id": "we_abc123def456",
"object": "webhook_endpoint",
"url": "https://yoursite.com/webhooks",
"description": "Production webhook",
"status": "enabled",
"events": [
"payment.succeeded",
"payment.failed",
"subscription.created"
],
"secret": "whsec_...",
"created_at": "2024-01-15T10:00:00Z"
}Attributes
| Attribute | Type | Description |
|---|---|---|
id | string | Unique identifier |
object | string | Always "webhook_endpoint" |
url | string | The endpoint URL |
description | string | Description |
status | string | enabled or disabled |
events | array | Events to subscribe to |
secret | string | Signing secret (only shown once) |
created_at | string | Creation timestamp |
Create a Webhook Endpoint
Creates a new webhook endpoint.
POST /v1/webhooksRequest Body
| Parameter | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Endpoint URL (must be HTTPS) |
events | array | Yes | Events to subscribe to |
description | string | No | Description |
curl -X POST https://api.13.220.123.118.nip.io/v1/webhooks \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://yoursite.com/webhooks",
"events": [
"payment.succeeded",
"payment.failed",
"subscription.created",
"subscription.canceled"
],
"description": "Production webhook"
}'const endpoint = await shikacreators.webhooks.endpoints.create({
url: 'https://yoursite.com/webhooks',
events: [
'payment.succeeded',
'payment.failed',
'subscription.created',
'subscription.canceled'
],
description: 'Production webhook'
})
// Save the secret! It's only shown once
console.log(endpoint.secret) // whsec_...endpoint = client.webhooks.endpoints.create(
url='https://yoursite.com/webhooks',
events=[
'payment.succeeded',
'payment.failed',
'subscription.created',
'subscription.canceled'
],
description='Production webhook'
)
# Save the secret! It's only shown once
print(endpoint.secret) # whsec_...$endpoint = $shikacreators->webhooks->endpoints->create([
'url' => 'https://yoursite.com/webhooks',
'events' => [
'payment.succeeded',
'payment.failed',
'subscription.created',
'subscription.canceled'
],
'description' => 'Production webhook'
]);
// Save the secret! It's only shown once
echo $endpoint->secret; // whsec_...Save the webhook secret immediately. It's only shown once when the endpoint is created.
Retrieve a Webhook Endpoint
Retrieves a webhook endpoint by ID.
GET /v1/webhooks/:idcurl https://api.13.220.123.118.nip.io/v1/webhooks/we_abc123def456 \
-H "Authorization: Bearer sk_test_..."const endpoint = await shikacreators.webhooks.endpoints.retrieve('we_abc123def456')endpoint = client.webhooks.endpoints.retrieve('we_abc123def456')Update a Webhook Endpoint
Updates a webhook endpoint.
PATCH /v1/webhooks/:idRequest Body
| Parameter | Type | Description |
|---|---|---|
url | string | Endpoint URL |
events | array | Events to subscribe to |
description | string | Description |
status | string | enabled or disabled |
curl -X PATCH https://api.13.220.123.118.nip.io/v1/webhooks/we_abc123def456 \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"events": ["payment.succeeded", "payment.failed"],
"status": "enabled"
}'const endpoint = await shikacreators.webhooks.endpoints.update('we_abc123def456', {
events: ['payment.succeeded', 'payment.failed'],
status: 'enabled'
})endpoint = client.webhooks.endpoints.update('we_abc123def456',
events=['payment.succeeded', 'payment.failed'],
status='enabled'
)Delete a Webhook Endpoint
Deletes a webhook endpoint.
DELETE /v1/webhooks/:idcurl -X DELETE https://api.13.220.123.118.nip.io/v1/webhooks/we_abc123def456 \
-H "Authorization: Bearer sk_test_..."await shikacreators.webhooks.endpoints.delete('we_abc123def456')client.webhooks.endpoints.delete('we_abc123def456')List Webhook Endpoints
Returns a list of webhook endpoints.
GET /v1/webhookscurl https://api.13.220.123.118.nip.io/v1/webhooks \
-H "Authorization: Bearer sk_test_..."const endpoints = await shikacreators.webhooks.endpoints.list()endpoints = client.webhooks.endpoints.list()Available Events
Payment Events
| Event | Description |
|---|---|
payment.created | A payment was created |
payment.pending | Payment is pending authorization |
payment.processing | Payment is being processed |
payment.succeeded | Payment completed successfully |
payment.failed | Payment failed |
payment.canceled | Payment was canceled |
Subscription Events
| Event | Description |
|---|---|
subscription.created | Subscription was created |
subscription.updated | Subscription was updated |
subscription.canceled | Subscription was canceled |
subscription.paused | Subscription was paused |
subscription.resumed | Subscription was resumed |
subscription.trial_will_end | Trial ending in 3 days |
subscription.payment_succeeded | Recurring payment succeeded |
subscription.payment_failed | Recurring payment failed |
Payout Events
| Event | Description |
|---|---|
payout.created | Payout was created |
payout.processing | Payout is being processed |
payout.completed | Payout was successful |
payout.failed | Payout failed |
payout.canceled | Payout was canceled |
Refund Events
| Event | Description |
|---|---|
refund.created | Refund was created |
refund.completed | Refund was successful |
refund.failed | Refund failed |
Checkout Events
| Event | Description |
|---|---|
checkout.session.completed | Checkout session completed |
checkout.session.expired | Checkout session expired |
Webhook Event Object
{
"id": "evt_abc123def456",
"object": "event",
"type": "payment.succeeded",
"created_at": "2024-01-15T10:30:00Z",
"data": {
"object": {
"id": "pay_xyz789",
"object": "payment",
"amount": 5000,
"currency": "GHS",
"status": "succeeded",
...
}
}
}Verifying Signatures
Always verify webhook signatures to ensure requests came from Shika Creators:
import { Webhook } from '@shikacreators/node'
const endpointSecret = 'whsec_...'
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-shikacreators-signature']
try {
const event = Webhook.constructEvent(
req.body,
signature,
endpointSecret
)
// Handle the event
console.log(`Received: ${event.type}`)
res.json({ received: true })
} catch (err) {
console.error('Signature verification failed:', err.message)
res.status(400).send('Invalid signature')
}
})import shikacreators
endpoint_secret = 'whsec_...'
@app.route('/webhooks', methods=['POST'])
def webhook():
payload = request.data
signature = request.headers.get('X-Shika Creators-Signature')
try:
event = shikacreators.Webhook.construct_event(
payload, signature, endpoint_secret
)
except shikacreators.SignatureVerificationError as e:
return 'Invalid signature', 400
print(f'Received: {event["type"]}')
return {'received': True}$endpointSecret = 'whsec_...';
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_PAYGATE_SIGNATURE'];
try {
$event = \Shika Creators\Webhook::constructEvent(
$payload,
$signature,
$endpointSecret
);
} catch (\Exception $e) {
http_response_code(400);
exit('Invalid signature');
}
echo "Received: " . $event->type;
http_response_code(200);Never skip signature verification in production. Unsigned webhooks could be spoofed.