> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bango.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Asynchronous charging model

DVM charging supports payment partners that settle asynchronously.

The Partners can acknowledge a request immediately and confirm the outcome later, from seconds to days afterwards, by calling back into the DVM.

## Choosing a settlement mode

The settlement mode is determined by the HTTP status code you return to each charge or refund request. There is no configuration flag and no declaration at onboarding.

| Your response | Meaning |
| :- | :- |
| `200 OK` | The outcome in the response body is final. The DVM resolves the charge or refund immediately. |
| `202 Accepted` | The request is accepted and the outcome will follow separately, via a notification callback. |

You can mix the two,  return `200` where an outcome is immediately available, and `202` where it is not.

## Acknowledging a request with `202 Accepted`

The `202` body carries the originating `requestId`. You may optionally include your own identifier for the transaction (`partnerChargeId` or `partnerRefundId`). The DVM stores this against its own charge or refund ID, and you can use it to identify the transaction in your later callback.

## Confirming the outcome

Two inbound endpoints accept the delayed outcome.

Each accepts a `responseCode` of `APPROVED` or `DECLINED`. On a decline, supply `reason` and `reasonDescription`.

Identify the transaction using the Bango identifier (`chargeId` or `refundId`). Where the Bango identifier is not available to you, supply your own identifier (`partnerChargeId` or `partnerRefundId`) and Bango will resolve it.

### `/charge/notifications`

**Approved**

json

```json theme={null}
{
  "requestId": "a95ec4ff-ac07-40ac-905c-0bbfdfacf409",
  "chargeId": "fc6eab7c-8814-490b-adfb-ac3be76e809f",
  "responseCode": "APPROVED"
}
```

**Declined**

json

```json theme={null}
{
  "requestId": "a95ec4ff-ac07-40ac-905c-0bbfdfacf409",
  "partnerChargeId": "p100134567890",
  "responseCode": "DECLINED",
  "reason": "USER_SUSPENDED",
  "reasonDescription": "User is suspended"
}
```

### `/refund/notifications`

**Approved**

json

```json theme={null}
{
  "requestId": "a95ec4ff-ac07-40ac-905c-0bbfdfacf409",
  "refundId": "d56442de-ca64-411f-8585-830291b3d6cf",
  "responseCode": "APPROVED"
}
```

**Declined**

json

```json theme={null}
{
  "requestId": "a95ec4ff-ac07-40ac-905c-0bbfdfacf409",
  "partnerRefundId": "r100134567890",
  "responseCode": "DECLINED",
  "reason": "USER_INVALID",
  "reasonDescription": "User is not recognised"
}
```

## Pending state

A charge awaiting an asynchronous outcome is held in a pending state, with its correlation keys intact. The associated invoice stays unsettled and moves to `PAID` only when a successful outcome is confirmed. You are then notified with `RENEWAL_SUCCEEDED` or `RENEWAL_FAILED` as normal. No new notification types are introduced for asynchronous settlement.

## Retries

If no callback arrives within a configured interval, the DVM re-sends the original charge or refund request rather than leaving it open indefinitely. The re-sent request indicates that it is a retry, and which attempt number it is.

**The Partner must be able to handle repeat requests idempotently.** When you receive a retry for a transaction you have already started, return the outcome of that existing transaction, do not create a second one.

Once the configured maximum number of attempts is exhausted, the charge is marked failed and is not retried further.

The retry interval and maximum number of attempts are configured per partner and per action (charge, refund). Bango sets these during onboarding.

## Error responses on callbacks

| Situation | Response |
| :- | :- |
| Repeat callback for a charge already resolved | `409` |
| Callback for a charge or refund Bango does not recognize | `400` |
| Refund requested against a declined charge | `400` |
| Partial refunds exceeding the original charge amount while still unapproved | `400` |
| Approval arriving after retries are exhausted and the charge has reached a final state | `409` |

## Getting started

To adopt the asynchronous flow:

1. Return `202 Accepted` to charge and refund requests that will settle later.
2. Implement calls to the Bango charge and refund notification endpoints to approve or decline each request.
3. Handle repeat requests for the same charge or refund idempotently.

[Contact](mailto:support@bango.com) your Bango representative to have your retry interval and maximum attempts configured.
