# Webhooks

The goal of the webhooks is to give your organization a real time update on the status and events of users, transactions, products, invoices, subscriptions, taxes and common fees so you can automate your next call to action depending of the status of the payments or the occurrence of events.

To enable webhooks you have to open the settings page using the portal.&#x20;

<figure><img src="/files/gqdI38MHWQaGe5rs9RwJ" alt=""><figcaption></figcaption></figure>

When a URL is defined, Zūm will send a POST request each time there is a status change or event triggered for:

* Users (only available for customers)
* Transactions (only available for customers)
* Customers (only available for partners)
* Recurrent Transaction (only available for customers)
* Products (only available for customers)
* Invoices (only available for customers)
* Subscriptions (only available for customers)
* Taxes (only available for customers)
* Common Fees (only available for customers)
* Insights (only available for customers)
* Chargeback Action (only available for customers)
* Aggregation Status (only available for customers)
* Aggregation Transaction Events (only available for customers)

{% tabs %}
{% tab title="Canada" %}

```json
  {
      "Type": "Invoice",
      "Event": "Created",
      "Data": {
          ...
      }
  }
```

{% endtab %}

{% tab title="US" %}

```json
  {
      "Type": "Transaction",
      "Event": "Updated",
      "Data": {
          ...
      }
  }
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**INFO**

The payload has a property Type to indicate to each entity the webhook status change is coming from and also a property called Event that indicates the type of event that trigger the webhook.
{% endhint %}

**Event**

<table><thead><tr><th width="156">Event</th><th width="292">Description</th><th align="center">Availability</th></tr></thead><tbody><tr><td>Created</td><td>Entity was created</td><td align="center">Invoice, Subscription, Product, Tax Rate, Common Fee</td></tr><tr><td>Updated</td><td>Entity was updated on some manner</td><td align="center">Invoice, Subscription, Product, Tax Rate, Common Fee</td></tr><tr><td>Deleted</td><td>Entity was deleted</td><td align="center">Product</td></tr><tr><td>StatusChange</td><td>Entity had it's status changed</td><td align="center">Invoice, Subscription, Product, Tax Rate, Common Fee</td></tr><tr><td>Completed</td><td>Entity was ready to use</td><td align="center">Insights</td></tr><tr><td>Failed</td><td>Entity was not ready to use</td><td align="center">Insights</td></tr></tbody></table>

{% hint style="info" %}
**NOTE**

For now, transactions and user entities does not posses events to be associated with
{% endhint %}

**Type**

<table><thead><tr><th width="226">Type</th><th>Description</th></tr></thead><tbody><tr><td>User</td><td>Indicates the webhook call is for a user status change</td></tr><tr><td>Transaction</td><td>Indicates the webhook call is for a transaction status change</td></tr><tr><td>Customer</td><td>Indicates the webhook call is for a customer account status change</td></tr><tr><td>Recurrent Transaction</td><td>Indicates the webhook call is for a recurrent transaction creation</td></tr><tr><td>Product</td><td>Indicates the webhook call is for a product event</td></tr><tr><td>Invoice</td><td>Indicates the webhook call is for a invoice event</td></tr><tr><td>Subscription</td><td>Indicates the webhook call is for a subscription event</td></tr><tr><td>TaxRate</td><td>Indicates the webhook call is for a tax rate event</td></tr><tr><td>CommonFee</td><td>Indicates the webhook call is for a common fee event</td></tr><tr><td>Insights</td><td>Indicates the webhook call is for a insights event</td></tr></tbody></table>

{% tabs %}
{% tab title="Canada" %}

<table><thead><tr><th width="226">Type</th><th>Description</th></tr></thead><tbody><tr><td>User</td><td>Indicates the webhook call is for a user status change</td></tr><tr><td>Transaction</td><td>Indicates the webhook call is for a transaction status change</td></tr><tr><td>Customer</td><td>Indicates the webhook call is for a customer account status change</td></tr><tr><td>Recurrent Transaction</td><td>Indicates the webhook call is for a recurrent transaction creation</td></tr><tr><td>Product</td><td>Indicates the webhook call is for a product event</td></tr><tr><td>Invoice</td><td>Indicates the webhook call is for a invoice event</td></tr><tr><td>Subscription</td><td>Indicates the webhook call is for a subscription event</td></tr><tr><td>TaxRate</td><td>Indicates the webhook call is for a tax rate event</td></tr><tr><td>CommonFee</td><td>Indicates the webhook call is for a common fee event</td></tr><tr><td>Insights</td><td>Indicates the webhook call is for a insights event</td></tr></tbody></table>
{% endtab %}

{% tab title="US" %}

<table><thead><tr><th width="187.39996337890625">Type</th><th>Description</th></tr></thead><tbody><tr><td>Transaction</td><td>Indicates the webhook call is for a transaction status change</td></tr><tr><td>Customer</td><td>Indicates the webhook call is for a customer account status change</td></tr><tr><td>Chargeback Action </td><td>Indicates the webhook call is for a transaction chargeback status change</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

The webhook payload uses the same JSON format as the responses for the get [User](/api-reference/users.md#get-a-specific-user), [Transaction](/api-reference/transactions.md#get-a-specific-transaction), [Product](/api-reference/products.md#get-a-specific-product), [Invoice](/api-reference/invoices.md#get-a-specific-invoice), [Subscription](/api-reference/subscriptions.md#get-a-specific-subscription), Tax Rates, Common Fees and [Insights](/api-reference/insights.md).

The [Chargeback](/api-reference/webhooks.md#chargeback-webhook) webhook payload follows the JSON structure shown in the example response.&#x20;

{% hint style="info" %}
**INFO**

If you don't want to receive webhook for a specific status, then you can specify the status in the portal settings.
{% endhint %}

## Verifying authenticity

When Zūm Rails sends data to external services (e.g. when triggering a webhook to a service owned by you), the payload will be authenticated with a [hash-based message authentication code (HMAC)](https://en.wikipedia.org/wiki/HMAC).

The key used to create the HMAC is your Webhook Secret, and you verify it by running the algorithm yourself with the payload and the key to re-create the HMAC. Your Webhook Secret can be found in the portal under your settings.

The signature is always sent with the webhook in a header named *zumrails-signature*

You can verify the authenticity of the webhook response by using HMAC. The HMAC verification process is as follows:

1. You receive a POST request via the webhook
2. Your app computes a signature based on payload received, using your Webhook Secret
3. You verify that your signature matches the zumrails-signature in the request

Here are the steps to validate a request coming from Zūm Rails You’ll need the zumrails-signature sent by the webhook and your key (which is your Webhook Secret):

1. Retrieve the zumrails-signature header
2. Retrieve json body of the request. Make sure you are not adding any new spaces or formats.
3. Using HMAC SHA256 implemented in your programming language, calculate the signature in your side. The body is the payload and the secret is your Webhook Secret.
4. Compare your hash with the value provided under the zumrails-signature in the request, they should match.

A few examples on how to calculate HMAC in different languages: <https://github.com/danharper/hmac-examples>

{% tabs %}
{% tab title="Canada" %}
{% hint style="info" %}
**INFO**

When generating the signature, make sure you are using the body received in the payload, as it is. Some languages might add spaces or tabs.
{% endhint %}

{% hint style="info" %}
**WE CALCULATE THE SIGNATURE MAKING SURE THE PAYLOAD IS IN UTF-8 CHARSET,**

When generating the signature, make sure you are using the body received in the payload, as it is. Some languages might add spaces or tabs.
{% endhint %}
{% endtab %}

{% tab title="US" %}
{% hint style="danger" %}
**CAUTION**

When generating the signature, make sure you are using the body received in the payload, as it is. Some languages might add spaces or tabs.
{% endhint %}

{% hint style="danger" %}
**CAUTION**

We calculate the signature when the payload is in UTF-8 charset, so make sure it is the same on your side, or else the signatures won't match.
{% endhint %}
{% endtab %}
{% endtabs %}

## Retry in case of failure

In the event of a failure to deliver the webhook (!= 200) we will try again 3 times every 5 minutes in sandbox. In production we will retry 5 times every 60 minutes.

If you have anything specific in our retry policy, don't hesitate to talk with us, to <support@zumrails.com>, changes can be made.

## Receiving users' financial institution details

{% tabs %}
{% tab title="Response" %}

```json
{
    "Type": "Transaction",
    "Data": {
        ...
        "InteracDebtorInstitutionNumber": "999",
        "InteracDebtorInstitutionName": "Testing Financial Institution",
        "InteracDebtorFullName": "Debtor Full Name",
        ...
    }
}
```

{% endtab %}
{% endtabs %}

For Interac transactions, you can now receive the end users' financial institution name and financial institution number which was used to complete the Interac requests. To receive this information, make sure you have configured the InteracSettledIntoWallet webhook event. (You can set this event by going to settings > webhook and API settings > Interac status change).

{% hint style="info" %}
**NOTE**

In some cases the bank may return the same input provided on Zum Rails and not the name on the user’s account for the parameter "InteracDebtorFullName". This will result in the transaction going through successfully even when the name might not be a match. This is rare and the banks are working to improve on their end.
{% endhint %}

{% hint style="info" %}
**INFO**

This information might not be available for all accounts. For any questions contact our support team
{% endhint %}

## Chargeback webhook

{% tabs %}
{% tab title="Response" %}

```json
  {
      "Type": "ChargebackAction",
      "Event": "Disputed",
      "Data": {
        "Id": "e5ec36c3...5445500db505",
        "TransactionId": "ff116078...eee1a4f399a5",
        "ReceivedDate": "2024-04-10",
        "AuthorizationCode": "OK5234",
        "AcquirerReferenceNumber": "1674915201620667421592979",
        "ChargebackAmount": 9.9131,
        "DisputeCurrencyCode": "USD",
        "DisputeReasonCode": "1350",
        "MemberMessageText": "Misrepresentation",
        "FileId": "685221186",
        "ChargebackControlNumber": "771638347",
        "DueDate": "2024-04-14",
        "ChargebackWorkTypeCode": "1",
        "ChargebackStatus": "Disputed"
      }
  }
