Skip to main content

Webhooks

TropiPay webhooks allow you to receive real-time notifications about events that occur in your account. This is especially useful for keeping your systems synchronized with TropiPay events, such as received payments, completed transactions, card status changes, and more.

What are webhooks?

Webhooks are HTTP callbacks that are sent to a specific URL when certain events occur in your TropiPay account. Instead of having to constantly poll the API to check if something has changed, webhooks automatically notify you when something relevant happens.

Benefits of using webhooks

  • Real-time: Receive immediate notifications when events occur
  • Efficiency: Reduces the need for periodic API polling
  • Automation: Enables automated workflows based on TropiPay events
  • Synchronization: Keep your systems updated with the latest data

The Webhook Event Object

All webhook notifications have the following basic structure:

{
"event": "payment.completed",
"data": {
"id": "pay_123456789",
"amount": 10000,
"currency": "EUR",
"status": "completed",
"created_at": "2023-07-22T12:30:00.000Z",
"completed_at": "2023-07-22T12:34:56.789Z",
"metadata": {
"order_id": "order_987654321"
}
},
"timestamp": "2023-07-22T12:34:56.789Z"
}

Attributes

AttributeTypeDescription
eventstringName of the event that triggered the webhook
dataobjectEvent-specific data payload
timestampstringISO 8601 timestamp when the event occurred

Event Types

Payment Events

EventDescription
payment.createdA new payment has been created
payment.completedA payment has been completed successfully
payment.failedA payment has failed
payment.refundedA payment has been refunded

Card Events

EventDescription
card.createdA new card has been created
card.activatedA card has been activated
card.blockedA card has been blocked
card.transactionA transaction has been made with a card

Account Events

EventDescription
account.updatedAccount data has been updated
account.verifiedThe account has been verified
account.loginA login has occurred on the account

Merchant Hooks

Merchant hooks are webhooks that are managed at the merchant/business level. These endpoints allow you to manage webhook subscriptions for your merchant account.

List Merchant Hooks

Returns a list of all events that the merchant is subscribed to via webhooks.

GET/merchant/hooks
curl -X GET https://sandbox.tropipay.me/api/v3/merchant/hooks \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json"

Response

[
{
"event": "user_signup",
"target": "email",
"value": "user@example.com",
"createdAt": "2021-02-13T21:30:59.154Z",
"updatedAt": "2021-02-13T21:30:59.154Z"
},
{
"event": "payment_created",
"target": "web",
"value": "https://example.com/webhooks/payment-created",
"createdAt": "2021-02-13T21:30:59.154Z",
"updatedAt": "2021-02-13T21:30:59.154Z"
}
]

Response Parameters

ParameterTypeDescription
eventstringName of the subscribed event
targetstringType of webhook target (web, email)
valuestringTarget value (URL for web, email address for email)
createdAtstringISO 8601 timestamp when subscription was created
updatedAtstringISO 8601 timestamp when subscription was last updated

Subscribe to Merchant Event

Allows a merchant to subscribe to an event, specifying the options to receive information at the time it is triggered.

POST/merchant/hooks
curl -X POST https://sandbox.tropipay.me/api/v3/merchant/hooks \
-H "Authorization: Bearer {merchant-token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"event": "user_signup",
"target": "web",
"value": "https://www.merchant_domain.com/api/user/signup/listen"
}'

Parameters

ParameterTypeRequiredDescription
eventstringYesString that represents the name of the event. You must select from the list of available events, otherwise it will not produce an error but will not be executed. For the full list of available events see endpoint GET /hook/events.
targetstringYesString representing the type of event supported. Currently available: web (allows to receive information in a URL), email (allows to receive information in an email address).
valuestringYesString that represents the value depending on the type of selected event determined by the 'target' property. For example, if the selected 'target' is email the value would be an email address, likewise if the selected 'target' is web the expected value corresponds to a URL that receives information through the HTTP POST method.

Response

Status Code: 200 OK

{
"action": "update",
"status": "success",
"details": "user_signup"
}

