data-src=../../../includes/saas-only.md
Custom shipping discounts
The custom shipping discounts let an administrator or integration apply an arbitrary discount to the shipping amount of a specific cart. Use it for cases that do not fit a cart price rule, such as a goodwill credited to an individual shopper.
If a discount fits a rule-based pattern, use a cart price rule instead.
How Commerce applies the discount
Commerce reapplies the custom shipping discount each time it recalculates the cart totals, so the discount persists when the cart changes. The following rules apply:
- The applied amount never exceeds the remaining shipping amount. If a cart price rule already discounts shipping, the custom discount applies only to the shipping amount that remains. In this case,
applied_amountis less thanamount. - The cart totals (
GET /V1/carts/:cartId/totals) include a separate Shipping Discount total segment with theadmin_shipping_discountcode. - The discount is added to the cart and order discount amount, with the Shipping Discount label in the discount description. The Shipping & Handling amount continues to show the full shipping amount before the discount.
Apply a shipping discount during an order edit
You can apply a custom shipping discount when you edit an order. Call POST /V1/carts/:cartId/shipping-discount with the cart ID that POST /V1/orders/{orderId}/edit/start returns, then submit the edit. If order edit history comments are enabled, Commerce adds a comment to the replacement order when the edit applies, changes, or removes a custom shipping discount. The comment shows the applied amount, which can be less than the requested amount.
When you edit an order that already has a custom shipping discount, Commerce carries the discount forward to the new edit cart. The discount remains on the order across subsequent edits until you remove it with DELETE /V1/carts/:cartId/shipping-discount.
Endpoints
GET/V1/carts/:cartId/shipping-discountPOST/V1/carts/:cartId/shipping-discountDELETE/V1/carts/:cartId/shipping-discountAll three endpoints require an admin or integration token with the Magento_ShippingDiscountApi::manage role.
The :cartId value must identify an active cart. If the cart does not exist or has already been converted to an order, the endpoints return HTTP status 404.
Apply a shipping discount
The POST /V1/carts/:cartId/shipping-discount endpoint applies a custom shipping discount to the cart and immediately recalculates the cart totals.
The request body contains the following fields:
amountreasongoodwill credit. Maximum 255 characters. The reason is stored for auditing and is not shown to the customer.A cart can have only one custom shipping discount. If the cart already has one, a new POST request replaces the existing amount and reason instead of adding a second discount.
Example: apply a shipping discount
Request:
curl -X POST "https://<host>/rest/V1/carts/42/shipping-discount" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <admin-token>" \
-d '{"amount": 2.00, "reason": "goodwill credit"}'
A successful request returns HTTP status 200.
Retrieve a shipping discount
The GET /V1/carts/:cartId/shipping-discount endpoint returns the active custom shipping discount on the cart.
Example: retrieve a shipping discount
Request:
curl -X GET "https://<host>/rest/V1/carts/42/shipping-discount" \
-H "Authorization: Bearer <admin-token>"
Response:
{
"cart_id": 42,
"amount": 2.00,
"base_amount": 2.00,
"applied_amount": 2.00,
"base_applied_amount": 2.00,
"reason": "goodwill credit",
"actor_user_id": 7,
"actor_user_type": 2
}
The response contains the following fields:
cart_idamountbase_amountapplied_amountbase_applied_amountreasonactor_user_idactor_user_type, because admin user IDs and integration IDs can overlap.actor_user_type1 for an integration or 2 for an admin user.If the cart has no active custom shipping discount, the endpoint returns HTTP status 404.
Remove a shipping discount
The DELETE /V1/carts/:cartId/shipping-discount endpoint removes the custom shipping discount from the cart and recalculates the cart totals. If the cart has no discount, the request still succeeds.
Example: remove a shipping discount
Request:
curl -X DELETE "https://<host>/rest/V1/carts/42/shipping-discount" \
-H "Authorization: Bearer <admin-token>"
A successful request returns HTTP status 200.
Errors
400amount is zero, negative, too large, or too small to store, either as submitted or after conversion to the base currency, or the reason exceeds 255 characters.400400401Magento_ShippingDiscountApi::manage role resource.404GET) the cart has no active custom shipping discount.