# Refunds and post-sales

> Issue refunds against a Shoplazza order, list refund records, and read the returns and exchanges buyers start, all through the Open API.

Issue refunds against an order, list refund records, and read the post-sales (returns and exchanges) that buyers start.

## When to use this

Handling refunds from a support tool, or reconciling returns with an external system.

## Prerequisites

- A working public app with OAuth and token storage — follow [Develop a standalone app](/docs/app/getting-started/create-public-app/develop-app) first. Every request below carries an `Access-Token: {token}` header, using the token you saved for each shop.
- The order access scope granted during OAuth.

## How it works

Refunds and post-sales are two related objects, created through different paths:

- A **refund** is something you initiate — call `refund` on an order and the response returns two ids: `refund_record_id`, which identifies the refund itself and can be looked up later in the refund records list, and `post_sale_id` — Shoplazza automatically creates a post-sale record alongside the refund.
- A **post-sale** (return or exchange) is otherwise **started by the buyer on the storefront**, not by your app. The API only lets you read and delete post-sale records — there's no create endpoint for the buyer-initiated flow.

So issuing a refund through the API is the one path that produces a post-sale record you can read back; every other post-sale is out of your app's control until the buyer creates it.

### Issue a refund

`refund_total` is the only required field. For a full refund, pass the order's `total_price`.

`POST /openapi/2026-01/orders/{id}/refund`

Request body:

```json5
{
  "refund": {
    "refund_total": "205.51" // for a full refund, pass the order's total_price
  }
}
```

Response (excerpt, `data.data` is just the two ids):

```json
{
  "code": "Success",
  "data": {
    "refund_record_id": "626516830554446103",
    "post_sale_id": "56008987-fb4d-41b9-aefa-9d38478f486c"
  }
}
```

Partial refunds and per-line-item or per-payment amounts are in [Create refund](/api/order-refund-record-create).

### List refund records

`GET /openapi/2026-01/orders/refund_records`

Response (excerpt, list under `data.data.records`):

```json
{
  "code": "Success",
  "data": {
    "records": [
      {
        "id": "626516830554446103",
        "order_id": "2386979206089232618121",
        "refund_price": "205.51",
        "refund_method": "customize",
        "refund_status": "finished",
        "created_at": "2026-07-01T07:06:35Z",
        "payment_details": [
          {
            "payment_method": "bogus_gateway",
            "refund_price": "205.51",
            "refund_status": "finished"
          }
        ]
      }
    ]
  }
}
```

See [List refund records](/api/order-refund-records).

### Read post-sales (read-only)

:::note
Post-sales (returns and exchanges) are **started by buyers on the storefront**. The API only lets you **read** them (`GET /orders/post_sales`) and **delete** a record (`DELETE /orders/post_sales/{id}`) — there is no create endpoint.
:::

`GET /openapi/2026-01/orders/post_sales`

Response (excerpt — note the list is under `data.data.orders`, not `post_sales`):

```json
{
  "code": "Success",
  "data": {
    "orders": [
      {
        "id": "56008987-fb4d-41b9-aefa-9d38478f486c",
        "number": "VMT95165-S1",
        "order_number": "VMT95165",
        "order_total": "205.51",
        "refund_amount": "205.51",
        "financial_status": "refunded",
        "fulfillment_status": "shipped",
        "status": "finished",
        "customer_name": "Jane Doe",
        "line_items": [
          {
            "id": "ee73a839-61a2-4504-b4b6-ea55f73f1340",
            "product_title": "Denim dress",
            "quantity": 1,
            "refund_price": "205.51",
            "sku": "A002013"
          }
        ]
      }
    ]
  }
}
```

See [List post-sales](/api/order-post-sales) and [Delete post-sale](/api/order-post-sale-delete).

Issuing a refund from a payment app's refund callback is a different flow — see [Processing refund](/docs/app/getting-started/create-payment-app/processing-refund).

## Next steps

- [Listen for order events](/docs/app/use-cases/orders-and-fulfillment/listen-for-order-events) (`orders/refunded`)