Response Parameters

ParameterTypeDescription
actionstringThe action performed (e.g., "update")
statusstringStatus of the operation ("success" or "error")
detailsstringAdditional details about the operation, typically the event name

Update Merchant Hook Subscription

Allows a merchant to update an event subscription, specifying the options to receive information at the time it is triggered. Take into account that the value of the name or denomination of the event cannot be modified. In case it is required to change this field, it is recommended to delete it and create a new subscription.

PUT/merchant/hooks
curl -X PUT https://sandbox.tropipay.me/api/v3/merchant/hooks \
-H "Authorization: Bearer {merchant-token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"event": "user_signup",
"target": "email",
"value": "merchant@example.com"
}'

Parameters

ParameterTypeRequiredDescription
eventstringYesString that represents the name of the event. This field cannot be modified - if you need to change the event, delete the subscription and create a new one.
targetstringYesString representing the type of event supported. Currently available: web (allows to receive information in a URL), email (allows to receive information in an email address).
valuestringYesString that represents the value depending on the type of selected event determined by the 'target' property. For example, if the selected 'target' is email the value would be an email address, likewise if the selected 'target' is web the expected value corresponds to a URL.

Response

Status Code: 200 OK

{
"action": "update",
"status": "success",
"details": "user_signup"
}

Response Parameters

ParameterTypeDescription
actionstringThe action performed ("update")
statusstringStatus of the operation ("success" or "error")
detailsstringAdditional details about the operation, typically the event name

Delete Merchant Hook Subscription

Allows a merchant to unsubscribe from an event by name or denomination.

DELETE/merchant/hooks
curl -X DELETE https://sandbox.tropipay.me/api/v3/merchant/hooks \
-H "Authorization: Bearer {merchant-token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"event": "user_signup"
}'

Parameters

ParameterTypeRequiredDescription
eventstringYesString that represents the name of the event to unsubscribe from

Response

Status Code: 200 OK

{
"action": "update",
"status": "success",
"details": "user_signup"
}

Response Parameters

ParameterTypeDescription
actionstringThe action performed ("update")
statusstringStatus of the operation ("success" or "error")
detailsstringAdditional details about the operation, typically the event name

Get Available Events for Merchant

Endpoint for getting the full list of available events that allow subscription for merchant hooks.

GET/merchant/hooks/events
curl -X GET https://sandbox.tropipay.me/api/v3/merchant/hooks/events \
-H "Authorization: Bearer {merchant-token}" \
-H "Accept: application/json"

Response

Status Code: 200 OK

[
{
"name": "user_signup",
"description": "Event launched once a user completes registration on the TropiPay platform."
},
{
"name": "user_login",
"description": "Event launched once a user completes login on the TropiPay platform."
},
{
"name": "user_kyc",
"description": "Event launched once a user completes KYC process, indicated in each case the process status."
},
{
"name": "payment_in_state_change",
"description": "The event is fired once a user changes their status payment in entry method."
},
{
"name": "payment_out_state_change",
"description": "The event is fired once a user changes their status payment out entry method."
}
]

Response Parameters

ParameterTypeDescription
namestringThe name of the event that can be subscribed to
descriptionstringDetailed description of when the event is triggered

Available Events

Events are made up of an object with two fundamental properties (name, description):

  • user_signup: Event launched once a user completes registration on the TropiPay platform.
  • user_login: Event launched once a user completes login on the TropiPay platform.
  • user_kyc: Event launched once a user completes KYC process, indicated in each case the process status. Payload of response includes:
    {
    "userId": "string",
    "status": "string",
    "event": "string",
    "user": {}
    }
  • payment_in_state_change: The event is fired once a user changes their status payment in entry method.
  • payment_out_state_change: The event is fired once a user changes their status payment out entry method.

User Hooks

User hooks are webhooks that are managed at the individual user level. These endpoints allow users to manage their personal webhook subscriptions.

List User Hooks

Returns a list of user hook subscriptions for the authenticated user.

