Webhook Types

MoneyHash uses a variety of webhooks to notify you regarding every action that happens on our integration side. The webhook types are listed below. Use each link to access the details regarding each existing type:

Intent Webhooks

The intent webhook will be received on your app whenever an intent changes status. These webhook types will be in the form of intent.{status}. The table below shows the events available for this webhook:

EventWebhook TypeDescription
Intent Processedintent.processedThe intent was processed and reached the final state. Users can't take any new action with the intent.
Intent Time Expiredintent.time_expiredIntent expires after the specified amount of seconds set by expires_after_seconds User can't take any action with the intent.
Intent Closedintent.closedIntent gets closed, and the User can't take any new action with the intent.
Sample Intent Webhook
1  {
2       "type": "intent.processed",
3       "intent_type": "PAYMENT",
4       "data": {
5           "intent_id": "gQlovBL",
6           "intent": {
7               "id": "gQlovBL",
8               "status": "PROCESSED",
9               "amount": 50,
10              "amount_currency": "USD",
11              "type": "Payin",
12              "account": "4L2W2bg",
13              "custom_fields": null,
14              "billing_data": {
15                  "first_name": "",
16                  "last_name": "",
17                  "email": "",
18                  "phone_number": ""
19              },
20              "active_transaction": {
21                  "id": "c5a09deb-5f7c-499f-85b7-143218591dbc",
22                  "custom_fields": null,
23                  "created": "2023-01-15T11:58:09.458587Z",
24                  "status": "SUCCESSFUL",
25                  "amount": "50.00",
26                  "amount_currency": "USD",
27                  "billing_data": null,
28                  "external_action_message": [],
29                  "payment_method": "CARD",
30                  "payment_method_name": "Card",
31                  "custom_form_answers": null,
32                  "custom_message": "",
33                  "service_provider": "XZOkmZ8",
34                  "account": "4L2W2bg",
35                  "provider_transaction_fields": {},
36                  "provider_signature_match": false
37              },
38              "transactions_history": [
39                  {
40                      "id": "c5a09deb-5f7c-499f-85b7-143218591dbc",
41                      "custom_fields": null,
42                      "created": "2023-01-15T11:58:09.458587Z",
43                      "status": "PENDING",
44                      "amount": "50.00",
45                      "amount_currency": "USD",
46                      "billing_data": null,
47                      "external_action_message": [],
48                      "payment_method": "CARD",
49                      "payment_method_name": "Card",
50                      "custom_form_answers": null,
51                      "custom_message": "",
52                      "service_provider": "XZOkmZ8",
53                      "account": "4L2W2bg",
54                      "provider_transaction_fields": {},
55                      "provider_signature_match": false
56                  }
57              ],
58              "flow": null,
59              "is_live": false,
60              "created": "2023-01-15T11:58:01.313334Z"
61          }
62      },
63      "api_version": "1.1"
64 }
        

Transactions Webhooks

The transaction webhook will be received on your app whenever an operation inside the transaction changes status. Each event will also carry the status of the current payment flow to indicate its current state.

These webhook types will be in the form of transaction.{operation}.{status}. Below, you will find more about the possible operation types, the possible statuses for these operations, and the available webhook events per operation type:

Operation types

OperationDescription
AuthorizeWhen you authorize a payment, some checks will happen with the card issuing bank to confirm the card cardholder’s ability to pay the requested amount and that there are sufficient funds to complete the purchase, ensure that the card issuing bank will hold the amount, and it will be available when you request capturing them using capture operation.
CaptureAfter authorizing the required amount, capturing them to your merchant account will be available.
You can capture the authorized amount multiple times, or you can do it once by executing the capture operation. You have a limit to the authorized amount and can't capture an amount greater than the authorized amount.
PurchaseIf your business doesn't require the auth and capture flow, and you need to get the full amount automatically without holding it for some time, you should use the purchase operation instead of the authorized operation
Void / CancelWhen you decide not to complete the authorization process and don't need to capture the authorized amount anymore, you can release the funds you authorized on your customer's card by voiding the authorization using the void command. Even if your authorization automatically expires, you should consider canceling the authorization you hold on your client's card if they decide not to make their purchase. Doing so gives your customer faster access to their funds.
RefundIf you captured the full amount or part of it, and you need to refund either the full captured amount or a part of it, then you need to consider using the refund operation. Also, you can do multiple partial refunds as long as you don't exceed the full amount.