```

{% endtab %}
{% endtabs %}

The payload has a property Type to indicate to each entity the webhook status change is coming from and also a property called Event that indicates the type of event that trigger the webhook.

**Event**

| Event             | Description                            |
| ----------------- | -------------------------------------- |
| AcceptedByUser    | Chargeback was accepted by user.       |
| AcceptedByDefault | Chargeback was accepted past due date. |
| Disputed          | Chargeback was disputed by user.       |

## Aggregation Transaction webhook

The webhook is triggered at the end of the aggregation process, once the user’s bank account transactions have been retrieved.

If the process completes successfully, the response payload will include all account and transaction data. In this case, there is no need to call the API to retrieve aggregation details, as all the required information is already provided in the webhook.

If the process fails, the webhook payload will include an error message describing the issue.

**Event**

<table><thead><tr><th width="155">Event</th><th>Description</th></tr></thead><tbody><tr><td>Completed</td><td>Aggregation transaction scraping has been successfully completed. This event is triggered regardless of whether the process runs synchronously or asynchronously.</td></tr><tr><td>Failed</td><td>Aggregation transaction scraping has failed. This event is triggered only when  the process runs asynchronously.</td></tr></tbody></table>

**Response**

{% tabs %}
{% tab title="Untitled" %}

```json
{
    "Type": "AggregationTransaction",
    "Event": "Completed",
    "EventGeneratedAt": "2026-04-23T17:07:27.324644Z",
    "Data": {
        "RequestId": "2986eb0d-ae75-4190-847b-559972cfaf59",
        "CustomerId": "b9f7c096-6fb0-4338-aba3-b59f1da27d46",
        "Card": {
            "Id": "c2b3b4a4-2c5a-499e-a318-6a3c35426abf",
            "UpdatedAt": "2026-04-23T17:07:26.166376",
            "CreatedAt": "0001-01-01T00:00:00Z",
            "Accounts": [
                {
                    "Id": "6a020cee-3147-4b29-a4c0-dd38e142e036",
                    "InstitutionNumber": "900",
                    "TransitNumber": "10000",
                    "AccountNumber": "35317855",
                    "Title": "Zum Chequing",
                    "Balance": 662.64,
                    "Currency": "CAD",
                    "AccountCategory": "Operation",
                    "AccountSubCategory": "Chequing",
                    "Transactions": [
                        {
                            "Id": "b75d43db-e2e8-458d-ad9e-eb912a9730f8",
                            "UpdatedAt": "0001-01-01T00:00:00Z",
                            "Date": "2026-04-23T00:00:00",
                            "Description": "VISA DEBIT PURCHASE REVERSAL Questrade",
                            "Credit": 0.01,
                            "Balance": 662.64,
                            "Category": {
                                "Id": "baeda044-cca9-4da7-8a50-ae6ed78cf547",
                                "Name": "Credit Reversals",
                                "CategoryGroupId": "00000000-0000-0000-0000-000000000000",
                                "InsightsType": "Expense"
                            }
                        },
                        ...
                    ]
                },
                {
                    "Id": "167b866a-e9d6-4851-a44d-c9b53ef245d4",
                    "InstitutionNumber": "900",
                    "TransitNumber": "10000",
                    "AccountNumber": "8806974",
                    "Title": "Savings",
                    "Balance": 662.64,
                    "Currency": "CAD",
                    "AccountCategory": "Operation",
                    "AccountSubCategory": "Savings",
                    "Transactions": [
                        {
                            "Id": "b75d43db-e2e8-458d-ad9e-eb912a9730f8",
                            "UpdatedAt": "0001-01-01T00:00:00Z",
                            "Date": "2026-04-23T00:00:00",
                            "Description": "VISA DEBIT PURCHASE REVERSAL Questrade",
                            "Credit": 0.01,
                            "Balance": 662.64,
                            "Category": {
                                "Id": "baeda044-cca9-4da7-8a50-ae6ed78cf547",
                                "Name": "Credit Reversals",
                                "CategoryGroupId": "00000000-0000-0000-0000-000000000000",
                                "InsightsType": "Expense"
                            }
                        },
                        ...
                    ]
                },
                {
                    "Id": "422be6f9-1198-40f4-bde0-9895f73c77fb",
                    "AccountNumber": "4242424242424242",
                    "Title": "Credit Card",
                    "Balance": 2247.67,
                    "Currency": "CAD",
                    "AccountCategory": "Credit",
                    "AccountSubCategory": "CreditCard",
                    "Transactions": [
                        {
                            "Id": "1aaa80ad-7b2c-49b4-b2e2-8a251329b9c7",
                            "UpdatedAt": "0001-01-01T00:00:00Z",
                            "Date": "2026-04-23T00:00:00",
                            "Description": "Roku for Sirius XM 816-2728107, DE 4500********2426",
                            "Credit": 1.34,
                            "Category": {
                                "Id": "baeda044-cca9-4da7-8a50-ae6ed78cf598",
                                "Name": "Uncategorized Income",
                                "CategoryGroupId": "00000000-0000-0000-0000-000000000000",
                                "InsightsType": "Expense"
                            }
                        },
                        ...
                    ]
                },
                {
                    "Id": "0196cbff-ee96-4969-9bbd-8df326fde7eb",
                    "AccountNumber": "78953",
                    "Title": "Mortgage",
                    "Balance": 9876.0,
                    "Currency": "CAD",
                    "AccountCategory": "Product",
                    "AccountSubCategory": "Mortgage",
                    "Transactions": []
                }
            ],
            "InstitutionId": "2a778283-d87a-4b8c-aa3e-af1ed16bc486",
            "InstitutionName": "Zūm Rails Testing Bank",
            "HolderId": "75924a9c-0023-4418-b870-a06b813ec0be",
            "Holder": {
                "FirstName": "John",
                "LastName": "Doe",
                "FullName": "John Doe",
                "Email": "john@doe.com",
                "PhoneNumber": "8171204182",
                "DateOfBirth": "01-01-1990",
                "AddressCivic": "1st Street",
                "AddressCity": "Toronto",
                "AddressProvince": "ON",
                "AddressCountry": "CA",
                "AddressPostalCode": "A0A0A0"
            },
            "SelectedAccountId": "6a020cee-3147-4b29-a4c0-dd38e142e036"
        }
    }
}
```

{% endtab %}

{% tab title="Failed" %}

```json
{
  "Type": "AggregationTransaction",
  "Event": "Failed",
  "EventGeneratedAt": "2026-04-23T17:38:07.935049Z",
  "Data": {
    "RequestId": "8a6ac025-2685-437f-9739-a7c65bedca89",
    "CustomerId": "0d0df5d6-6bbd-46f5-802c-bd1afd16b06f",
    "Card": {
      "Id": "c003a54c-3a7a-4c3c-b6b1-137f00108aba",
      "UpdatedAt": "2026-04-23T17:22:41.372738",
      "CreatedAt": "0001-01-01T00:00:00Z",
      "Accounts": [
        {
          "Id": "8958e418-ff29-4040-b42e-5127343906a4",
          "AccountNumber": "499968763",
          "RoutingNumber": "021000021",
          "Title": "Zum Chequing",
          "Balance": 662.64,
          "Currency": "USD",
          "AccountCategory": "Operation",
          "AccountSubCategory": "Chequing",
          "Transactions": []
        },
        {
          "Id": "385513bf-2159-409c-b106-f75aad902479",
          "AccountNumber": "599168988",
          "RoutingNumber": "021000021",
          "Title": "Savings",
          "Balance": 662.64,
          "Currency": "USD",
          "AccountCategory": "Operation",
          "AccountSubCategory": "Savings",
          "Transactions": []
        },
        {
          "Id": "9dc0dd2b-3fac-4423-b513-253ad7a730ca",
          "AccountNumber": "4242424242424242",
          "RoutingNumber": "021000021",
          "Title": "Credit Card",
          "Balance": 2247.67,
          "Currency": "USD",
          "AccountCategory": "Credit",
          "AccountSubCategory": "CreditCard",
          "Transactions": []
        },
        {
          "Id": "b3e4f549-8f20-4a50-902f-757914a71c1f",
          "AccountNumber": "265900951",
          "RoutingNumber": "021000021",
          "Title": "Mortgage",
          "Balance": 2506,
          "Currency": "USD",
          "AccountCategory": "Product",
          "AccountSubCategory": "Mortgage",
          "Transactions": []
        }
      ],
      "InstitutionId": "2a778283-d87a-4b8c-aa3e-af1ed16bc486",
      "InstitutionName": "Zūm Rails Testing Bank",
      "HolderId": "7605617a-d085-4603-a057-62d1e984300a",
      "Holder": {
        "FirstName": "John",
        "LastName": "Doe",
        "FullName": "John Doe",
        "Email": "john@doe.com",
        "PhoneNumber": "9486778618",
        "DateOfBirth": "01-01-1990",
        "AddressCivic": "1st Street",
        "AddressCity": "New York",
        "AddressProvince": "New York",
        "AddressCountry": "US",
        "AddressPostalCode": "111111111"
      },
      "SelectedAccountId": "8958e418-ff29-4040-b42e-5127343906a4"
    },
    "ErrorMessage": "Simulated permanent async transaction failure (zumAsyncTxnFail): all retries will be exhausted"
  }
}
```

{% endtab %}
{% endtabs %}

## Prepaid Card User webhook

{% tabs %}
{% tab title="OnboardIncomplete" %}

```json
{
  "Type": "PrepaidCardUser",
  "Event": "OnboardIncomplete",
  "EventGeneratedAt": "2026-03-31T16:14:53.5639672Z",
  "Data": {
    "CardVerificationStatus": "INCOMPLETE",
    "Warnings": [
      "Face mismatch between document/govern,ent photo and selfie photo.",
      "The given identity document/number has been previously verified.",
      "Selfie photo is not live."
    ],
    "CardOnboardingSession": "https://checkout-master.zumrails.ca/baas/register/21d76d60-559f-48a3-bf17-68878956e2bc/508a2a3f-8cdc-40e9-987c-6d9343a21b9e",
    "User": {
      "FirstName": "Test",
      "LastName": "webhook3",
      "DateOfBirth": "01/01/1990"
    },
    "CardApplicationStatus": "Incomplete",
    "CardRegistrationStatus": "",
    "CustomerId": "21d76d60-559f-48a3-bf17-68878956e2bc",
    "CreatedAt": "2026-03-31T16:13:49.758566",
    "UserCardId": "e4d41dc2-b369-4888-aa18-741fa8c556f1",
    "CardType": "PrepaidCard",
    "UserId": "4a78182b-4958-4f88-a50b-89f15835b81b"
  }
}
```

{% endtab %}

{% tab title="OnboardApproval" %}

```json
{
  "Type": "PrepaidCardUser",
  "Event": "OnboardApproval",
  "EventGeneratedAt": "2026-03-31T16:20:07.8649699Z",
  "Data": {
    "CardVerificationStatus": "APPROVED",
    "Warnings": [],
    "CardOnboardingSession": "https://checkout-master.zumrails.ca/baas/register/21d76d60-559f-48a3-bf17-68878956e2bc/508a2a3f-8cdc-40e9-987c-6d9343a21b9e",
    "User": {
      "FirstName": "Test",
      "LastName": "webhook3",
      "DateOfBirth": "01/01/1990",
      "Occupation": "Financial Services (Investment Advisor, Insurance Agent, Mortgage Broker, Financial Analyst, etc)",
      "ShippingAddress": {
        "AddressLine1": "5456 Tomken Road",
        "AddressPostalCode": "L4W 2Z5",
        "AddressCountry": "CA",
        "AddressCity": "Mississauga",
        "AddressState": "ON"
      },
      "BillingAddress": {
        "AddressLine1": "5456 Tomken Road",
        "AddressPostalCode": "L4W 2Z5",
        "AddressCountry": "CA",
        "AddressCity": "Mississauga",
        "AddressState": "ON"
      }
    },
    "CardApplicationStatus": "PendingApproval",
    "CardStatus": "PendingCardIssuance",
    "CardRegistrationStatus": "NotRegistered",
    "CustomerId": "21d76d60-559f-48a3-bf17-68878956e2bc",
    "CreatedAt": "2026-03-31T16:13:49.758566",
    "UserCardId": "e4d41dc2-b369-4888-aa18-741fa8c556f1",
    "CardType": "PrepaidCard",
    "UserId": "4a78182b-4958-4f88-a50b-89f15835b81b"
  }
}
```

{% endtab %}

{% tab title="Card Issued" %}

```json
{
  "Type": "PrepaidCardUser",
  "Event": "CardIssued",
  "EventGeneratedAt": "2026-03-31T16:44:07.1663038Z",
  "Data": {
    "User": {
      "FirstName": "Test",
      "LastName": "webhook3",
      "DateOfBirth": "01/01/1990",
      "Occupation": "Financial Services (Investment Advisor, Insurance Agent, Mortgage Broker, Financial Analyst, etc)",
      "ShippingAddress": {
        "AddressLine1": "5456 Tomken Road",
        "AddressPostalCode": "L4W 2Z5",
        "AddressCountry": "CA",
        "AddressCity": "Mississauga",
        "AddressState": "ON"
      },
      "BillingAddress": {
        "AddressLine1": "5456 Tomken Road",
        "AddressPostalCode": "L4W 2Z5",
        "AddressCountry": "CA",
        "AddressCity": "Mississauga",
        "AddressState": "ON"
      }
    },
    "CardBrand": "Unknown",
    "CardApplicationStatus": "Approved",
    "CardNumber": "************4204",
    "ExpireMonth": "03",
    "ExpireYear": "29",
    "CardStatus": "IssuedInactive",
    "CardReferenceId": "599000169970",
    "CardRegistrationStatus": "NotRegistered",
    "CardProgramId": "Zumrail_ProdT",
    "CardHolderId": "599000000000001699",
    "AvailableBalance": 0,
    "LedgerBalance": 0,
    "CustomerId": "21d76d60-559f-48a3-bf17-68878956e2bc",
    "CreatedAt": "2026-03-31T16:13:49.758566",
    "CardActivatedAt": "2026-03-31T16:44:04.223791Z",
    "UserCardId": "e4d41dc2-b369-4888-aa18-741fa8c556f1",
    "CardType": "PrepaidCard",
    "UserId": "4a78182b-4958-4f88-a50b-89f15835b81b"
  }
}

