# Webhooks

> Receive and verify Onerway payment notifications, acknowledge and deduplicate them correctly, and fall back to query APIs when no notification arrives.

Onerway pushes the final results of payments, tokenization, subscriptions, pre-authorizations, and refunds to your server through webhooks. This page describes the notification handling contract shared by every integration method; the Checkout, Web SDK, and Direct API integration guides only add the notification types and additional considerations for that integration method.

The delivery, verification, acknowledgement, and deduplication rules on this page apply to the notifications listed below. Profit share and reversal notifications use the body `sign` for verification; see the [Profit share result webhook](/payments/api-reference/webhooks/profit-share-result) for their notification URLs and acknowledgement requirements.

Ethoca / RDR enrollment status notifications also use the body `sign`. Configure their notification URLs in the merchant portal and return the received `id` in the acknowledgement. See the [Ethoca enrollment status webhook](/payments/api-reference/webhooks/ethoca-enrollment-changed) and [RDR enrollment status webhook](/payments/api-reference/webhooks/rdr-enrollment-changed) for the complete requirements.

## Delivery

Onerway sends notifications via HTTP POST to the `notifyUrl` submitted when the transaction was created. The payload for each scenario is documented separately:

| Webhook | Scenario |
| --- | --- |
| [Payment result webhook](/payments/api-reference/webhooks/payment-result) | Ordinary payments that succeeded, failed, timed out, or were canceled |
| [Saved payment method result webhook](/payments/api-reference/webhooks/payment-method-result) | Results of saving a payment method (tokenization, `txnType=BIND_CARD`) |
| [Subscription payment webhook](/payments/api-reference/webhooks/subscription-payment) | Subscription lifecycle events such as initial subscription, renewal, change, and cancellation |
| [Authorization, capture, and void webhook](/payments/api-reference/webhooks/authorization-capture) | Pre-authorization (`txnType=AUTH`), capture (`txnType=CAPTURE`), and void (`txnType=VOID`) results |
| [Refund result webhook](/payments/api-reference/webhooks/refund-result) | Refund results (`txnType=REFUND`) |
| [Refund request rejection webhook](/payments/api-reference/webhooks/refund-audit-rejected) | A refund request rejected by Onerway (`notifyType=REFUND_AUDIT`) |

Refund notifications are sent to the original transaction’s `notifyUrl`. Onerway sends `REFUND_AUDIT` only when it rejects a refund request during review. A successful cancellation of a refund request does not trigger a notification; use the [Create or cancel refund](/payments/api-reference/endpoints/create-or-cancel-refund) response.

Confirm payment results through Webhooks or query APIs. Do not treat a redirect to `returnUrl` or a client-side event as confirmation that a payment succeeded. For a refund request (`refundType=0`), `respCode=20000` means that Onerway accepted the request; it does not mean that the refund succeeded.

## Verify the signature

You must verify the notifications in the table above with the `X-Rh-Signature` header — do not rely on the `sign` field in the notification body. `sign` is computed with only the first enabled key and may differ from the signature you calculate using your configured `SECRET` during key rotation. See [Request signing](/payments/get-started/request-signing#webhook-signature-verification) for the verification rules and the fields excluded from verification.

## Acknowledge and retries

After processing, return HTTP 200 with `Content-Type: text/plain` and the notification's `transactionId` unchanged in the response body. Without a successful response, Onerway retries at 30-minute intervals, up to 3 times.

## Deduplicate

A single transaction may receive multiple notifications. Handle them idempotently by `transactionId`: process a repeated notification with the same `transactionId` only once, but still acknowledge it.

Tokenization, subscription-with-binding, and pre-authorization flows with a later capture or void produce several related notifications with different `transactionId` values. Handle each idempotently on its own and associate them with the same payment intent or subscription contract through business identifiers such as `paymentId` and `contractId`.

## Interpret the status

- `status` is the result of the current operation, such as `S` for success and `F` for failure.
- `paymentStatus` is the payment intent state, such as `A` after a successful pre-authorization, `S` after a successful capture, and `N` (closed) after a successful void.

For pre-authorization, capture, and void results, use `paymentId` plus `paymentStatus` to determine whether the funds are held, captured, or released. Process a refund result using its refund `transactionId` and `status`. See the API Reference page of each webhook for the corresponding fields and values.

## Handle differences between query results and Webhooks

These rules apply to payments, refunds, and other scenarios. When a query result differs from a Webhook already received, compare results for the same transaction and operation:

- Use the Webhook result if the query returns a status other than success (`S`) or failure (`F`), but the Webhook reports success or failure.
- Otherwise, use the query result, including when the query returns success (`S`) or failure (`F`).

## Query results when needed

Once you receive a Webhook reporting success (`S`) or failure (`F`), process the corresponding payment or refund result. No confirming query is needed.

For payments, if the customer has returned to your page but no Webhook has arrived, or you need to reconcile records, you can query at increasing intervals until the query returns success (`S`) or failure (`F`), or a Webhook arrives.

For refunds, wait for a Webhook; continuous polling is not required. When you need to check progress or reconcile records, use [Query refunds](/payments/api-reference/endpoints/query-refunds) with the refund transaction ID or the original payment transaction ID.

For payment results, the query API depends on the integration method: the Checkout and Direct API integrations use [Query transactions](/payments/api-reference/endpoints/query-transactions); the Web SDK integration calls [Query payments](/payments/api-reference/endpoints/query-payments) with the `paymentId` saved when the payment was created.

## Go-live checklist

- The notifications in the table above are verified with `X-Rh-Signature`, and notifications that fail verification are not processed.
- For the notifications in the table above, your endpoint returns HTTP 200 with the `transactionId` after processing and deduplicates by `transactionId`.
- Your webhook endpoint accepts every notification type involved in the scenarios you use.
- Success, failure, and retry scenarios are verified in the sandbox with the [test cards](/payments/get-started/testing).