GET/user/hooks
curl -X GET https://sandbox.tropipay.me/api/v3/user/hooks \
-H "Authorization: Bearer {user-token}" \
-H "Accept: application/json"

Response

Status Code: 200 OK

[
{
"event": "user_login",
"target": "web",
"value": "https://webhook.site/680826a5-199e-4455-babc-f47b7f26ee7e",
"createdAt": "2022-02-11T18:36:48.300Z",
"updatedAt": "2022-02-11T18:36:48.300Z"
},
{
"event": "user_kyc",
"target": "email",
"value": "user@example.com",
"createdAt": "2022-02-11T18:53:30.397Z",
"updatedAt": "2022-02-11T18:53:30.397Z"
},
{
"event": "beneficiary_added",
"target": "email",
"value": "user@example.com",
"createdAt": "2022-02-11T18:53:54.027Z",
"updatedAt": "2022-02-11T18:53:54.027Z"
}
]

Response Parameters

ParameterTypeDescription
eventstringName of the subscribed event
targetstringType of webhook target (web, email)
valuestringTarget value (URL for web, email address for email)
createdAtstringISO 8601 timestamp when subscription was created
updatedAtstringISO 8601 timestamp when subscription was last updated

Create User Hook

Insert a user hook to subscribe to webhook events.

POST/user/hooks
curl -X POST https://sandbox.tropipay.me/api/v3/user/hooks \
-H "Authorization: Bearer {user-token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"event": "user_login",
"target": "web",
"value": "https://webhook.site/680826a5-199e-4455-babc-f47b7f26ee7e"
}'

Parameters

Events are made up of an object with three fundamental properties (event, target, value):

ParameterTypeRequiredDescription
eventstringYesString that represents the name of the event. You must select from the list of available events, otherwise it will not produce an error but it will not be executed. For the full list of available events see endpoint GET /user/hooks/events.
targetstringYesString representing the type of event supported. Currently available: web (allows to receive information in a URL), email (allows to receive information in an email address).
valuestringYesString that represents the value depending on the type of selected event determined by the 'target' property. For example, if the selected 'target' is email the value would be an email address, likewise if the selected 'target' is web the expected value corresponds to a URL that receives information through the HTTP POST method.

Response

Status Code: 200 OK

In general, valid responses are defined as an object with three elementary properties:

{
"action": "subscribe",
"status": "success",
"details": "user_login"
}

Response Parameters

ParameterTypeDescription
actionstringRepresents the type of operation that was just executed
statusstringRepresents the status of the operation, taking value success in case everything goes well
detailsstringDisplays additional values related to the operation, usually returns the name of the event

Update User Hook

Explicit update hook on payload request.

PUT/user/hooks
curl -X PUT https://sandbox.tropipay.me/api/v3/user/hooks \
-H "Authorization: Bearer {user-token}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"event": "user_login",
"target": "email",
"value": "user@example.com"
}'

Parameters

Events are made up of an object with three fundamental properties (event, target, value):

ParameterTypeRequiredDescription
eventstringYesString that represents the name of the event. You must select from the list of available events, otherwise it will not produce an error but it will not be executed. For the full list of available events see endpoint GET /user/hooks/events.
targetstringYesString representing the type of event supported. Currently available: web (allows to receive information in a URL), email (allows to receive information in an email address).
valuestringYesString that represents the value depending on the type of selected event determined by the 'target' property. For example, if the selected 'target' is email the value would be an email address, likewise if the selected 'target' is web the expected value corresponds to a URL that receives information through the HTTP POST method.

Response

Status Code: 200 OK

In general, valid responses are defined as an object with three elementary properties:

{
"action": "update",
"status": "success",
"details": "user_login"
}

Response Parameters

ParameterTypeDescription
actionstringRepresents the type of operation that was just executed
statusstringRepresents the status of the operation, taking value success in case everything goes well
detailsstringDisplays additional values related to the operation, usually returns the name of the event

Get Available Events for User

Get user hook event list.