```

{% endtab %}
{% endtabs %}

**Event**

| Type            | Event              | Description                                                                            |
| --------------- | ------------------ | -------------------------------------------------------------------------------------- |
| PrepaidCardUser | OnboardIncomplete  | Prepaid card application profile setup completed but did not complete the KYC/IDV step |
| PrepaidCardUser | OnboardInProgress  | Prepaid card application verification started but not finished                         |
| PrepaidCardUser | OnboardApproval    | Prepaid card application verification is successful and passed                         |
| PrepaidCardUser | OnboardDeclined    | Prepaid card application is declined (same format as OnboardIncomplete)                |
| PrepaidCardUser | OnboardUnderReview | Prepaid card application is under review (same format as OnboardIncomplete)            |
| PrepaidCardUser | CardIssued         | Prepaid card is issued to the approved user                                            |
| PrepaidCardUser | CardActivated      | Prepaid card is activated (same format as CardIssued)                                  |
| PrepaidCardUser | CardStatusChanged  | Prepaid card status change (same format as CardIssued)                                 |
| PrepaidCardUser | CardProgramChanged | Prepaid card program change (same format as CardIssued)                                |
| PrepaidCardUser | CardReissue        | Prepaid card is reissued (same format as CardIssued)                                   |
| PrepaidCardUser | ProfileUpdate      | Prepaid card profile change (same format as CardIssued)                                |

Onboard Status

| Type            | Event              | Card Verification Status |
| --------------- | ------------------ | ------------------------ |
| PrepaidCardUser | OnboardIncomplete  | INCOMPLETE               |
| PrepaidCardUser | OnboardInProgress  | IN PROGRESS              |
| PrepaidCardUser | OnboardApproval    | APPROVED                 |
| PrepaidCardUser | OnboardDeclined    | DECLINED                 |
| PrepaidCardUser | OnboardUnderReview | UNDER REVIEW             |

## Secured Credit Card User webhook

{% tabs %}
{% tab title="OnboardIncomplete" %}

```json
{
  "Type": "SecuredCreditCardUser",
  "Event": "OnboardIncomplete",
  "EventGeneratedAt": "2026-04-30T14:45:23.1203217Z",
  "Data": {
    "CardVerificationStatus": "INCOMPLETE",
    "Warnings": [],
    "CardOnboardingSession": "https://checkout-master.zumrails.ca/baas/register/secured-credit-card/5c6b68c7-225a-4611-be48-b6b338d9f4fe/c5af2fa7-c110-4fe6-8c1d-581c371577db",
    "User": {
      "FirstName": "Test",
      "LastName": "web1",
      "DateOfBirth": "09/23/1987",
      "Email": "juliana.correa+web1@zumrails.com",
      "PhoneNumber": "8768768768",
      "Language": "En"
    },
    "CardApplicationStatus": "Incomplete",
    "CardRegistrationStatus": "",
    "CustomerId": "5c6b68c7-225a-4611-be48-b6b338d9f4fe",
    "CreatedAt": "2026-04-30T14:44:37.023242",
    "CreditLimitRequested": 1000,
    "UserCardId": "62cfe658-b5fe-47d7-aea4-36745872ea96",
    "CardType": "SecuredCreditCard",
    "UserId": "f1a816b1-a480-4fd9-b1eb-fff65f24c30d"
  }
}

