Cashin Refund Webhook
Asynchronous refund status notification.
Endpoint
POST/merchant-callback-urlAuthentication
Merchant Credential. See Authentication.
1. Notification Background
After a merchant submits a cashin refund request, the refund result may not be determinable in the synchronous response. Once the refund succeeds or fails, Adopay notifies the merchant of the final refund result through an HTTP asynchronous callback.
The same refund order may be notified multiple times due to retries. The merchant should perform idempotency handling using the merchant ID together with the merchant refund order number, or platOrderNo.
2. Callback URL and Request Method
Adopay sends JSON notifications using POST with Content-Type set to application/json. The callback URL prefers the notifyUrl submitted when the refund was initiated; if none was submitted, the merchant's configured and enabled refund notification URL is used. The URL must be a complete HTTP or HTTPS URL.
For signature verification and success response requirements, see Webhook Specification.
3. Request Header Fields
| Field | Type | Required | Description |
|---|---|---|---|
Content-Type | string | Yes | Fixed to application/json. |
X-Merchant-Id | string | Yes | Merchant ID receiving the notification. |
X-Timestamp | string | Yes | Unix timestamp in seconds. |
X-Nonce | string | Yes | Random string for this request, used for anti-replay; regenerated on every retry. |
Digest | string | Yes | Digest of the raw request body. Format: SHA-256=<Base64(SHA256(body_bytes))>. |
Authorization | string | Yes | ES256 HTTP Signature. |
Both Digest and Authorization are computed over the raw JSON bytes actually sent. When verifying the signature, the merchant must not re-serialize the JSON first.
4. Request Body Fields
Business status: status is an integer; status = 200 indicates the business succeeded, in which case msg = "sucesso". Any value other than 200 indicates a business error; see msg for the reason.
| Field | Type | Length | Returned | Description |
|---|---|---|---|---|
event | string | 32 | Yes | Refund event type; see the refund event and status descriptions below. |
attach | string | 128 | Yes | The attach value passed by the merchant when the original cashin order was created; returned as-is if provided at order creation, empty otherwise. |
merchantOrderNo | string | 64 | Yes | Merchant refund order number passed by the merchant when initiating the refund. |
platOrderNo | string | 64 | Yes | Adopay platform refund order number. |
origMerchantOrderNo | string | 64 | Yes | Original merchant cashin order number. |
origPlatOrderNo | string | 64 | Yes | Original Adopay cashin platform order number. |
origAmount | decimal(25,2) | 25,2 | Yes | Original cashin order amount. |
origTotalRefundAmount | decimal(25,2) | 25,2 | Yes | Cumulative principal successfully refunded on the original cashin order as of the completion of this refund, excluding fees. |
origTotalFeeRefundAmount | decimal(25,2) | 25,2 | Yes | Cumulative fee amount successfully refunded on the original cashin order as of the completion of this refund, excluding the refunded principal. |
amount | decimal(25,2) | 25,2 | Yes | Principal amount requested for this refund, excluding fees. |
refundAmount | decimal(25,2) | 25,2 | Yes | Principal amount successfully refunded this time, excluding fees; see feeRefundAmount for the fee refunded this time. |
feeRefundAmount | decimal(25,2) | 25,2 | Yes | Fee amount refunded with this refund; 0 when no fee is refunded. |
currency | string | 3 | Yes | Refund currency, same as the original order currency, for example BRL. |
e2eId | string | 64 | No | Pix end-to-end transaction ID; may be empty when the channel does not return it. |
orderStatus | string | 16 | Yes | Refund result: SUCCESS means the refund succeeded, FAILED means the refund failed. |
refundTime | int | 19 | No | Refund time, Unix timestamp in seconds. |
status | int | - | Yes | Response code |
msg | string | 128 | Yes | Corresponds to status |
Refund Events and Status Descriptions
event | orderStatus | Meaning |
|---|---|---|
QR_CODE_COPY_AND_PASTE_REFUNDED | SUCCESS | Pix QR code cashin/acquiring - refund succeeded. |
QR_CODE_COPY_AND_PASTE_REFUNDED_ERROR | FAILED | Pix QR code cashin/acquiring - refund failed. |
Callbacks notify only final refund states. While the refund is still PENDING, no result notification is sent; the merchant can query the current status through the refund order query API.
5. Request Example
The following example shows the first successful refund on the original order: principal 50.00 and fee 0.30 refunded, cumulative refunded principal 50.00, and cumulative refunded fee 0.30.
POST /notify/adopay/cashin/refund HTTP/1.1
Host: merchant.example.com
Content-Type: application/json
X-Merchant-Id: 92315566000120
X-Timestamp: 1786838460
X-Nonce: 4de901987ca14b25acf2639056ac6002
Digest: SHA-256=<REQUEST_BODY_SHA256_BASE64>
Authorization: Signature keyId="v1",alg="ES256",headers="(request-target) x-timestamp x-nonce digest",signature="<ES256_SIGNATURE_BASE64>"
{
"status": 200,
"msg": "sucesso",
"event": "QR_CODE_COPY_AND_PASTE_REFUNDED",
"attach": "order-source=checkout",
"merchantOrderNo": "REFUND202608160001",
"platOrderNo": "RFD202608160000000001",
"origMerchantOrderNo": "CASHIN202608160001",
"origPlatOrderNo": "BAS202608160000000001",
"origAmount": 100,
"origTotalRefundAmount": 50,
"origTotalFeeRefundAmount": 0.30,
"amount": 50,
"refundAmount": 50,
"feeRefundAmount": 0.3,
"currency": "BRL",
"e2eId": "E1234567820260816000000000000001",
"orderStatus": "SUCCESS",
"refundTime": 1786887025
}6. Merchant Response Requirements
After completing signature verification, idempotency handling, and persisting the business data, the merchant should return HTTP 200—299 with a response body that is strictly the plain text SUCCESS or OK:
HTTP/1.1 200 OK
Content-Type: text/plain
SUCCESS7. Notification Scenarios and Retry Count
When a cashin refund succeeds or fails, Adopay sends a callback notification to the merchant.
After the first delivery attempt of a notification fails, it is retried at most 9 times, for a maximum of 10 attempts in total. Once the merchant successfully receives the notification and returns the required success response, no more retries are made.
Whether to retry is determined jointly by the HTTP status code and the response body:
| HTTP Status Code | Response Body | Result |
|---|---|---|
200—299 | Strictly equal to SUCCESS or OK after trimming leading and trailing whitespace | Notification succeeded, no more retries |
200—299 | Empty body, JSON, other text, or different casing than required | Notification failed, retry continues |
Non-2xx | Any content | Notification failed, retry continues |
| No HTTP response received | Network timeout or connection failure | Notification failed, retry continues |
SUCCESS and OK are case-sensitive. For example, success, Success, or {"status":"SUCCESS"} are not recognized as a success response. Although HTTP 204 is a 2xx status, retries continue because the response body is empty.
X-Timestamp, X-Nonce, Digest, and Authorization are regenerated for each delivery.
8. Integration Notes
- Use the merchant ID plus the merchant refund order number (
merchantOrderNo), orplatOrderNo, as the equivalent unique key; do not judge duplication by the number of notifications received. - The merchant should complete signature verification first, then verify the merchant ID, original order number, refund order number, currency, and amount; only after all of them match should the refund result be updated.
e2eIdand order numbers should be included in audit records; for sensitive information involving the merchant, payer, or channel, logs should be masked or record only a digest.- Return the required success response only after signature verification, idempotency handling, and business data persistence all succeed, so the notification is not incorrectly acknowledged and thereby never retried.