GET/user/hooks/events
curl -X GET https://sandbox.tropipay.me/api/v3/user/hooks/events \
-H "Authorization: Bearer {user-token}" \
-H "Accept: application/json"

Response

Status Code: 200 OK

[
{
"name": "user_signup",
"description": "Event launched once a user completes registration on the TropiPay platform."
},
{
"name": "user_login",
"description": "Event launched once a user completes login on the TropiPay platform."
},
{
"name": "user_kyc",
"description": "Event launched once a user completes kyc process."
},
{
"name": "payment_in_state_change",
"description": "The event is fired once a user changes their status payment in entry method."
},
{
"name": "payment_out_state_change",
"description": "The event is fired once a user changes their status payment out entry method."
},
{
"name": "beneficiary_added",
"description": "Launched after new beneficiary is created."
},
{
"name": "beneficiary_updated",
"description": "Launched after a beneficiary is modified."
},
{
"name": "beneficiary_deleted",
"description": "Launched after a beneficiary is deleted."
}
]

Response Parameters

ParameterTypeDescription
namestringThe name of the event that can be subscribed to
descriptionstringDetailed description of when the event is triggered

Available Events

The following events are available for user hook subscriptions:

  • user_signup: Event launched once a user completes registration on the TropiPay platform.
  • user_login: Event launched once a user completes login on the TropiPay platform.
  • user_kyc: Event launched once a user completes kyc process.
  • payment_in_state_change: The event is fired once a user changes their status payment in entry method.
  • payment_out_state_change: The event is fired once a user changes their status payment out entry method.
  • beneficiary_added: Launched after new beneficiary is created.
  • beneficiary_updated: Launched after a beneficiary is modified.
  • beneficiary_deleted: Launched after a beneficiary is deleted.

Get Specific User Hook

Select all hooks subscribed to a given event name. The URL for a certain event name would be as follows /user/hooks/user_login. For the previous case, all the hooks associated with the user_login event would be obtained, where basically a list would be returned where the target and the associated value would change.

GET/user/hooks/{event_name}
curl -X GET https://sandbox.tropipay.me/api/v3/user/hooks/user_login \
-H "Authorization: Bearer {user-token}" \
-H "Accept: application/json"

Path Parameters

ParameterTypeRequiredDescription
event_namestringYesThe name of the event to retrieve hooks for (e.g., user_login, user_signup, beneficiary_added)

Response

Status Code: 200 OK

[
{
"event": "user_login",
"target": "web",
"value": "https://webhook.site/680826a5-199e-4455-babc-f47b7f26ee7e",
"createdAt": "2022-02-11T18:36:48.300Z",
"updatedAt": "2022-02-11T18:36:48.300Z"
},
{
"event": "user_login",
"target": "email",
"value": "user@example.com",
"createdAt": "2022-02-11T18:43:24.882Z",
"updatedAt": "2022-02-11T18:43:24.882Z"
}
]

Response Parameters

ParameterTypeDescription
eventstringName of the subscribed event
targetstringType of webhook target (web, email)
valuestringTarget value (URL for web, email address for email)
createdAtstringISO 8601 timestamp when subscription was created
updatedAtstringISO 8601 timestamp when subscription was last updated

Get User Hook by Target

Select hook by event name and target name. Note that, to select the data of a very specific hook, you must filter by the name of the event and the target similar as below /user/hooks/user_login/web, in this case we try to request the data of the hook subscribed to the user_login event with notification via web hook.

GET/user/hooks/{event_name}/{target_name}
curl -X GET https://sandbox.tropipay.me/api/v3/user/hooks/user_login/web \
-H "Authorization: Bearer {user-token}" \
-H "Accept: application/json"

Path Parameters

ParameterTypeRequiredDescription
event_namestringYesThe name of the event to filter by (e.g., user_login, user_signup, beneficiary_added)
target_namestringYesThe target type to filter by (web, email)

Response

Status Code: 200 OK