```

{% endtab %}

{% tab title="OnboardApproval" %}

```json
{
  "Type": "SecuredCreditCardUser",
  "Event": "OnboardApproval",
  "EventGeneratedAt": "2026-04-30T14:48:28.3292066Z",
  "Data": {
    "CardVerificationStatus": "APPROVED",
    "Warnings": [],
    "CardOnboardingSession": "https://checkout-master.zumrails.ca/baas/register/secured-credit-card/5c6b68c7-225a-4611-be48-b6b338d9f4fe/c5af2fa7-c110-4fe6-8c1d-581c371577db",
    "User": {
      "FirstName": "Test",
      "LastName": "web1",
      "DateOfBirth": "09/23/1987",
      "Email": "juliana.correa+web1@zumrails.com",
      "PhoneNumber": "8768768768",
      "Language": "En",
      "Occupation": "Information Technology (Software Developer, IT Consultant, Systems Analyst, Network Administrator, etc)",
      "ShippingAddress": {
        "AddressLine1": "435 Wilson Avenue",
        "AddressPostalCode": "N2C 2R9",
        "AddressCountry": "CA",
        "AddressCity": "Kitchener",
        "AddressState": "ON"
      },
      "BillingAddress": {
        "AddressLine1": "435 Wilson Avenue",
        "AddressPostalCode": "N2C 2R9",
        "AddressCountry": "CA",
        "AddressCity": "Kitchener",
        "AddressState": "ON"
      }
    },
    "CardApplicationStatus": "PendingApproval",
    "CardStatus": "PendingCardIssuance",
    "CardRegistrationStatus": "NotRegistered",
    "CustomerId": "5c6b68c7-225a-4611-be48-b6b338d9f4fe",
    "CreatedAt": "2026-04-30T14:44:37.023242",
    "CreditLimitRequested": 1000,
    "UserCardId": "62cfe658-b5fe-47d7-aea4-36745872ea96",
    "CardType": "SecuredCreditCard",
    "UserId": "f1a816b1-a480-4fd9-b1eb-fff65f24c30d"
  }
}