Operation Statuses

Operation StatusesDescription
PendingThe operation is awaiting processing.
Pending AuthenticationAwaiting authentication or verification.
Pending External ActionAwaiting an action from an external source.
Pending Online External ActionAwaiting an online action from an external source.
SuccessfulThe operation has been completed successfully without errors or issues.
FailedThe operation has encountered an error or failure during processing.
Increase purchaseIndicates an increase in the purchase amount for this specific transaction and doesn't impact the intent amount

Available Webhook events per Operation type

pendingsuccessfulfailedPending AuthenticationPending External ActionPending Online External ActionIncrease purchase
Purchasetransaction.purchase.pendingtransaction.purchase.successfultransaction.purchase.failedtransaction.purchase.pending_authenticationtransaction.purchase.pending_external_actiontransaction.purchase.pending_online_external_actiontransaction.increase_purchase.successful
Authorizetransaction.authorize.pendingtransaction.authorize.successfultransaction.authorize.failedtransaction.authorize.pending_authenticationNot ApplicableNot ApplicableNot Applicable
Capturetransaction.capture.pendingtransaction.capture.successfultransaction.capture.failedNot ApplicableNot ApplicableNot ApplicableNot Applicable
Voidtransaction.void.pendingtransaction.void.successfultransaction.void.failedNot ApplicableNot ApplicableNot ApplicableNot Applicable
Refundtransaction.refund.pendingtransaction.refund.successfultransaction.refund.failedNot ApplicableNot ApplicableNot ApplicableNot Applicable
Sample Transaction Webhook
1  {
2       "type": "transaction.purchase.successful",
3       "status_id": "gMpKN2L",
4       "intent": {
5           "id": "ZvwG5Y9",
6           "created": "2022-12-08 13:50:48.298834+00:00",
7           "custom_fields": null,
8           "custom_form_answers": null,
9           "amount": {
10              "value": 50,
11              "currency": "USD"
12          }
13      },
14      "account": {
15          "id": "YVglAZx"
16      },
17      "transaction": {
18          "type": "payment",
19          "id": "ff21dfa2-48c3-4f1b-a1bb-f7d3597f1ef3",
20          "created": "2022-12-08 13:51:01.900745+00:00",
21          "status": "purchase.successful",
22          "billing_data": {
23              "first_name": "Joe",
24              "last_name": "Doe",
25              "email": "[email protected]",
26              "phone_number": null,
27              "apartment": null,
28              "floor": null,
29              "building": null,
30              "street": null,
31              "city": null,
32              "state": null,
33              "country": null,
34              "postal_code": null
35          },
36          "external_action_message": [],
37          "operations": [
38              {
39                  "id": "gXoANML",
40                  "type": "purchase",
41                  "status": "successful",
42                  "amount": {
43                      "value": 50,
44                      "currency": "USD"
45                  },
46                  "statuses": [
47                      {
48                          "id": "gMpKN2L",
49                          "value": "successful",
50                          "created": "2022-12-08 13:51:01.949061+00:00"
51                      }
52                  ]
53              }
54          ],
55          "custom_message": "",
56          "method": {
57              "id": "W9KWv9X",
58              "display_name": "Demo - Card",
59              "service_provider": {
60                  "id": "qYLP2Z3"
61              }
62          }
63      },
64      "api_version": "1.1"
65 }
        

Card Token Webhooks

The card token webhook will be received on your app whenever a card tokenization changes status.

These webhook types will be in the form of card_token.{event}. The table below shows the events available for this webhook:

EventWebhook TypeDescription
Card token createdcard_token.createdA new card token has been created and associated with a customer entity.
Card token updatedcard_token.updatedA card token has been updated.
Card token deletedcard_token.deletedA card token has been removed.
Sample Card Token Webhook
1  {
2       "type": "card_token.updated",
3       "data": {
4           "intent_id": "98B8jMg",
5           "card_token": {
6               "id": "b1cbd010-78fc-4bac-ac55-880149907c99",
7               "brand": "MasterCard",
8               "card_holder_name": null,
9               "last_4": "2346",
10              "expiry_month": "01",
11              "expiry_year": "25",
12              "country": null,
13              "custom_fields": {
14                  "user_uid": "b836b4b7-1c2d-40b7-bb85-36f10500cca7",
15                  "customer_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
16              },
17              "provider_token_data": [
18                  {
19                      "last_4": "1234",
20                      "service_provider_id": "eZAVN9x",
21                      "pay_in_method": "jgxNP9r",
22                      "provider_specific_data": {
23                          "payment_token": "93e50bb163c640910506de431ce13d607f8d187be6c0f4f5f38145f5"
24                      }
25                  }
26              ]
27          }
28      }
29 }
        

Customer Webhooks

The customer webhook will be received on your app whenever the entity of a customer changes status.

These webhook types will be in the form of customer.{event}. The table below shows the events available for this webhook:

EventWebhook TypeDescription
Customer Createdcustomer.createdA new customer entity has been created.
Sample Customer Webhook
1  {
2       "type": "customer.created",
3       "data": {
4           "customer_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
5           "customer": {
6               "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
7               "organization": "demo org",
8               "name": null,
9               "email": "[email protected]",
10              "phone_number": "+201064610000",
11              "description": null,
12              "address": null,
13              "is_live": false,
14              "wallets": {}
15          }
16      }
17 }
        

Methods Webhooks

The method webhook will be received on your app whenever a payment method is activated or deactivated on an Account.

These webhook types will be in the form of account.method.{event}. The table below shows the events available for this webhook:

Payment method eventWebhook TypeDescription
Payment Method Activatedaccount.method.activeA payment method has been activated on an account
Payment Method Deactivatedaccount.method.inactiveA payment method has been deactivated on an account.
Sample Methods Webhook
1 {
2       "type": "account.method.active",
3       "account": {
4           "id": "1Zv0zLB",
5           "name": "Merchant Account X"
6       },
7       "service_provider": {
8           "id": "8LVE39r",
9           "display_name": "Network International",
10          "code": "NETWORK_INTERNATIONAL"
11      },
12      "method": {
13          "id": "A9eqX9m",
14          "type": "PayIn",
15          "code": "NETWORK_INTERNATIONAL.PayIn.CARD",
16          "active": true
17      }
18 }
        

Subscription Webhooks

The subscription webhook will be received on your app whenever a subscription status is updated.

These webhook types will be in the form of subscription.current_status. The table below shows the events available for this webhook:

Subscription StatusDescription
NEWThe initial status for any subscription before its start date.
TRIALThe trial period is in progress.
INCOMPLETEThe first recurring cycle is due, and the customer payment details are missing.
ACTIVEThere aren't any pending invoices, and the last cycle was paid.
PAST_DUEThere is an overdue invoice that wasn't paid.
PENDING_CANCELLATIONThe subscription received a request to be canceled and is waiting for the recurring date.
CANCELLEDThe subscription was canceled.
ENDEDThe end date of the subscription was reached.
Sample Subscription Webhook
1 {
2       "type": "subscription",
3       "id": "Yz98Bgy",
4       "account": {
5           "id": "YVglAZx",
6           "name": "Demo Account"
7       },
8       "plan": {
9           "id": "wA9eY9m",
10          "name": "test plan"
11      },
12      "current_status": {
13          "id": "akLnog3",
14          "value": "INCOMPLETE",
15          "created": "2023-01-16 14:24:53.824895+00:00"
16      },
17      "statuses": [
18          {
19              "id": "o19zj9Y",
20              "value": "NEW",
21              "created": "2023-01-16 14:24:53.819900+00:00"
22          },
23          {
24              "id": "akLnog3",
25              "value": "INCOMPLETE",
26              "created": "2023-01-16 14:24:53.824895+00:00"
27          }
28      ],
29      "start_date": "2023-01-16",
30      "customer": {
31          "id": "d1aa2379-c74c-4886-bc6b-8f491a3e331e",
32          "name": "Subscription Test Customer"
33      },
34      "charge_automatically": false,
35      "remaining_recurring_cycles": null,
36      "remaining_discount_cycles": null,
37      "configuration": {
38          "amount": 10,
39          "one_time_fee": null,
40          "trial_period": null,
41          "recurrency": 1,
42          "recurring_cycles": null,
43          "discount_amount": null,
44          "discount_percentage": null,
45          "discount_cycles": null
46      },
47      "webhook_url": "https://webhook.site/8fb2166e-a0c4-4d64-a20e-7d89a31e2d43",
48      "custom_fields": {},
49      "due_invoices": [
50          {
51              "id": "AXZOML8",
52              "subscription_id": "Yz98Bgy",
53              "status": {
54                  "id": "voZpKgM",
55                  "value": "DUE",
56                  "created": "2023-01-16 14:24:53.843352+00:00"
57              },
58              "amount": 10,
59              "currency": "EGP",
60              "due_date": "2023-01-16",
61              "is_live": false,
62              "payment_intent_url": "https://dev-embed.moneyhash.io/embed/payment/yoZoVgp",
63              "statuses": [
64                  {
65                      "id": "6eZAeZx",
66                      "value": "NEW",
67                      "created": "2023-01-16 14:24:53.839221+00:00"
68                  },
69                  {
70                      "id": "voZpKgM",
71                      "value": "DUE",
72                      "created": "2023-01-16 14:24:53.843352+00:00"
73                  }
74              ]
75          }
76      ],
77      "next_recurring_cycle_invoice": {
78          "id": "yW9KvZX",
79          "subscription_id": "Yz98Bgy",
80          "status": {
81              "id": "7lgajZ3",
82              "value": "OPEN",
83              "created": "2023-01-16 14:24:53.859019+00:00"
84          },
85          "amount": 10,
86          "currency": "EGP",
87          "due_date": "2023-02-16",
88          "is_live": false,
89          "payment_intent_url": "https://dev-embed.moneyhash.io/embed/payment/K1ZvzZB",
90          "statuses": [
91              {
92                  "id": "q7L5d9d",
93                  "value": "NEW",
94                  "created": "2023-01-16 14:24:53.855159+00:00"
95              },
96              {
97                  "id": "7lgajZ3",
98                  "value": "OPEN",
99                  "created": "2023-01-16 14:24:53.859019+00:00"
100             }
101         ]
102     },
103     "all_invoices": [
104         {
105             "id": "AXZOML8",
106             "subscription_id": "Yz98Bgy",
107             "status": {
108                 "id": "voZpKgM",
109                 "value": "DUE",
110                 "created": "2023-01-16 14:24:53.843352+00:00"
111             },
112             "amount": 10,
113             "currency": "EGP",
114             "due_date": "2023-01-16",
115             "is_live": false
116         },
117         {
118             "id": "yW9KvZX",
119             "subscription_id": "Yz98Bgy",
120             "status": {
121                 "id": "7lgajZ3",
122                 "value": "OPEN",
123                 "created": "2023-01-16 14:24:53.859019+00:00"
124             },
125             "amount": 10,
126             "currency": "EGP",
127             "due_date": "2023-02-16",
128             "is_live": false
129         }
130     ],
131     "is_live": false,
132     "end_date": null,
133     "created": "2023-01-16T14:24:53.813988Z"
134 }
        

Create a Historical Transaction Webhook

After creating the Create a Historical Transaction with an API call, you will receive a webhook that confirms that the operation has been successfully processed.

Sample Historical Transaction Webhook
1  {
2       "intent": "2L3RE9m",
3       "status": "SUCCESSFUL",
4       "message": "This Transaction history intent has been processed successfully"
5   }

Payout Webhooks

Payout webhooks are fired when a disburse or void operation changes status on a payout intent. These events follow the same transaction webhook pattern but are scoped to payout operations.

These webhook types take the form transaction.{operation_type}.{status}. Disburse operations may pass through intermediate states before reaching a terminal outcome.