[
{
"event": "user_login",
"target": "email",
"value": "user@example.com",
"createdAt": "2022-02-11T18:43:24.882Z",
"updatedAt": "2022-02-11T18:43:24.882Z"
}
]

Response Parameters

ParameterTypeDescription
eventstringName of the subscribed event
targetstringType of webhook target (web, email)
valuestringTarget value (URL for web, email address for email)
createdAtstringISO 8601 timestamp when subscription was created
updatedAtstringISO 8601 timestamp when subscription was last updated

Delete User Hook

Delete or unsubscribe hook by event name and target name.

DELETE/user/hooks/{event_name}/{target_name}
curl -X DELETE https://sandbox.tropipay.me/api/v3/user/hooks/user_login/web \
-H "Authorization: Bearer {user-token}" \
-H "Accept: application/json"

Path Parameters

ParameterTypeRequiredDescription
event_namestringYesThe name of the event to unsubscribe from (e.g., user_login, user_signup, beneficiary_added)
target_namestringYesThe target type to unsubscribe from (web, email)

Response

Status Code: 200 OK

In general, valid responses are defined as an object with three elementary properties:

{
"action": "unsubscribe",
"status": "success",
"details": "user_login"
}

Response Parameters

ParameterTypeDescription
actionstringRepresents the type of operation that was just executed
statusstringRepresents the status of the operation, taking value success in case everything goes well
detailsstringDisplays additional values related to the operation, usually returns the name of the event

Event Structure

Events are composed of an object with three fundamental properties:

  • event: String representing the event name. You must select from the list of available events, otherwise it will not produce an error but will not be executed. For the complete list of available events, see the endpoint GET /hook/events.

  • target: String representing the supported event type. Currently available:

    • web: allows receiving information at a URL
    • email: allows receiving information at an email address
  • value: String representing the value depending on the selected event type determined by the 'target' property. For example, if the selected 'target' is 'email', the value would be an email address. Similarly, if the selected 'target' is 'web', the expected value corresponds to a URL that receives information through the HTTP POST method.

Webhook Implementation

Setting up your endpoint

To start receiving webhook notifications, you must register your endpoint URL in the TropiPay developer panel:

  1. Log in to your TropiPay account
  2. Go to Developers > Webhooks section
  3. Click "Add new webhook"
  4. Enter your endpoint URL (must be HTTPS)
  5. Select the events you want to receive
  6. Save the configuration

Once registered, you'll receive a webhook secret that you should use to verify notifications.

Example Implementation

Node.js (Express)

const express = require('express');
const crypto = require('crypto');
const bodyParser = require('body-parser');

const app = express();

// Important to use raw body for signature verification
app.use(bodyParser.json({
verify: (req, res, buf) => {
req.rawBody = buf;
}
}));

// Your webhook secret provided by TropiPay
const webhookSecret = 'your_webhook_secret';

// Function to verify signature
function verifySignature(signature, payload) {
const expectedSignature = crypto
.createHmac('sha256', webhookSecret)
.update(payload)
.digest('hex');

return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}

// Endpoint to receive webhooks
app.post('/tropipay-webhook', (req, res) => {
const signature = req.headers['x-tropipay-signature'];

// Verify that the signature is valid
try {
if (!signature || !verifySignature(signature, req.rawBody)) {
console.error('Invalid signature');
return res.status(401).send('Invalid signature');
}

// Process the event according to its type
const event = req.body.event;
const data = req.body.data;

console.log(`Event received: ${event}`);

switch (event) {
case 'payment.completed':
// Logic to process a completed payment
handlePaymentCompleted(data);
break;

case 'card.transaction':
// Logic to process a card transaction
handleCardTransaction(data);
break;

// Handle other event types...

default:
console.log(`Unhandled event: ${event}`);
}

// Always respond with 200 OK to confirm receipt
res.status(200).send('OK');

} catch (error) {
console.error('Error processing webhook:', error);
res.status(500).send('Error processing webhook');
}
});