```

{% endtab %}

{% tab title="Card Issued" %}

```json
{
  "Type": "SecuredCreditCardUser",
  "Event": "CardIssued",
  "EventGeneratedAt": "2026-04-30T14:50:27.133021Z",
  "Data": {
    "User": {
      "FirstName": "Test",
      "LastName": "web1",
      "DateOfBirth": "09/23/1987",
      "Email": "juliana.correa+web1@zumrails.com",
      "PhoneNumber": "8768768768",
      "Language": "En",
      "Occupation": "Information Technology (Software Developer, IT Consultant, Systems Analyst, Network Administrator, etc)",
      "ShippingAddress": {
        "AddressLine1": "435 Wilson Avenue",
        "AddressPostalCode": "N2C 2R9",
        "AddressCountry": "CA",
        "AddressCity": "Kitchener",
        "AddressState": "ON"
      },
      "BillingAddress": {
        "AddressLine1": "435 Wilson Avenue",
        "AddressPostalCode": "N2C 2R9",
        "AddressCountry": "CA",
        "AddressCity": "Kitchener",
        "AddressState": "ON"
      }
    },
    "CardBrand": "Unknown",
    "CardApplicationStatus": "Approved",
    "CardNumber": "************6644",
    "ExpireMonth": "04",
    "ExpireYear": "28",
    "CardStatus": "IssuedInactive",
    "CardRegistrationStatus": "NotRegistered",
    "CardProgramId": "SECURE_TEST",
    "CardHolderId": "599000000000002218",
    "AvailableBalance": -10,
    "LedgerBalance": -10,
    "CustomerId": "5c6b68c7-225a-4611-be48-b6b338d9f4fe",
    "CreatedAt": "2026-04-30T14:44:37.023242",
    "PendingAmount": 0,
    "CreditLimitRequested": 1000,
    "CreditLimit": 250,
    "SecurityDepositAmount": 250,
    "SecurityDepositCardNumber": "95T5925560164758685",
    "SecurityDepositCardReferenceId": "599000221747",
    "LastPaymentAmount": 0,
    "MinimumPaymentAmount": 0,
    "StatementAmount": 0,
    "UserCardId": "62cfe658-b5fe-47d7-aea4-36745872ea96",
    "CardType": "SecuredCreditCard",
    "UserId": "f1a816b1-a480-4fd9-b1eb-fff65f24c30d"
  }
}

