Public Alpha. Easel is in early development, so expect rough edges.

Easel

← API Documentation

Refunds API

List and create refunds for an order. Refunds are recorded against the order
and reflected in its refund_status. A refund can also put order lines back
in stock.

Endpoints


List Refunds

Retrieve the refunds for an order. This endpoint is not paginated.

Endpoint: GET /api/v1/orders/{order_id}/refunds/

Scope Required: refunds:read

Request

curl -X GET "https://studio.easel.engineering/api/v1/orders/ord_d0b6fmv28q6vn14peun0/refunds/" \
  -H "Authorization: Bearer your_api_key_here"

Response

Status: 200 OK

{
  "data": [
    {
      "id": "ref_d0b6fmv28q6vn14peun0",
      "number": 1,
      "amount": 500,
      "tax": 40,
      "gift_card_amount": 0,
      "reason": "Damaged item",
      "restocks": [
        {
          "order_variant_id": "orv_d0b6fmv28q6vn14peun0",
          "quantity": 1
        }
      ],
      "created_at": "2023-01-03T10:00:00Z"
    }
  ]
}

Create Refund

Refund an amount against an order. The amount must be greater than zero and is
denominated in the store's smallest currency unit. When the order collected tax,
the refund gives back the same share of each jurisdiction's tax as it does of
the order's total, which the refund's tax reports.

Orders that bought gift cards

A refund of an order that bought gift cards comes out of the rest of the
order first: its other lines, shipping, gift option, and tax. Refunding a
returned item never touches a gift card. Past that, the refund gives back
the cards' price and takes it back off them, in the same step, so it can't
be spent again.

By default it gives back only what's left unspent on the cards, since the
buyer already had the rest. Refunding more is a 400 with INVALID_FIELD
on amount. With refund_spent_gift_cards set to true it can give back
everything not yet refunded, and empties and disables every card the order
bought. Each card's transactions show
what a refund took back as returned.

Gift cards carry no tax, so only the rest of the order gives back any.

To put units back in stock, list them in restocks. Restocking is opt-in:
without restocks the refund changes no stock, which suits an amount-only
refund such as a goodwill credit. Each restocked unit adds one to the
variant's stock and is recorded on the refund. Across all of an order's
refunds, a line can be restocked at most as many units as were ordered, so
retrying a request can't put the same units back twice. Digital products have
no stock and can't be restocked. A restock that brings a variant back into
stock emails the shoppers on its restock waitlist,
the same as raising the stock directly.

Restocks are checked before any money moves: an invalid restock rejects the
whole request and nothing is refunded.

Refunds made outside Easel, such as in the Stripe dashboard, or lost disputes
are recorded on the order from Stripe's webhook but never restock, since Easel
can't know whether the goods came back.

When a gift card paid part of the order, the refund goes
back to the buyer's card first, up to what was charged to it, and the rest
back onto the gift card, which needs no Stripe refund. A refund of an order
a gift card paid in full goes wholly back onto the card.

Endpoint: POST /api/v1/orders/{order_id}/refunds/

Scope Required: refunds:write

Request Body

{
  "amount": 500,
  "reason": "Damaged item",
  "restocks": [
    {
      "order_variant_id": "orv_d0b6fmv28q6vn14peun0",
      "quantity": 1
    }
  ]
}
Field Type Required Description
amount integer Yes Refund amount in the store's smallest currency unit (must be greater than zero)
reason string No Reason for the refund
restocks array No Order lines to put back in stock (see below). Omit to restock nothing
refund_spent_gift_cards boolean No Refund the full price of gift cards the order bought, even what was spent of them, which empties and disables them. Omitted or false, a refund gives back only what's left on them (see below)

Each restocks entry:

Field Type Required Description
order_variant_id string Yes The line's order_variant_id from the order's items; each line at most once
quantity integer Yes Units to put back in stock; 0 restocks nothing. At most the line's quantity less any units earlier refunds restocked

Request

curl -X POST "https://studio.easel.engineering/api/v1/orders/ord_d0b6fmv28q6vn14peun0/refunds/" \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id-12345" \
  -d '{
    "amount": 500,
    "reason": "Damaged item"
  }'

Response

Status: 201 Created

The response body is empty.

Error Responses

Invalid amount

Status: 400 Bad Request

{
  "error": "Amount must be greater than zero",
  "code": "INVALID_FIELD"
}

Amount exceeds the refundable balance, or the order isn't paid

Status: 400 Bad Request

{
  "error": "Amount exceeds the order's refundable balance",
  "code": "INVALID_FIELD"
}

Invalid restock

A restock that names a line not on the order, names a line twice, has a
negative quantity, names a digital product, or asks for more units than the
line can still take.

Status: 400 Bad Request

{
  "error": "Restock quantity exceeds the units ordered, less any already restocked",
  "code": "INVALID_FIELD"
}

Order not found

Status: 404 Not Found

{
  "error": "Resource not found",
  "code": "NOT_FOUND"
}

Refund Object

Fields

Field Type Description
id string Refund public ID
number integer Refund number within the order
amount integer Refund amount in the store's smallest currency unit
tax integer The part of amount that gave back the order's tax, in proportion to the share of the order refunded
gift_card_amount integer Part of amount put back on the order's gift card rather than its card
reason string|null Reason for the refund
restocks array Units the refund put back in stock; empty when it restocked nothing
created_at string ISO 8601 timestamp

Refund Restock Object

Field Type Description
order_variant_id string The restocked order line
quantity integer Units put back in stock