MCP Cart & Checkout API Integration
Guide for integrating Cart & Checkout APIs via MCP
Cart & Checkout API — MCP Integration
Public Swagger UI & OpenAPI URLs
Direct via Cloud Run (recommended)
| Service | Swagger UI | OpenAPI JSON |
|---|---|---|
| Cart (cart, user carts, sync) | https://cart-service-222426967009.us-east1.run.app/docs | https://cart-service-222426967009.us-east1.run.app/openapi.json |
| Payment (checkout carts, checkout, orders, payments, customers) | https://payment-service-222426967009.us-east1.run.app/docs | https://payment-service-222426967009.us-east1.run.app/openapi.json |
| Search (search, AI endpoints, inventory) | https://search-service-222426967009.us-east1.run.app/docs | https://search-service-222426967009.us-east1.run.app/openapi.json |
| User | https://user-service-222426967009.us-east1.run.app/docs | https://user-service-222426967009.us-east1.run.app/openapi.json |
Note: API Gateway (
https://api.crop-dev.app) proxies only API endpoints (/api/...), NOT Swagger UI pages (/docs). Use Cloud Run URLs directly to browse documentation.
Via API Gateway (API calls only)
Base URL: https://api.crop-dev.app
API Gateway proxies all /api/... endpoints. Swagger UI and OpenAPI JSON via gateway may be unavailable (504 timeout).
Local Development
| Service | Swagger UI | OpenAPI JSON |
|---|---|---|
| Cart | http://localhost:3000/docs | http://localhost:3000/openapi.json |
| Payment | http://localhost:3004/docs | http://localhost:3004/openapi.json |
| Search | http://localhost:3001/docs | http://localhost:3001/openapi.json |
Architecture: Two Services with Cart Functionality
CROP has two services that handle carts:
| Service | Purpose | Endpoints |
|---|---|---|
| Cart Service (port 3000) | Frontend cart sync, user carts, persistent storage | POST /api/cart, GET /api/cart, GET/DELETE /api/cart/{cartId}, PUT /api/cart/sync, POST /api/cart/clear, GET/PUT/DELETE /api/cart/user/{userId} |
| Payment Service (port 3004) | Checkout carts — save cart before payment, 24h TTL | POST /api/cart, GET /api/cart/{cartId}, DELETE /api/cart/{cartId} |
Warning — Gateway routing: API Gateway (
api.crop-dev.app) routes all/api/cart/*requests to Payment Service. This means:
Endpoint Via Gateway Direct (Cart Service) Direct (Payment Service) POST /api/cart✅ → payment ✅ ✅ GET /api/cart/{cartId}✅ → payment ✅ ✅ DELETE /api/cart/{cartId}✅ → payment ✅ ✅ GET /api/cart(current cart)❌ 404 ✅ — PUT /api/cart/sync❌ 404 ✅ — POST /api/cart/clear❌ 404 ✅ — GET/PUT/DELETE /api/cart/user/{userId}❌ 404 ✅ — For
sync,clear,user/{userId}— use the direct Cart Service URL:https://cart-service-222426967009.us-east1.run.app
For MCP integration (checkout flow) use Payment Service cart endpoints (via gateway or direct) — they are tied to cartId and ensure checkout idempotency.
Cart Service is used by the frontend for cart state synchronization. Endpoints sync, clear, user/{userId} are available only directly via Cloud Run URL.
Recommended Flow: Add to Cart and Checkout via MCP
Overall Architecture
MCP Client
│
├─ 1. Search product ─────► Search Service (GET /api/search)
├─ 2. Save cart ───────────► Payment Service (POST /api/cart)
├─ 3. Get cart ────────────► Payment Service (GET /api/cart/{cartId})
├─ 4. Create checkout ─────► Payment Service (POST /api/checkout/session)
├─ 5. [User pays on Stripe Hosted Checkout]
├─ 6. Check order ─────────► Payment Service (GET /api/orders/by-session/{id})
└─ 7. Get order details ──► Payment Service (GET /api/orders/{orderId})Step 1: Search for Product
GET https://api.crop-dev.app/api/search?q=hydraulic+filter&limit=10Response includes productId, partNumber, title, unitPrice, manufacturer, imageUrl.
AI-optimized search (for MCP/LLM agents):
GET https://api.crop-dev.app/api/ai?q=hydraulic+filter&limit=10Additional AI endpoints:
GET /api/ai/parts/{id}— part details with equipment fitment dataPOST /api/ai/availability— batch availability check (see example below)GET /api/ai/equipment— equipment ↔ parts bidirectional lookupGET /api/ai/diagrams— equipment diagram images
Batch availability check:
POST https://api.crop-dev.app/api/ai/availability
Content-Type: application/json
{
"partNumbers": ["HF-1234", "OF-5678"]
}Required field: partNumbers (array of strings, 1–10 items). Returns results array with partNumber, found, title, price, availability, stock for each part, plus a summary object.
Step 2: Save Cart for Checkout
POST https://api.crop-dev.app/api/cart
Content-Type: application/json
{
"cartId": "cart_1708444800_abc123xyz",
"userId": "user_2abc...",
"sessionId": "<uuid>",
"items": [
{
"productId": "abc123",
"partNumber": "HF-1234",
"title": "Hydraulic Filter",
"manufacturer": "Donaldson",
"quantity": 2,
"unitPrice": 45.99,
"currency": "USD",
"imageUrl": "https://...",
"availability": "in_stock"
}
]
}| Field | Required | Description |
|---|---|---|
cartId | Yes | Unique cart ID. Format: cart_{timestamp}_{random}, min 20 chars, pattern ^[a-zA-Z0-9_-]+$ |
items | Yes | Array of items (1–100) |
userId | No | Clerk user ID (for authenticated users) |
sessionId | No | Session ID (for anonymous users) |
Required fields per item: productId, partNumber, title, quantity, unitPrice.
Optional fields per item: manufacturer, currency, imageUrl, availability.
Response:
{
"success": true,
"data": {
"cartId": "cart_1708444800_abc123xyz",
"items": [...],
"subtotal": 91.98,
"currency": "USD"
}
}Step 3: Get Cart by ID
GET https://api.crop-dev.app/api/cart/{cartId}Response:
{
"success": true,
"data": {
"cartId": "cart_1708444800_abc123xyz",
"items": [...],
"subtotal": 91.98,
"currency": "USD"
}
}Step 4: Create Checkout Session
POST https://api.crop-dev.app/api/checkout/session
Content-Type: application/json
{
"items": [
{
"productId": "abc123",
"partNumber": "HF-1234",
"title": "Hydraulic Filter",
"manufacturer": "Donaldson",
"quantity": 2,
"unitPrice": 45.99,
"currency": "USD"
}
],
"shippingRate": {
"provider": "UPS",
"serviceType": "Ground",
"cost": 12.99,
"estimatedDays": 5
},
"shippingAddress": {
"name": "John Doe",
"street": "123 Main St",
"city": "Clinton",
"state": "NY",
"postalCode": "13323",
"country": "US",
"phone": "+1-315-555-0100"
},
"cartId": "cart_1708444800_abc123xyz",
"customerId": "user_2abc...",
"successUrl": "https://www.clintontractor.net/parts/checkout/success?session_id={CHECKOUT_SESSION_ID}",
"cancelUrl": "https://www.clintontractor.net/parts/checkout/cancel"
}| Field | Required | Description |
|---|---|---|
items | Yes | Array of items (1–100) |
cartId | No | Cart ID for idempotency — resubmitting same cartId returns existing Stripe Session |
customerId | No | Clerk user ID |
successUrl | No | Redirect URL after successful payment (supports {CHECKOUT_SESSION_ID} placeholder) |
cancelUrl | No | Redirect URL if user cancels payment |
shippingRate | No | Shipping rate object (provider, serviceType, cost, estimatedDays) |
shippingAddress | No | Shipping address object (name, street, city, state, postalCode, country, phone) |
currency | No | Ignored — server forces "usd" |
metadata | No | Custom key-value pairs (max 20 keys) |
Response:
{
"success": true,
"data": {
"sessionId": "cs_abc123def456",
"url": "https://checkout.stripe.com/c/pay/cs_abc123def456...",
"paymentIntentId": "pi_abc123..."
}
}
paymentIntentIdmay be absent — it is not required in the response.
MCP action: return the url to the user to proceed with payment.
Step 5: Check Result After Payment
After the user returns to successUrl:
GET https://api.crop-dev.app/api/orders/by-session/cs_abc123def456Response:
{
"success": true,
"data": {
"orderId": "order_abc123",
"orderNumber": "CTS-2026-00042",
"status": "pending",
"createdAt": "2026-02-20T12:05:00Z"
}
}Step 6: Get Order Details
GET https://api.crop-dev.app/api/orders/order_abc123
Authorization: Bearer <clerk-jwt>Response:
{
"success": true,
"data": {
"orderId": "order_abc123",
"orderNumber": "CTS-2026-00042",
"userId": "user_2abc...",
"items": [
{
"partNumber": "HF-1234",
"name": "Hydraulic Filter",
"quantity": 2,
"price": 45.99,
"total": 91.98
}
],
"subtotal": 91.98,
"tax": 0,
"shipping": 12.99,
"total": 104.97,
"currency": "USD",
"status": "pending",
"paymentStatus": "paid",
"shippingAddress": { "name": "John Doe", "street": "123 Main St", "..." : "..." },
"createdAt": "2026-02-20T12:05:00Z"
}
}Key Recommendations for MCP Integration
Authentication
| Scenario | Method | Header |
|---|---|---|
| Guest cart | Session ID | X-Session-Id: <uuid> |
| Authenticated user | Clerk JWT | Authorization: Bearer <token> |
| Public endpoints (by-session, by-payment) | Not required | — |
Idempotency
- Always pass
cartIdinPOST /api/cartandPOST /api/checkout/session— this guarantees idempotency - Format:
cart_{timestamp}_{random}, minimum 20 characters, pattern^[a-zA-Z0-9_-]+$ - Resubmitting with the same
cartIdreturns the same Stripe Session
Example generation:
const cartId = `cart_${Date.now()}_${crypto.randomUUID().slice(0, 8)}`;
// → "cart_1708444800000_a1b2c3d4"Price Validation
- Backend validates prices when creating a Checkout Session (
checkoutValidationService) - If the price has changed, the API returns
400 VALIDATION_FAILED - MCP should re-fetch current prices and recreate the session
Error Handling
All APIs return errors in a standard format:
{
"success": false,
"error": {
"code": "VALIDATION_FAILED",
"message": "Price for item HF-1234 has changed from $45.99 to $47.99"
}
}HTTP status codes:
400 — Bad request / validation failed / prices changed
401 — Unauthorized (protected endpoints)
403 — Forbidden (accessing another user's order/cart)
404 — Cart/order not found
409 — Conflict (duplicate cartId / cannot cancel order)
500 — Internal server error
503 — Database unavailableOrder Statuses
| Status | Description |
|---|---|
pending | Order created, awaiting processing |
processing | Being processed |
shipped | Shipped |
delivered | Delivered |
cancelled | Cancelled |
Payment Statuses
| Status | Description |
|---|---|
pending | Awaiting payment |
paid | Paid |
failed | Payment failed |
refunded | Refunded |
partially_refunded | Partially refunded |
Order Creation
Orders are created automatically via Stripe Webhook (checkout.session.completed). MCP does not create orders directly — it only creates a Checkout Session and checks the result.
Webhook Flow (for reference)
Stripe Webhook (checkout.session.completed)
│
├─ Create order in MongoDB
├─ Save payment record
├─ Publish event to Kafka
└─ Clear cartCancel Order
POST https://api.crop-dev.app/api/orders/{orderId}/cancel
Authorization: Bearer <clerk-jwt>
Content-Type: application/json
{
"reason": "requested_by_customer",
"adminNote": "Customer changed their mind",
"forceCancel": false
}| Field | Required | Description |
|---|---|---|
reason | No | One of: requested_by_customer (default), duplicate, fraudulent, other |
adminNote | No | Admin note (max 500 characters) |
forceCancel | No | Force cancel (default: false) |
Cancellation is only possible before shipment. Cancelling automatically initiates a full refund via Stripe.
Alternative Flow: PaymentIntent (Express Checkout)
For embedded checkout (Apple Pay / Google Pay buttons directly on the site):
POST https://api.crop-dev.app/api/payment-intent
Content-Type: application/json
{
"amount": 10498,
"currency": "usd",
"cartId": "cart_1708444800_abc123xyz",
"customerId": "user_2abc..."
}
amountis in cents! $104.98 = 10498. Required fields:amount,cartId.
Response:
{
"success": true,
"data": {
"clientSecret": "pi_abc123_secret_xyz...",
"paymentIntentId": "pi_abc123..."
}
}clientSecret is used for stripe.confirmPayment() on the frontend.
Then verify:
GET https://api.crop-dev.app/api/payment/verify/{paymentIntentId}Additional Endpoints (Payment Service)
Customer Management
| Method | Endpoint | Description |
|---|---|---|
POST | /api/customers | Create customer |
GET | /api/customers/{id} | Get customer |
POST | /api/customers/{id}/setup-intent | Create SetupIntent to save card |
GET | /api/customers/{id}/payment-methods | List payment methods |
DELETE | /api/customers/{id}/payment-methods/{pmId} | Delete payment method |
PUT | /api/customers/{id}/default-payment-method | Set default payment method |
Admin Orders (requires X-Admin-Token header)
| Method | Endpoint | Description |
|---|---|---|
GET | /api/admin/orders | List all orders |
GET | /api/admin/orders/stats | Order statistics |
GET | /api/admin/orders/{orderId} | Order details (admin) |
PATCH | /api/admin/orders/{orderId} | Update order (admin) |
Order Lookup
| Method | Endpoint | Description |
|---|---|---|
GET | /api/orders/user/{userId} | User's orders |
GET | /api/orders/{orderId} | Order details |
GET | /api/orders/by-payment/{paymentIntentId} | Order by PaymentIntent ID |
GET | /api/orders/by-session/{sessionId} | Order by Checkout Session ID |
Cart Service Endpoints (frontend sync)
These endpoints are used by the frontend for cart state synchronization. For MCP checkout flow, use Payment Service cart endpoints.
Note: All Cart Service endpoints are available only directly via
https://cart-service-222426967009.us-east1.run.app. Via API Gateway (api.crop-dev.app), onlyPOST /api/cart,GET/DELETE /api/cart/{cartId}work — they are routed to Payment Service.
| Method | Endpoint | Description |
|---|---|---|
POST | /api/cart | Save cart (duplicated in Payment Service) |
GET | /api/cart/{cartId} | Get cart by ID (duplicated in Payment Service) |
DELETE | /api/cart/{cartId} | Delete cart by ID (duplicated in Payment Service) |
GET | /api/cart | Current cart (authenticated/anonymous) |
PUT | /api/cart/sync | Sync cart state |
POST | /api/cart/clear | Clear cart |
GET | /api/cart/user/{userId} | Get user cart |
PUT | /api/cart/user/{userId} | Replace user cart |
DELETE | /api/cart/user/{userId} | Clear user cart |
Cart Sync (
GET /api/cart,PUT /api/cart/sync) returns:{ items, total, itemCount, lastSyncedAt }. User Cart (GET/PUT /api/cart/user/{userId}) returns:{ userId, items, subtotal, currency, updatedAt }.
Base URLs by Environment
| Environment | Base URL |
|---|---|
| Production (API Gateway) | https://api.crop-dev.app |
| Cart (Cloud Run direct) | https://cart-service-222426967009.us-east1.run.app |
| Payment (Cloud Run direct) | https://payment-service-222426967009.us-east1.run.app |
| Search (Cloud Run direct) | https://search-service-222426967009.us-east1.run.app |
| Local dev | http://localhost:3000 (cart) / http://localhost:3004 (payment) / http://localhost:3001 (search) |
All endpoints via Gateway use the
/api/prefix. Direct Cloud Run access also uses/api/(configured in Hono basePath).