Skip to main content

What gets delivered

HG.Cash enqueues an asynchronous POST to:
  1. Your user’s default webhook URL (configured in HG.Cash Settings alongside the webhook signing secret), or
  2. A webhookUrl you pass per operation where the API or form allows it — for example creating a ledger transaction via the REST API (POST /api/v1/transactions) or a transaction request from the transfers flow when that field is available.
Payloads are identical in shape regardless of queue: Content-Type: application/json. Every payload includes topic and eventType at the top level for routing. Most webhook bodies are a single flat JSON object; checkout.completed may additionally include a nested transaction object with ledger movement details (same fields as Account movement, without topic or eventType).

Topic and eventType

Transaction request webhooks always use topic TRANSACTION_REQUEST. When a cash-out is linked to its bank movement, look for eventType transaction_associated (not a separate topic). Payload shape and examples live in the API reference (open the API reference tab, then Webhooks):
  • Transaction requests (cash-out pipeline, type is always "request"): Transaction Request Status Updated — schema TransactionRequestStatusWebhook with a full example payload.
  • Transaction request linked to ledger row (after Urbana associates the cash-out with the bank movement): Transaction request associated — same schema with required transactionId, topic TRANSACTION_REQUEST, and eventType transaction_associated. You may receive this in addition to a status update when the link is established.
  • Ledger / account movements (money in or out of your HG.Cash accounts; type is your movement / transaction type name such as inbound or outbound): Account movement — schema AccountMovementWebhook with example payloads. When a fee snapshot was stored, the body includes optional feeBreakdown. See Fee breakdown. When a Brazil PIX movement stores an end-to-end id, the body includes optional endToEndId. See PIX end-to-end id.
  • Hosted checkouts (event such as checkout.completed): Checkout events — schema WebhookCheckoutPayload. On checkout.completed, when a ledger transaction is linked, the payload includes a nested transaction object (same fields as Account movement, without topic or eventType). See Hosted checkout for flows by country.
  • Claim status changes (topic CLAIM, eventType status_change): Claim status updated — schema ClaimStatusWebhook. Sent to your default webhook URL when a claim is updated by an admin or auto-reconciled by COELSA. The body matches the Get claim (GET /claims/{id}) response (without fileUrl) plus routing metadata, with an optional comment field. Webhooks are not sent on claim create or comment-only updates. See Claims for the full flow.
Transaction requests (type: "request") Callbacks are sent when HG.Cash updates a transaction request’s status or when a request is cancelled. When an outbound request is linked to its ledger transaction, HG.Cash may send Transaction request associated with topic TRANSACTION_REQUEST, eventType transaction_associated, and the transactionId of the bank movement row. You may not receive a webhook as soon as a request is created while it is only PENDING; integrate defensively against ordering and duplicates. Ledger transactions When a ledger transaction row is ingested from webhooks/API and your resolved URL applies, HG.Cash can notify immediately after persistence; type is the business type name, not "request".

Fee breakdown

Account movement webhooks (topic TRANSACTION, eventType created or status_change) include optional feeBreakdown when HG.Cash stored a fee snapshot on the movement. The field is omitted when there is no breakdown. Internal fee rows do not send a webhook. The webhook object has two fields. flatFee.amount is the flat fee. collectedAmount is the percentage charged to you plus that flat fee. Webhooks do not include platformFee, transactionFee, or flatFee.source. On checkout.completed, the nested transaction object uses the same fields, including feeBreakdown when the linked movement has a snapshot.
In this example the movement amount is 12,000. The client percentage is 1% (120) plus a flat fee of 15, so collectedAmount is 135. Those percentage amounts stay on the status response. They are not on the webhook. GET /api/v1/{br,cl,co,bo}/transactions/{id}/status returns platformFee, transactionFee, flatFee (including source: account or platform), and collectedAmount when a snapshot is stored. Venezuela status returns the same amounts and omits flatFee.source. GET /transaction/{id}/status is a transaction-request status and does not include feeBreakdown.

PIX end-to-end id

Account movement webhooks (topic TRANSACTION, eventType created or status_change) include optional endToEndId when the movement stores a Brazil PIX end-to-end identifier. The value is that stored string with surrounding spaces removed. HG.Cash omits the field when the identifier is absent or empty. The field is a top-level property of the JSON body, next to fields such as id and status. It applies to inbound and outbound PIX. You receive it in these cases:
  • A PIX status update posts eventType status_change and the identifier is already stored.
  • A later provider update stores the identifier for the first time and that update did not already notify you. HG.Cash then sends one TRANSACTION / status_change with the updated body.
  • A dashboard resend posts eventType created from the stored movement, and the identifier is already saved.
A status change in the same update includes endToEndId once. An identifier that is already stored does not trigger another delivery by itself. On checkout.completed, the nested transaction object uses the same movement fields, including endToEndId when the linked movement has one.

Signing secret (X-HG-Webhook-Signature)

If your HG.Cash profile has a webhook signing secret set, HG.Cash signs the exact raw JSON body:
  • Algorithm: HMAC-SHA256 over the UTF-8 bytes of the body string HG.Cash will send (JSON.stringify equivalent of the payload object).
  • Header: X-HG-Webhook-Signature.
  • Format: sha256=<hex> where <hex> is lowercase hex (64 chars).
Verification steps on your server:
  1. Read the raw request body as delivered — do not re-serialize parsed JSON unless you replicate every key order/spacing HG.Cash used.
  2. Compute hex = HMAC_SHA256(secret, rawBody_utf8) and compare securely to header value after stripping the optional sha256= prefix (case insensitive).
  3. Reject mismatches (401/403 on your side is fine).
If no secret is configured in HG.Cash, the X-HG-Webhook-Signature header omitted entirely.

Retries

Failed deliveries (non-2xx HTTP status, network errors, or timeouts) are retried automatically with this policy: Each attempt is allowed up to 30 seconds of total run time before the delivery job is treated as failed for that attempt.

Operational expectations

  • Respond with 2xx quickly so the delivery counts as successful; otherwise you may receive repeat POSTs until attempts are exhausted or one succeeds.
  • Prefer idempotent handlers keyed by HG.Cash id and status transitions you care about — redeliveries or duplicate emits are possible alongside provider quirks.

Dashboard tools

HG.Cash also records each delivery attempt in the dashboard (transactions and transfers → Webhooks) and can disable your webhook automatically if failures persist. See Delivery history and health monitoring for delivery logs, manual retry, and email alerts.