# Postback Service v2.14

Real-time server-to-server notifications for purchases, rebills, subscription changes, reversals, chargebacks, and account updater events.

Source: https://developer.inoviopay.com/api/postback.html  
Markdown: https://developer.inoviopay.com/api/postback.md

Postback is our way of communicating important payment processing and customer related information to your system in real-time. A Postback is triggered by events such as new purchase requests, rebills, subscription cancellations, transaction reversal, chargebacks, and others. Merchants must provide us with a valid webpage URL that will accept Postback data.

### Successful Response & Retries

In order to tell the service that the postback request was received successfully, merchants must simply reply with the string, `100` inside the `<BODY>` of the response. Note that anything other than "100" will be considered as a failed response. This does not reference the HTTPS response header.

In the event of a failed postback response, the service will attempt the postback three additional times:

- **2nd attempt:** 5 minutes after first failed attempt
- **3rd attempt:** 1 hour after the second failed attempt
- **4th attempt:** 1 day after the third failed attempt

> **DATA REPOST WARNING**
> Merchants must be aware that some data may be reposted for any reason. Your system should verify if a postback with the exact same data (e.g., Order ID / PO_ID) has already been recorded and prevent duplicate ledger entries.

### Postback Event Types

The `TYPE` element describes the type of postback, corresponding to specific system or user actions:

| Event Type | Action Description |
|---|---|
| PURCHASE | Product purchase, Reactivate subscription, Upgrade subscription, Capture transaction. Also used for 3D Secure approved transactions. |
| RENEWAL | Subscription Renewal/Rebill. |
| SUBSCRIPTION TERMINATION REQUEST | User requests subscription cancellation. |
| SUBSCRIPTION TERMINATION | System cancels subscription. |
| CREDIT | Credit transaction. Also triggered when TC40, RDR, Ethoca, or Verifi alerts result in automated refunds. |
| REVERSAL | Void transaction. |
| CHARGEBACK | Chargeback transaction. |
| CHARGEBACK_REPRESENTMENT | Chargeback representment outcome (won or lost). Sent for EPX MIDs when a disputed chargeback is resolved. |
| CREDIT_REVERSE | Refund blocked on chargeback |
| BLACKLIST PAYMENT NUMBER | Add credit card to black list. |
| PAYMENT AAU UPDATE | Automatic Account Updater (e.g., Closed Account, Expiration Date Change, New Account Number). |
| TRANSACTION STATUS UPDATE | Status changes from DECLINE to APPROVED. Also used for 3DS declined or failed transactions. |
| TRANSACTION ARN UPDATE | ARN (acquirer reference number) value updated on a previously authorized transaction. |
| VERIFY | Postback URL verification. |
| TC40 / RDR / RDR STANDALONE | Chargeback Mitigation Alert Events (TC40 Alerts, RDR Disputes). |

### Postback Top-Level Elements

| Element Name | Description |
|---|---|
| TYPE | Postback Event Type Name (Example: "PURCHASE"). |
| CUSTOMER | Contains customer record information (CUST_ID, CUST_EMAIL, CUST_BRCPFCNPJ, etc.). |
| MEMBERSHIP | Contains membership (subscription) record information. Includes SITE and ORIGINAL_TRANSACTION_DATA sub-elements. |
| PURCHASE_ORDER | Contains purchase order (invoice record) information (PO_ID, PO_VALUE, CURRENCY, XTL_UDFxx, etc.). |
| LINE_ITEM | Contains line item parameters (LI_AMOUNT, LI_TYPE, PROD_ID, etc.). |
| BILL_ADDRESS / SHIP_ADDRESS | Contains billing and shipping address parameters. |
| PAYMENT | Contains billing account information (PAYMENT_TYPE, PMT_BIN, PAYMENT_HASH, MERCH_ACCT_ID, etc.). |
| TRANSACTION | Contains important transaction information (TRANS_ID, TRANS_STATUS_NAME, PROCESSOR_RESPONSE, etc.). |
| SOURCE / MESSAGE | Contains the originating source of the event (used in Alerts: "TC40", "RDR", "ETHOCA", "VERIFI") and a short description. |

### Acknowledging a postback

Reply to every postback with the literal body text `100` to acknowledge receipt. Anything else is treated as a failure and retried per the schedule above.

```text
100
```

### Verifying the postback signature

Postback signature validation is available on v2.9+ to enhance security. The gateway computes an HMAC-SHA256 over the raw JSON body using your postback secret; recompute the same HMAC on your end and compare it to the signature the gateway sends so you can reject forged postback traffic.

```php
<?php
/* Postback signature is available on v2.9+ to enhance security. */
$secret = "1a63f9840a0a16b14d11ce386ac8123a";
$body = '{"EVENT": {"secret":"1a63f9840a0a16b14d11ce386ac8123a", "TYPE":"PURCHASE"}}';
$sig = hash_hmac('sha256', $body, $secret);
echo($sig);
?>
```

### Example postback payloads

