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

# Mark as Settled (Sandbox)

> Batch captured payments — plus optional refunds and chargebacks — into one settlement and fire PAYMENT_SETTLED, without waiting for real money movement.

<Warning>
  **Sandbox only.** This endpoint returns `400` in production. It operates only on transactions created through the **Simulator** payment gateway — a real Cashfree or ICICI transaction is rejected.

  Your account must be assigned the Simulator gateway in sandbox. Contact your EximPe integration manager if it isn't.
</Warning>

## Overview

Settlement is the one part of the payment lifecycle you cannot trigger yourself: it happens when money actually moves, on the bank's schedule. That makes settlement webhook handlers and reconciliation logic awkward to test.

This endpoint settles payments on demand. It applies a simulated fee schedule, creates a real settlement record, and fires [`PAYMENT_SETTLED`](/api-reference/v3/webhooks/payment-settled) exactly as production would.

## How the amounts are calculated

Per payment, against the **order amount**:

| Component    | Rule                              |
| ------------ | --------------------------------- |
| Platform fee | 5% of the order amount            |
| GST          | 18% of the platform fee           |
| Net          | order amount − platform fee − GST |
| Forex rate   | Fixed at `96`                     |

The settlement totals are the sums across the batch:

* `settlement_amount` = Σ payment net − Σ refund amounts − Σ chargeback amounts
* `settlement_charges` = Σ platform fees
* `settlement_gst` = Σ GST

Refunds and chargebacks carry **no fee of their own**. They debit the total at their full amount, mirroring the real settlement pipeline.

<Accordion title="Worked example — ₹1,000 payment, ₹100 refund, ₹50 chargeback">
  ```
  Payment order amount        ₹1,000.00
    platform fee (5%)         −  ₹50.00
    GST (18% of fee)          −   ₹9.00
    net                       =  ₹941.00

  Refund                      − ₹100.00
  Chargeback                  −  ₹50.00
                              ──────────
  settlement_amount           =  ₹791.00
  settlement_charges          =   ₹50.00
  settlement_gst              =    ₹9.00
  ```
</Accordion>

<Note>
  These are simulator figures, not your contracted rates. Use them to check that your reconciliation *arithmetic* holds, not to predict production settlement amounts.
</Note>

## Side effects

Each payment in the batch gets `settlement_status` = `SETTLED` and its per-payment breakdown populated — fee, tax, net, forex rate, settlement currency — in the same shape a real settlement produces.

<Tip>
  The batch is atomic. If any payment fails validation **nothing** is written, so a partially-settled batch is not a state you can reach.
</Tip>

## What each payment must satisfy

A payment is rejected unless it is:

1. **Yours** — belonging to your merchant account or one of your sub-merchants
2. **On the Simulator gateway**
3. **`CAPTURED`**
4. **Not already settled** — a payment belongs to exactly one settlement

<Note>
  A UID owned by a different merchant is indistinguishable from one that does not exist. Both simply fail to resolve.
</Note>

## Reading validation errors

Unresolvable UIDs come back grouped by category, with the **first** failure in each. Empty categories return `[]`.

```json theme={null}
{
  "success": false,
  "error": {
    "code": "ERR_SERVICE_ERROR_000",
    "message": "Payment gateway error",
    "details": {
      "payment_uids": "PR0000000000",
      "refund_uids": [],
      "chargeback_uids": []
    }
  }
}
```

Because only the first failure per category is reported, fix them one at a time or pre-validate your list.

State problems name the offending UID directly:

| `details.payment_uids`                | Meaning                                                |
| ------------------------------------- | ------------------------------------------------------ |
| `PR… is not on the simulator gateway` | Created on a real gateway                              |
| `PR… is not captured`                 | Payment has not succeeded                              |
| `PR… is already settled`              | Belongs to another settlement — create a fresh payment |

## Testing your settlement handler

