Payment Methods
Base URL: https://apinexgate.glueauth.com/api/v1/
Short Description: The CheckoutPayment SessionMethods API managesenables theusers completeto checkoutmanage processtheir payment methods for e-commerce transactions. It handles creating checkout sessions from cart or direct purchase, managing payment intents, processing payments throughSupports multiple payment methodstypes including credit/debit cards, mobile money (Wallet,M-Pesa, CashAirtel Money, Tigo Pesa), bank transfers, PayPal, cryptocurrency wallets, gift cards, and cash on Delivery,delivery. Cards,Features Mobileinclude Money),setting default payment methods, masking sensitive data, and supportsvalidation advancedto featuresprevent likeduplicate group purchasing and installment payments. Each session maintains state, inventory holds, and payment attempt tracking with automatic expiration handling.entries.
Hints:
- Sensitive data (card numbers, account numbers, PINs) are automatically masked in responses
- Only one payment method can be set as default at a time
- Duplicate payment methods are automatically detected and prevented
- All
checkoutpaymentsessionsmethodsexpirerequireafterverification15beforeminutesusebyin transactions - Inactive payment methods cannot be set as default
InventoryCashisonautomaticallyDeliveryheldrequiresduringnoactivesensitivesessions and released upon expiration or cancellationinformationMaximumMobile5moneypayment(MNO_PAYMENT)retryrequiresattemptsvalidallowedTanzanianperphonesessionnumber formatGroupCardpurchasenumberssessions require WALLET payment method onlySessions in PAYMENT_PROCESSING status cannotmust bemodified13-19 Installment payment type is planned for future release (placeholder only)digits- All
monetarydatetimevaluesfieldsare in TZS (Tanzanian Shillings) Useuse ISO 8601 formatfor all datetime fieldsSessions can only be updated when in PENDING_PAYMENT or PAYMENT_FAILED status
Standard Response Format
All API responses follow a consistent structure using our Globe Response Builder pattern:
Success Response Structure
{
"success": true,
"httpStatus": "OK",
"message": "Operation completed successfully",
"action_time": "2025-10-02T10:30:45",
"data": {
// Actual response data goes here
}
}
Error Response Structure
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Error description",
"action_time": "2025-10-02T10:30:45",
"data": "Error description"
}
Standard Response Fields
| Field | Type | Description |
|---|---|---|
success |
boolean | Always true for successful operations, false for errors |
httpStatus |
string | HTTP status name (OK, |
message |
string | Human-readable message describing the operation result |
action_time |
string | ISO 8601 timestamp of when the response was generated |
data |
object/string | Response payload for success, error details for failures |
HTTP Method Badge Standards
For better visual clarity, all endpoints use colored badges for HTTP methods with the following standard colors:
- GET - GET - Green (Safe, read-only operations)
- POST - POST - Blue (Create new resources)
- PUT - PUT - Yellow (Update/replace entire resource)
- PATCH - PATCH - Orange (Partial updates)
- DELETE - DELETE - Red (Remove resources)
Endpoints
1. Create CheckoutPayment SessionMethod
Purpose: Creates a new checkoutpayment sessionmethod for processingthe aauthenticated purchase.user. SupportsValidates multipledetails checkoutbased types:on directpayment product purchase, cart checkout, group purchasing,type and installmentprevents paymentsduplicate (future).entries.
Endpoint: POST {base_url}/checkout-sessionspayment-methods
Access Level: 🔒 Protected (Requires Authentication)
Authentication: Bearer Token required in Authorization header
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authenticated user |
| Content-Type | string | Yes | Must be application/json |
Request JSON Sample (Credit Card):
{
"sessionType"paymentMethodType": "REGULAR_DIRECTLY"CREDIT_CARD",
"items"methodDetails": [ {
"productId"cardType": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"Visa",
"quantity"cardNumber": 2
}
]"4242424242424242",
"shippingAddressId"expiry": "f1e2d3c4-b5a6-7890-cdef-123456789abc"12/2028",
"shippingMethodId"cardholderName": "standard-shipping"John Doe"
},
"paymentMethodId"billingAddress": {
"street": "p1a2y3m4-e5n6-7890-tdef-987654321abc"123 Main Street",
"city": "Dar es Salaam",
"state": "Dar es Salaam Region",
"postalCode": "12345",
"country": "Tanzania"
},
"metadata": {
"couponCode"nickname": "SAVE20",My "referralCode":Primary "REF123",
"notes": "Please handle with care"Card"
},
"installmentPlanId"isDefault": true
}
Request JSON Sample (Mobile Money - M-Pesa):
{
"paymentMethodType": "MNO_PAYMENT",
"methodDetails": {
"phoneNumber": "+255712345678",
"mccMnc": "640-02"
},
"billingAddress": null,
"groupInstanceId"metadata": null{
"provider": "M-Pesa"
},
"isDefault": false
}
Request Body Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| string | Yes | Type of |
enum: |
|
| No | ||||
| metadata | object | No | Additional |
Key-value pairs |
| No |
Method FUTUREDetails by Payment Type:
CREDIT_CARD / DEBIT_CARD:
| Field | Type | Required | Validation |
|---|---|---|---|
| cardType | string | No | e.g., "Visa", "Mastercard" |
| string | Yes | 13-19 digits | |
| expiry | string | Yes | Format: MM/YY or MM/YYYY |
| cardholderName | string | Yes | Min: 2, Max: 100 characters |
MNO_PAYMENT (UUID)M-Pesa, Airtel Money, Tigo Pesa):
| Field | Type | Required | Validation |
|---|---|---|---|
| phoneNumber | string | Yes | Format: +255XXXXXXXXX (Tanzanian format) |
| mccMnc | string | No |
PAYPAL:
| Field | Type | Required | Validation |
|---|---|---|---|
| string | Yes | Valid |
|
| paypalId | string | No | PayPal account ID |
BANK_TRANSFER:
| Field | Type | Required | Validation |
|---|---|---|---|
| bankName | string | Yes | Min: 2, Max: 100 characters |
| accountNumber | string | Yes | Bank account number |
| routingNumber | string | No | Bank routing/SWIFT code |
| accountType | string | No | e.g., "Checking", "Savings" |
| accountHolderName | string | Yes | Min: 2, Max: 100 characters |
CRYPTOCURRENCY:
| Field | Type | Required | Validation |
|---|---|---|---|
| cryptoType | string | Yes | e.g., "Bitcoin", "Ethereum" |
| walletAddress | string | Yes | Cryptocurrency wallet address |
| network | string | No | e.g., "Mainnet", "Testnet" |
GIFT_CARD:
| Field | Type | Required | Validation |
|---|---|---|---|
| pin | string | Yes | Gift card PIN |
| balance | number | Yes | Must be |
| currency | string | Yes | 3-letter currency code (e.g., "TZS") |
CASH_ON_DELIVERY:
| Field | Type | Required | Validation |
|---|---|---|---|
| instructions | string | No | Special instructions for delivery |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "CheckoutPayment sessionmethod created successfully",
"action_time": "2025-10-02T14:30:45",
"data": {
"sessionId"paymentMethodId": "c1d2e3f4-a5b6-pm123456-7890-cdef-123456789abc"abcd-ef12-345678901234",
"sessionType"ownerId": "REGULAR_DIRECTLY"user1234-5678-90ab-cdef-123456789012",
"status": "PENDING_PAYMENT",
"customerId": "u1s2e3r4-i5d6-7890-abcd-ef1234567890",
"customerUserName"ownerUserName": "john_doe",
"items": [
{
"productId"paymentMethodType": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"CREDIT_CARD",
"productName": "Premium Wireless Headphones",
"productSlug": "premium-wireless-headphones",
"productImage": "https://cdn.nextgate.com/products/headphones-001.jpg",
"quantity": 2,
"unitPrice": 150000.00,
"discountAmount": 20000.00,
"subtotal": 300000.00,
"tax": 0.00,
"total": 280000.00,
"shopId": "s1h2o3p4-i5d6-7890-abcd-ef1234567890",
"shopName": "TechWorld Electronics",
"shopLogo": "https://cdn.nextgate.com/shops/techworld-logo.jpg",
"availableForCheckout": true,
"availableQuantity": 50
}
],
"pricing"methodDetails": {
"subtotal": 300000.00,
"discount": 20000.00,
"shippingCost": 5000.00,
"tax": 0.00,
"total": 285000.00,
"currency"cardType": "TZS"
}Visa",
"shippingAddress"maskedCardNumber": {"**** **** **** 4242",
"fullName"expiry": "12/2028",
"cardholderName": "John Doe"
},
"addressLine1"billingAddress": {
"street": "123 Main Street",
"addressLine2": "Apartment 4B",
"city": "Dar es Salaam",
"state": "Dar es Salaam Region",
"postalCode": "12345",
"country": "Tanzania",
"phone": "+255123456789"
},
"billingAddress": {
"sameAsShipping": false,
"fullName": "John Doe",
"addressLine1": "456 Business Ave",
"city": "Dar es Salaam",
"state": "Dar es Salaam Region",
"postalCode": "12346",
"country": "Tanzania"
},
"shippingMethod": {
"id": "standard-shipping",
"name": "Standard Shipping",
"carrier": "DHL",
"cost": 5000.00,
"estimatedDays": "3-5 business days",
"estimatedDelivery": "2025-10-07T14:30:45"
},
"paymentIntent": {
"provider": "WALLET",
"clientSecret": null,
"paymentMethods": ["WALLET"],
"status": "READY"
},
"paymentAttempts": [],
"inventoryHeld": true,
"inventoryHoldExpiresAt": "2025-10-02T14:45:45",
"metadata": {
"couponCode"nickname": "SAVE20",My "referralCode":Primary "REF123",
"notes": "Please handle with care"Card"
},
"expiresAt"isDefault": true,
"2025-10-02T14:45:45",isActive": true,
"isVerified": false,
"createdAt": "2025-10-02T14:30:45",
"updatedAt": "2025-10-02T14:30:45",
"completedAt": null,
"createdOrderId": null,
"cartId": null
}
}
Success Response Fields:
| Field | Description |
|---|---|
| Unique identifier for the |
|
| User ID who |
|
| Username of the |
|
| billingAddress | Billing address |
| metadata | Custom metadata |
| isActive | Whether the payment method is active |
| isVerified | Whether the payment method is verified |
| createdAt | |
| updatedAt | Last update timestamp |
Error Response JSON Sample:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Validation failed",
"action_time": "2025-10-02T14:30:45",
"data": {
"sessionType": "must not be null",
"items": "Items are required for checkout",
"shippingAddressId": "must not be null"
}
}
Standard Error Types:
Application-Level Exceptions (400-499)
400 BAD_REQUEST: Invalid request data, validation errors, business rule violations401 UNAUTHORIZED: Missing, invalid, or expired authentication token403 FORBIDDEN: Insufficient permissions or verification required404 NOT_FOUND: Product, payment method, shipping address, or other resource not found422 UNPROCESSABLE_ENTITY: Validation errors with detailed field information
Server-Level Exceptions (500+)
500 INTERNAL_SERVER_ERROR: Unexpected server errors
Error Response Examples:
Bad Request - InvalidMissing SessionRequired TypeFields (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "REGULAR_DIRECTLYCard checkoutnumber supportsis only 1 item. Use REGULAR_CART for multiple items."required",
"action_time": "2025-10-02T14:30:45",
"data": "REGULAR_DIRECTLYCard checkoutnumber supportsis only 1 item. Use REGULAR_CART for multiple items."required"
}
Bad Request - InsufficientDuplicate InventoryPayment Method (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Insufficient stock. Available: 3, Requested: 5",
"action_time": "2025-10-02T14:30:45",
"data": "Insufficient stock. Available: 3, Requested: 5"
}
Bad Request - Insufficient Wallet Balance (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Insufficient wallet balance. Required: 285000 TZS, Available: 150000 TZS",
"action_time": "2025-10-02T14:30:45",
"data": "Insufficient wallet balance. Required: 285000 TZS, Available: 150000 TZS"
}
{
"success": false,
"httpStatus": "UNAUTHORIZED",
"message": "Authentication token is required",
"action_time": "2025-10-02T14:30:45",
"data": "Authentication token is required"
}
Not Found - Product Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Product not found",
"action_time": "2025-10-02T14:30:45",
"data": "Product not found"
}
Not Found - Payment Method Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Payment method notwith foundsimilar ordetails doesalready notexists belongfor toyour you"account",
"action_time": "2025-10-02T14:30:45",
"data": "Payment method notwith foundsimilar ordetails doesalready notexists belongfor toyour you"account"
}
Validation Error (422):
{
"success": false,
"httpStatus": "UNPROCESSABLE_ENTITY",
"message": "Validation failed",
"action_time": "2025-10-02T14:30:45",
"data": {
"sessionType"methodDetails.cardNumber": "mustInvalid notcard be null"number",
"items[0].quantity"methodDetails.expiry": "mustInvalid beexpiry greaterformat than or equal to 1"(MM/YY)",
"shippingAddressId"billingAddress.street": "mustStreet notis be null"required"
}
}
2. Get CheckoutPayment SessionMethod by ID
Purpose: Retrieves detailed information about a specific checkoutpayment session by its ID.method. Only the session owner can access their session.payment methods.
Endpoint: GET {base_url}/checkout-sessions/payment-methods/{sessionId}paymentMethodId}
Access Level: 🔒 Protected (Requires Authentication and Ownership)
Authentication: Bearer Token required in Authorization header
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authenticated user |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| string (UUID) | Yes | Unique identifier of the |
Valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "CheckoutPayment sessionmethod retrieved successfully",
"action_time": "2025-10-02T14:35:45",
"data": {
"sessionId"paymentMethodId": "c1d2e3f4-a5b6-pm123456-7890-cdef-123456789abc"abcd-ef12-345678901234",
"sessionType"ownerId": "REGULAR_DIRECTLY"user1234-5678-90ab-cdef-123456789012",
"status": "PENDING_PAYMENT",
"customerId": "u1s2e3r4-i5d6-7890-abcd-ef1234567890",
"customerUserName"ownerUserName": "john_doe",
"items": [
{
"productId"paymentMethodType": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"MNO_PAYMENT",
"productName": "Premium Wireless Headphones",
"productSlug": "premium-wireless-headphones",
"productImage": "https://cdn.nextgate.com/products/headphones-001.jpg",
"quantity": 2,
"unitPrice": 150000.00,
"discountAmount": 20000.00,
"subtotal": 300000.00,
"tax": 0.00,
"total": 280000.00,
"shopId": "s1h2o3p4-i5d6-7890-abcd-ef1234567890",
"shopName": "TechWorld Electronics",
"shopLogo": "https://cdn.nextgate.com/shops/techworld-logo.jpg",
"availableForCheckout": true,
"availableQuantity": 50
}
],
"pricing"methodDetails": {
"subtotal": 300000.00,
"discount": 20000.00,
"shippingCost": 5000.00,
"tax": 0.00,
"total": 285000.00,
"currency": "TZS"
},
"shippingAddress": {
"fullName": "John Doe",
"addressLine1": "123 Main Street",
"addressLine2": "Apartment 4B",
"city": "Dar es Salaam",
"state": "Dar es Salaam Region",
"postalCode": "12345",
"country": "Tanzania",
"phone"maskedPhoneNumber": "+255123456789"255****5678",
"mccMnc": "640-02"
},
"billingAddress": {null,
"sameAsShipping": false,
"fullName": "John Doe",
"addressLine1": "456 Business Ave",
"city": "Dar es Salaam",
"state": "Dar es Salaam Region",
"postalCode": "12346",
"country": "Tanzania"
},
"shippingMethod": {
"id": "standard-shipping",
"name": "Standard Shipping",
"carrier": "DHL",
"cost": 5000.00,
"estimatedDays": "3-5 business days",
"estimatedDelivery": "2025-10-07T14:30:45"
},
"paymentIntent"metadata": {
"provider": "WALLET",
"clientSecret": null,
"paymentMethods": ["WALLET"],
"status": "READY"M-Pesa"
},
"paymentAttempts": [],
"inventoryHeld"isDefault": true,
"inventoryHoldExpiresAt"isActive": "2025-10-02T14:45:45",true,
"metadata"isVerified": {
"couponCode": "SAVE20"
},
"expiresAt": "2025-10-02T14:45:45",true,
"createdAt": "2025-10-02T14:30:45"01T10:20:30",
"updatedAt": "2025-10-02T14:30:35:45",
"completedAt": null,
"createdOrderId": null,
"cartId": null
}
}
Success Response Fields:
Error Response JSON Sample:
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Checkout session not found or you don't have permission to access it",
"action_time": "2025-10-02T14:35:45",
"data": "Checkout session not found or you don't have permission to access it"
}
Error Response Examples:
Not Found - Session Not Found or No Permission (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "CheckoutPayment sessionmethod not foundfound, or you don'tdo not have permissionaccess to access it",
"action_time": "2025-10-02T14:35:45",
"data": "CheckoutPayment sessionmethod not foundfound, or you don'tdo not have permissionaccess to access it"
}
{
"success": false,
"httpStatus": "UNAUTHORIZED",
"message": "Authentication token is required",
"action_time": "2025-10-02T14:35:45",
"data": "Authentication token is required"
}
3. Get My CheckoutPayment SessionsMethods
Purpose: Retrieves all checkoutpayment sessionsmethods belonging to the authenticated user,user orderedwith bysummary creationinformation dateand (newest first).statistics.
Endpoint: GET {base_url}/checkout-sessionspayment-methods/my-payment-methods
Access Level: 🔒 Protected (Requires Authentication)
Authentication: Bearer Token required in Authorization header
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authenticated user |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "CheckoutPayment sessionsmethods retrieved successfully",
"action_time": "2025-10-02T14:40:45",
"data": {
"paymentMethods": [
{
"sessionId"paymentMethodId": "c1d2e3f4-a5b6-pm123456-7890-cdef-123456789abc"abcd-ef12-345678901234",
"sessionType"paymentMethodType": "REGULAR_DIRECTLY"MNO_PAYMENT",
"displayName": "M-Pesa +255****5678",
"isDefault": true,
"isActive": true,
"isVerified": true,
"createdAt": "2025-10-01T10:20:30",
"details": {
"maskedPhoneNumber": "+255****5678",
"status": "PENDING_PAYMENT"Active"
}
},
{
"paymentMethodId": "pm234567-8901-bcde-f123-456789012345",
"itemCount": 1,
"totalAmount": 285000.00,
"currency"paymentMethodType": "TZS"CREDIT_CARD",
"expiresAt"displayName": "2025-10-02T14:45:45"Visa ****4242",
"isDefault": false,
"isActive": true,
"isVerified": false,
"createdAt": "2025-10-02T14:30:45",
"isExpired"details": false,
"canRetryPayment": false,
"itemPreviews": [ {
"productId"cardType": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"Visa",
"productName"lastFourDigits": "Premium Wireless Headphones"4242",
"productImage"status": "https://cdn.nextgate.com/products/headphones-001.jpg",
"quantity": 2,
"unitPrice": 150000.00,
"total": 280000.00,
"shopName": "TechWorld Electronics"Pending"
}
]
},
{
"sessionId"paymentMethodId": "d2e3f4a5-b6c7-8901-def0-234567890abc"pm345678-9012-cdef-1234-567890123456",
"sessionType"paymentMethodType": "REGULAR_CART"CASH_ON_DELIVERY",
"displayName": "Cash on Delivery",
"isDefault": false,
"isActive": true,
"isVerified": true,
"createdAt": "2025-09-28T08:15:20",
"details": {
"status": "COMPLETED"Active"
}
}
],
"itemCount"totalCount": 3,
"totalAmount"activeCount": 500000.00,3,
"currency"defaultPaymentMethod": {
"paymentMethodId": "TZS"pm123456-7890-abcd-ef12-345678901234",
"expiresAt"paymentMethodType": "2025-10-01T10:15:30"MNO_PAYMENT",
"displayName": "M-Pesa +255****5678",
"isDefault": true,
"isActive": true,
"isVerified": true,
"createdAt": "2025-10-01T10:00:20:30",
"isExpired"details": false,
"canRetryPayment": false,
"itemPreviews": [ {
"productId"maskedPhoneNumber": "p1r2o3d4-u5c6-7890-abcd-ef1234567890",
"productName": "Smart Watch Series 5",
"productImage": "https://cdn.nextgate.com/products/watch-005.jpg",
"quantity": 1,
"unitPrice": 350000.00,
"total": 350000.00,
"shopName": "Gadget Hub"
},
{
"productId": "p2r3o4d5-u6c7-8901-bcde-f12345678901",
"productName": "Wireless Mouse",
"productImage": "https://cdn.nextgate.com/products/mouse-003.jpg",
"quantity": 2,
"unitPrice": 45000.00,
"total": 90000.00,
"shopName": "TechWorld Electronics"
}
]
},
{
"sessionId": "e3f4a5b6-c7d8-9012-ef01-345678901bcd",
"sessionType": "PAYMENT_FAILED"+255****5678",
"status": "PAYMENT_FAILED",
"itemCount": 1,
"totalAmount": 120000.00,
"currency": "TZS",
"expiresAt": "2025-10-02T15:00:00",
"createdAt": "2025-10-02T14:45:00",
"isExpired": false,
"canRetryPayment": true,
"itemPreviews": [
{
"productId": "p3r4o5d6-u7c8-9012-cdef-234567890123",
"productName": "USB-C Cable 2m",
"productImage": "https://cdn.nextgate.com/products/cable-002.jpg",
"quantity": 5,
"unitPrice": 15000.00,
"total": 75000.00,
"shopName": "Accessories World"Active"
}
]}
}
]
}
Success Response Fields:
| Field | Description |
|---|---|
| paymentMethods[].details.status | Status text: "Active", "Inactive", or "Pending" |
| totalCount | Total number of payment methods |
| activeCount | Number of active payment methods |
| defaultPaymentMethod | The default payment method (null if none set) |
Error Response JSON Sample:
{
"success": false,
"httpStatus": "UNAUTHORIZED",
"message": "Authentication token is required",
"action_time": "2025-10-02T14:40:45",
"data": "Authentication token is required"
}
Error Response Examples:
{
"success": false,
"httpStatus": "UNAUTHORIZED",
"message": "Authentication token is required",
"action_time": "2025-10-02T14:40:45",
"data": "Authentication token is required"
}
4. Get My Active Checkout Sessions
Purpose: Retrieves only active checkout sessions (PENDING_PAYMENT or PAYMENT_FAILED status) that haven't expired yet, ordered by creation date (newest first).
Endpoint: GET {base_url}/checkout-sessions/active
Access Level: 🔒 Protected (Requires Authentication)
Authentication: Bearer Token required in Authorization header
Request Headers:
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Active checkout sessions retrieved successfully",
"action_time": "2025-10-02T14:42:45",
"data": [
{
"sessionId": "c1d2e3f4-a5b6-7890-cdef-123456789abc",
"sessionType": "REGULAR_DIRECTLY",
"status": "PENDING_PAYMENT",
"itemCount": 1,
"totalAmount": 285000.00,
"currency": "TZS",
"expiresAt": "2025-10-02T14:45:45",
"createdAt": "2025-10-02T14:30:45",
"isExpired": false,
"canRetryPayment": false,
"itemPreviews": [
{
"productId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"productName": "Premium Wireless Headphones",
"productImage": "https://cdn.nextgate.com/products/headphones-001.jpg",
"quantity": 2,
"unitPrice": 150000.00,
"total": 280000.00,
"shopName": "TechWorld Electronics"
}
]
},
{
"sessionId": "e3f4a5b6-c7d8-9012-ef01-345678901bcd",
"sessionType": "GROUP_PURCHASE",
"status": "PAYMENT_FAILED",
"itemCount": 1,
"totalAmount": 120000.00,
"currency": "TZS",
"expiresAt": "2025-10-02T15:00:00",
"createdAt": "2025-10-02T14:45:00",
"isExpired": false,
"canRetryPayment": true,
"itemPreviews": [
{
"productId": "p3r4o5d6-u7c8-9012-cdef-234567890123",
"productName": "USB-C Cable 2m",
"productImage": "https://cdn.nextgate.com/products/cable-002.jpg",
"quantity": 5,
"unitPrice": 15000.00,
"total": 75000.00,
"shopName": "Accessories World"
}
]
}
]
}
Success Response Fields:
Error Response JSON Sample:
{
"success": false,
"httpStatus": "UNAUTHORIZED",
"message": "Authentication token is required",
"action_time": "2025-10-02T14:42:45",
"data": "Authentication token is required"
}
Error Response Examples:
{
"success": false,
"httpStatus": "UNAUTHORIZED",
"message": "Authentication token is required",
"action_time": "2025-10-02T14:42:45",
"data": "Authentication token is required"
}
5. Update CheckoutPayment SessionMethod
Purpose: Updates an existing checkoutpayment session.method. Can modifyupdate shippingmethod details, billing address, shipping method, payment method,metadata, or metadata.default Only sessions in PENDING_PAYMENT or PAYMENT_FAILED status can be updated.status.
Endpoint: PATCHPUT {base_url}/checkout-sessions/payment-methods/{sessionId}paymentMethodId}
Access Level: 🔒 Protected (Requires Authentication and Ownership)
Authentication: Bearer Token required in Authorization header
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authenticated user |
| Content-Type | string | Yes | Must be application/json |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| string (UUID) | Yes | Unique identifier of the |
Valid UUID format |
Request JSON Sample:
{
"shippingAddressId"paymentMethodType": "f9e8d7c6-b5a4-3210-fedc-ba9876543210"CREDIT_CARD",
"shippingMethodId"methodDetails": {
"expiry": "express-shipping"12/2029",
"paymentMethodId"cardholderName": "p9a8y7m6-e5n4-3210-tdef-ba9876543210"John Michael Doe"
},
"billingAddress": {
"street": "456 New Address Street",
"city": "Dar es Salaam",
"state": "Dar es Salaam Region",
"postalCode": "12346",
"country": "Tanzania"
},
"metadata": {
"giftWrapping": true,
"giftMessage"nickname": "HappyUpdated Birthday!"Primary Card"
},
"isDefault": true
}
Request Body Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| string | Yes | Type of payment method ( |
Same validation as create | |
| methodDetails | object | Yes | Updated payment method details | Only provided fields are updated |
| billingAddress | object | No | ||
| metadata | object | No | ||
| isDefault | boolean | No | Update default status | If true, unsets other defaults |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "CheckoutPayment sessionmethod updated successfully",
"action_time": "2025-10-02T14:50:45",
"data": {
"sessionId"paymentMethodId": "c1d2e3f4-a5b6-pm123456-7890-cdef-123456789abc"abcd-ef12-345678901234",
"sessionType"ownerId": "REGULAR_DIRECTLY"user1234-5678-90ab-cdef-123456789012",
"status": "PENDING_PAYMENT",
"customerId": "u1s2e3r4-i5d6-7890-abcd-ef1234567890",
"customerUserName"ownerUserName": "john_doe",
"items": [
{
"productId"paymentMethodType": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"CREDIT_CARD",
"productName": "Premium Wireless Headphones",
"productSlug": "premium-wireless-headphones",
"productImage": "https://cdn.nextgate.com/products/headphones-001.jpg",
"quantity": 2,
"unitPrice": 150000.00,
"discountAmount": 20000.00,
"subtotal": 300000.00,
"tax": 0.00,
"total": 280000.00,
"shopId": "s1h2o3p4-i5d6-7890-abcd-ef1234567890",
"shopName": "TechWorld Electronics",
"shopLogo": "https://cdn.nextgate.com/shops/techworld-logo.jpg",
"availableForCheckout": true,
"availableQuantity": 50
}
],
"pricing"methodDetails": {
"subtotal": 300000.00,
"discount": 20000.00,
"shippingCost": 8000.00,
"tax": 0.00,
"total": 288000.00,
"currency"cardType": "TZS"
}Visa",
"shippingAddress"maskedCardNumber": {"**** **** **** 4242",
"fullName"expiry": "12/2029",
"cardholderName": "John Michael Doe",
"addressLine1": "789 New Address Street",
"addressLine2": null,
"city": "Dar es Salaam",
"state": "Dar es Salaam Region",
"postalCode": "12347",
"country": "Tanzania",
"phone": "+255987654321"
},
"billingAddress": {
"sameAsShipping": false,
"fullName"street": "John456 Doe",New "addressLine1":Address "321 Payment Ave"Street",
"city": "Dar es Salaam",
"state": "Dar es Salaam Region",
"postalCode": "12348"12346",
"country": "Tanzania"
},
"shippingMethod": {
"id": "express-shipping",
"name": "Express Shipping",
"carrier": "DHL",
"cost": 8000.00,
"estimatedDays": "1-2 business days",
"estimatedDelivery": "2025-10-04T14:50:45"
},
"paymentIntent": {
"provider": "CREDIT_CARD",
"clientSecret": "pi_1234567890abcdef",
"paymentMethods": ["CREDIT_CARD", "DEBIT_CARD"],
"status": "READY"
},
"paymentAttempts": [],
"inventoryHeld": true,
"inventoryHoldExpiresAt": "2025-10-02T15:05:45",
"metadata": {
"couponCode"nickname": "SAVE20"Updated Primary Card"
},
"giftWrapping"isDefault": true,
"giftMessage"isActive": "Happy Birthday!"
},true,
"expiresAt"isVerified": "2025-10-02T15:05:45",false,
"createdAt": "2025-10-02T14:30:45",
"updatedAt": "2025-10-02T14:50:45",
"completedAt": null,
"createdOrderId": null,
"cartId": null
}
}
Success Response Fields:
Error Response JSON Sample:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot update - payment has been completed",
"action_time": "2025-10-02T14:50:45",
"data": "Cannot update - payment has been completed"
}
Error Response Examples:
Bad Request - Cannot Update Completed Session (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot update a completed checkout session",
"action_time": "2025-10-02T14:50:45",
"data": "Cannot update a completed checkout session"
}
Bad Request - Cannot Update Cancelled Session (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot update a cancelled checkout session",
"action_time": "2025-10-02T14:50:45",
"data": "Cannot update a cancelled checkout session"
}
Bad Request - Cannot Update Expired Session (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot update an expired checkout session",
"action_time": "2025-10-02T14:50:45",
"data": "Cannot update an expired checkout session"
}
Not Found - Session Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Checkout session not found or you don't have permission to access it",
"action_time": "2025-10-02T14:50:45",
"data": "Checkout session not found or you don't have permission to access it"
}
Not Found - Payment Method Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Payment method not found or does not belong to you"found",
"action_time": "2025-10-02T14:50:45",
"data": "Payment method not foundfound"
or}
does
Bad belongRequest to- you"Duplicate (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "This payment method already exists for your account",
"action_time": "2025-10-02T14:50:45",
"data": "This payment method already exists for your account"
}
6.5. CancelDelete CheckoutPayment SessionMethod
Purpose: CancelsPermanently andeletes existinga checkoutpayment sessionmethod. andThis releasesaction heldcannot inventory.be Cannot cancel sessions that are completed or have successful payment.undone.
Endpoint: DELETE {base_url}/checkout-sessions/payment-methods/{sessionId}/cancelpaymentMethodId}
Access Level: 🔒 Protected (Requires Authentication and Ownership)
Authentication: Bearer Token required in Authorization header
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authenticated user |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| string (UUID) | Yes | Unique identifier of the |
Valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "CheckoutPayment sessionmethod cancelleddeleted successfully",
"action_time": "2025-10-02T14:55:45",
"data": null
}
Success Response Fields:
Error Response JSON Sample:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot cancel a completed checkout session",
"action_time": "2025-10-02T14:55:45",
"data": "Cannot cancel a completed checkout session"
}
Error Response Examples:
Bad Request - Cannot Cancel Completed Session (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot cancel a completed checkout session",
"action_time": "2025-10-02T14:55:45",
"data": "Cannot cancel a completed checkout session"
}
Bad Request - Cannot Cancel with Successful Payment (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot cancel - payment has been completed. Please contact support.",
"action_time": "2025-10-02T14:55:45",
"data": "Cannot cancel - payment has been completed. Please contact support."
}
Bad Request - Already Cancelled (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Checkout session is already cancelled",
"action_time": "2025-10-02T14:55:45",
"data": "Checkout session is already cancelled"
}
Not Found - Session Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "CheckoutPayment sessionmethod not found or you don't have permission to access it"found",
"action_time": "2025-10-02T14:55:45",
"data": "CheckoutPayment sessionmethod not found or you don't have permission to access it"found"
}
7.6. ProcessSet Payment Method as Default
Purpose: Initiates payment processing forSets a checkout session. Validates session status, inventory availability, and payment method before processing. Delegates toas the appropriatedefault for transactions. Automatically unsets any existing default payment provider based on payment method type.method.
Endpoint: POSTPATCH {base_url}/checkout-sessions/payment-methods/{sessionId}paymentMethodId}/process-paymentset-default
Access Level: 🔒 Protected (Requires Authentication and Ownership)
Authentication: Bearer Token required in Authorization header
Request Headers:
| Header | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer token for authenticated user |
Path Parameters:
| Parameter | Type | Required | Description | Validation |
|---|---|---|---|---|
| string (UUID) | Yes | Unique identifier of the |
Valid UUID format |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Payment processedmethod set as default successfully",
"action_time": "2025-10-02T15:00:45",
"data": {
"success"paymentMethodId": "pm123456-7890-abcd-ef12-345678901234",
"ownerId": "user1234-5678-90ab-cdef-123456789012",
"ownerUserName": "john_doe",
"paymentMethodType": "MNO_PAYMENT",
"methodDetails": {
"maskedPhoneNumber": "+255****5678",
"mccMnc": "640-02"
},
"billingAddress": null,
"metadata": {
"provider": "M-Pesa"
},
"isDefault": true,
"paymentProvider"isActive": true,
"isVerified": true,
"createdAt": "WALLET"2025-10-01T10:20:30",
"transactionId": "txn_1234567890abcdef",
"amount": 285000.00,
"currency": "TZS",
"status": "COMPLETED",
"message": "Payment successful",
"paymentMethod": "WALLET",
"processedAt"updatedAt": "2025-10-02T15:00:45",
"orderId": "ord_9876543210fedcba",
"receiptUrl": null
}
}
Success Response Fields:
Error Response JSON Sample:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot process payment - session status: PAYMENT_COMPLETED",
"action_time": "2025-10-02T15:00:45",
"data": "Cannot process payment - session status: PAYMENT_COMPLETED"
}
Error Response Examples:
Bad Request - InvalidInactive SessionPayment StatusMethod (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot processset inactive payment -method sessionas status: PAYMENT_COMPLETED"default",
"action_time": "2025-10-02T15:00:45",
"data": "Cannot processset inactive payment -method sessionas status: PAYMENT_COMPLETED"default"
}
Bad Request - Session Expired (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Checkout session has expired",
"action_time": "2025-10-02T15:00:45",
"data": "Checkout session has expired"
}
Bad Request - Insufficient Wallet Balance (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Insufficient wallet balance. Required: 285000 TZS, Available: 150000 TZS",
"action_time": "2025-10-02T15:00:45",
"data": "Insufficient wallet balance. Required: 285000 TZS, Available: 150000 TZS"
}
Not Found - Session Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "CheckoutPayment sessionmethod not found or you don't have permission to access it"found",
"action_time": "2025-10-02T15:00:45",
"data": "CheckoutPayment sessionmethod not found or you don't have permission to access it"found"
}
8.Payment RetryMethod Types
Supported Payment Methods in Tanzania
MNO_PAYMENT (Mobile Money)
- M-Pesa (Vodacom)
- Airtel Money
- Tigo Pesa
- Halo Pesa
- Azam Pesa
- Ezy Pesa
CREDIT_CARD / DEBIT_CARD
- Visa
- Mastercard
- American Express
- Local bank cards
BANK_TRANSFER Supported Banks:
- CRDB Bank
- NMB Bank
- EXIM Bank
- KCB Bank
- NBC Bank
- Stanbic Bank
- Diamond Bank
- Access Bank
- Azania Bank
- Equity Bank
- FNB Bank
Other Methods:
- PAYPAL - International payments
- CRYPTOCURRENCY - Bitcoin, Ethereum, etc.
- GIFT_CARD - Store gift cards
- CASH_ON_DELIVERY - Pay on delivery
- WALLET - Internal wallet system
- MOBILE_PAYMENT - Google Pay, Apple Pay, etc.
Data Masking
Purpose:All Retriessensitive paymentdata is automatically masked in API responses for a failed checkout session. Validates that the session is in PAYMENT_FAILED status, hasn't exceeded maximum retry attempts (5), and hasn't expired. Re-validates inventory availability and extends session expiration before retrying.
Endpoint: POST {base_url}/checkout-sessions/{sessionId}/retry-payment
Access Level: 🔒 Protected (Requires Authentication and Ownership)
Authentication: Bearer Token required in Authorization header
Request Headers:security:
| Type | |||
|---|---|---|---|
| Account Number | ****7890 | ||
| Phone Number | +255712345678 | +255****5678 | |
| Crypto Wallet | 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa | 1A1z...fNa | |
| PIN | 1234 | **** |
Validation Rules
Card Numbers
- Must be 13-19 digits
- No spaces or dashes
- Pattern:
^[0-9]{13,19}$
Expiry Dates
- Format: MM/YY or MM/YYYY
- Pattern:
^(0[1-9]|1[0-2])/[0-9]{2,4}$
Phone Numbers (Tanzania)
- Format: +255XXXXXXXXX
- Pattern:
^\\+[1-9]\\d{8,14}$
Email Addresses
- Must be valid email format
- Used for PayPal
Currency Codes
- Must be 3-letter ISO code
- Pattern:
^[A-Z]{3}$ - Example: TZS, USD, EUR
Duplicate Detection
The system automatically prevents duplicate payment methods:
- Cards: Checks last 4 digits
- Mobile Money: Checks phone number
- Bank Accounts: Checks account number
- PayPal: Checks email address
- Crypto: Checks wallet address
Path ParametersNote: Gift cards and cash on delivery can have multiple instances.
Quick Reference Guide
Endpoint Summary
/payment-methods |
Success Response JSON Sample:
{
"success": true,
"httpStatus": "OK",
"message": "Payment retry successful",
"action_time": "2025-10-02T15:10:45",
"data": {
"success": true,
"paymentProvider": "WALLET",
"transactionId": "txn_retry_1234567890abcdef",
"amount": 285000.00,
"currency": "TZS",
"status": "COMPLETED",
"message": "Payment successful on retry",
"paymentMethod": "WALLET",
"processedAt": "2025-10-02T15:10:45",
"orderId": "ord_retry_9876543210fedcba",
"receiptUrl": null
}
}
Success Response Fields:
/payment-methods/{id} |
Get |
|
/payment-methods/my-payment-methods |
List |
|
/payment-methods/{id} |
Update |
|
/payment-methods/{id} |
Delete |
|
/payment-methods/{id}/set-default |
||
Error Response JSON Sample:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot retry payment - session status: PENDING_PAYMENT. Expected: PAYMENT_FAILED",
"action_time": "2025-10-02T15:10:45",
"data": "Cannot retry payment - session status: PENDING_PAYMENT. Expected: PAYMENT_FAILED"
}
Error Response Examples:
Bad Request - Invalid Status (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Cannot retry payment - session status: PENDING_PAYMENT. Expected: PAYMENT_FAILED",
"action_time": "2025-10-02T15:10:45",
"data": "Cannot retry payment - session status: PENDING_PAYMENT. Expected: PAYMENT_FAILED"
}
Bad Request - Session Expired (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Checkout session has expired. Please create a new checkout session.",
"action_time": "2025-10-02T15:10:45",
"data": "Checkout session has expired. Please create a new checkout session."
}
Bad Request - Max Retry Attempts Exceeded (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Maximum payment attempts (5) exceeded. Please create a new checkout session.",
"action_time": "2025-10-02T15:10:45",
"data": "Maximum payment attempts (5) exceeded. Please create a new checkout session."
}
Bad Request - Product No Longer Available (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Product 'Premium Wireless Headphones' is no longer available in requested quantity. Please create a new checkout session.",
"action_time": "2025-10-02T15:10:45",
"data": "Product 'Premium Wireless Headphones' is no longer available in requested quantity. Please create a new checkout session."
}
Bad Request - Insufficient Wallet Balance (400):
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Insufficient wallet balance. Required: 285000 TZS, Available: 150000 TZS. Please top up your wallet or update your payment method.",
"action_time": "2025-10-02T15:10:45",
"data": "Insufficient wallet balance. Required: 285000 TZS, Available: 150000 TZS. Please top up your wallet or update your payment method."
}
Not Found - Session Not Found (404):
{
"success": false,
"httpStatus": "NOT_FOUND",
"message": "Checkout session not found or you don't have permission to access it",
"action_time": "2025-10-02T15:10:45",
"data": "Checkout session not found or you don't have permission to access it"
}
Checkout Session Types
REGULAR_DIRECTLY
Direct product purchase without using a cart. Must include exactly 1 item in the request.
Characteristics:
Single item purchase flowItems array must contain exactly 1 productDoes not link to any cartcartId field will be null in responseBest for "Buy Now" buttons or quick checkout flows
Example Use Case:
User clicks "Buy Now" on a product detail page and proceeds directly to checkout.
REGULAR_CART
Checkout from existing shopping cart. Items are retrieved from the user's active cart.
Characteristics:
Multi-item purchase flowItems array not required in request (fetched from cart automatically)Links to user's cart via cartIdCart is validated before checkout creationcartId field will be populated in response
Example Use Case:
User adds multiple products to cart, reviews cart, and clicks "Proceed to Checkout".
GROUP_PURCHASE
Special checkout type for group buying where multiple users purchase the same product at a discounted group price.
Characteristics:
Single item purchase at group priceItems array must contain exactly 1 productPayment method MUST be WALLET (other methods not supported)Can join existing group via groupInstanceId or create new groupUses product's groupPrice instead of regular priceRequires product to have groupBuyingEnabled = trueQuantity cannot exceed product's groupMaxSizeGroup has time limit defined by product's groupTimeLimitHours
Example Use Case:
User sees a product available for group buying at 80,000 TZS (regular price: 150,000 TZS). User can either start a new group or join an existing group with available seats.
Request Example (Create New Group):
{
"sessionType": "GROUP_PURCHASE",
"items": [{
"productId": "prod-uuid",
"quantity": 2
}],
"shippingAddressId": "addr-uuid",
"shippingMethodId": "standard",
"paymentMethodId": null,
"groupInstanceId": null
}
Request Example (Join Existing Group):
{
"sessionType": "GROUP_PURCHASE",
"items": [{
"productId": "prod-uuid",
"quantity": 3
}],
"shippingAddressId": "addr-uuid",
"shippingMethodId": "standard",
"paymentMethodId": null,
"groupInstanceId": "group-uuid-to-join"
}
INSTALLMENT
Status: PLACEHOLDER - Not Yet Implemented
Future checkout type for installment payment plans. Will allow users to split payments into multiple installments.
Planned Characteristics:
Will require installmentPlanId in requestPayment spread over multiple periodsMay require down paymentInterest rates may apply based on planCredit check may be required
Current Behavior:
Returns error: "INSTALLMENT checkout not implemented yet"
Checkout Session Status Flow
Status Definitions
Common HTTP Status Transition FlowCodes
PENDING_PAYMENT
├─> PAYMENT_PROCESSING (when payment initiated)
│ ├─> PAYMENT_COMPLETED (on success)
│ │ └─> COMPLETED (after order creation)
│ └─> PAYMENT_FAILED (on failure, can retry max 5 times)
│ ├─> PENDING_PAYMENT (when retry initiated)
│ └─> EXPIRED (after max retries or session timeout)
├─> CANCELLED (user cancels)
└─> EXPIRED (15 minutes timeout)
Payment Methods Supported
WALLET
Internal wallet system for storing and using funds.
Requirements:
User200:mustOKhaveSuccessfulactive walletoperationSufficient400: Validation error or duplicatebalanceBad Request401 Unauthorized: Authentication requiredBalance404:checkedNotbeforeFoundpaymentPaymentprocessingmethod not foundInstant422paymentUnprocessableprocessingEntity: NoFieldadditionalvalidationfees
Payment Flow:
Validate wallet is activeCheck sufficient balanceDeduct amount from walletCreate transaction recordCreate order
Default Behavior:
If no paymentMethodId provided in request, WALLET is used as default.
CASH_ON_DELIVERY
Pay in cash when order is delivered.
Requirements:
No pre-payment requiredPayment collected by delivery agentOrder created immediatelyMay have geographic restrictions
Payment Flow:
Create payment intent with status "PENDING"Create order immediatelyPayment marked as "COD"Delivery agent collects payment on delivery
CREDIT_CARD / DEBIT_CARD
Status: Planned - Not Yet Implemented
Future support for credit and debit card payments.
Planned Features:
Card tokenization for securityPCI compliance3D Secure authenticationSaved cards supportInternational cards supporterrors
MNO_PAYMENT (Mobile Money)
Status: Planned - Not Yet Implemented
Future support for mobile money payments (M-Pesa, Tigo Pesa, Airtel Money, etc.).
Planned Features:
USSD push notificationsCallback confirmationTransaction reconciliationMultiple operators support
Other Payment Methods
Method Additional payment methods (PayPal, Bank Transfer, Cryptocurrency, Gift Card) are placeholders for future implementation.
Inventory Management
Inventory Hold Mechanism
When a checkout session is created, inventory is automatically held to prevent overselling.
Hold Behavior:
Inventory held for 15 minutes (matches session expiration)Held quantity deducted from available stockOther users cannot purchase held inventoryHold automatically released on:Session expirationSession cancellationPayment failure (after 5 retry attempts)
Hold converted to permanent deduction on successful payment
Hold Fields:
inventoryHeld: Boolean indicating if inventory is currently heldinventoryHoldExpiresAt: Timestamp when hold will be released
Example:
{
"inventoryHeld": true,
"inventoryHoldExpiresAt": "2025-10-02T14:45:45"
}
Inventory Validation
Before processing payment or retry, system validates:
Product still exists and is activeProduct still in stockRequested quantity still availableProduct hasn't been deleted
If validation fails, user must create new checkout session with current availability.
Session Expiration
Expiration Rules
Default Expiration: 15 minutes from creation
Expiration Extended When:
Payment retry initiated (adds 15 minutes)Session updated successfully (adds 15 minutes)
What Happens on Expiration:
Session status changes to EXPIREDHeld inventory released back to available stockSession cannot be updated or paidSession cannot be cancelled (already effectively ended)User must create new checkout session
Checking Expiration:
expiresAtfield shows expiration timestampisExpiredfield (in summary responses) shows if session expired
Preventing Expiration
To prevent session expiration:
Complete payment before expirationUpdate session if needed (extends timer)If expired, create new checkout session
Best Practice:
Display countdown timer to users showing time remaining before expiration.
Payment Attempts Tracking
Attempt Limits
Maximum Attempts: 5 per session
Attempt Tracking:
Each payment attempt recorded with:
Attempt number (1-5)Payment method used- Status
(SUCCESS, FAILED, RETRY_INITIATED) Error message (if failed)TimestampTransaction ID (if available)
Example Payment Attempts:
{
"paymentAttempts": [
{
"attemptNumber": 1,
"paymentMethod": "WALLET",
"status": "FAILED",
"errorMessage": "Insufficient wallet balance",
"attemptedAt": "2025-10-02T14:35:00",
"transactionId": null
},
{
"attemptNumber": 2,
"paymentMethod": "WALLET",
"status": "RETRY_INITIATED",
"errorMessage": null,
"attemptedAt": "2025-10-02T14:40:00",
"transactionId": null
},
{
"attemptNumber": 3,
"paymentMethod": "WALLET",
"status": "SUCCESS",
"errorMessage": null,
"attemptedAt": "2025-10-02T14:42:00",
"transactionId": "txn_1234567890abcdef"
}
]
}
After Max Attempts
When 5 attempts exceeded:
Session status set to EXPIREDInventory releasedCannot retry paymentUser must create new checkout session
Metadata Usage
Purpose
Metadata allows storing custom key-value data with checkout sessions for business-specific needs.
Common Use Cases
Coupons & Discounts:
{
"metadata": {
"couponCode": "SAVE20",
"couponDiscount": 20000,
"couponAppliedAt": "2025-10-02T14:30:00"
}
}
Referral Tracking:
{
"metadata": {
"referralCode": "REF123",
"referredBy": "user-uuid",
"referralBonus": 5000
}
}
Gift Options:
{
"metadata": {
"isGift": true,
"giftWrapping": true,
"giftMessage": "Happy Birthday!",
"giftRecipientName": "Jane Doe"
}
}
Delivery Instructions:
{
"metadata": {
"deliveryInstructions": "Leave package at front desk",
"deliveryTimePreference": "morning",
"contactOnArrival": true
}
}
Group Purchase:
{
"metadata": {
"groupInstanceId": "group-uuid",
"isGroupLeader": true,
"groupCreatedAt": "2025-10-02T14:30:00"
}
}
Marketing Attribution:
{
"metadata": {
"source": "facebook_ad",
"campaign": "summer_sale_2025",
"medium": "social_media"
}
}
Metadata Rules
StoredActive:asCanJSONbeobjectused for transactionsKey-valueInactive:pairsCannotwithbestringusedkeysfor transactionsValuesPending:canAwaitingbe strings, numbers, booleans, or nested objectsNo size limit enforced at API level (reasonable usage expected)Merged with existing metadata on update (not replaced)Persisted with session throughout lifecycleAccessible in order after completionverification
Error Handling Best Practices
Client-Side Handling
Before Creating Checkout:
Validate user has shipping addressCheck product availabilityVerify payment method exists (if not using wallet)Display clear pricing breakdown
During Checkout:
Show expiration countdown timerHandle session expiration gracefullyProvide clear error messagesSuggest actions (e.g., "Top up wallet" if insufficient balance)
Payment Failures:
Display specific error reasonShow remaining retry attemptsOffer to update payment methodSuggest alternative payment methods
Common Error Scenarios
Insufficient Inventory:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Insufficient stock. Available: 3, Requested: 5"
}
Action: Reduce quantity or create new session with available quantity.
Insufficient Wallet Balance:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Insufficient wallet balance. Required: 285000 TZS, Available: 150000 TZS"
}
Action: Top up wallet or change payment method.
Session Expired:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Checkout session has expired"
}
Action: Create new checkout session.
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Product is not available for purchase"
}
Action: Remove product from cart or select alternative product.
Max Retries Exceeded:
{
"success": false,
"httpStatus": "BAD_REQUEST",
"message": "Maximum payment attempts (5) exceeded. Please create a new checkout session."
}
Action: Create new checkout session, possibly with different payment method.
Integration Examples
Example 1: Direct Product Purchase Flow
Step 1: Create Checkout Session
POST /api/v1/checkout-sessions
Authorization: Bearer {token}
Content-Type: application/json
{
"sessionType": "REGULAR_DIRECTLY",
"items": [{
"productId": "prod-uuid",
"quantity": 1
}],
"shippingAddressId": "addr-uuid",
"shippingMethodId": "standard",
"paymentMethodId": null
}
Step 2: Process Payment
POST /api/v1/checkout-sessions/{sessionId}/process-payment
Authorization: Bearer {token}
Step 3: Check Order Created
Response will include orderId field after successful payment.
Example 2: Cart Checkout Flow
Step 1: Create Checkout from Cart
POST /api/v1/checkout-sessions
Authorization: Bearer {token}
Content-Type: application/json
{
"sessionType": "REGULAR_CART",
"shippingAddressId": "addr-uuid",
"shippingMethodId": "express",
"metadata": {
"couponCode": "SAVE20"
}
}
Step 2: Review Session
GET /api/v1/checkout-sessions/{sessionId}
Authorization: Bearer {token}
Step 3: Update if Needed
PATCH /api/v1/checkout-sessions/{sessionId}
Authorization: Bearer {token}
Content-Type: application/json
{
"shippingMethodId": "standard",
"metadata": {
"giftWrapping": true
}
}
Step 4: Process Payment
POST /api/v1/checkout-sessions/{sessionId}/process-payment
Authorization: Bearer {token}
Example 3: Group Purchase Flow
Step 1: Create Group Purchase Session
POST /api/v1/checkout-sessions
Authorization: Bearer {token}
Content-Type: application/json
{
"sessionType": "GROUP_PURCHASE",
"items": [{
"productId": "prod-uuid",
"quantity": 2
}],
"shippingAddressId": "addr-uuid",
"shippingMethodId": "standard",
"groupInstanceId": null
}
Step 2: Process Payment (WALLET only)
POST /api/v1/checkout-sessions/{sessionId}/process-payment
Authorization: Bearer {token}
Example 4: Payment Retry Flow
Step 1: Get Active Sessions
GET /api/v1/checkout-sessions/active
Authorization: Bearer {token}
Step 2: Identify Failed Session
Look for session with status: "PAYMENT_FAILED" and canRetryPayment: true
Step 3: Update Payment Method (Optional)
PATCH /api/v1/checkout-sessions/{sessionId}
Authorization: Bearer {token}
Content-Type: application/json
{
"paymentMethodId": "new-payment-method-uuid"
}
Step 4: Retry Payment
POST /api/v1/checkout-sessions/{sessionId}/retry-payment
Authorization: Bearer {token}
Rate Limiting
Rate Limits:
Create Checkout: 20 requests per minute per userGet Sessions: 60 requests per minute per userProcess/Retry Payment: 10 requests per minute per userUpdate/Cancel: 30 requests per minute per user
Rate Limit Headers:
X-RateLimit-Limit: 20
X-RateLimit-Remaining: 15
X-RateLimit-Reset: 1696258800
Rate Limit Exceeded:
{
"success": false,
"httpStatus": "TOO_MANY_REQUESTS",
"message": "Rate limit exceeded. Please try again later.",
"action_time": "2025-10-02T15:30:45",
"data": "Rate limit exceeded. Please try again later."
}