Transaction Processed Webhook¶
Overview¶
The Transaction Processed Webhook is triggered when a transaction reaches a terminal state, such as approved, declined, canceled, or expired.\ This webhook enables you to synchronize your system with the transaction outcome without polling.
When It Is Triggered¶
Finrelay will send the Transaction Processed Webhook when:
- A transaction is approved or declined by the PSP.
- A transaction is voided or expired.
- A transaction fails due to an error.
Only terminal transaction states trigger this webhook.
Supported Events¶
The Transaction Processed Webhook is triggered for the following events:
Event Value | Description |
---|---|
transaction-svc:transaction:authorized |
Transaction authorized (initial auth) |
transaction-svc:transaction:authorize:authorized |
Authorization transaction successful |
transaction-svc:transaction:purchase:approved |
Purchase transaction approved |
transaction-svc:transaction:authorize:declined |
Authorization declined |
transaction-svc:transaction:purchase:declined |
Purchase declined |
transaction-svc:transaction:authorize:pending |
Authorization pending |
transaction-svc:transaction:purchase:pending |
Purchase pending |
transaction-svc:transaction:pending |
General transaction pending |
transaction-svc:transaction:declined |
General transaction declined |
transaction-svc:transaction:management:declined |
Management operation declined |
transaction-svc:transaction:management:approved |
Management operation approved |
transaction-svc:transaction:management:refund:declined |
Refund operation declined |
transaction-svc:transaction:management:refund:approved |
Refund operation approved |
transaction-svc:transaction:management:void:declined |
Void operation declined |
transaction-svc:transaction:management:void:approved |
Void operation approved |
transaction-svc:transaction:management:capture:declined |
Capture operation declined |
transaction-svc:transaction:management:capture:approved |
Capture operation approved |
Request Details¶
Detail | Value |
---|---|
HTTP Method | POST |
Content-Type | application/json |
Authorization Header | Bearer <JWT> |
Retries | Yes, with exponential backoff |
Retry Window | 24 hours |
Signature Validation | JWT signed using Merchant Private Key |
Headers¶
Header | Description |
---|---|
Authorization |
Bearer token containing a signed JWT with SHA-512 digest validation |
Content-Type |
application/json |
Example:
POST /your/webhook/endpoint HTTP/1.1
Host: your-server.com
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json
Payload Schema¶
Here’s the JSON structure you can expect:
{
"event": "transaction-svc:transaction:authorized",
"payload": {
"id": "KlLQpgjqCmsmogHfNjuS",
"merchant_id": "eyCnTugDzIMADoQLTUJF",
"terminal_id": "eyCnTugDzIMADoQLTUJF",
"order_id": "auDCeVomqaFvBLxStpuO",
"payment_link_id": null,
"reference": "oONQfOdgIF",
"description": "kzCPRVsEbY",
"currency": "EUR",
"amount": 100,
"transaction_type": "AUTHORIZE",
"processing_code": "0000",
"response_message": "approved or completed successfully",
"status": "APPROVED",
"metadata": {
"response_code": "TRX_STATUS_APPROVED",
"simulated_flow": "VERSIONING_FINGERPRINT_N_FRICTIONLESS",
"additionalProp1": "string",
"additionalProp2": "string"
},
"created_at": "2025-04-28T12:42:26.976811Z",
"updated_at": "2025-04-28T12:42:27.144339Z",
"approval_code": "bfzLph",
"reference_number": "",
"parent_id": null,
"systan": null,
"integration_type": "UNRECOGNIZED",
"transaction_initiated_by": "CUSTOMER",
"authentication_level": null,
"payment_provider_response_code": "approved",
"payment_provider_response_message": "approved",
"normalized_amount": 100,
"customer_id": null,
"outgoing_amount": null,
"outgoing_currency": null,
"payment_method_method": "411111-******-1111",
"payment_method_hash": null,
"payment_method_type": "card",
"payment_method_brand": "VISA",
"payment_method_masked": "411111-******-1111",
"payment_method_token": null,
"customer_first_name": "Carey",
"customer_last_name": "Kuhn",
"customer_address": "877 Don Centers",
"customer_city": "Port Dalton",
"customer_country": "Singapore",
"customer_postal_code": "43000",
"customer_email": "barrett.rolfson@hotmail.com",
"customer_phone_number": "+1 985-502-6937 x8449",
"authentication_status": "AUTHENTICATED"
}
}
Field Descriptions¶
Field | Type | Description |
---|---|---|
event |
string |
One of transaction processed events |
payload.id |
string |
Unique transaction identifier |
payload.merchant_id |
string |
Merchant identifier |
payload.terminal_id |
string |
Terminal identifier |
payload.order_id |
string |
Order ID associated with transaction |
payload.payment_link_id |
string |
Payment Link ID (nullable) |
payload.reference |
string |
Merchant-provided reference |
payload.description |
string |
Transaction description |
payload.currency |
string |
Currency code (ISO 4217) |
payload.amount |
number (integer) |
Amount in minor units (e.g., cents) |
payload.transaction_type |
string |
Transaction type (e.g., "purchase", "refund") |
payload.processing_code |
string |
Processor-specific code |
payload.response_message |
string |
Human-readable response |
payload.status |
string |
Final transaction status (approved , declined , etc.) |
payload.metadata |
object |
Custom merchant metadata (optional) |
payload.created_at |
string (ISO-8601 datetime) |
When the transaction was created |
payload.updated_at |
string (ISO-8601 datetime) |
When the transaction was last updated |
JSON Schema¶
Here is the JSON Schema for validating the Transaction Processed Webhook payload (download and view):
transaction-processed-payload.json
Important Notes¶
- Always verify the JWT signature using the appropriate merchant public key.
- Always validate that the SHA-512 digest of the request body matches the value inside the JWT.
- Finrelay retries failed webhook deliveries with exponential backoff for up to 24 hours.
- Duplicate webhook deliveries are possible: ensure your webhook handlers are idempotent.