EventWebhook TypeTerminal?Description
Disburse pending approvaltransaction.disburse.pending_approvalNoThe disburse operation is awaiting approval before execution proceeds.
Disburse successfultransaction.disburse.successfulYesFunds have been disbursed successfully. The payout intent moves to processed.
Disburse failedtransaction.disburse.failedYesThe disbursement failed. The payout intent remains unprocessed.
Void successfultransaction.void.successfulYesThe payout was cancelled before funds were disbursed. The intent moves to processed.
Void failedtransaction.void.failedYesThe void attempt failed. The disburse operation continues.
Sample Payout Webhook
{
  "type": "transaction.disburse.successful",
  "status_id": "v02QJad",
  "operation_id": "LYp5ek0",
  "intent": {
    "id": "9eQVWzj",
    "created": "2026-05-22 08:13:38.259170+00:00",
    "custom_fields": null,
    "custom_form_answers": null,
    "amount": {
      "value": "50.00",
      "currency": "EGP",
      "formatted": 50,
      "display_value": "50.00 EGP"
    },
    "payout_status": {
      "status": "DISBURSED"
    }
  },
  "account": {
    "id": "4L2W2bg"
  },
  "transaction": {
    "type": "payout",
    "id": "7ec43ca6-96ca-45b6-82ef-b6d2c1777c21",
    "created": "2026-05-22 08:13:43.405692+00:00",
    "status": "disburse.successful",
    "billing_data": {
      "issuer": "vodafone",
      "last_name": "Doe",
      "first_name": "John",
      "phone_number": "+201111111111"
    },
    "external_action_message": [],
    "provider_transaction_fields": {
      "paymob_transaction_id": null
    },
    "provider_unique_reference": null,
    "operations": [
      {
        "id": "LYp5ek0",
        "type": "disburse",
        "status": "successful",
        "amount": {
          "value": "50.00",
          "currency": "EGP",
          "formatted": 50,
          "display_value": "50.00 EGP"
        },
        "latest_status": {
          "id": "v02QJad",
          "value": "successful",
          "code": "6000",
          "provider_error_code": null,
          "provider_error_message": null,
          "message": "Successful",
          "localized_message": "Successful"
        },
        "statuses": [
          {
            "id": "8jW5PGr",
            "value": "pending",
            "code": "8000",
            "message": "Pending",
            "localized_message": "Pending",
            "created": "2026-05-22 08:13:43.436840+00:00"
          },
          {
            "id": "v02QJad",
            "value": "successful",
            "code": "6000",
            "message": "Successful",
            "localized_message": "Successful",
            "created": "2026-05-22 08:14:37.081263+00:00"
          }
        ]
      }
    ],
    "method": {
      "id": "gqwWO79",
      "display_name": "PaymobPayout - Mobile Wallet",
      "service_provider": {
        "id": "Vg6lNY9",
        "display_name": "Paymob"
      }
    }
  },
  "api_version": "1.4"
}

Bulk Payout Webhooks

Bulk payout webhooks are fired at two levels: the bulk request level (status of the overall batch) and the item level (status of each individual payout). Both are delivered to the webhook_url provided when creating the bulk request.

Bulk request events

These events reflect the overall status of the bulk payout request.

