> For the complete documentation index, see [llms.txt](https://docs.coda.co/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coda.co/codapay/hosted-payment-page-integration/fraud-and-chargeback-notifications.md).

# Fraud and Chargeback Notifications

This reference describes the webhook notifications Coda sends to keep your backend informed of chargeback lifecycle changes and early fraud warnings on your transactions.

> **Note:** Chargeback and Fraud updates requires POST notifications to be enabled for your account. Contact your Codapay account manager to enable them.

### Overview

Codapay uses webhooks to notify your "Complete Notification URL" whenever a chargeback progresses through its lifecycle, or an early fraud warning is received on one of your transactions.

> Ensure your "Complete Notification URL" is configured in the Publisher Portal. Refer to the [Set up payments](https://claude.ai/chat/cb09ca98-8996-43b7-87cb-cd20a04c1dea#) guide for detailed instructions.

### Event Types

#### Chargeback Events

For chargeback lifecycle events, your endpoint should be prepared to handle the following `eventType` values:

| Event Type           | Description                                                              |
| -------------------- | ------------------------------------------------------------------------ |
| `chargeback_created` | A chargeback has been raised against a transaction                       |
| `dispute_sent`       | The chargeback has been escalated and a dispute submitted to the gateway |
| `dispute_lost`       | The dispute was resolved in the customer's favour                        |
| `dispute_won`        | The dispute was resolved in the merchant's favour                        |

#### Fraud Events

For fraud events, your endpoint should be prepared to handle the following `eventType` values:

| Event Type           | Description                                                |
| -------------------- | ---------------------------------------------------------- |
| `fraud_notification` | An early fraud warning has been received for a transaction |

### Notification Payload Structure

Notifications are sent as a `POST` request with a JSON body.

| Field               | Type           | Description                                                                                  |
| ------------------- | -------------- | -------------------------------------------------------------------------------------------- |
| eventType           | string         | The specific event type being reported (e.g., `chargeback_created`)                          |
| timestamp           | string         | Notification timestamp                                                                       |
| data.chargebackId   | string         | Coda's internal chargeback identifier                                                        |
| data.stage          | string         | Lifecycle stage of the chargeback. See [Stage Values](#stage-values) below                   |
| data.txnId          | string         | Coda's internal transaction ID                                                               |
| data.reason         | string         | Chargeback reason as provided by the Issuing Bank (e.g. Other Fraud-Card Absent Environment) |
| data.outcome        | string \| null | Final outcome of a dispute: WON, LOST, or null if not yet resolved.                          |
| data.amountValue    | decimal        | Transaction amount                                                                           |
| data.amountCurrency | string         | ISO 4217 currency code (e.g. CHF, USD)                                                       |
| data.orderId        | string         | Your order ID (if provided)                                                                  |

### Stage Values

| Stage                 | Meaning                                           |
| --------------------- | ------------------------------------------------- |
| `CHARGEBACK`          | Chargeback has been created                       |
| `DISPUTE_SENT`        | Dispute submitted to gateway                      |
| `DISPUTE_LOST`        | Dispute closed — outcome: lost                    |
| `DISPUTE_WON`         | Dispute closed — outcome: won                     |
| `EARLY_FRAUD_WARNING` | Fraud signal received before chargeback is raised |

### Chargeback Notification Examples

`chargeback_created`

```json
{
  "eventType": "chargeback_created",
  "timestamp": "1773860416000",
  "data": {
    "chargebackId": "CBKJTNRS9XDNBVQ9",
    "stage": "CHARGEBACK",
    "txnId": "7677293394619242496",
    "reason": "Other Fraud-Card Absent Environment",
    "outcome": null,
    "amountValue": 100,
    "amountCurrency": "CHF",
    "orderId": "c8856951-b495-4e9b-8b48-01123cf4f5eb"
  }
}
```

`dispute_sent`

```json
{
  "eventType": "dispute_sent",
  "timestamp": "1773860416000",
  "data": {
    "chargebackId": "CBKJTNRS9XDNBVQ9",
    "stage": "DISPUTE_SENT",
    "txnId": "7677293394619242496",
    "reason": "Other Fraud-Card Absent Environment",
    "outcome": null,
    "amountValue": 100,
    "amountCurrency": "CHF",
    "orderId": "c8856951-b495-4e9b-8b48-01123cf4f5eb"
  }
}
```

`dispute_lost`

```json
{
  "eventType": "dispute_lost",
  "timestamp": "1773860416000",
  "data": {
    "chargebackId": "CBKJTNRS9XDNBVQ9",
    "stage": "DISPUTE_LOST",
    "txnId": "7677293394619242496",
    "reason": "Other Fraud-Card Absent Environment",
    "outcome": "LOST",
    "amountValue": 100,
    "amountCurrency": "CHF",
    "orderId": "c8856951-b495-4e9b-8b48-01123cf4f5eb"
  }
}
```

`dispute_won`

```json
{
  "eventType": "dispute_won",
  "timestamp": "1773860416000",
  "data": {
    "chargebackId": "CBKJTNRS9XDNBVQ9",
    "stage": "DISPUTE_WON",
    "txnId": "7677293394619242496",
    "reason": "Other Fraud-Card Absent Environment",
    "outcome": "WON",
    "amountValue": 100,
    "amountCurrency": "CHF",
    "orderId": "c8856951-b495-4e9b-8b48-01123cf4f5eb"
  }
}
```

### Fraud Notification Example

`fraud_notification`

```json
{
  "eventType": "fraud_notification",
  "timestamp": "1773860416000",
  "data": {
    "chargebackId": "CBKJTNRS9XDNBVQ9",
    "stage": "EARLY_FRAUD_WARNING",
    "txnId": "7677293394619242496",
    "reason": "Other Fraud-Card Absent Environment",
    "amountValue": 100,
    "amountCurrency": "CHF",
    "orderId": "c8856951-b495-4e9b-8b48-01123cf4f5eb"
  }
}
```

### Notification Signature Verification

Every POST notification includes two headers that allow you to verify the request originated from Codapay and has not been tampered with:

| Header           | Description                                                                        |
| ---------------- | ---------------------------------------------------------------------------------- |
| `X-Request-Time` | The timestamp of the request, represented as epoch milliseconds (string of digits) |
| `X-Signature`    | HMAC-SHA512 hex digest computed by Codapay using your merchant API key             |

#### How It Works

Codapay and your server both agree on a single UTF-8 string to sign:

```
X-Request-Time + "." + raw POST body (UTF-8)
```

The HMAC-SHA512 algorithm is applied to this string using your merchant **API key**, producing a **128-character lowercase hexadecimal** digest.

Codapay sends this digest in the `X-Signature` header. Your server must recompute the same hex digest and compare it to the received value.

#### Validation Steps

1. Read the `X-Request-Time` and `X-Signature` headers from the incoming request.
2. Read the **raw body** bytes of the request.
3. Build the signed string: `requestTime + "." + body` (interpreted as UTF-8).
4. Compute the expected signature: `HMAC-SHA512(secretKey, signedString)` → lowercase hex.
5. Compare `expectedHex` to the `X-Signature` header value using a **constant-time** comparison to prevent timing attacks. The comparison is case-insensitive.

If the values do not match, reject the request.

#### Example — Java

```java
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public class SignatureValidator {

    private static final String HMAC_SHA512 = "HmacSHA512";

    public static boolean validate(String secretKey, String requestTime, byte[] body, String xSignature) {
        String bodyUtf8 = new String(body, StandardCharsets.UTF_8);
        String text = requestTime + "." + bodyUtf8;
        String expected = hmacSha512Hex(secretKey, text);
        return MessageDigest.isEqual(
            expected.toLowerCase().getBytes(),
            xSignature.toLowerCase().getBytes()
        );
    }

    private static String hmacSha512Hex(String secretKey, String text) {
        try {
            Mac mac = Mac.getInstance(HMAC_SHA512);
            mac.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), HMAC_SHA512));
            byte[] raw = mac.doFinal(text.getBytes(StandardCharsets.UTF_8));
            return HEX.formatHex(raw);
        } catch (Exception e) {
            throw new IllegalStateException("HMAC-SHA512 not available", e);
        }
    }
}
```

### Responding to Notifications

To acknowledge receipt of the notification, your server must respond with a `200 OK` and the following JSON body:

```json
{
  "ResultCode": 0
}
```

Retry Policy: If no valid response is received, Codapay will re-send the notification 3 times at 5-minute intervals. If all attempts fail, an email alert will be triggered to your technical contact.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.coda.co/codapay/hosted-payment-page-integration/fraud-and-chargeback-notifications.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
