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 -
GET /api/v1/orders/{order_id}/refunds/ - Create Refund -
POST /api/v1/orders/{order_id}/refunds/
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 |