E-Commerce Purchase Flow
Complete customer journey from product discovery to delivery and post-purchase support.
Overview
The purchase flow includes:
- Product discovery (browsing, search, filtering)
- Product details and reviews
- Cart management
- Checkout process (shipping, payment)
- Order confirmation and tracking
- Delivery and post-purchase activities
Main Flow Diagram
Step Details
1. Product Discovery
Browsing Endpoint: GET /products
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| category | string | Category slug |
| minPrice | number | Minimum price filter |
| maxPrice | number | Maximum price filter |
| sort | string | popular, newest, price_asc, price_desc |
| page | number | Page number (default: 1) |
| limit | number | Items per page (default: 20, max: 100) |
| inStock | boolean | Only show in-stock items |
Search Endpoint: GET /products/search
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
| q | string | Search query (min 2 chars) |
| category | string | Optional category filter |
| sort | string | relevance, popular, price_asc, price_desc |
Search Implementation:
- PostgreSQL full-text search with tsvector
- Weighted search: name (A), description (B), SKU (C)
- Fuzzy matching for typo tolerance
2. Product Details
Endpoint: GET /products/{slug}
Response:
{
"id": "uuid",
"sku": "WH-BT-001",
"name": "Wireless Headphones Pro",
"slug": "wireless-headphones-pro",
"shortDescription": "Premium wireless headphones with noise cancellation",
"description": "Full HTML description...",
"basePrice": 9990.00,
"salePrice": 7990.00,
"currency": "RUB",
"status": "ACTIVE",
"stockQuantity": 45,
"inStock": true,
"images": [
{ "url": "https://cdn.../main.jpg", "isPrimary": true },
{ "url": "https://cdn.../side.jpg", "isPrimary": false }
],
"category": {
"id": "uuid",
"name": "Electronics",
"slug": "electronics"
},
"reviewsSummary": {
"averageRating": 4.5,
"totalReviews": 128
},
"careerPointsValue": 100.00
}Stock Status Display:
| Stock Level | Display |
|---|---|
| > 10 | "In Stock" |
| 1-10 | "Only X left" |
| 0 | "Out of Stock" |
3. Add to Cart
Endpoint: POST /cart/items
Request:
{
"productId": "product-uuid",
"quantity": 2
}Validation Rules:
| Rule | Constraint |
|---|---|
| Quantity | Min: 1, Max: 99 |
| Stock | quantity <= available stock |
| Product status | Must be ACTIVE |
| Cart items | Max 50 unique items |
Cart Identification:
- Authenticated: By user_id
- Guest: By session_id (cookie)
Referral Attribution:
- Cart inherits
referring_partner_idfrom session attribution - Preserved even if user logs in during checkout
4. Cart Management
Get Cart Endpoint: GET /cart
Response:
{
"id": "cart-uuid",
"items": [
{
"id": "item-uuid",
"product": {
"id": "product-uuid",
"name": "Wireless Headphones Pro",
"sku": "WH-BT-001",
"imageUrl": "https://cdn.../thumb.jpg",
"slug": "wireless-headphones-pro"
},
"quantity": 2,
"unitPrice": 7990.00,
"totalPrice": 15980.00,
"stockStatus": "IN_STOCK",
"availableQuantity": 45
}
],
"subtotal": 15980.00,
"discountTotal": 0.00,
"total": 15980.00,
"currency": "RUB",
"itemCount": 2,
"referringPartnerCode": "ABC123"
}Update Quantity Endpoint: PATCH /cart/items/{itemId}
Request:
{
"quantity": 3
}Remove Item Endpoint: DELETE /cart/items/{itemId}
Save for Later: POST /cart/items/{itemId}/save-for-later
5. Guest vs Authenticated Checkout
Guest Checkout Flow:
- Email collection (required)
- Shipping address entry
- Payment processing
- Account creation offer (optional, post-purchase)
Guest Checkout Limitations:
- Order history only via email lookup
- No saved addresses/payment methods
- Cannot use loyalty points
- Still receives referral attribution
Cart Merge (when guest logs in):
- Guest cart items merged into user cart
- Duplicate products: quantities summed
- Attribution preserved from original cart
6. Checkout Step 1: Shipping Address
Saved Addresses Endpoint: GET /users/me/addresses?type=SHIPPING
New Address Request:
{
"firstName": "Ivan",
"lastName": "Petrov",
"phone": "+79001234567",
"addressLine1": "ul. Lenina, d. 10, kv. 5",
"addressLine2": "",
"city": "Moscow",
"state": "Moscow Oblast",
"postalCode": "101000",
"country": "RUS",
"saveAddress": true,
"setAsDefault": true
}Address Validation:
| Field | Rules |
|---|---|
| firstName, lastName | Required, 2-100 chars |
| addressLine1 | Required, max 255 chars |
| city | Required, max 100 chars |
| postalCode | Required, format varies by country |
| country | Required, ISO 3166-1 alpha-3 |
| phone | Required, E.164 format |
7. Checkout Step 2: Shipping Method
Endpoint: GET /checkout/shipping-methods
Response:
{
"methods": [
{
"id": "method-uuid",
"name": "CDEK Express",
"carrier": "CDEK",
"price": 350.00,
"currency": "RUB",
"estimatedDays": { "min": 2, "max": 4 },
"description": "Fast delivery to your door"
},
{
"id": "method-uuid-2",
"name": "Standard Delivery",
"carrier": "CDEK",
"price": 200.00,
"currency": "RUB",
"estimatedDays": { "min": 5, "max": 7 },
"description": "Economic delivery option"
}
]
}Rate Calculation:
- Based on: destination, weight, dimensions
- Cached for 15 minutes
- Real-time API call to carrier if cache miss
8. Checkout Step 3: Payment
Supported Payment Methods:
| Method | Provider | Features |
|---|---|---|
| Credit/Debit Card | Stripe | 3D Secure, saved cards |
| Bank Card (RU) | YooKassa | Russian cards, SberPay |
| E-wallet | YooKassa | YooMoney, QIWI |
| Bank Transfer | YooKassa | Invoice payment |
Payment Flow (Stripe):
- Frontend creates PaymentIntent
- User enters card details in Stripe Elements
- Frontend confirms payment
- Backend verifies via webhook
Complete Checkout Endpoint: POST /checkout/complete
Request:
{
"paymentMethodId": "pm_xxx",
"paymentIntentId": "pi_xxx",
"billingAddressId": "address-uuid",
"notes": "Leave at door"
}9. Order Confirmation
Order Created:
{
"id": "order-uuid",
"orderNumber": "ORD-2024-001234",
"status": "CONFIRMED",
"items": [...],
"subtotal": 15980.00,
"shippingCost": 350.00,
"discountTotal": 0.00,
"taxAmount": 0.00,
"total": 16330.00,
"currency": "RUB",
"shippingAddress": {...},
"shippingMethod": {...},
"createdAt": "2024-01-15T10:30:00Z",
"estimatedDelivery": "2024-01-19"
}Confirmation Email Contains:
- Order number and summary
- Itemized list with prices
- Shipping address and method
- Estimated delivery date
- Support contact
10. Order Tracking
Endpoint: GET /orders/{orderNumber}
Order Status Timeline:
| Status | Description | User Action |
|---|---|---|
| PENDING | Order created, awaiting payment | Complete payment |
| CONFIRMED | Payment successful | Wait for processing |
| PROCESSING | Being prepared | Wait for shipping |
| SHIPPED | Handed to carrier | Track shipment |
| DELIVERED | Received by customer | Leave review, request return |
| CANCELLED | Order cancelled | Contact support |
| REFUNDED | Money returned | N/A |
Tracking Integration:
- Real-time tracking via carrier API
- Webhook updates for status changes
- SMS/Email notifications at each stage
11-12. Fulfillment and Delivery
Order State Transitions:
PENDING -> CONFIRMED -> PROCESSING -> SHIPPED -> DELIVERED
| | |
v v v
CANCELLED CANCELLED CANCELLED (rare)
|
v
REFUNDEDCarrier Webhook Events:
| Event | Action |
|---|---|
| picked_up | Update shipment status |
| in_transit | Update tracking events |
| out_for_delivery | Send notification |
| delivered | Update order to DELIVERED |
| returned | Initiate return process |
13. Post-Purchase
Reviews
Endpoint: POST /products/{productId}/reviews
Request:
{
"rating": 5,
"title": "Great headphones!",
"content": "Sound quality is amazing, battery lasts all day.",
"orderId": "order-uuid"
}Review Rules:
- Must have purchased product (order DELIVERED)
- One review per product per user
- Moderation required before publishing
Returns
Endpoint: POST /orders/{orderNumber}/returns
Request:
{
"items": [
{
"orderItemId": "item-uuid",
"quantity": 1,
"reason": "DEFECTIVE",
"description": "Left speaker not working"
}
]
}Return Reasons:
| Code | Description | Refund Timeline |
|---|---|---|
| DEFECTIVE | Product defect | Full refund, 3-5 days |
| WRONG_ITEM | Received wrong item | Full refund, 3-5 days |
| NOT_AS_DESCRIBED | Doesn't match listing | Full refund, 3-5 days |
| CHANGED_MIND | Customer changed mind | Refund minus shipping, 5-7 days |
Return Window: 14 days from delivery
Error Scenarios
Cart Errors
| Scenario | HTTP Code | Error Code | Message |
|---|---|---|---|
| Product not found | 404 | PRODUCT_NOT_FOUND | "Product no longer available" |
| Out of stock | 422 | INSUFFICIENT_STOCK | "Only X items available" |
| Product discontinued | 422 | PRODUCT_UNAVAILABLE | "This product is no longer sold" |
| Cart empty | 400 | EMPTY_CART | "Your cart is empty" |
Checkout Errors
| Scenario | HTTP Code | Error Code | Message |
|---|---|---|---|
| Stock changed during checkout | 409 | STOCK_CHANGED | "Some items are no longer available" |
| Price changed | 409 | PRICE_CHANGED | "Prices have been updated" |
| Invalid address | 400 | INVALID_ADDRESS | "Please check your address" |
| Shipping unavailable | 422 | SHIPPING_UNAVAILABLE | "Delivery not available to this address" |
Payment Errors
| Scenario | HTTP Code | Error Code | Message |
|---|---|---|---|
| Card declined | 422 | CARD_DECLINED | "Your card was declined" |
| Insufficient funds | 422 | INSUFFICIENT_FUNDS | "Insufficient funds" |
| 3DS failed | 422 | 3DS_FAILED | "3D Secure verification failed" |
| Payment timeout | 408 | PAYMENT_TIMEOUT | "Payment timed out, please try again" |