Skip to main content
Authenticated API

This endpoint requires a valid JWT Bearer token. Accessible via the API gateway at /v1/commerce/*.

Payments API

Process payments, refunds, and manage transactions.

Authentication Required

All endpoints require a valid Bearer token. See Authentication for details.

Overview

The Payments API supports multiple payment methods:

MethodDescriptionProvider
CardCredit/debit cardsStripe
CashCash paymentsInternal
Gift CardRestaurant gift cardsInternal
MobileApple Pay, Google PayStripe
SplitMultiple methodsInternal

Payment Flow

PENDING → AUTHORIZED → CAPTURED → COMPLETED
↓ ↓
DECLINED REFUNDED

Process Payment

PCI Compliance

Payment processing handles sensitive cardholder data. All payment operations must comply with PCI DSS requirements. Never log, store, or transmit full card numbers. Use tokenized payment methods via Stripe.

Request

POST /api/v1/payments
Authorization: Bearer {access_token}
Content-Type: application/json
{
"order_id": "order-12345",
"amount": 50.00,
"method": "card",
"payment_method_id": "pm_card_visa",
"tip_amount": 8.00
}

Parameters

FieldTypeRequiredDescription
order_idstringYesOrder to pay
amountnumberYesPayment amount
methodstringYesPayment method type
payment_method_idstringCardStripe payment method
tip_amountnumberNoTip amount
cash_tenderednumberCashAmount given

Response

{
"id": "payment-001",
"order_id": "order-12345",
"status": "completed",
"method": "card",
"amount": 50.00,
"tip": 8.00,
"total": 58.00,
"card": {
"brand": "visa",
"last4": "4242"
},
"receipt_url": "https://receipts.olympuscloud.ai/r/abc123",
"created_at": "2026-01-18T13:30:00Z"
}

Cash Payment

Request

POST /api/v1/payments
Authorization: Bearer {access_token}
Content-Type: application/json
{
"order_id": "order-12345",
"amount": 46.61,
"method": "cash",
"cash_tendered": 60.00
}

Response

{
"id": "payment-002",
"order_id": "order-12345",
"status": "completed",
"method": "cash",
"amount": 46.61,
"cash_tendered": 60.00,
"change_due": 13.39,
"created_at": "2026-01-18T13:30:00Z"
}

Split Payment

Pay with multiple methods.

Request

POST /api/v1/payments/split
Authorization: Bearer {access_token}
Content-Type: application/json
{
"order_id": "order-12345",
"payments": [
{
"amount": 25.00,
"method": "card",
"payment_method_id": "pm_card_visa"
},
{
"amount": 21.61,
"method": "cash",
"cash_tendered": 25.00
}
]
}

Split by Seat

{
"order_id": "order-12345",
"split_type": "by_seat",
"payments": [
{
"seats": [1, 2],
"method": "card",
"payment_method_id": "pm_card_visa"
},
{
"seats": [3, 4],
"method": "card",
"payment_method_id": "pm_card_mastercard"
}
]
}

Gift Card Payment

Check Balance

GET /api/v1/gift-cards/{card_number}/balance
Authorization: Bearer {access_token}
{
"card_number": "****1234",
"balance": 50.00,
"status": "active"
}

Pay with Gift Card

POST /api/v1/payments
Authorization: Bearer {access_token}
Content-Type: application/json
{
"order_id": "order-12345",
"amount": 46.61,
"method": "gift_card",
"gift_card_number": "1234567890123456",
"gift_card_pin": "1234"
}

Add Tip

Add or adjust tip after payment authorization.

Request

POST /api/v1/payments/{payment_id}/tip
Authorization: Bearer {access_token}
Content-Type: application/json
{
"tip_amount": 10.00
}

Response

{
"id": "payment-001",
"original_amount": 50.00,
"tip": 10.00,
"total": 60.00,
"tip_adjusted_at": "2026-01-18T13:45:00Z"
}

Process Refund

Request

POST /api/v1/payments/{payment_id}/refund
Authorization: Bearer {access_token}
Content-Type: application/json
{
"amount": 14.99,
"reason": "Item returned",
"item_ids": ["line-001"]
}

Parameters

FieldTypeRequiredDescription
amountnumberNoRefund amount (default: full)
reasonstringYesReason for refund
item_idsarrayNoSpecific items being refunded

Response

{
"id": "refund-001",
"payment_id": "payment-001",
"amount": 14.99,
"reason": "Item returned",
"status": "completed",
"refunded_at": "2026-01-18T14:00:00Z"
}

Void Payment

Irreversible Operation

Voiding a payment releases the authorization permanently. This action cannot be undone. A manager PIN is required for all void operations.

Cancel an uncaptured payment.

Request

POST /api/v1/payments/{payment_id}/void
Authorization: Bearer {access_token}
Content-Type: application/json
{
"reason": "Customer cancelled order",
"manager_pin": "1234"
}

Get Payment

Request

GET /api/v1/payments/{payment_id}
Authorization: Bearer {access_token}

Response

{
"id": "payment-001",
"order_id": "order-12345",
"status": "completed",
"method": "card",
"amount": 50.00,
"tip": 8.00,
"total": 58.00,
"card": {
"brand": "visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2028
},
"refunds": [],
"receipt_url": "https://receipts.olympuscloud.ai/r/abc123",
"created_at": "2026-01-18T13:30:00Z"
}

List Payments

Request

GET /api/v1/payments?
location_id=loc-xyz789&
start_date=2026-01-18&
method=card&
limit=50
Authorization: Bearer {access_token}

Query Parameters

ParameterTypeDescription
location_idstringFilter by location
order_idstringFilter by order
methodstringFilter by method
statusstringFilter by status
start_datedateFrom date
end_datedateTo date

Pre-Authorization (Bar Tabs)

Open Tab

POST /api/v1/payments/preauth
Authorization: Bearer {access_token}
Content-Type: application/json
{
"order_id": "order-12345",
"payment_method_id": "pm_card_visa",
"amount": 100.00
}

Response

{
"id": "preauth-001",
"order_id": "order-12345",
"status": "authorized",
"authorized_amount": 100.00,
"card": {
"brand": "visa",
"last4": "4242"
},
"expires_at": "2026-01-19T13:30:00Z"
}

Capture Tab

POST /api/v1/payments/preauth/{preauth_id}/capture
Authorization: Bearer {access_token}
Content-Type: application/json
{
"amount": 75.50,
"tip_amount": 15.00
}

Batch Settlement

Request

POST /api/v1/payments/batch/settle
Authorization: Bearer {access_token}
Content-Type: application/json
{
"location_id": "loc-xyz789"
}

Response

{
"batch_id": "batch-001",
"location_id": "loc-xyz789",
"transactions": 145,
"total_amount": 8542.50,
"settled_at": "2026-01-18T23:00:00Z"
}

Error Responses

Payment Declined (402)

{
"error": {
"code": "PAYMENT_DECLINED",
"message": "Card was declined",
"decline_code": "insufficient_funds"
}
}

Invalid Amount (400)

{
"error": {
"code": "INVALID_AMOUNT",
"message": "Payment amount exceeds order balance"
}
}