Checkout API Reference¶
Complete REST API reference for all checkout endpoints. These are public-facing (anonymous) endpoints used by the checkout frontend.
All checkout endpoints are prefixed with /api/merchello/checkout and accept JSON request bodies. The surface is split across two controllers that share the route prefix:
CheckoutApiController— basket, countries, addresses, shipping, discounts, auth, address lookup, recovery.CheckoutPaymentsApiController— payment methods, payment session creation, express checkout, widget orders, provider returns.
Invariant: Controllers do no business logic. They validate input, delegate to
ICheckoutService/ICheckoutPaymentsOrchestrationService, and map the result. Basket totals are always produced byCheckoutService.CalculateBasketAsync().
Basket¶
Get Basket¶
Retrieves the current basket with formatted totals in the customer's display currency.
Response 200 OK -- CheckoutBasketDto
The DTO carries both store-currency amounts (for calculation reconciliation) and display-currency amounts (for rendering). Pre-formatted strings are included so views never need to format money themselves.
{
"id": "8b0a...",
"isEmpty": false,
"lineItems": [],
"subTotal": 99.99,
"adjustedSubTotal": 99.99,
"discount": 0,
"tax": 17.50,
"shipping": 5.00,
"total": 122.49,
"currency": "GBP",
"currencySymbol": "£",
"formattedSubTotal": "£99.99",
"formattedTotal": "£122.49",
"displaySubTotal": 122.49,
"displayDiscount": 0,
"displayTax": 21.46,
"displayShipping": 6.13,
"displayTotal": 150.08,
"displayCurrencyCode": "USD",
"displayCurrencySymbol": "$",
"formattedDisplayTotal": "$150.08",
"exchangeRate": 1.2253,
"displayPricesIncTax": false,
"taxInclusiveDisplaySubTotal": 0,
"taxIncludedMessage": null,
"billingAddress": null,
"shippingAddress": null,
"appliedDiscounts": [],
"errors": []
}
If the basket is empty, isEmpty is true and all totals are zero.
Invariant — multi-currency: Basket amounts are always stored in store currency. Display amounts are produced on-the-fly by multiplying by
exchangeRate. The payment/invoicing path divides by the locked rate — never charge fromdisplayTotal. See Multi-Currency Overview.
Countries and Regions¶
Get Shipping Countries¶
Returns countries you can ship to (restricted by warehouse service regions).
Response 200 OK -- CountryDto[]
Get Shipping Regions¶
Returns regions (states/provinces) for a shipping country.
Get Billing Countries¶
Returns all countries (no restrictions) for billing addresses.
Get Billing Regions¶
Returns all regions for a billing country.
Addresses¶
Save Addresses¶
Saves billing and shipping addresses. This is the main address submission endpoint that also handles account creation (when a password is included) and checkout initialization.
Request Body -- SaveAddressesRequestDto
{
"email": "customer@example.com",
"billingAddress": {
"name": "Jane Smith",
"company": "",
"addressOne": "123 Main St",
"addressTwo": "",
"townCity": "London",
"countyState": "Greater London",
"regionCode": "",
"postalCode": "SW1A 1AA",
"countryCode": "GB",
"phone": "020 1234 5678"
},
"shippingAddress": { ... },
"shippingSameAsBilling": true,
"acceptsMarketing": false,
"password": null
}
Note: If
passwordis provided, a new member account is created during address save. See Checkout Authentication.
Response 200 OK -- SaveAddressesResponseDto
Error 400 Bad Request when validation fails.
Checkout Initialization¶
Initialize Checkout¶
Initializes the checkout with a country/state, calculates shipping groups, and auto-selects the cheapest shipping option per group. Used when the page first loads and when the customer changes their shipping country.
Request Body -- InitializeCheckoutRequestDto
{
"countryCode": "US",
"stateCode": "CA",
"autoSelectShipping": true,
"email": null,
"previousShippingSelections": null
}
Response 200 OK -- InitializeCheckoutResponseDto
{
"success": true,
"basket": { ... },
"shippingGroups": [
{
"groupId": "...",
"groupName": "Warehouse 1",
"warehouseId": "...",
"lineItems": [...],
"shippingOptions": [
{
"id": "...",
"name": "Standard Shipping",
"daysFrom": 3,
"daysTo": 5,
"cost": 5.99,
"formattedCost": "$5.99",
"selectionKey": "so:abc123...",
"isNextDay": false
}
],
"selectedShippingOptionId": "so:abc123..."
}
],
"combinedShippingTotal": 5.99,
"shippingAutoSelected": true
}
Error 422 Unprocessable Entity when items can't ship to the destination.
Shipping¶
Get Shipping Groups¶
Returns shipping groups with available options for the current basket and address.
Save Shipping Selections¶
Saves the customer's shipping selection for each shipping group.
Request Body -- SelectShippingRequestDto
{
"selections": {
"group-id-1": "so:shipping-option-guid",
"group-id-2": "dyn:fedex:FEDEX_GROUND"
},
"quotedCosts": {
"group-id-2": 12.50
},
"deliveryDates": null
}
Selection key formats (stable contract — do not invent new shapes):
- Flat-rate:
so:{shippingOptionGuid} - Dynamic (carrier):
dyn:{providerKey}:{serviceCode}
QuotedCosts only needs entries for dynamic selections — flat-rate costs are re-computed deterministically by ShippingCostResolver. See Checkout Shipping.
Response 200 OK -- SelectShippingResponseDto with updated basket and groups.
Discounts¶
Apply Discount Code¶
Response 200 OK -- ApplyDiscountResponseDto
{
"success": true,
"message": "Discount applied successfully.",
"basket": { ... },
"discountDelta": 10.00
}
Remove Discount¶
Authentication¶
Check Email¶
Always returns { "hasExistingAccount": false } to prevent email enumeration. See Checkout Authentication.
Sign In¶
Validate Password¶
Forgot Password¶
Validate Reset Token¶
Reset Password¶
Credit Check¶
For purchase order payments -- checks whether a customer has exceeded their credit limit.
Requires authentication. Returns default (no limit) for anonymous callers.
Address Lookup¶
Get Config¶
Returns address lookup provider configuration (e.g., Loqate/Google Places) for the frontend.
Get Suggestions¶
Rate limited: 30 requests/minute per IP.
Resolve Address¶
Rate limited: 20 requests/minute per IP.
Terms and Policies¶
Get Terms Content¶
Renders policy content by key. For terms and privacy, content is sourced from the store policies configured in the backoffice. Other keys fall back to Razor views.
Cart Recovery¶
Recover Basket¶
Restores a basket from an abandoned cart recovery link. Rate limited: 10 requests/minute per IP. See Abandoned Cart Recovery.
Validate Recovery Token¶
Validates a recovery token without restoring the basket.
Payment Endpoints¶
Payment operations use a separate controller at the same base path. See Payment System Overview for details.
Get Payment Methods¶
Returns available payment methods for checkout.
Get Payment Options¶
Returns full payment options including saved methods, express checkout availability, and configured payment methods.
Initiate Payment¶
Request Body -- InitiatePaymentDto
Create Payment Session (Invoice)¶
Creates a payment session for a specific invoice (used after order creation).
Process Payment¶
Processes a payment after client-side interaction (token submission, SDK confirmation).
Process Direct Payment¶
Processes a direct form payment (e.g., purchase order number).
Process Saved Payment¶
Pays using a saved payment method. Requires authentication.
Handle Return¶
Handles redirect returns from payment providers.
Handle Cancel¶
Handles payment cancellation redirects.
Express Checkout¶
Get Express Methods¶
Returns available express checkout methods (Apple Pay, Google Pay, PayPal).
Get Express Config¶
Returns SDK configuration for initializing express checkout buttons.
Create Express Payment Intent¶
Creates a payment intent for express checkout (e.g., Stripe Payment Request).
Process Express Checkout¶
Processes an express checkout payment (creates order + processes payment in one step).
Create Widget Order¶
Creates an order via a payment widget (e.g., PayPal Buttons).
Capture Widget Order¶
Captures a widget order after customer approval.
Apple Pay Merchant Validation (WorldPay)¶
Validates the Apple Pay merchant session for WorldPay integration.