diff --git a/source/includes/wp-api-v3/_order-refunds.md b/source/includes/wp-api-v3/_order-refunds.md index d5e6c5f..5d38eac 100644 --- a/source/includes/wp-api-v3/_order-refunds.md +++ b/source/includes/wp-api-v3/_order-refunds.md @@ -20,6 +20,7 @@ The order refunds API allows you to create, view, and delete individual refunds, | `fee_lines` | array | Fee lines data. See [Order refund - Fee lines properties](#order-refund-fee-lines-properties) | | `api_refund` | boolean | When true, the payment gateway API is used to generate the refund. Default is `true`. write-only | | `api_restock` | boolean | When true, the selected line items are restocked Default is `true`. write-only | +| `compute_totals` | boolean | When true, the server computes per-line refund amounts and validates them against the order's refund history. See [Server-computed refunds](#server-computed-refunds-compute_totals). Default is `false`. Available as of WooCommerce 11.1.0. write-only | ### Order refund - Meta data properties ### @@ -112,7 +113,7 @@ curl -X POST https://example.com/wp-json/wc/v3/orders/723/refunds \ -u consumer_key:consumer_secret \ -H "Content-Type: application/json" \ -d '{ - "amount": "30", + "amount": "30", "line_items": [ { "id": "111", @@ -124,6 +125,7 @@ curl -X POST https://example.com/wp-json/wc/v3/orders/723/refunds \ } ] } + ] }' ``` @@ -263,6 +265,212 @@ woocommerce.post("orders/723/refunds", data).parsed_response | `id` | integer | The ID of the tax rate. | | `refund_total` | number | The amount of tax to refund for this line item. | +### Server-computed refunds (compute_totals) ### + +Available as of WooCommerce 11.1.0. + +Set `compute_totals` to `true` to have the server compute per-line refund amounts. Line items can be sent with just `id` and `quantity`; alternatively, you can supply explicit `refund_total` (and optionally `refund_tax`) to override the computed amount. The server derives the amount from the order's stored unit prices and taxes, caps it to the line's remaining refundable amount, and validates the request against the order's refund history. The refund `amount` is derived from the line items unless supplied explicitly. + +```shell +curl -X POST https://example.com/wp-json/wc/v3/orders/723/refunds \ + -u consumer_key:consumer_secret \ + -H "Content-Type: application/json" \ + -d '{ + "compute_totals": true, + "line_items": [ + { + "id": 111, + "quantity": 1 + } + ] +}' +``` + +```javascript +const data = { + compute_totals: true, + line_items: [ + { + id: 111, + quantity: 1 + } + ] +}; + +WooCommerce.post("orders/723/refunds", data) + .then((response) => { + console.log(response.data); + }) + .catch((error) => { + console.log(error.response.data); + }); +``` + +#### Line item parameters with `compute_totals` #### + +| Parameter | Type | Description | +|----------------|---------|-------------| +| `id` | integer | The ID of the line item in the order. Required. Each line item may appear only once per request. | +| `quantity` | integer | Required as a positive whole number when `refund_total` is omitted; shipping and fee lines must use `1`. With an explicit `refund_total`, it is optional and can be `0` for an amount-only refund, but any supplied value must be a non-negative whole number and is still validated. | +| `refund_total` | number | Optional explicit amount for this line. Tax-inclusive when `refund_tax` is omitted (the server splits out the tax portion); tax-exclusive when `refund_tax` is supplied. When sent with `quantity`, this value determines the refund amount. The gross line refund, including any explicit tax, must be non-zero and match the line's sign. | +| `refund_tax` | array | Optional explicit tax refunds. Requires an explicit `refund_total`; it cannot be combined with an automatically computed amount. Tax IDs must belong to the original line and may appear only once. See [Refund tax parameters](#refund-tax-parameters). | + +When `amount` is omitted, it is calculated from the line items. When supplied, it must be at least the calculated line-item total and no more than the order's remaining refundable amount. + +Common validation errors include: + +| Code | HTTP status | Condition | +| ------ | ------------- | ----------- | +| `woocommerce_rest_invalid_quantity` | 400 | A quantity does not meet the rules above, or a shipping or fee quantity is greater than `1`. | +| `woocommerce_rest_duplicate_line_item` | 400 | A line item appears more than once. | +| `woocommerce_rest_duplicate_tax_id` | 400 | A tax ID appears more than once within a line item. | +| `woocommerce_rest_invalid_refund_amount` | 400 | The refund amount is non-positive or below the calculated line-item total, or an explicit tax amount is invalid. | +| `woocommerce_rest_quantity_exceeds_refundable` | 422 | The requested quantity exceeds the line's remaining refundable quantity. | +| `woocommerce_rest_refund_total_exceeds_remaining` | 422 | An explicit line amount exceeds that line's remaining refundable amount. | +| `woocommerce_rest_refund_exceeds_remaining` | 422 | The final refund amount exceeds the order's remaining refundable amount. | + + + +## Preview a refund ## + +Available as of WooCommerce 11.1.0. + +This API computes the totals a refund would have without creating it. It uses the same calculation engine as refund creation with `compute_totals`, so clients do not have to replicate tax, rounding, or currency-precision logic. + +The request requires the same capability as creating a refund; API keys with read permissions receive a `401`. + +### HTTP request ### + +
+
+ POST +
/wp-json/wc/v3/orders/<id>/refunds/preview
+
+
+ +```shell +curl -X POST https://example.com/wp-json/wc/v3/orders/723/refunds/preview \ + -u consumer_key:consumer_secret \ + -H "Content-Type: application/json" \ + -d '{ + "line_items": [ + { + "line_item_id": 111, + "quantity": 2 + } + ] +}' +``` + +```javascript +const data = { + line_items: [ + { + line_item_id: 111, + quantity: 2 + } + ] +}; + +WooCommerce.post("orders/723/refunds/preview", data) + .then((response) => { + console.log(response.data); + }) + .catch((error) => { + console.log(error.response.data); + }); +``` + +> JSON response example: + +```json +{ + "breakdown": { + "products": { + "subtotal": "100.00", + "tax": "10.00", + "total": "110.00", + "items": [ + { + "id": 111, + "name": "Woo Album", + "product_id": 93, + "quantity": 2, + "subtotal": "100.00", + "tax": "10.00", + "total": "110.00" + } + ] + }, + "shipping": { + "subtotal": "0.00", + "tax": "0.00", + "total": "0.00", + "items": [] + }, + "fees": { + "subtotal": "0.00", + "tax": "0.00", + "total": "0.00", + "items": [] + } + }, + "subtotal": "100.00", + "tax": "10.00", + "total": "110.00", + "max_refundable": "110.00" +} +``` + +### Request properties ### + +| Attribute | Type | Description | +|--------------|-------|-------------------------------------------------------------------------------------------------| +| `line_items` | array | Line items to preview. Required, at least one entry. See properties below. Unknown keys are rejected. | + +### Preview line item properties ### + +| Attribute | Type | Description | +|----------------|---------|-------------| +| `line_item_id` | integer | ID of the original order line item (product, shipping, or fee line). required | +| `quantity` | integer | Positive whole number of units to preview. Required when `refund_total` is omitted. Shipping and fee lines must use `1`. If supplied with `refund_total`, the quantity is still validated. | +| `refund_total` | number | Optional explicit tax-inclusive amount for this line. Must be non-zero and match the line's sign: negative for discount or credit lines, positive otherwise. When sent with `quantity`, this value determines the previewed amount. | + +### Response properties ### + +| Attribute | Type | Description | +|------------------|--------|------------------------------------------------------------------------------------------------------| +| `breakdown` | object | Per-section breakdown with `products`, `shipping`, and `fees`, each carrying `subtotal`, `tax`, `total`, and `items`. | +| `subtotal` | string | Tax-exclusive total of the previewed refund. | +| `tax` | string | Tax portion of the previewed refund. | +| `total` | string | Tax-inclusive total of the previewed refund. | +| `max_refundable` | string | The order's remaining refundable amount. | + +### Errors ### + +Controller-generated validation errors include: + +| Code | HTTP status | Condition | +| ------ | ------------- | ----------- | +| `woocommerce_rest_invalid_refund_amount` | 400 | The aggregate preview total is not greater than zero. | +| `woocommerce_rest_invalid_refund_total` | 400 | An explicit amount is zero, non-numeric, or has the wrong sign. | +| `woocommerce_rest_invalid_quantity` | 400 | A shipping or fee quantity is not `1`. | +| `woocommerce_rest_duplicate_line_item` | 400 | A line item appears more than once. | +| `woocommerce_rest_line_item_not_found` | 400 | The line item does not belong to the order. | +| `woocommerce_rest_unsupported_item_type` | 400 | The referenced item is not a product, shipping, or fee line. | +| `woocommerce_rest_missing_quantity_or_refund_total` | 400 | A line item supplies neither a valid quantity nor an explicit amount. | +| `woocommerce_rest_order_not_refundable` | 422 | The order cannot be refunded or has already been fully refunded. | +| `woocommerce_rest_line_item_already_refunded` | 422 | The line item has already been fully refunded. | +| `woocommerce_rest_quantity_exceeds_refundable` | 422 | The requested quantity exceeds the line's remaining refundable quantity. | +| `woocommerce_rest_refund_total_exceeds_line` | 422 | An explicit amount exceeds the original line total. | +| `woocommerce_rest_refund_total_exceeds_remaining` | 422 | An explicit amount exceeds the line's remaining refundable amount. | +| `woocommerce_rest_preview_exceeds_max_refundable` | 422 | The preview total exceeds the order's remaining refundable amount. | +| `woocommerce_rest_invalid_order_id` | 404 | The order does not exist. | + +REST schema, authentication, and permission failures can use WordPress REST API error codes instead. For example, an unknown request property returns `rest_invalid_param`, and a read-only API key receives HTTP 401. + ## Retrieve a refund ## This API lets you retrieve and view a specific refund from an order.