Postbacks are pushed by the gateway to your merchant URL, so they aren't modeled as outbound `REQUEST_ACTION` calls the way the payment API is. Below is one representative `PURCHASE` event body. `VERIFY` postbacks (used to confirm your endpoint is reachable), `CHARGEBACK` postbacks (populated `TRANSACTION` fields describing the dispute), and `PAYMENT AAU UPDATE` postbacks (populated `PAYMENT` fields describing the card change) follow the same top-level shape with different `TYPE` values and populated sub-elements.

```json
{
  "TYPE": "PURCHASE",
  "CUSTOMER": {
    "CUST_ID": 9928102,
    "CUST_EMAIL": "customer@example.com",
    "CUST_BRCPFCNPJ": ""
  },
  "PURCHASE_ORDER": {
    "PO_ID": 77281920,
    "PO_VALUE": 49.99,
    "CURRENCY": "USD",
    "XTL_UDF01": "INV-999"
  },
  "LINE_ITEM": {
    "LI_AMOUNT": 49.99,
    "LI_TYPE": "PRODUCT",
    "PROD_ID": "SKU-992"
  },
  "BILL_ADDRESS": {
    "CUST_ADDRESS1": "123 Main St",
    "CUST_CITY": "Austin",
    "CUST_STATE": "TX",
    "CUST_ZIP": "78701",
    "CUST_COUNTRY": "US"
  },
  "PAYMENT": {
    "PAYMENT_TYPE": "CREDITCARD",
    "PMT_BIN": "411111",
    "PAYMENT_HASH": "a1b2c3d4e5f6",
    "MERCH_ACCT_ID": 110203
  },
  "TRANSACTION": {
    "TRANS_ID": 8839201112,
    "TRANS_STATUS_NAME": "APPROVED",
    "PROCESSOR_RESPONSE": "AUTH99"
  }
}
```

### Chargeback representment postbacks

A `CHARGEBACK_REPRESENTMENT` postback (`TYPE` = `CHARGEBACK_REPRESENTMENT`) is sent for EPX MIDs when a disputed chargeback case is resolved. It fires for both outcomes, won and lost. The outcome is carried in `RESULT` (`CASE_WON` or `CASE_LOST`) and `RESULT_CATEGORY` (`won` or `lost`).

| Field | Description |
|---|---|
| ORDER_ID | The Inovio order id. |
| RESULT | Resolution result: `CASE_WON` or `CASE_LOST`. |
| RESULT_CATEGORY | Resolution result category: `won` or `lost`. |
| RESULT_DATE | Resolution date, `YYYY-MM-DD`. |
| REASON_CODE | Chargeback reason code. |
| CB_AMOUNT | The chargeback amount. |

Example, won case:

```json
{
  "EVENT": {
    "@TYPE": "CHARGEBACK_REPRESENTMENT",
    "ORDER_ID": "18887541",
    "RESULT": "CASE_WON",
    "RESULT_CATEGORY": "won",
    "RESULT_DATE": "2026-08-28",
    "REASON_CODE": "4837",
    "CB_AMOUNT": "10.00"
  }
}
```

```xml
<?xml version="1.0" encoding="UTF-8"?>
<EVENT TYPE="CHARGEBACK_REPRESENTMENT">
    <ORDER_ID>18887541</ORDER_ID>
    <RESULT>CASE_WON</RESULT>
    <RESULT_CATEGORY>won</RESULT_CATEGORY>
    <RESULT_DATE>2026-08-28</RESULT_DATE>
    <REASON_CODE>4837</REASON_CODE>
    <CB_AMOUNT>10.00</CB_AMOUNT>
</EVENT>
```

A lost case is identical except `RESULT` is `CASE_LOST` and `RESULT_CATEGORY` is `lost`.

### Refund blocked on chargeback postbacks

A `CREDIT_REVERSE` postback (`TYPE` = `CREDIT_REVERSE`) is an EPX-specific notification: it fires when a return/refund is blocked because the card already has a chargeback on it.

| Field | Description |
|---|---|
| ORDER_ID | The Inovio order id. |
| TRANS_ID | The Inovio transaction id. |
| GUID | EPX's credit-reversal identifier |
| RESULT_DATE | Completion date, `YYYY-MM-DD`. |
| AMOUNT | The signed transaction amount of the blocked refund. |

```json
{
  "EVENT": {
    "@TYPE": "CREDIT_REVERSE",
    "ORDER_ID": "18887541",
    "TRANS_ID": "8839201112",
    "GUID": "094NKX7T2QHRB8M4F0Z",
    "RESULT_DATE": "2026-08-28",
    "AMOUNT": "10.00"
  }
}
```

```xml
<?xml version="1.0" encoding="UTF-8"?>
<EVENT TYPE="CREDIT_REVERSE">
    <ORDER_ID>18887541</ORDER_ID>
    <TRANS_ID>8839201112</TRANS_ID>
    <GUID>094NKX7T2QHRB8M4F0Z</GUID>
    <RESULT_DATE>2026-08-28</RESULT_DATE>
    <AMOUNT>10.00</AMOUNT>
</EVENT>
```