<Steps>
  <Step title="Capture a payment">
    Create an order and complete it on the Simulator gateway so the payment reaches `CAPTURED`.
  </Step>

  <Step title="Settle it">
    `POST /pg/settlements/mark-settled/` with that payment's UID.
  </Step>

  <Step title="Receive the webhook">
    Your endpoint gets [`PAYMENT_SETTLED`](/api-reference/v3/webhooks/payment-settled) carrying the new settlement.
  </Step>

  <Step title="Reconcile">
    `GET /pg/settlements/{settlement_id}/` and check your records agree.
  </Step>
</Steps>

To exercise a **net** settlement, create a refund and a chargeback against the payment first, then pass all three UIDs in one call and confirm `settlement_amount` equals the payment net minus both.

## Gotchas

<AccordionGroup>
  <Accordion title="Amounts are strings in rupees, not integer paise">
    `"941.00"`, not `94100`. Parse as decimal — never as a float, for money.
  </Accordion>

  <Accordion title="A payment can be settled only once">
    Re-settling returns `is already settled`. Create a fresh payment for each settlement test.
  </Accordion>

  <Accordion title="settlement_charges and settlement_gst cover payments only">
    Refunds and chargebacks carry no fee. They only reduce `settlement_amount`.
  </Accordion>

  <Accordion title="It is a POST, despite reading like a bulk update">
    Both simulator endpoints are `POST`.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Set Refund Status" icon="rotate-left" href="/api-reference/v3/refunds/simulate-status">
    Drive a refund to any status on demand.
  </Card>

  <Card title="PAYMENT_SETTLED" icon="webhook" href="/api-reference/v3/webhooks/payment-settled">
    The event this endpoint fires.
  </Card>
</CardGroup>


## OpenAPI

````yaml POST /pg/settlements/mark-settled/
openapi: 3.0.0
info:
  title: Eximpe Payment Gateway API
  description: >-
    API for payment processing and order management through Eximpe payment
    gateway. This specification is for v3 API version.
  license:
    name: Proprietary
  version: 3.0.0
servers:
  - url: https://api-pacb-uat.eximpe.com
    description: Payment Gateway Sandbox URL
security:
  - clientAuth: []
    clientSecretAuth: []
    apiVersionHeader: []
tags:
  - name: Card Tokens
  - name: Merchants
  - name: Orders
  - name: Payment Links
  - name: Payments
  - name: Refunds
  - name: Settlements
  - name: Subscriptions
  - name: Virtual Bank Accounts
    description: Create and manage ICICI virtual accounts and read collected payments.