```

{% endtab %}
{% endtabs %}

**Event**

| Type                  | Event               | Description                                                                                                  |
| --------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------ |
| SecuredCreditCardUser | OnboardIncomplete   | Card application profile setup completed but did not complete the KYC/IDV step                               |
| SecuredCreditCardUser | OnboardInProgress   | Card application verification started but not finished                                                       |
| SecuredCreditCardUser | OnboardApproval     | Card application verification is successful and passed                                                       |
| SecuredCreditCardUser | OnboardDeclined     | Card application is declined (same format as OnboardIncomplete)                                              |
| SecuredCreditCardUser | OnboardUnderReview  | Card application is under review (same format as OnboardIncomplete)                                          |
| SecuredCreditCardUser | CardIssued          | Card is issued to the approved user                                                                          |
| SecuredCreditCardUser | CardActivated       | Caard is activated (same format as CardIssued)                                                               |
| SecuredCreditCardUser | CardStatusChanged   | Card status change (same format as CardIssued)                                                               |
| SecuredCreditCardUser | CardProgramChanged  | Card program change (same format as CardIssued)                                                              |
| SecuredCreditCardUser | CardReissue         | Card is reissued (same format as CardIssued)                                                                 |
| SecuredCreditCardUser | ProfileUpdate       | Card profile change (same format as CardIssued)                                                              |
| SecuredCreditCardUser | CardAttributeUpdate | Card related attribute updates such as security deposit and credit limit changes (same format as CardIssued) |

Onboard Status

| Type                  | Event              | Card Verification Status |
| --------------------- | ------------------ | ------------------------ |
| SecuredCreditCardUser | OnboardIncomplete  | INCOMPLETE               |
| SecuredCreditCardUser | OnboardInProgress  | IN PROGRESS              |
| SecuredCreditCardUser | OnboardApproval    | APPROVED                 |
| SecuredCreditCardUser | OnboardDeclined    | DECLINED                 |
| SecuredCreditCardUser | OnboardUnderReview | UNDER REVIEW             |

## Card Transaction webhook

{% tabs %}
{% tab title="NetworkDebit" %}

```json
{
  "Type": "PrepaidCardTransaction",
  "Event": "NetworkDebit",
  "EventGeneratedAt": "2026-03-31T19:46:21.0615358Z",
  "Data": {
    "Transaction": {
      "TransactionId": "511",
      "MessageType": "0200",
      "Date": "2026-03-31",
      "Time": "21:47:27",
      "CardAcceptor": {
        "AcquirerId": "ACQ987",
        "MerchantCode": "MERCH12345",
        "NameAndLocation": "AIR LANKA (ABBR. AIR LANKA). New York NY",
        "MerchantCity": "New York",
        "MerchantState": "NY",
        "MerchantZipCode": "10001",
        "MCC": "3044",
        "DeviceId": "POS001",
        "DeviceType": "Terminal",
        "LocalDateTime": "2026-03-06T11:20:30"
      },
      "TransactionType": "00",
      "TransactionAmount": -3.22,
      "TransactionResponseCode": "00",
      "NetworkId": "mastercard",
      "TransactionDescription": " Network Posted Debit Transaction"
    },
    "CardReferenceId": "599000170193",
    "UserCardId": "4be272ca-81b8-43d5-840a-aa23a514403e",
    "CardType": "PrepaidCard",
    "UserId": "4a78182b-4958-4f88-a50b-89f15835b81b"
  }
}

