payout / developers
Guide

PISP payment status webhook

On this page

When you initiate a bank payment (PIS) for a Payout checkout, notify Payout of its final result by sending a signed JSON request. data.resource_id is the ID of the Payout checkout.

Send the status once the payment is final:

  • completed: the payment succeeded. Payout creates the payment and the checkout succeeds.
  • Any other value, such as failed, rejected or canceled: the payment failed. Payout marks the checkout as failed.

Important

Do not send intermediate states such as pending. Every status other than completed fails the checkout.

Endpoint

HTTP
POST https://{our-domain}/api/v1/integrations/pisp
Content-Type: application/json

{our-domain} is provided during onboarding, together with your client_id and the secret key for the signature.

Request body

Field Type Description
type string Always order_status
data.resource_id string ID of the Payout checkout
data.status string completed, or the reason the payment failed
data.nonce string Standard Base64 of at least 16 cryptographically random bytes, unique per request
data.client_id string The ID Payout assigned to you (your account ID)
signature string HMAC signature of the request, see Signature

The body is UTF-8 JSON. Base64 values use the standard alphabet, not the URL-safe one.

Signature

  1. Build the canonical string. Join resource_id, status, nonce and client_id with |, in this order and without spaces:

    TEXT
    resource_id|status|nonce|client_id
    
  2. Sign it. Compute HMAC-SHA256 of the canonical string with your secret key as the key.

  3. Encode it. Encode the raw HMAC bytes with standard Base64 and send the result as the top-level signature.

Important

The canonical string must use exactly the values in the body.

TEXT
payload_string = resource_id + "|" + status + "|" + nonce + "|" + client_id
raw_hmac       = HMAC_SHA256(key = secret_key, message = payload_string)
signature      = BASE64_ENCODE(raw_hmac)

Example

With the secret key example-pisp-api-key, the canonical string

TEXT
12345|completed|bC8w3o7M0y7o0t4cC8h3jg==|123

gives this request:

HTTP
POST /api/v1/integrations/pisp HTTP/1.1
Host: {our-domain}
Content-Type: application/json

{
  "type": "order_status",
  "data": {
    "resource_id": "12345",
    "status": "completed",
    "nonce": "bC8w3o7M0y7o0t4cC8h3jg==",
    "client_id": "123"
  },
  "signature": "gDw25w5+/1+5SAhZBXvqdfestQ6IJqz5bYwEwbDqeU4="
}

Responses

Case HTTP status Body
Status accepted 200 "ok"
signature missing 400 {"error": "missing_signature", "message": "Signature must be provided"}
Signature does not match, or unknown client_id 401 {"error": "invalid_signature", "message": "Signature verification failed"}
No checkout with this resource_id for your client_id 404 {"error": "not_found", "message": "Resource does not exist"}
Any other problem, for example the checkout already has a payment 422 {"error": "invalid_payload"}

Was this page helpful?