paths:
  /pg/settlements/mark-settled/:
    post:
      tags:
        - Settlement
      summary: Mark payments as settled (sandbox)
      description: >-
        Batches one or more captured payments — plus, optionally, refunds and
        chargebacks — into a single new settlement, applies a simulated fee
        schedule, and fires the
        [`PAYMENT_SETTLED`](/api-reference/v3/webhooks/payment-settled) webhook.
        Use it to exercise your settlement handler and reconciliation without
        waiting for real money movement.


        **Sandbox only.** This endpoint returns `400` in production, and
        operates only on transactions created through the **Simulator** payment
        gateway — a real Cashfree or ICICI transaction is rejected.


        The batch is atomic: if any payment fails validation nothing is written,
        so a partially-settled batch is not a state you can reach.


        **PSP callers must send `X-Merchant-ID`.**
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - payment_uids
              properties:
                payment_uids:
                  type: array
                  minItems: 1
                  items:
                    type: string
                  description: >-
                    Payments to settle. Each must be `CAPTURED`, on the
                    Simulator gateway, yours, and not already settled.
                  example:
                    - PR1234567890
                    - PR1234567891
                refund_uids:
                  type: array
                  items:
                    type: string
                  default: []
                  description: >-
                    Refunds to fold into the same settlement. Each debits the
                    total at its full amount and carries no fee of its own.
                  example:
                    - RF9876543210
                chargeback_uids:
                  type: array
                  items:
                    type: string
                  default: []
                  description: Chargebacks to fold in. Same treatment as refunds.
                  example:
                    - CB5555555555
            example:
              payment_uids:
                - PR1234567890
                - PR1234567891
              refund_uids:
                - RF9876543210
              chargeback_uids:
                - CB5555555555
      responses:
        '200':
          description: Settlement created and the payments marked settled.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Payments marked as settled successfully
                  data:
                    type: object
                    properties:
                      settlement_id:
                        type: string
                        description: >-
                          UID of the new settlement — use it with the settlement
                          detail and list endpoints.
                        example: ST7362075798
                      utr_number:
                        type: string
                        description: Simulated bank UTR reference.
                        example: bb6708d5-367f-4ff4-baea-2743a7e649a3
                      settlement_completed_at:
                        type: string
                        format: date-time
                        example: '2026-08-12T11:32:50.432063Z'
                      forex_rate:
                        type: string
                        description: Always `"96"` in the simulator.
                        example: '96'
                      settlement_amount:
                        type: string
                        description: >-
                          Net settled amount, in **rupees** with 2 decimals —
                          not integer paise.
                        example: '791.00'
                      settlement_charges:
                        type: string
                        description: Total platform fees, in rupees. Payments only.
                        example: '50.00'
                      settlement_gst:
                        type: string
                        description: Total GST on those fees, in rupees. Payments only.
                        example: '9.00'
              example:
                success: true
                message: Payments marked as settled successfully
                data:
                  settlement_id: ST7362075798
                  utr_number: bb6708d5-367f-4ff4-baea-2743a7e649a3
                  settlement_completed_at: '2026-08-12T11:32:50.432063Z'
                  forex_rate: '96'
                  settlement_amount: '791.00'
                  settlement_charges: '50.00'
                  settlement_gst: '9.00'
        '400':
          description: >-
            Validation failed, a UID did not resolve, a payment is not on the
            Simulator gateway / not captured / already settled, or the endpoint
            was called in production. `error.code` is `ERR_SERVICE_ERROR_000`;
            `error.details` says which.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/v3_ErrorResponse'
              example:
                success: false
                error:
                  code: ERR_SERVICE_ERROR_000
                  message: Payment gateway error
                  details:
                    payment_uids: PR4673100896 is not on the simulator gateway
        '500':
          description: Unexpected processing failure.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/v3_ErrorResponse'
      security:
        - clientAuth: []
          clientSecretAuth: []
          merchantAuth: []
          apiVersionHeader: []
components:
  schemas:
    v3_ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          description: Indicates if the request was successful
        error:
          $ref: '#/components/schemas/v3_ErrorDetails'
    v3_ErrorDetails:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Error code (e.g., ERR_ORDER_002)
        message:
          type: string
          description: Error message
        details:
          type: object
          description: Detailed validation error information with field-specific errors
          additionalProperties:
            type: string
            description: Error message for the specific field
  securitySchemes:
    clientAuth:
      type: apiKey
      name: X-Client-ID
      in: header
      description: >-
        **Client Application ID** - Your unique application identifier used to
        authenticate API requests. You can find your Client ID in the Developer
        Settings section of the merchant dashboard.
      x-displayName: Client ID
      x-example: your-client-id
    clientSecretAuth:
      type: apiKey
      name: X-Client-Secret
      in: header
      description: >-
        **Client Secret Key** - Your secret key used alongside the Client ID for
        secure authentication. Keep this confidential and never expose it in
        client-side code. Available in the Developer Settings section of the
        merchant dashboard.
      x-displayName: Client Secret
      x-example: your-client-secret
    apiVersionHeader:
      type: apiKey
      name: X-API-Version
      in: header
      description: >-
        **API Version** - Specifies which version of the API to use (e.g.,
        '1.X.X', '2.X.X', or '3.X.X'). This header allows you to control which
        API version your integration uses. Default version information is
        available in the Developer Settings.
      x-displayName: API Version
      x-example: 3.0.0
    merchantAuth:
      type: apiKey
      name: X-Merchant-ID
      in: header
      description: >-
        **Merchant Identifier** - The unique ID for the merchant account. This
        is required for PSP (Payment Service Provider) merchants who manage
        multiple merchant accounts. You can find merchant IDs in the Merchant
        Management section of the dashboard.
      x-displayName: Merchant ID
      x-example: your-merchant-id

````