Webhooks
Receive real-time HTTP POST notifications when events occur in your account.
Event Types
payment.completedA payment has been successfully processed
payment.failedA payment attempt has failed
payment.refundedA payment has been fully or partially refunded
customer.createdA new customer record was created
customer.updatedCustomer information was updated
invoice.createdA new invoice was created
invoice.sentAn invoice was sent to the customer
invoice.paidAn invoice has been paid
invoice.overdueAn invoice is past its due date
subscription.createdA new subscription was started
subscription.renewedA subscription billing cycle renewed
subscription.cancelledA subscription was cancelled
subscription.past_dueA subscription payment failed
payout.completedA payout has funded to your bank (distinct from payment SETTLED)
dispute.createdA chargeback or dispute was opened
dispute.resolvedA dispute was resolved
tls.cipher_policy.changedAPT cipher suite policy changed — review your client posture
tls.protocol.deprecatedA TLS protocol version has entered its 12-month sunset window
certificate.rotatedEdge certificate or issuing CA rotated
mle.key.rotatedYour message-level encryption public key rotated
mle.policy.changedAn endpoint will require MLE — at least 12 months ahead of enforcement
Payload Structure
{
"id": "evt_1a2b3c4d",
"type": "payment.completed",
"created_at": "2026-03-14T12:00:00Z",
"data": {
"object": {
"id": "txn_abc123",
"amount": 9900,
"currency": "usd",
"status": "completed"
}
}
}Signature Verification
Each webhook includes an X-AptCommerce-Signature header. Verify it to ensure the request is authentic.
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Retry Policy
Failed deliveries are retried up to 5 times with exponential backoff: 1 min, 5 min, 30 min, 2 hours, 24 hours. After all retries fail, the endpoint is marked as failing.
Best Practices
- Always verify webhook signatures before processing.
- Return a
200response quickly. Process the event asynchronously. - Handle duplicate events idempotently using the event
id. - Use the webhook settings page to test deliveries.