Settings
Webhook URL settingsThe target URL to which HTTP POST requests will be sent needs to be provided to your integration manager, and confirmation should be received that it has been added to the partner settings on Paybis end.
Available webhooks
Crypto Payouts
Webhook on the successfully executed event, after the crypto transaction is submitted to the blockchain.
Request
| Parameter | Type | Description |
|---|---|---|
event_id | REQUIRED uuid | Event id. |
transaction_id | REQUIRED uuid | Transaction id. Paybis will return value from payment.transaction.id from the corresponding Event. |
digital_amount_sent | REQUIRED object | |
digital_amount_sent.currency | REQUIRED string | Cryptocurrency is sent to the crypto address. |
digital_amount_sent.amount | REQUIRED string | Crypto amount sent to the crypto address. |
blockchain_txn_hash | OPTIONAL string | The blockchain transaction hash. |
fees | REQUIRED object | Breakdown of the fees applied to the transaction. Initial fees are based on the quote; final fees are taken from the executed transaction (the transaction is the source of truth), so values may be updated in subsequent webhooks. |
fees.currency | REQUIRED string | Currency in which all fee amounts are expressed (e.g. EUR). |
fees.network_fee | REQUIRED string | Blockchain network fee. |
fees.service_fee | REQUIRED string | Paybis service fee. |
fees.partner_fee | REQUIRED string | Partner fee (your markup). |
fees.total_fee | REQUIRED string | Sum of all fees: network_fee + service_fee + partner_fee. |
{
"event_id": "0000079f-6981-4cd7-bf7b-88c5699eebb5",
"transaction_id": "26e312b9-2206-1005-227e-f95808946cd3",
"digital_amount_sent": {
"currency": "BTC",
"amount": "0.699999"
},
"blockchain_txn_hash": "492e43fa04ec86d7d4bc7deb38e4956312e78eb68d97824e73660a52283344ab",
"fees": {
"currency": "EUR",
"network_fee": "0.00",
"service_fee": "2.07",
"partner_fee": "1.05",
"total_fee": "3.12"
}
}{
"event_id": "4e882fc8-07d1-4759-bbc5-4c0d8029109d",
"event_type": "TransactionCryptoPayoutError",
"transaction_id": "785bae8a-759d-4eb3-b1c1-307f221018f1",
"invoice": "PBQA240628300573TX2",
"status": "Rejected",
"amount_sent": {
"amount": "1000",
"currency": "BTC-TESTNET"
},
"reason": "some reason test 28.06",
"timestamp": 1719293227
}Failed transaction
Webhook is sent for the transaction that were created in the Paybis system but failed during processing.
Funds for these transactions will not be deducted from the prefunded balance.
Request
| Parameter | Type | Description |
|---|---|---|
event_id | REQUIRED uuid | Event id. |
transaction_id | REQUIRED uuid | Transaction id. Paybis will return value from payment.transaction.id from the corresponding Event. |
event_type | REQUIRED string | For failed transactions, the value will always be TransactionRejected. |
invoice | REQUIRED string | The ID of the transaction in both the Paybissystem and the Partner Portal.. |
{
"event_id": "8194cf8b-4d45-4086-b3e5-53b22269db75",
"event_type": "TransactionRejected",
"transaction_id": "596decb6-43e5-41c6-87f0-22d91771e11f",
"invoice": "PBQA250711396021TX13"
}Crypto Payins
Transaction Status Lifecycle
Every Pay-in transaction moves through a defined set of statuses.
| Status | Description |
|---|---|
in_progress | The transaction has been successfully created and an internal ID assigned. |
waiting_for_funds | The unique deposit address is active, and the system is monitoring the blockchain for the user's deposit. |
deposit_confirmed | A valid blockchain transaction has been detected and has reached the required number of confirmations. The exchange rate is locked. |
completed | The crypto has been successfully sold, and the fiat equivalent has been credited to your prefunded balance. |
failed | The transaction was rejected (e.g., AML risk, slippage error) or timed out. Funds are not credited. |
Request
| Parameter | Type | Description |
|---|---|---|
event_id | REQUIRED uuid | Unique event identifier provided during creation. |
id | REQUIRED string | Paybis internal transaction ID. |
event_type | REQUIRED string | The type of event. Always PayIn for deposit events. |
status | REQUIRED string | Current status of the transaction (e.g., deposit_confirmed, completed). |
blockchain_address | REQUIRED string | The specific crypto deposit address generated for this transaction. |
crypto | REQUIRED object | Object containing the amount and currency of the cryptocurrency received. |
fiat | REQUIRED object | Object containing the amount and currency of the fiat credited to the ledger. |
rate | REQUIRED string | The exchange rate applied to the conversion. |
fees | REQUIRED object | Breakdown of the fees applied to the transaction, expressed in fiat. Initial values are based on the quote; final values are set once the transaction is executed (the transaction is the source of truth). Final fee values are delivered with the completed status. |
fees.currency | REQUIRED string | Currency in which all fee amounts are expressed (e.g. EUR). |
fees.network_fee | REQUIRED string | Blockchain network fee. |
fees.service_fee | REQUIRED string | Paybis service fee. |
fees.partner_fee | REQUIRED string | Partner fee (your markup). |
fees.total_fee | REQUIRED string | Sum of all fees: network_fee + service_fee + partner_fee. |
Payload
{
"timestamp": 1720609400,
"event_type": "PayIn",
"event_id": "2c3ae520-97b5-4e2c-995e-48f9b59f9f95",
"id": "tx-88392010",
"status": "deposit_confirmed",
"blockchain_address": "bc1q6v5tpkkpqu5r6gwvpa9xh3atnpyvw2cs9talpp",
"rate": "82408.12",
"crypto": {
"amount": "0.02154870",
"currency": "BTC"
},
"fiat": {
"amount": "1344.82",
"currency": "EUR"
},
"fees": {
"currency": "EUR",
"network_fee": "0.00",
"service_fee": "2.07",
"partner_fee": "1.05",
"total_fee": "3.12"
}
}{
"timestamp": 1720609100,
"event_type": "PayIn",
"event_id": "1f2ae520-97b5-4e2c-995e-48f9b59f9f95",
"id": "tx-88392010",
"status": "waiting_for_funds",
"blockchain_address": "bc1q6v5tpkkpqu5r6gwvpa9xh3atnpyvw2cs9talpp",
"rate": "82408.12",
"crypto": {
"amount": "0.02154870",
"currency": "BTC"
},
"fiat": {
"amount": "1344.82",
"currency": "EUR"
},
"fees": {
"currency": "EUR",
"network_fee": "0.00",
"service_fee": "2.07",
"partner_fee": "1.05",
"total_fee": "3.12"
}
}{
"timestamp": 1720609800,
"event_type": "PayIn",
"event_id": "3d4ae520-97b5-4e2c-995e-48f9b59f9f95",
"id": "tx-88392010",
"status": "completed",
"blockchain_address": "bc1q6v5tpkkpqu5r6gwvpa9xh3atnpyvw2cs9talpp",
"rate": "82408.12",
"crypto": {
"amount": "0.02154870",
"currency": "BTC"
},
"fiat": {
"amount": "1344.82",
"currency": "EUR"
},
"fees": {
"currency": "EUR",
"network_fee": "0.00",
"service_fee": "2.07",
"partner_fee": "1.05",
"total_fee": "3.12"
}
}
Note
- The deposit address is generated asynchronously, so blockchain_address may not yet be available in the in_progress webhook.
- The completed webhook carries the final fee values. Use these amounts for reconciliation.
Fiat Payouts
Webhook on the successfully executed event, after the fiat transaction has been sent to the beneficiary bank account.
Transaction Status Lifecycle
Every Fiat Payout transaction moves through a defined set of statuses.
| Status | Description |
|---|---|
in_progress | The payout has been created. The OpenPayd API has been called, the partner webhook has been sent, and the database has been updated. |
in_transit | Funds have been transferred and are currently in the OpenPayd system. The partner webhook has been sent and the database has been updated. |
completed | The beneficiary has received the funds. The partner webhook has been sent, the database has been updated, and the transaction is closed. |
failed | The transaction was rejected or could not be processed. Funds are not deducted from the prefunded balance. |
Successful Transaction
Webhook is sent when the fiat payout has been successfully delivered to the beneficiary bank account.
Request
| Parameter | Type | Description |
|---|---|---|
event_type | REQUIRED string | For successful fiat payouts, the value will always be payout.completed. |
transaction_id | REQUIRED uuid | Transaction id. Paybis will return value from payment.transaction.id from the corresponding Event. |
status | REQUIRED string | Current status of the transaction. For this webhook, the value will always be completed. |
payout_amount | REQUIRED string | The fiat amount sent to the beneficiary bank account. |
commission_amount | REQUIRED string | Commission amount deducted from the prefunded balance. |
total_deduction | REQUIRED string | Total amount deducted from the prefunded balance. Equals payout_amount + commission_amount. |
beneficiary | REQUIRED object | Object containing details of the payment recipient. |
beneficiary.iban | REQUIRED string | The IBAN of the beneficiary bank account to which funds were sent. |
beneficiary.name | REQUIRED string | The name of the beneficiary as provided in the payout request. |
timestamp | REQUIRED string | ISO 8601 timestamp of the event (e.g., 2026-03-27T10:25:00Z). |
// Successful Transaction
{
"event_type": "payout.completed",
"transaction_id": "txn-fiat-123456",
"status": "completed",
"payout_amount": "100.00",
"commission_amount": "2.50",
"total_deduction": "102.50",
"beneficiary": {
"iban": "DE89370400440532013000",
"name": "John Doe"
},
"timestamp": "2026-03-27T10:25:00Z"
}Failed Transaction
Webhook is sent for transactions that were created in the Paybis system but failed during processing.
Funds for these transactions will not be deducted from the prefunded balance.
Request
| Parameter | Type | Description |
|---|---|---|
event_type | REQUIRED string | For failed fiat payouts, the value will always be payout.failed. |
transaction_id | REQUIRED uuid | Transaction id. Paybis will return value from payment.transaction.id from the corresponding Event. |
status | REQUIRED string | For failed transactions, the value will always be failed. |
failure_reason | REQUIRED string | Machine-readable failure code (e.g., INVALID_IBAN, INSUFFICIENT_FUNDS). |
failure_message | OPTIONAL string | Human-readable description of the failure reason, if available. |
timestamp | REQUIRED string | ISO 8601 timestamp of the event (e.g., 2026-03-27T10:05:00Z). |
// Failed Transaction
{
"event_type": "payout.failed",
"transaction_id": "txn-fiat-123456",
"status": "failed",
"failure_reason": "INVALID_IBAN",
"failure_message": "Bank validation failed: Invalid IBAN checksum",
"timestamp": "2026-03-27T10:05:00Z"
}Prefunded balance top-up
This webhook notifies the partner when a prefunded balance has been successfully credited to their account. It provides transaction details, sender information, and updated balance state to help partners reconcile funding events in near real time.
Payload Parameters
| Parameter | Type | Description |
|---|---|---|
event_type | REQUIRED string | Type of the event. Always "PrefundedBalanceToppedUp" for successful top-ups. |
amount | string | Total amount credited to IBAN. |
fees | string | Transaction fee debited from partner's account. |
net_amount | string | Amount credited to the prefunded balance. |
currency | string | Currency of the credited amount (e.g., EUR). |
transaction_type | string | "credit" for top-up transactions. |
balance_before | string | Balance before the top-up. |
balance_after | string | Balance after the top-up. |
sender_name | string | Name of the sender initiating the transfer (available for auto top-up only). |
sender_iban | string | Sender’s IBAN (available for auto top-up only). |
payment_reference | string | Reference message provided with the payment. |
{
"event": "PrefundedBalanceToppedUp",
"time": "2025-07-21T08:35:59+00:00",
"amount":"100.00",
"fees":"2.50",
"net_amount":"97.50",
"currency": "EUR",
"transaction_type": "credit",
"balance_before": "100.00",
"balance_after": "197.50",
"sender_name": "Acme Inc",
"sender_iban": "GR22SEOU19870010111222",
"payment_reference": "Payment for inv. 123 as of 12.06.2025"
}{
"event": "PrefundedBalanceToppedUp",
"time": "2025-07-21T08:35:59+00:00",
"amount":"100.00",
"fees":"2.50",
"net_amount":"97.50",
"currency": "EUR",
"transaction_type": "credit",
"balance_before": "100.00",
"balance_after": "197.50",
"payment_reference": "Payment for inv. 123 as of 12.06.2025"
}Security
For your safety we sign each webhook message with the NIST P-256 (secp256r1) key using the SHA256withECDSA (ECDSA with SHA-256) asymmetric signing algo. The signature is encoded to base64 and sent with the original request in the `
Important When verifying the signature, use the raw request body as the message, without any modifications or transformations. Treat the request body as a plain string of characters.
Use our public key to verify incoming POST calls.
Production public key:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEi+Op2heNAuGVOFjRiv9jB2eNva6p
vqCHARX5a0JGXDcZvrdX8KGfa/4uceMiJ0pTTVzMRFVSduIxKEisFz4D0w==
-----END PUBLIC KEY-----Sandbox environment public key:
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYQi7GQ67Zb5EyWExUP5swcruMw3N
m+cKdzxHJE6Qeht8ze/ADfWdMy49Tee3ctWQRkf/+6Q358iFhxo8qpNKGg==
-----END PUBLIC KEY-----Response
A successful HTTP response is expected (2xx code).