```

{% endtab %}

{% tab title="NonNetworkDebit" %}

```json
{
  "Type": "PrepaidCardTransaction",
  "Event": "NonNetworkDebit",
  "EventGeneratedAt": "2026-03-31T20:09:28.5640318Z",
  "Data": {
    "LocalDateTime": "2026-03-05T11:20:30",
    "TransactionId": "865",
    "Date": "2026-03-31",
    "Time": "21:47:27",
    "TransactionAmount": -1.2,
    "TransactionDescription": " NO - Network Posted Debit Transaction",
    "CardReferenceId": "599000170193",
    "UserCardId": "4be272ca-81b8-43d5-840a-aa23a514403e",
    "CardType": "PrepaidCard",
    "UserId": "4a78182b-4958-4f88-a50b-89f15835b81b"
  }
}
```

{% endtab %}

{% tab title="InactiveCardFee" %}

```json
{
  "Type": "PrepaidCardTransaction",
  "Event": "InactiveCardFee",
  "EventGeneratedAt": "2026-04-01T15:03:05.4325256Z",
  "Data": {
    "TransactionId": "7706",
    "Date": "2026-04-01",
    "Time": "00:53:29",
    "TransactionAmount": -1.5,
    "TransactionCurrency": "CAD",
    "TransactionDescription": "Fee - Card Inactivity",
    "CardReferenceId": "599000170193",
    "UserCardId": "4be272ca-81b8-43d5-840a-aa23a514403e",
    "CardType": "PrepaidCard",
    "UserId": "4a78182b-4958-4f88-a50b-89f15835b81b"
  }
}
```

{% endtab %}
{% endtabs %}

**Card Transaction Event**

<table><thead><tr><th width="257.515625">Type</th><th>Event</th><th>Description</th></tr></thead><tbody><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>NetworkDebit</td><td>Card network debit related financial transactions</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>NetworkCredit</td><td>Card network credit related financial transactions (same format as NetworkDebit)</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>NetworkDecline</td><td>Card network decline related financial transactions (same format as NetworkDebit)</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>NonNetworkDebit</td><td>Card non-network debit related financial transactions</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>NonNetworkCredit</td><td>Card non-network credit related financial transactions (same format as NonNetworkDebit)</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>NonNetworkDecline</td><td>Card non-network decline related financial transactions (same format as NonNetworkDebit)</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>TransactionReversal</td><td>Card transaction reversals (same formast as NonNetworkDebit)</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>InactiveCardFee</td><td>Card inactivity fee applied to the card</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>OverdraftFee</td><td>Card overdraft fee applied to the card</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>LatePaymentFee</td><td>Card late payment fee applied to the card</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>MaintenanceFee</td><td>Card maintenance fee applied to the card</td></tr><tr><td><p>PrepaidCardTransaction /</p><p>SecuredCreditCardTransaction</p></td><td>IssuingCardFee</td><td>Card issuing fee applied to the card</td></tr><tr><td></td><td></td><td></td></tr></tbody></table>

**MessageType**

Based on the `Transaction` object, you can determine the type of transaction based on the following `Transaction.MessageType`

| Value | Description                   |
| ----- | ----------------------------- |
| 0200  | Posted Transaction Normal     |
| 0220  | Posted Transaction Force Post |
| 0400  | Posted Transaction Reversal   |
| 0420  | Posted Transaction Reversal   |
| 0100  | Pending Transaction           |
| 0120  | Pending Transaction           |
| 0720  | Fee-based Transaction         |
| 0722  | Fee-based Transaction         |

## OTP webhook

{% tabs %}
{% tab title="CardholderPortalOtp" %}

```json
{
  "Type": "CardUserOTP",
  "Event": "CardHolderPortal",
  "EventGeneratedAt": "2026-03-31T15:25:51.9038934Z",
  "Data": {
    "CreateAt": "2026-03-31T15:25:51.9036441Z",
    "OtpMessage": "84059320",
    "OtpExpiry": "10",
    "UserEmail": "testcard@zumrails.com",
    "UserId": "007db275-bdfa-4869-b407-501698a52fdd"
  }
}
```

{% endtab %}

{% tab title="MobileWalletOtp" %}

```json
{
  "Type": "PrepaidCardOTP",
  "Event": "MobileWalletOtp",
  "EventGeneratedAt": "2026-04-01T13:22:03.6225619Z",
  "Data": {
    "WalletType": "ApplePay",
    "CardType": "SecuredCreditCard",
    "UserCardId": "fa9e1fd6-cc5a-478d-82f1-f6929e64c9d6",
    "CreateAt": "2026-04-30T00:00:00",
    "OtpMessage": "777880",
    "OtpExpiry": "10",
    "UserEmail": "testcard@zumrails.com",
    "UserId": "f1a816b1-a480-4fd9-b1eb-fff65f24c30d"
  }
}

