# Reference: Webhook Events Complete specifications for all Forage webhook events, payload schemas, and IP addresses ## Example webhook payload ```json { "created": "2023-10-05T17:38:26.698516-07:00", "data": { "ebt_cash_total": "10.00", "external_order_id": "58503b96-5111-495b-b13b-d9247be12e75", "merchant_fns": "121212", "merchant_id": "2fb3asdz40", "order_ref": "3ee466e0ef", "payments": [ { "amount": "10.00", "funding_type": "ebt_snap", "merchant_fns": "0256679", "merchant_id": "07839ae280", "order_ref": "3ee466e0ef", "payment_ref": "5fa6e45620", "status": "succeeded" }, { "amount": "10.00", "funding_type": "ebt_cash", "merchant_fns": "0256679", "merchant_id": "07839ae280", "order_ref": "3ee466e0ef", "payment_ref": "sd7v223HsA", "status": "succeeded" } ], "remaining_total": "0.00", "snap_total": "10.00", "status": "succeeded" }, "ref": "72672bab12", "type": "ORDER_STATUS_UPDATED" } ``` > ⚠️ **Some numeric values are represented as strings** > > The decimal values in webhook payloads are returned as strings. Refer to the [API introduction](https://docs.joinforage.app/reference/introduction#some-numeric-values-are-returned-as-strings) for details on how to parse the data. ### Common payload fields All webhooks, no matter the `type`, return the following properties: | | Type | Description | Example value | | --------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | `created` | date-time | The timestamp of event creation, represented as an [ISO-8601 date-time](https://www.iso.org/iso-8601-date-and-time-format.html) string. | `2023-10-05T17:38:26.698516-07:00` | | `data` | object | An object including event-specific information. | Refer to the event sections below for example values corresponding to each event type. | | `ref` | string | A unique string identifier for the event. | `72672bcxgq` | | `type` | string | A string representing the type of the event. Refer to the event sections below for available types. | `ORDER_STATUS_UPDATED` | ## Onboarding events If you're using the the Forage Merchant Onboarding UI, then you can listen for webhooks that indicate when a merchant enters a different stage of the onboarding lifecycle. These webhooks include: * [`MERCHANT_ONBOARDING_SUBMITTED`](https://docs.joinforage.app/docs/configure-webhooks#merchant_onboarding_submitted) * [`MERCHANT_ONBOARDING_VERIFICATION_FAILED`](https://docs.joinforage.app/docs/configure-webhooks#merchant_onboarding_verification_failed) * [`MERCHANT_ONBOARDING_LIVE`](https://docs.joinforage.app/docs/configure-webhooks#merchant_onboarding_live) ```mermaid stateDiagram-v2 [*] --> Submitted : Merchant completes Onboarding UI Submitted --> VerificationFailed : FNS cannot be validated Submitted --> Live : FNS verified VerificationFailed --> [*] : No automatic retry Live --> [*] note right of Submitted : SUBMITTED fires note right of VerificationFailed : VERIFICATION_FAILED fires note right of Live : LIVE fires ``` In addition to the common payload fields that all webhooks return, every onboarding event webhook details the following attributes: | | Type | Description | Example value | | ----------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | `merchant_ref` | string | The unique merchant ID that Forage provides during onboarding. | `36e7fcecbb` | | `merchant_fns` | string | The merchant's unique FNS number. | `121212` | | `name` | string | The name of the merchant. | `MerchantName` | | `store_number` | string | A unique number provided by the platform (not Forage) to identify the merchant. | `123456` | | `address` | object | The merchant's physical address. | `{ "line1": "1856 Market St.", "line2": null, "city": "San Francisco", "state": "CA", "zipcode": "94102", "country": "US" }` | | `timezone_offset` | number | The number of hours between UTC and the merchant's timezone. For example, if a merchant is based in EST, then the timezone\_offset is `-4`. If based in PST, then the value is `-7`. | `-7` | | `is_physical_store` | boolean | Whether this onboarded merchant represents a physical store location. | `true` | | `contact_email` | string | An email address that can be used to contact the merchant. | `hello@merchantname.com` | | `chargeback_email` | string | The email address that Forage uses to contact the merchant in case of chargebacks. | `finance@merchantname.com` | | `agreed_to_tos` | date-time | A timestamp of when the merchant signed the platform's terms of service, represented as an [ISO-8601 date-time](https://www.iso.org/iso-8601-date-and-time-format.html) string. | `2023-10-05T17:38:26.698516-07:00` | | `customer_merchant_reference` | string | A unique reference hash identifier for the onboarding merchant provided by the platform (not Forage). | `987xy12z34` | | `go_live_date` | date-time | A timestamp of when a merchant is live with Forage and can begin processing EBT, represented as an [ISO-8601 date-time](https://www.iso.org/iso-8601-date-and-time-format.html) string. The actual live date may differ depending on the parent platform. | `2023-11-05T17:38:26.698516-07:00` | ### MERCHANT\_ONBOARDING\_SUBMITTED The `MERCHANT_ONBOARDING_SUBMITTED` webhook fires when an onboarding merchant has completed the Onboarding UI and submitted the information to Forage. ```json { "created": "2023-10-05T17:38:26.698516-07:00", "data": { "merchant_ref": "36e7fcecbb", "fns_number": "121212", "name": "MerchantName", "store_number": "123456", "address": { "line1": "1856 Market St.", "city": "San Francisco", "state": "CA", "zipcode": "94102", "country": "US" }, "timezone_offset": -7, "is_physical_store": true, "contact_email": "hello@merchantname.com", "chargeback_email": "finance@merchantname.com", "agreed_to_tos": "2023-10-05T17:38:26.698516-07:00", "customer_merchant_reference": "987xy12z34", "go_live_date": "2023-11-05T17:38:26.698516-07:00", }, "ref": "72672b13bb", "type": "MERCHANT_ONBOARDING_SUBMITTED", } ``` ### MERCHANT\_ONBOARDING\_VERIFICATION\_FAILED Forage sends a `MERCHANT_ONBOARDING_VERIFICATION_FAILED` webhook if the FNS number that the merchant submitted through the Onboarding UI is unable to be validated. ```json { "created": "2023-10-05T17:38:26.698516-07:00", "data": { "merchant_ref": "36e7fcecbb", "fns_number": "121212", "name": "MerchantName", "store_number": "123456", "address": { "line1": "1856 Market St.", "city": "San Francisco", "state": "CA", "zipcode": "94102", "country": "US" }, "timezone_offset": -7, "is_physical_store": true, "contact_email": "hello@merchantname.com", "chargeback_email": "finance@merchantname.com", "agreed_to_tos": "2023-10-05T17:38:26.698516-07:00", "customer_merchant_reference": "987xy12z34", "go_live_date": "2023-11-05T17:38:26.698516-07:00", }, "ref": "72672b13bb", "type": "MERCHANT_ONBOARDING_VERIFICATION_FAILED", } ``` ### MERCHANT\_ONBOARDING\_LIVE The `MERCHANT_ONBOARDING_LIVE` webhook fires when Forage has successfully verified and onboarded the merchant. ```json { "created": "2023-10-05T17:38:26.698516-07:00", "data": { "merchant_ref": "36e7fcecbb", "fns_number": "121212", "name": "MerchantName", "store_number": "123456", "address": { "line1": "1856 Market St.", "city": "San Francisco", "state": "CA", "zipcode": "94102", "country": "US" }, "timezone_offset": -7, "is_physical_store": true, "contact_email": "hello@merchantname.com", "chargeback_email": "finance@merchantname.com", "agreed_to_tos": "2023-10-05T17:38:26.698516-07:00", "customer_merchant_reference": "987xy12z34", "go_live_date": "2023-11-05T17:38:26.698516-07:00", }, "ref": "72672b13bb", "type": "MERCHANT_ONBOARDING_LIVE", } ``` ## SDK integrations SDK integrations interact with Forage `Payment` and `PaymentRefund` resources. The following webhooks are relevant to SDK integrations. ### PAYMENT\_STATUS\_UPDATED The `PAYMENT_STATUS_UPDATED` webhook fires when the status of an EBT SNAP or EBT Cash payment is updated. The webhook `data.status` attribute is always one of `succeeded`, `failed`, or `canceled`. `data.status == succeeded` when: * The EBT [state processor](https://docs.joinforage.app/docs/ebt-online-101#state-processor) completes the payment and sends Forage a success response `succeeded` is a terminal state. `data.status == failed` when: * The state processor cannot complete the payment and sends Forage a failure response, like if a customer doesn't have sufficient funds on their EBT card * Forage is unable to contact the state processor `failed` is not a terminal state. `data.status == canceled` when: * You manually cancel a payment via a `POST` to [`/payments/{payment_ref}/cancel/`](https://docs.joinforage.app/reference/cancel-a-payment) `canceled` is a terminal state. For guidance on using this event to trigger internal processes, see [How Forage Webhooks Work](./webhooks-concepts.md). ```json { "created": "2023-10-05T17:38:26.698516-07:00", "data": { "amount": "10.00", "external_order_id": "a238d043-5d88-4bd8-bdf5-769c83e2482e", "funding_type": "ebt_snap", "merchant_fns": "121212", "merchant_id": "2fb3asd", "payment_ref": "3a16426601", "status": "succeeded", }, "ref": "72672b13bb", "type": "PAYMENT_STATUS_UPDATED", } ``` ```json { "ref": "cd9e3b2c83", "created": "2024-05-21T14:50:57.861207+00:00", "type": "PAYMENT_STATUS_UPDATED", "data": { "payment_ref": "2a629162f4", "status": "failed", "amount": "20.00", "merchant_fns": "1234567", "merchant_id": "4f984ec909", "failure_reason": { "code": "ebt_error_51", "message": "Insufficient funds - Insufficient Funds. Remaining balances are SNAP: $100.00, EBT Cash: $100.00" }, "funding_type": "ebt_cash", "previous_errors": [ { "code": "ebt_error_51", "message": "Insufficient funds - Insufficient Funds. Remaining balances are SNAP: $100.00, EBT Cash: $100.00", "details": { "cash_balance": "100.00", "snap_balance": "100.00" }, "source": { "resource": "Payments", "ref": "2a629162f4" } } ] } } ``` #### PAYMENT\_STATUS\_UPDATED `data` attributes | | Type | Description | Example value | | --------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- | | `amount` | string | The amount charged to the payment method. | `10.00` | | `external_order_id` | string | A unique identifier for the order as created by the merchant or platform (not Forage). | `a238d043-5d88-4bd8-bdf5-769c83e2482e` | | `funding_type` | string | A string that represents the type of tender. One of: `benefit`, `ebt_cash`, `ebt_snap` | `ebt_snap` | | `merchant_fns` | string | The merchant's unique [FNS](https://docs.joinforage.app/docs/ebt-online-101#food-and-nutrition-service-fns) number. | `121212` | | `merchant_id` | string | A 10-character unique hash identifying the merchant associated with this transaction. | `gxe37pc24y` | | `payment_ref` | string | A unique reference identifier for the payment. | `3a16426601` | | `status` | string | A string representing the payment's state in the processing cycle. | `succeeded` | | `failure_reason` *(failure only)* | object | An object with the following keys: `code`: A short string that helps identify the cause of the error. For example, `"55"` indicates that a customer entered an invalid EBT Card PIN. `message`: A developer-facing description of the error. Refer to the [errors reference](https://docs.joinforage.app/reference/errors#code-and-message-pairs-1) for common `code` and `message` pairs. | `55` `Invalid PIN or PIN not selected - Invalid PIN` | | `previous_errors` | array | An array of objects that include the `code`, `message` and `source` values corresponding to the most recent EBT network-related error associated with a canceled or failed `Payment`. This field is only returned when the `data.status` of the webhook is `canceled` or `failed`. | Refer to the complete Failed example above. | ### REFUND\_STATUS\_UPDATED The `REFUND_STATUS_UPDATED` webhook fires when the status of a refund is updated. The webhook `data.status` attribute is always one of `succeeded`, `failed`, or `canceled`. `data.status == succeeded` when: * The EBT [state processor](https://docs.joinforage.app/docs/ebt-online-101#state-processor) completes the refund and sends Forage a success response `succeeded` is a terminal state. `data.status == failed` when: * The EBT [state processor](https://docs.joinforage.app/docs/ebt-online-101#state-processor) cannot complete the refund and sends Forage a failure response * Forage is unable to contact the state processor `failed` is not a terminal state. `data.status == canceled` when: * A refund is voided. In this rare case, the financial effect of the refund is reversed `canceled` is a terminal state. For guidance on using this event to trigger internal processes, see [How Forage Webhooks Work](./webhooks-concepts.md). ```json { "ref": "72672bc724", "created": "2023-10-05T17:38:26.698516-07:00", "type": "REFUND_STATUS_UPDATED", "data": { "refund_ref": "87432dehkk", "external_order_id": "a238d043-5d88-4bd8-bdf5-769c83e2482e", "status": "succeeded", "amount": "25.99", "merchant_fns": "121212", "merchant_id": "2fb3asd", "payment_ref": "8e3c6a9d07" } } ``` ```json { "ref": "e1ecf255f4", "created": "2024-01-31T19:50:10.065453+00:00", "type": "REFUND_STATUS_UPDATED", "data": { "refund_ref": "60ddf6e386", "external_order_id": "a238d043-5d88-4bd8-bdf5-769c83e2482e", "status": "failed", "amount": "20.00", "merchant_fns": "9000012", "merchant_id": "bacb08ea2a", "payment_ref": "234ccb21d6", "failure_reason": { "code": "55", "message": "Invalid PIN or PIN not selected - Invalid PIN" } } } ``` #### REFUND\_STATUS\_UPDATED `data` attributes | | Type | Description | Example value | | --------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- | | `refund_ref` | string | A unique identifier for the refund. | `87432dehkk` | | `status` | string | A string representing the refund's state in the processing cycle. | `succeeded` | | `external_order_id` | string | A unique identifier for the order as created by the merchant or platform (not Forage). | `a238d043-5d88-4bd8-bdf5-769c83e2482e` | | `amount` | string | The amount charged to be refunded to the payment method. | `25.99` | | `merchant_fns` | string | The merchant's unique [FNS](https://docs.joinforage.app/docs/ebt-online-101#food-and-nutrition-service-fns) number. | `121212` | | `merchant_id` | string | A 10-character unique hash identifying the merchant associated with this transaction. | `gxe37pc24y` | | `payment_ref` | string | The ref of the payment associated with this refund | `8e3c6a9d07` | | `failure_reason` *(failure only)* | object | An object with the following keys: `code`: A short string that helps identify the cause of the error. For example, `"55"` indicates that a customer entered an invalid EBT Card PIN. `message`: A developer-facing description of the error. Refer to the [errors reference](https://docs.joinforage.app/reference/errors#code-and-message-pairs-1) for common `code` and `message` pairs. | `55` `Invalid PIN or PIN not selected - Invalid PIN` | ## Fully Hosted and Custom integrations Fully Hosted and Custom integrations interact with Forage `Order`, `OrderPayment`, and `OrderRefund` resources. You can use Forage webhooks to track the entire order status, in addition to individual payments and refunds associated with the order. Webhooks for order-related payments and refunds include an `order_ref` in the `data` field. ### ORDER\_STATUS\_UPDATED > 📘 **Integration type** > > `ORDER_STATUS_UPDATED` is only available to [Fully Hosted](https://docs.joinforage.app/docs/fully-hosted) and [Custom](https://docs.joinforage.app/docs/custom) integrations. > > If you're building with a Forage SDK, use the [`PAYMENT_STATUS_UPDATED`](#payment_status_updated) or [`REFUND_STATUS_UPDATED`](#refund_status_updated) webhooks instead. The `ORDER_STATUS_UPDATED` webhook fires when the status of an order is updated. An order can contain multiple payments (for example, one SNAP payment and one EBT Cash payment), and the `Order` status reflects the outcome of all associated payments. The webhook `data.status` attribute is one of `succeeded`, `canceled`, or `failed`. `data.status == succeeded` when: * All of the payments associated with an Order have successfully processed `succeeded` is a terminal state. `data.status == failed` when: * The EBT [state processor](https://docs.joinforage.app/docs/ebt-online-101#state-processor) cannot complete the order and sends Forage a failure response * Forage is unable to contact the state processor * A credit card refund for a Fully Hosted Checkout session fails `failed` is not a terminal state. `data.status == canceled` when: * You manually cancel an order via a `POST` to [`/orders/{ref}/cancel/`](https://docs.joinforage.app/reference/cancel-order) * Forage cancels the order due to an associated payment failure or a 30-minute timeout (for example, if the order is still in draft status) `canceled` is a terminal state. For guidance on using this event, see [How Forage Webhooks Work](./webhooks-concepts.md). > ⚠️ **Creation events not included** > > `ORDER_STATUS_UPDATED` only fires on updates to an existing order. It is not triggered when an order is created. ```json { "created": "2023-10-05T17:38:26.698516-07:00", "data": { "ebt_cash_total": "10.00", "external_order_id": "58503b96-5111-495b-b13b-d9247be12e75", "merchant_fns": "121212", "merchant_id": "2fb3asd", "order_ref": "3ee466e0ef", "payments": [ { "amount": "10.00", "funding_type": "ebt_snap", "merchant_fns": "0256679", "merchant_id": "07839ae280", "order_ref": "3ee466e0ef", "payment_ref": "5fa6e45620", "status": "succeeded" }, { "amount": "10.00", "funding_type": "ebt_cash", "merchant_fns": "0256679", "merchant_id": "07839ae280", "order_ref": "3ee466e0ef", "payment_ref": "sd7v223HsA", "status": "succeeded" } ], "remaining_total": "0.00", "snap_total": "10.00", "status": "succeeded" }, "ref": "72672bab12", "type": "ORDER_STATUS_UPDATED" } ``` ```json { "ref": "d700e94235", "created": "2024-05-21T14:50:57.852878+00:00", "type": "ORDER_STATUS_UPDATED", "data": { "order_ref": "c8ac066123", "status": "failed", "snap_total": "0.00", "ebt_cash_total": "20.00", "remaining_total": "0.00", "merchant_fns": "1234789", "merchant_id": "4f984ec818", "failure_reason": { "code": "ebt_error_51", "message": "Insufficient funds - Insufficient Funds. Remaining balances are SNAP: $100.00, EBT Cash: $100.00" }, "payments": [ { "payment_ref": "2a629165G6", "status": "failed", "amount": "20.00", "merchant_fns": "1234567", "merchant_id": "4f984ec909", "order_ref": "c8ac066123", "failure_reason": { "code": "ebt_error_51", "message": "Insufficient funds - Insufficient Funds. Remaining balances are SNAP: $100.00, EBT Cash: $100.00" }, "funding_type": "ebt_cash" } ], "previous_errors": [ { "code": "ebt_error_51", "message": "Insufficient funds - Insufficient Funds. Remaining balances are SNAP: $100.00, EBT Cash: $100.00", "details": { "cash_balance": "100.00", "snap_balance": "100.00" }, "source": { "resource": "Payments", "ref": "2a629162f4" } } ] } } ``` #### ORDER\_STATUS\_UPDATED `data` attributes | | Type | Description | Example value | | ------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- | | `ebt_cash_total` | string | The amount charged to the customer's EBT Cash balance. | `10.00` | | `external_order_id` | string | A unique identifier for the order as created by the merchant or platform (not Forage). | `58503b96-5111-495b-b13b-d9247be12e75` | | `merchant_fns` | string | The merchant's unique [FNS](https://docs.joinforage.app/docs/ebt-online-101#food-and-nutrition-service-fns) number. | `121212` | | `merchant_id` | string | The unique merchant ID that Forage provides during onboarding. | `2fb3asd` | | `order_ref` | string | A unique identifier for the order. | `93410bcaff` | | `payments` | array | An array of objects that detail information about each payment associated with the order. | Refer to [`payments`](#payments). | | `remaining_total` | string | The amount charged to the customer's non-EBT Card payment method. | `0.00` | | `snap_total` | string | The amount charged to the customer's SNAP balance. | `10.00` | | `status` | string | A string representing the order's state in the processing cycle. | `succeeded` | | `previous_errors` | array | An array of objects that include the `code`, `message` and `source` values corresponding to the most recent EBT network-related error associated with a canceled or failed `Order`. This field is only returned when the `data.status` of the webhook is `canceled` or `failed`. | Refer to the complete Failed example above. | #### `payments` Each object in the `payments` array contains the following information about an associated payment: | | Type | Description | Example value | | ---------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- | | `amount` | string | A positive decimal number that represents how the [`PaymentMethod`](https://docs.joinforage.app/reference/payment-methods) was charged in USD. | `10.00` | | `funding_type` | string | A string that represents the type of tender. One of: `benefit`, `ebt_cash`, `ebt_snap` | `ebt_snap` | | `merchant_fns` | string | The merchant's unique [FNS](https://docs.joinforage.app/docs/ebt-online-101#food-and-nutrition-service-fns) number. | `025667` | | `merchant_id` | string | The unique merchant ID that Forage provides during onboarding. | `07839ae280` | | `order_ref` | string | A unique identifier for the order. | `3ee466e0ef` | | `payment_ref` | string | A unique identifier for the payment. | `5fa6e45620` | | `status` | string | A string representing the payment's state in the processing cycle. | `succeeded` | | `failure_reason` | object | An object with the following keys: `code`: A short string that helps identify the cause of the error. For example, `"55"` indicates that a customer entered an invalid EBT Card PIN. `message`: A developer-facing description of the error. Refer to the [errors reference](https://docs.joinforage.app/reference/errors#code-and-message-pairs-1) for common `code` and `message` pairs. | `55` `Invalid PIN or PIN not selected - Invalid PIN` | ### PAYMENT\_STATUS\_UPDATED The `PAYMENT_STATUS_UPDATED` webhook for Fully Hosted and Custom integrations is almost identical to the webhook for SDK integrations, with two differences: * The `data` field includes an `order_ref` that links the payment to its parent order * This webhook also fires for credit/debit payment updates (not just EBT) ```json { "created": "2023-10-05T17:38:26.698516-07:00", "data": { "amount": "10.00", "external_order_id": "a238d043-5d88-4bd8-bdf5-769c83e2482e", "funding_type": "ebt_snap", "merchant_fns": "121212", "merchant_id": "2fb3asd", "payment_ref": "3a16426601", "status": "succeeded", "order_ref": "3a16426601" }, "ref": "72672b13bb", "type": "PAYMENT_STATUS_UPDATED", } ``` ```json { "ref": "cd9e3b2c83", "created": "2024-05-21T14:50:57.861207+00:00", "type": "PAYMENT_STATUS_UPDATED", "data": { "payment_ref": "2a629162f4", "status": "failed", "amount": "20.00", "merchant_fns": "1234567", "merchant_id": "4f984ec909", "order_ref": "c8ac066560", "failure_reason": { "code": "ebt_error_51", "message": "Insufficient funds - Insufficient Funds. Remaining balances are SNAP: $100.00, EBT Cash: $100.00" }, "funding_type": "ebt_cash", "previous_errors": [ { "code": "ebt_error_51", "message": "Insufficient funds - Insufficient Funds. Remaining balances are SNAP: $100.00, EBT Cash: $100.00", "details": { "cash_balance": "100.00", "snap_balance": "100.00" }, "source": { "resource": "Payments", "ref": "2a629162f4" } } ] } } ``` The `order_ref` is a unique identifier for the parent `Order` that the `Payment` is attached to. For details on the other fields, refer to [PAYMENT\_STATUS\_UPDATED data attributes](https://docs.joinforage.app/docs/configure-webhooks#payment_status_updated-data-attributes). ### REFUND\_STATUS\_UPDATED The `REFUND_STATUS_UPDATED` webhook for Fully Hosted and Custom integrations is almost identical to the webhook for SDK integrations. The only difference is the addition of an `order_ref` in the `data` field, as in the following example: ```json { "ref": "72672bc724", "created": "2023-10-05T17:38:26.698516-07:00", "type": "REFUND_STATUS_UPDATED", "data": { "refund_ref": "87432dehkk", "external_order_id": "a238d043-5d88-4bd8-bdf5-769c83e2482e", "status": "succeeded", "amount": "25.99", "merchant_fns": "121212", "merchant_id": "2fb3asd", "payment_ref": "8e3c6a9d07", "order_ref": "3a16426601" } } ``` ```json { "ref": "e1ecf255f4", "created": "2024-01-31T19:50:10.065453+00:00", "type": "REFUND_STATUS_UPDATED", "data": { "refund_ref": "60ddf6e386", "external_order_id": "a238d043-5d88-4bd8-bdf5-769c83e2482e", "status": "failed", "amount": "20.00", "merchant_fns": "9000012", "merchant_id": "bacb08ea2a", "payment_ref": "234ccb21d6", "order_ref": "3a16426601", "failure_reason": { "code": "55", "message": "Invalid PIN or PIN not selected - Invalid PIN" } } } ``` The `order_ref` is a unique identifier for the parent `Order` that the `Refund` is attached to. For details on the other fields, refer to [REFUND\_STATUS\_UPDATED attributes](https://docs.joinforage.app/docs/configure-webhooks#refund_status_updated-data-attributes). ## IP Addresses Webhook notifications may originate from any of the following IP addresses: | Environment | IP Address | | -------------- | ---------------- | | **Production** | `54.71.62.121` | | | `35.81.99.127` | | **Sandbox** | `35.84.122.17` | | | `44.232.107.207` | ## Related documentation * [How Forage Webhooks Work](./webhooks-concepts.md). What webhooks are, when events fire, and how Forage delivers them. * [How to Configure Webhooks](./webhooks-configure.md). Set up an endpoint, register it in the dashboard, and verify signatures. * [Errors (API Reference)](https://docs.joinforage.app/reference/errors). Full error response schema and error code/message pairs. * [Endpoint and SDK method errors](https://docs.joinforage.app/docs/sdk-errors#endpoint-and-sdk-method-errors). EBT-specific error codes returned by Forage endpoints.