Checkout
BlendX supports 3 checkout entry points. All prices are calculated again on the server from published items and configured modes. Never send or trust a price from the browser.
| Flow | Endpoint | Identity |
|---|---|---|
| Guest storefront | POST /blendxapi/discovery/guest/checkout/ | clientapisecret; authenticated users are rejected. |
| Authenticated storefront | POST /blendxapi/discovery/checkout/ | clientapisecret and the learner’s LMS session. |
| Existing learner cart | POST /blendxapi/payment/checkout/ | Authenticated learner plus orgName organisation context. |
Choose guest or authenticated checkout
Section titled “Choose guest or authenticated checkout”The storefront can inspect the forwarded LMS session before choosing a flow:
GET /blendxapi/discovery/user/clientapisecret: <CLIENT_API_SECRET>Cookie: sessionid=<forwarded-when-present>An active session returns authenticated: true with the user’s email, username,
and name. A machine-authenticated request without a learner session returns:
{"authenticated": false}Request items
Section titled “Request items”Guest and authenticated discovery checkout accept:
{ "organisation_id": "organisation-uuid", "items": [ {"type": "course", "id": "course-uuid", "mode": "verified"}, {"type": "program", "id": "program-uuid", "mode": "honor"} ], "billing_address": { "name": "Amina Khan", "line1": "10 Market Street", "line2": "", "city": "Dubai", "state": "Dubai", "postal_code": "00000", "country": "AE" }}billing_address is optional in the API shape but may be required by the
configured payment provider or local payment rules. Item IDs are BlendX UUIDs,
not Open edX course-v1: keys. Course modes must exist and be visible for
purchase. Items must be published.
Guest checkout
Section titled “Guest checkout”Add email to the common request body:
curl -X POST "https://<LMS_HOST>/blendxapi/discovery/guest/checkout/" \ -H "Content-Type: application/json" \ -H "clientapisecret: $BLENDX_CLIENT_API_SECRET" \ -d '{ "email": "[email protected]", "organisation_id": "organisation-uuid", "items": [{"type":"course","id":"course-uuid","mode":"verified"}] }'For a free basket, the response has status: "free". An existing account is
enrolled; an unknown email receives a registration link and its enrollment is
held until registration with that address.
For a paid basket, status is success and the response is gateway-specific:
- Stripe:
client_secret,publishable_key, and optionallycustomer_session_client_secret. - PayTabs:
redirect_urlandpayment_id. - Razorpay or Geidea:
order_id,key_id, and the amount in subunits asamount.
All variants also return gateway, total_price, currency, and
items_detail. Complete payment with the provider’s client integration. Access
is granted only after a signed success webhook is processed.
Authenticated discovery checkout
Section titled “Authenticated discovery checkout”Send the same body without email. Your server must forward the learner’s LMS
session cookie and add clientapisecret:
POST /blendxapi/discovery/checkout/Content-Type: application/jsonCookie: sessionid=<learner-session>clientapisecret: <CLIENT_API_SECRET>The server creates cart records before starting payment. If the learner already holds another course mode, checkout charges only the non-negative difference between the selected and current mode prices. Regional pricing is applied after that upgrade difference is calculated.
A free basket returns status: "free" and queues the cart for enrollment
without requiring payment-provider credentials.
Learner-cart checkout decision
Section titled “Learner-cart checkout decision”Use this route when the learner already built a server-side cart:
POST /blendxapi/payment/checkout/Cookie: sessionid=<learner-session>; orgName=acmeThe request has no price or item body. The server loads the cart for the signed-in user and selected organisation.
A free cart returns:
{ "status": "enrollment_pending", "total_price": 0, "currency": "usd", "redirect_url": "https://<LMS_HOST>/blendxapi/payment/stripe/payment_status_free/"}A paid cart returns status: "payment_required", gateway, total_price,
currency, and a gateway redirect_url. Open that URL to continue through the
existing hosted payment flow.
Inspect payment capabilities
Section titled “Inspect payment capabilities”Use the signed-in learner’s organisation context to decide which payment UI to show:
GET /blendxapi/payment/capabilities/Cookie: sessionid=<learner-session>; orgName=acme{ "gateway": "razorpay", "configured": true, "supports_subscriptions": true, "supports_billing_portal": false, "currency": "inr"}configured reports whether the selected gateway has its required organisation
credentials. Capability flags describe the gateway even when configuration is
incomplete.
Regional pricing
Section titled “Regional pricing”Checkout resolves the visitor’s region once, applies the configured per-item
discount, and records region, discountPct, and originalPrice with the
transaction. The checkout total is authoritative even if catalog data was
cached earlier.
Production controls
Section titled “Production controls”- Rate-limit guest checkout at the storefront edge by IP and, where practical, normalized email.
- Verify payment webhooks and keep gateway secrets server-side.
- Treat timeouts as unknown outcomes: query provider/payment state before creating another charge.
- Use idempotency controls supplied by the configured gateway.
- Monitor
400,401,429, and webhook-processing failures separately.