```

{% endtab %}

{% tab title="ThreeDsOtp" %}

```json
{
  "Type": "SecuredCreditCardOTP",
  "Event": "ThreeDsOtp",
  "EventGeneratedAt": "2026-04-30T15:52:03.7613484Z",
  "Data": {
    "CardType": "SecuredCreditCard",
    "UserCardId": "fa9e1fd6-cc5a-478d-82f1-f6929e64c9d6",
    "CreateAt": "2026-04-30T00:00:00",
    "OtpMessage": "123456",
    "OtpExpiry": "2",
    "UserEmail": "juliana.correa+web1@zumrails.com",
    "UserId": "f1a816b1-a480-4fd9-b1eb-fff65f24c30d"
  }
}

```

{% endtab %}
{% endtabs %}

**OTP Event**

The `OtpExpiry` parameter is in minutes.

| Type                                             | Event               | Description                                                                                  |
| ------------------------------------------------ | ------------------- | -------------------------------------------------------------------------------------------- |
| CardUserOTP                                      | CardHolderPortalOtp | OTP for cardholder portal login                                                              |
| <p>PrepaidCardOTP / <br>SecuredCreditCardOTP</p> | MobileWalletOtp     | Prepaid card mobile wallet provisioning triggered an OTP request                             |
| <p>PrepaidCardOTP / <br>SecuredCreditCardOTP</p> | ThreeDsOtp          | Prepaid card online transaction triggered a 3DS OTP request (same format as MobileWalletOtp) |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zumrails.com/api-reference/webhooks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
