Skip to main content
Authenticated API

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

Check Splitting API

Split checks by item, seat, amount, or custom configuration for flexible bill payment.

Overview

The Check Splitting API enables restaurants to split a single check into multiple payments, supporting common scenarios like splitting by item, dividing equally, or custom distributions.

Split TypeDescriptionUse Case
By ItemEach guest pays for their itemsIndividual orders
By SeatItems assigned to seat positionsTable service
Equal SplitDivide total equallyGroup dining
Custom AmountSpecify exact amountsPartial payments
PercentageSplit by percentageCost sharing

Check Model (Split View)

{
"check_id": "chk_abc123",
"order_id": "ord_xyz789",
"table_id": "tbl_001",
"original_total": 156.50,
"split_status": "partial",
"splits": [
{
"split_id": "spl_001",
"seat": 1,
"guest_name": "John",
"items": ["item_001", "item_002"],
"subtotal": 42.50,
"tax": 3.83,
"tip": 8.00,
"total": 54.33,
"status": "paid",
"payment_id": "pay_001"
},
{
"split_id": "spl_002",
"seat": 2,
"guest_name": "Jane",
"items": ["item_003", "item_004"],
"subtotal": 38.00,
"tax": 3.42,
"tip": null,
"total": 41.42,
"status": "pending"
}
],
"remaining_balance": 60.75,
"created_at": "2026-01-18T19:30:00Z"
}

Endpoints

Initialize Split

POST /v1/checks/{check_id}/split/initialize
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"split_type": "by_seat",
"seats": [
{"seat": 1, "guest_name": "John"},
{"seat": 2, "guest_name": "Jane"},
{"seat": 3, "guest_name": "Bob"}
]
}

Response:

{
"check_id": "chk_abc123",
"split_type": "by_seat",
"splits": [
{"split_id": "spl_001", "seat": 1, "guest_name": "John", "items": [], "total": 0},
{"split_id": "spl_002", "seat": 2, "guest_name": "Jane", "items": [], "total": 0},
{"split_id": "spl_003", "seat": 3, "guest_name": "Bob", "items": [], "total": 0}
],
"unassigned_items": [
{"id": "item_001", "name": "Steak", "price": 45.00},
{"id": "item_002", "name": "Salad", "price": 12.00},
{"id": "item_003", "name": "Wine", "price": 36.00}
]
}

Split By Item

POST /v1/checks/{check_id}/split/by-item
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"assignments": [
{"item_id": "item_001", "split_id": "spl_001"},
{"item_id": "item_002", "split_id": "spl_002"},
{"item_id": "item_003", "split_id": "spl_001"}
]
}

Response:

{
"check_id": "chk_abc123",
"splits": [
{
"split_id": "spl_001",
"items": [
{"id": "item_001", "name": "Steak", "price": 45.00},
{"id": "item_003", "name": "Wine", "price": 36.00}
],
"subtotal": 81.00,
"tax": 7.29,
"total": 88.29
},
{
"split_id": "spl_002",
"items": [
{"id": "item_002", "name": "Salad", "price": 12.00}
],
"subtotal": 12.00,
"tax": 1.08,
"total": 13.08
}
]
}

Split Equally

POST /v1/checks/{check_id}/split/equal
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"ways": 3,
"include_tip": true,
"tip_percentage": 20
}

Response:

{
"check_id": "chk_abc123",
"original_total": 156.50,
"tip_amount": 31.30,
"grand_total": 187.80,
"splits": [
{"split_id": "spl_001", "total": 62.60, "status": "pending"},
{"split_id": "spl_002", "total": 62.60, "status": "pending"},
{"split_id": "spl_003", "total": 62.60, "status": "pending"}
]
}

Split By Custom Amount

POST /v1/checks/{check_id}/split/custom
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"amounts": [
{"split_id": "spl_001", "amount": 50.00},
{"split_id": "spl_002", "amount": 75.00}
]
}

Response:

{
"check_id": "chk_abc123",
"splits": [
{"split_id": "spl_001", "amount": 50.00, "status": "pending"},
{"split_id": "spl_002", "amount": 75.00, "status": "pending"}
],
"remaining": 31.50,
"remaining_split_id": "spl_003"
}

Split By Percentage

POST /v1/checks/{check_id}/split/percentage
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"percentages": [
{"split_id": "spl_001", "percentage": 40},
{"split_id": "spl_002", "percentage": 35},
{"split_id": "spl_003", "percentage": 25}
]
}

Response:

{
"check_id": "chk_abc123",
"original_total": 156.50,
"splits": [
{"split_id": "spl_001", "percentage": 40, "amount": 62.60},
{"split_id": "spl_002", "percentage": 35, "amount": 54.78},
{"split_id": "spl_003", "percentage": 25, "amount": 39.12}
]
}

Move Item Between Splits

