For the complete documentation index, see llms.txt. This page is also available as Markdown.

Event Notification

Global Collections is an event-driven service. Many operations complete asynchronously — virtual account approval, incoming funds, payout results, refund and sub-merchant status changes are all delivered to the Merchant as webhooks.

This page explains how to configure and verify webhooks. The payload of each event type is documented in its own webhook page (linked below).

Configuration

There is no self-service Merchant Portal screen for webhook configuration. Instead:

  • For most event types, webhookUrl is supplied directly in the request body of the relevant Create API call — the URL is scoped to that specific request/entity, not managed separately. See:

  • The collection-transaction event group (7 event types — see the catalogue below) is the exception: it has no natural per-request origin, so its delivery URL and signing secret are pre-configured centrally for your merchant account rather than supplied by the Merchant. There is no self-service UI for this today — contact NeoX to have it configured. This also applies to refund status changes on trade/platform collections: although Create Refund Request accepts a webhookUrl field, it is not used for webhook delivery — refund status is delivered through this same pre-configured collection-transaction channel instead. See Refund Requests Webhook for details.

Delivery

  • NeoX sends an HTTP POST request to the configured URL whenever a subscribed event occurs.

  • The request body is application/json.

  • The Merchant endpoint must respond with HTTP 200 to acknowledge receipt.

  • If the endpoint does not acknowledge, NeoX retries the delivery with a backoff schedule. Webhook handlers must therefore be idempotent — the same event may be delivered more than once. De-duplicate on the event's primary identifier (e.g. requestId, transId, collectionOrderId).

Verifying secureHash

Every webhook payload includes a secureHash field, computed and embedded in the JSON body (never sent as a header). To verify it:

  1. Take all payload fields except secureHash itself.

  2. Sort the keys in alphabetical order, then concatenate their values only — not key=value pairs, just the values, in that sorted-key order.

  3. Append the Secret Key configured for your merchant account.

  4. Compute the SHA256 hash of the resulting string and Base64-encode the digest.

  5. Compare the result with the received secureHash. Reject the payload if they differ.

Event catalogue

#
Type
Triggered when
Payload reference

1

SUBMERCHANT_ONBOARDING_RESULT

A sub-merchant onboarding application reaches a terminal review outcome.

2

VA_SUPPLEMENT_REQUIRED

A virtual account application requires supplementary KYC material.

3

TRADE_COLLECTION_RECEIVED

Funds arrive in a virtual account for a trade-collection order.

4

PLATFORM_COLLECTION_RECEIVED

Funds arrive in a virtual account for a platform-collection order.

5

COLLECTION_COMPLETED

A collection order finishes matching/review and funds are credited.

6

COLLECTION_REJECTED

A collection order's review is rejected.

7

COLLECTION_CANCEL

A collection transaction is cancelled.

8

TRADE_COLLECTION_REFUND_PROCESS

A refund against a collection order starts processing.

9

TRADE_COLLECTION_REFUND_SUCCESS

A refund against a collection order completes successfully.

10

VA_CREATION_RESULT

A virtual account application reaches a terminal outcome (approved or rejected).

11

VA_MATERIAL_SUPPLEMENT

Supplementary virtual account material is reviewed.

12

PAYMENT_INITIAL

A payout request is accepted and initiated for processing.

13

PAYMENT_RESULT

A payout request (or per-payee distribution) reaches a terminal outcome.

14

BENEFICIARY_REGISTRATION

A beneficiary registration is reviewed, including supplement requests.

Events #8 and #9 relate to refund outcomes and are documented on the Refund Requests Webhook page, alongside the refund flow they belong to. They are still delivered through the collection-transaction channel described above, not to a per-request webhookUrl — see that page for why.

Last updated

Was this helpful?