Webhooks

Receive real-time notifications about payment events

Overview

Webhooks allow you to receive real-time notifications when events occur in your Yassir Payment account. Instead of polling our API for updates, we push event data to your server as they happen.

When you create a service during onboarding, you provide a webhookUrl. Yassir will send a POST request to this URL whenever a payment event occurs.

When Webhooks Fire

Webhooks are sent after the following events:

EventDescription
Proceed (success)Payment completed successfully via Yassir Wallet
Proceed (failure)Payment was rejected (e.g., insufficient balance)
Pre-authorizationFunds were successfully reserved
CaptureReserved funds were captured (full or partial)
ReleaseReserved funds were released back to the user
RefundA full or partial refund was processed

Webhook Payload

All webhook events are sent as a POST request with a JSON body in the following format:

Webhook Payload
{
  "actionId": "order_12345",
  "remoteStatus": "The amount was deposited successfully",
  "remoteStatusCode": 2,
  "contextType": "ORDER",
  "orderId": "123e4567-e89b-12d3-a456-426614174000",
  "additionalData": {}
}

Payload Fields

FieldTypeDescription
actionIdstringYour unique identifier from the original payment intent (e.g., your order ID)
remoteStatusstringHuman-readable status message
remoteStatusCodenumberNumeric status code (see table below)
contextTypestringAlways "ORDER"
orderIdstringThe Yassir payment ID
additionalDataobjectAdditional data (may be empty)

Status Codes (remoteStatusCode)

CodeStatusDescription
2SucceededPayment completed or captured successfully
3RejectedPayment was rejected by the provider
4RefundedFull refund was processed
10Reversed / ReleasedPre-authorized funds were released
13Pre-AuthorizedFunds reserved, awaiting capture or release
16Partially RefundedA partial refund was processed

Example Payloads

Payment Succeeded
// Payment succeeded
{
  "actionId": "order_12345",
  "remoteStatus": "The amount was deposited successfully",
  "remoteStatusCode": 2,
  "contextType": "ORDER",
  "orderId": "123e4567-e89b-12d3-a456-426614174000",
  "additionalData": {}
}
Pre-Authorized
// Pre-authorization completed
{
  "actionId": "order_12345",
  "remoteStatus": "Pre-authorized",
  "remoteStatusCode": 13,
  "contextType": "ORDER",
  "orderId": "123e4567-e89b-12d3-a456-426614174000",
  "additionalData": {}
}
Partial Refund
// Partial refund processed
{
  "actionId": "order_12345",
  "remoteStatus": "Partially Refunded",
  "remoteStatusCode": 16,
  "contextType": "ORDER",
  "orderId": "123e4567-e89b-12d3-a456-426614174000",
  "additionalData": {}
}

Setting Up Webhooks

1

Configure your endpoint

Create an HTTP endpoint on your server to receive webhook events. The endpoint must be publicly accessible and use HTTPS.

2

Register the webhook URL

Provide your webhook URL as the webhookUrl when creating your service during merchant onboarding. All payment events for that service will be sent to this URL.

3

Handle events

Process the webhook event and return a 2xx response:

JavaScript
app.post('/webhooks/yassir', async (req, res) => {
  const event = req.body;

  switch (event.remoteStatusCode) {
    case 2: // Succeeded
      await handlePaymentSuccess(event.actionId, event.orderId);
      break;
    case 3: // Rejected
      await handlePaymentFailure(event.actionId);
      break;
    case 4: // Refunded
      await handleRefund(event.actionId);
      break;
    case 10: // Released
      await handleRelease(event.actionId);
      break;
    case 13: // Pre-authorized
      await handlePreAuth(event.actionId, event.orderId);
      break;
    case 16: // Partially refunded
      await handlePartialRefund(event.actionId);
      break;
  }

  res.status(200).send('OK');
});

Best Practices

  • Respond to webhooks within 30 seconds
  • Process webhook data asynchronously for long operations
  • Handle duplicate events using idempotency (use actionId + remoteStatusCode as a key)
  • Always use the remoteStatusCode (not the text status) for programmatic logic