POST /v1/checks/{check_id}/split/move-item
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"item_id": "item_003",
"from_split_id": "spl_001",
"to_split_id": "spl_002"
}

Response:

{
"success": true,
"updated_splits": [
{"split_id": "spl_001", "subtotal": 45.00, "total": 49.05},
{"split_id": "spl_002", "subtotal": 48.00, "total": 52.32}
]
}

Share Item Across Splits

POST /v1/checks/{check_id}/split/share-item
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"item_id": "item_004",
"share_with": ["spl_001", "spl_002", "spl_003"],
"distribution": "equal"
}

Response:

{
"item_id": "item_004",
"item_name": "Appetizer Sampler",
"original_price": 24.00,
"shared_portions": [
{"split_id": "spl_001", "amount": 8.00},
{"split_id": "spl_002", "amount": 8.00},
{"split_id": "spl_003", "amount": 8.00}
]
}

Payment Operations

Pay Single Split

POST /v1/checks/{check_id}/splits/{split_id}/pay
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"payment_method": "card",
"card_token": "tok_visa_1234",
"tip_amount": 10.00
}

Response:

{
"split_id": "spl_001",
"payment_id": "pay_abc123",
"amount_paid": 62.60,
"tip": 10.00,
"total_charged": 72.60,
"status": "paid",
"remaining_on_check": 93.90
}

Get Split Status

GET /v1/checks/{check_id}/split/status
Authorization: Bearer {access_token}

Response:

{
"check_id": "chk_abc123",
"split_status": "partial",
"original_total": 156.50,
"total_paid": 62.60,
"remaining_balance": 93.90,
"splits": [
{"split_id": "spl_001", "total": 62.60, "status": "paid", "paid_at": "2026-01-18T20:15:00Z"},
{"split_id": "spl_002", "total": 54.78, "status": "pending"},
{"split_id": "spl_003", "total": 39.12, "status": "pending"}
]
}

Cancel Split

DELETE /v1/checks/{check_id}/split
Authorization: Bearer {access_token}

Response:

{
"check_id": "chk_abc123",
"split_cancelled": true,
"restored_to_single_check": true,
"note": "All items returned to single check. Previous partial payments retained."
}

Seat-Based Operations

Assign Items to Seat

POST /v1/checks/{check_id}/seats/{seat_number}/items
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"item_ids": ["item_001", "item_005"]
}

Get Seat Summary

GET /v1/checks/{check_id}/seats
Authorization: Bearer {access_token}

Response:

{
"check_id": "chk_abc123",
"seats": [
{
"seat": 1,
"guest_name": "John",
"items": [
{"id": "item_001", "name": "Steak", "price": 45.00}
],
"subtotal": 45.00,
"tax": 4.05,
"total": 49.05,
"status": "unpaid"
},
{
"seat": 2,
"guest_name": "Jane",
"items": [
{"id": "item_002", "name": "Pasta", "price": 22.00},
{"id": "item_003", "name": "Wine", "price": 12.00}
],
"subtotal": 34.00,
"tax": 3.06,
"total": 37.06,
"status": "unpaid"
}
],
"shared_items": [
{
"id": "item_004",
"name": "Appetizer",
"price": 18.00,
"shared_by": [1, 2],
"per_seat": 9.00
}
]
}

Tip Distribution

Add Tip to Split

POST /v1/checks/{check_id}/splits/{split_id}/tip
Authorization: Bearer {access_token}
Content-Type: application/json

Request:

{
"tip_type": "percentage",
"value": 20
}

Response:

{
"split_id": "spl_001",
"subtotal": 45.00,
"tax": 4.05,
"tip": 9.00,
"total": 58.05
}

Suggested Tips

GET /v1/checks/{check_id}/splits/{split_id}/suggested-tips
Authorization: Bearer {access_token}

Response:

{
"split_id": "spl_001",
"subtotal": 45.00,
"suggestions": [
{"percentage": 15, "amount": 6.75},
{"percentage": 18, "amount": 8.10},
{"percentage": 20, "amount": 9.00},
{"percentage": 25, "amount": 11.25}
]
}

Error Codes

CodeMessageDescription
CHECK_NOT_FOUNDCheck not foundInvalid check ID
ALREADY_SPLITCheck already splitCannot reinitialize
ITEM_NOT_FOUNDItem not foundInvalid item ID
SPLIT_PAIDSplit already paidCannot modify paid split
INVALID_AMOUNTAmount exceeds balanceCustom amount too high
PERCENTAGE_MISMATCHPercentages must equal 100Invalid percentage split

Best Practices

  1. Confirm with guests - Verify split preferences before processing
  2. Handle shared items - Ask how to distribute appetizers/shared dishes
  3. Show running totals - Display each person's total before payment
  4. Support mixed payment - Allow different payment methods per split
  5. Print itemized receipts - Provide detailed receipt for each split