Skip to content
This is a new version of the Kivra Developer Docs. Report issues or share feedback at avsandare.support@kivra.se. The previous version can be found here.

Payment webhooks

Tenant API payment webhooks notify your service when payments are settled, scheduled, failed, or when an eligible invoice is declined. Configure one or more webhook definitions with the API, then verify and process each delivery at your endpoint.

Create a definition with POST /v2/webhooks/payments. A definition contains an HTTPS destination URL and filters for the invoices and payment events you want to receive:

{
"url": "https://example.com/kivra/webhooks",
"cid_filter": "client-key",
"tkey_filter": "tenant-key",
"types": [
"bank",
"autogiro"
],
"events": [
"scheduled",
"settled",
"failed"
]
}

You can create multiple definitions, but duplicate definitions result in duplicate deliveries. The cid_filter identifies the OAuth client that sent the invoice and the tkey_filter identifies the sender tenant. The client may be acting as a partner for that tenant. The cid_filter must be a specific client key in this API; a wildcard requires arrangement with Kivra. tkey_filter can use * to match all applicable tenants, but both filters cannot be wildcards at the same time.

Use types to filter instant, bank, or autogiro payments. Use events to filter scheduled, settled, failed, or declined events. The available combinations are:

Payment type Events
instant settled, failed
bank settled, scheduled, failed
autogiro settled, scheduled, failed
Invoice declined

The invoice_declined event applies only to invoice.renewal and invoice.donation content. Regular invoice content cannot be declined in Kivra.

List definitions with GET /v2/webhooks/payments, update one with PATCH /v2/webhooks/payments/{id}, or remove one with DELETE /v2/webhooks/payments/{id}. The destination URL must use HTTPS and must not resolve to a reserved domain or reserved IPv4 range.

Call POST /v2/webhooks/payments/{id}/test to schedule a test delivery. The test has the same payload shape and signature format as a real delivery, but its data is static and should not be treated as a real payment.

Your endpoint must respond with a 2xx status within one second of the connection being established. A successful webhook delivery is acknowledged with 200 OK.

Kivra Payments follows Standard Webhooks. Every delivery includes these headers:

Header Description
webhook-id Unique identifier for the delivery
webhook-timestamp Unix timestamp when the delivery was sent
webhook-signature One or more signatures used to verify the payload

The signature header contains signatures such as v1,<signature1> v1a,<signature2>. Build the signed message by joining the delivery ID, timestamp, and raw request body with periods:

webhook-id.webhook-timestamp.raw-request-body

Use the shared secret and HMAC-SHA256 to verify the signature. Always verify the unmodified request body and reject requests with an unacceptable timestamp. Standard Webhooks provides verification libraries for several languages.

The JSON payload contains id, timestamp, type, and data. The type is one of:

Type Data
payment_callback Payment details, including content_key, payment_type, payment_event, event_time, amount, and currency
invoice_declined Declined invoice details, including content_key, due_date, remittance_type, remittance_string, event_time, and content_type
payment_callback_retry Deprecated retry type; use the original event type and identify the delivery as a retry

Optional payment data includes due and payment dates, destination account details, remittance information, payment option details, and Swish references. Payment amounts are strings, and payment times use ISO 8601 date-time values.

Kivra retries a delivery when your endpoint returns a non-200 response. The schedule is:

Attempt Delay Time since start
1 Immediately 00:00:00
2 5 seconds 00:00:05
3 5 minutes 00:05:05
4 30 minutes 00:35:05
5 2 hours 02:35:05
6 5 hours 07:35:05
7 10 hours 17:35:05
8 14 hours 31:35:05
9 20 hours 51:35:05
10 24 hours 75:35:05

After the tenth unsuccessful attempt, Kivra cancels the delivery. Store the webhook ID and make processing idempotent so retries do not apply the same payment event twice.

See the Tenant API reference for the complete request, response, and schema definitions.