function handlePaymentCompleted(data) {
// Implement your logic to handle completed payments
console.log('Payment completed:', data.id, data.amount, data.currency);
// For example: update order status in your database
}

function handleCardTransaction(data) {
// Implement your logic to handle card transactions
console.log('Card transaction:', data.card_id, data.amount, data.merchant);
// For example: log the transaction in your system
}

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}`);
});

PHP

<?php
// Get request body
$payload = file_get_contents('php://input');
$data = json_decode($payload, true);

// Get signature from header
$signature = $_SERVER['HTTP_X_TROPIPAY_SIGNATURE'] ?? '';

// Your webhook secret provided by TropiPay
$webhookSecret = 'your_webhook_secret';

// Verify signature
$expectedSignature = hash_hmac('sha256', $payload, $webhookSecret);

if (!hash_equals($expectedSignature, $signature)) {
http_response_code(401);
echo 'Invalid signature';
exit;
}

// Process the event according to its type
$event = $data['event'] ?? '';
$eventData = $data['data'] ?? [];

switch ($event) {
case 'payment.completed':
// Logic to process a completed payment
handlePaymentCompleted($eventData);
break;

case 'card.transaction':
// Logic to process a card transaction
handleCardTransaction($eventData);
break;

// Handle other event types...

default:
error_log("Unhandled event: $event");
}

// Functions to handle specific events
function handlePaymentCompleted($data) {
// Implement your logic to handle completed payments
error_log("Payment completed: {$data['id']}, {$data['amount']} {$data['currency']}");
// For example: update order status in your database
}

function handleCardTransaction($data) {
// Implement your logic to handle card transactions
error_log("Card transaction: {$data['card_id']}, {$data['amount']}, {$data['merchant']}");
// For example: log the transaction in your system
}

// Respond with 200 OK to confirm receipt
http_response_code(200);
echo 'OK';
?>

Webhook Security

To ensure that webhook notifications actually come from TropiPay, each request includes a signature in the X-Tropipay-Signature header. This signature is generated using the webhook secret associated with your account.

Verifying Signatures

Always verify the signature of webhook notifications:

  1. Get the signature from the X-Tropipay-Signature header
  2. Generate the expected signature using HMAC-SHA256 with your webhook secret
  3. Compare the signatures using a timing-safe comparison function

Best Practices

  1. Signature verification: Always verify the signature of notifications to ensure they come from TropiPay.

  2. Quick response: Respond quickly to notifications with a 200 OK code. If you need to perform extensive processing, do it asynchronously after responding.

  3. Retry handling: TropiPay will retry sending notifications if your endpoint doesn't respond or returns an error code. Make sure your implementation is idempotent to avoid duplicates.

  4. Event logging: Keep a log of all received events to facilitate debugging and tracking.

  5. Timeout: Configure an appropriate timeout for your endpoint. TropiPay expects a response in less than 10 seconds.

Troubleshooting

If you're not receiving webhook notifications, check the following:

  1. The endpoint URL is correctly configured in TropiPay
  2. Your server is accessible from the Internet and accepts HTTPS connections
  3. There are no firewalls or security configurations blocking requests
  4. The webhook secret you're using is correct
  5. You're responding correctly to notifications with a 200 OK code

To test your implementation, you can use the "Send test" function in the TropiPay developer panel, which will allow you to send a test notification to your endpoint.

Error Handling

The Webhooks API uses conventional HTTP response codes to indicate the success or failure of webhook delivery.

Common Error Codes

CodeDescription
200OK - Webhook delivered successfully
400Bad Request - Invalid webhook configuration
401Unauthorized - Invalid authentication
403Forbidden - Insufficient permissions
404Not Found - Webhook endpoint not found
422Unprocessable Entity - Invalid webhook data
429Too Many Requests - Rate limit exceeded
500Internal Server Error

Example Error Response

{
"error": {
"type": "webhook_error",
"code": "endpoint_unreachable",
"message": "Unable to reach webhook endpoint",
"endpoint": "https://example.com/webhook"
}
}