EventWebhook TypeDescription
Bulk request activepayout.bulk.activeThe bulk request has been created and items are queued for validation. Payload includes the full items array with initial statuses.
Bulk request cancelledpayout.bulk.cancelledThe bulk request was cancelled. All eligible items that had not yet entered processing are moved to CANCELLED.
Bulk request batch completedpayout.bulk.batch_completedAll items in the batch have been processed — validation and execution are complete. Includes item count breakdown per status.
Sample Bulk Request Webhook
{
  "type": "payout.bulk.active",
  "data": {
    "id": "wgjJ3wg",
    "label": "test bulk payout request",
    "source": "API",
    "status": "ACTIVE",
    "items_count": 1,
    "validation_pending_items_count": 1,
    "scheduled_items_count": 0,
    "validation_failed_items_count": 0,
    "cancelled_items_count": 0,
    "intent_created_items_count": 0,
    "intent_creation_failed_items_count": 0,
    "active_at": "2026-05-22T09:12:33.859011Z",
    "completed_at": null,
    "cancelled_at": null,
    "created": "2026-05-22T09:12:33.859198Z",
    "items": [
      {
        "id": "jgxdwag",
        "merchant_reference": "1234567890",
        "bulk_payout_request_id": "wgjJ3wg",
        "status": "VALIDATION_PENDING",
        "scheduled_date": "2026-06-20T00:00:00Z",
        "payout_intent_details": {
          "amount": 50,
          "webhook_url": "https://webhook.site/b959c817",
          "payout_method": "BANK_ACCOUNT",
          "amount_currency": "NGN",
          "merchant_reference": "1234567890"
        },
        "validation_result": {},
        "linked_intent_id": null,
        "created": "2026-05-22T09:12:33.864169Z"
      }
    ]
  }
}

Item validation events

These events reflect the validation outcome for each individual item.

EventWebhook TypeDescription
Item validation pendingpayout.item.validation_pendingThe item is queued and waiting for validation.
Item scheduledpayout.item.scheduledValidation passed. The item is scheduled for execution on its scheduled_date.
Item validation failedpayout.item.validation_failedValidation failed. The validation_result field in the payload describes the errors.
Sample Item Validation Webhook
{
  "type": "payout.item.validation_failed",
  "data": {
    "id": "jgxdwag",
    "merchant_reference": "1234567890",
    "bulk_payout_request_id": "wgjJ3wg",
    "status": "VALIDATION_FAILED",
    "scheduled_date": "2026-06-20T00:00:00Z",
    "payout_intent_details": {
      "amount": 50,
      "webhook_url": "https://webhook.site/b959c817",
      "payout_method": "BANK_ACCOUNT",
      "amount_currency": "NGN",
      "merchant_reference": "1234567890"
    },
    "validation_result": {
      "status": "error",
      "errors": {
        "account_number": ["Invalid key"]
      }
    },
    "linked_intent_id": null,
    "created": "2026-05-22T09:12:33.864169Z",
    "validation_failed_at": "2026-05-22T09:12:35.316634Z"
  }
}

Item execution events

These events are fired on the item's scheduled_date when execution begins.

EventWebhook TypeDescription
Intent createdpayout.item.intent_createdA payout intent was successfully created for this item. Payout lifecycle webhooks will follow.
Intent creation failedpayout.item.intent_creation_failedThe payout intent could not be created. The item moves to INTENT_CREATION_FAILED. Retry in a new bulk request.
Sample Item Execution Webhook
{
  "type": "payout.item.intent_created",
  "data": {
    "id": "L2WVlAg",
    "merchant_reference": "1234567890",
    "bulk_payout_request_id": "jZBnOWZ",
    "status": "INTENT_CREATED",
    "scheduled_date": "2026-05-24T00:00:00Z",
    "payout_intent_details": {
      "amount": 50,
      "webhook_url": "https://webhook.site/b959c817-4188-450c-a4de-e40ded0d4f5a",
      "billing_data": {
        "name": "MoneyHash",
        "bank_account": "035",
        "account_number": "0001234567"
      },
      "payout_method": "BANK_ACCOUNT",
      "amount_currency": "NGN",
      "merchant_reference": "1234567890"
    },
    "validation_result": {
      "status": "success"
    },
    "linked_intent_id": "ZdbvNvX",
    "created": "2026-05-24T13:38:25.714298Z",
    "scheduled_at": "2026-05-24T13:38:26.863991Z",
    "cancelled_at": null,
    "validation_failed_at": null,
    "intent_created_at": "2026-05-24T13:40:00.464801Z",
    "intent_creation_failed_at": null
  }
}

Payout intent lifecycle events

Once an item creates a payout intent, standard payout webhooks are fired for that intent's disburse and void operations:

  • transaction.disburse.pending_approval
  • transaction.disburse.successful
  • transaction.disburse.failed
  • transaction.void.successful
  • transaction.void.failed

See Payout Webhooks above for event details and payload structure.