Developer Guide

Submit Purchase Transaction

Submit a customer purchase transaction from your Point of Sale system to GrandShift. When a customer completes a purchase at your store and provides their registered phone number, use this endpoint to submit the transaction details.

Development Environment

For testing and development, prepend the base URL: https://dev.api.grandshifts.com
POST/pos/v1/invoices

What This Endpoint Does

When you submit a transaction, the system will:

  • Validate the transaction details (amounts, VAT, customer)
  • Automatically approve the invoice
  • Calculate and credit cashback rewards to the customer's GrandShift wallet
  • Return the invoice status and cashback amount

Important Notes

Headers

PropertyTypeDescription
x-api-keyRequired
string
Your PoS API key for authentication.
x-idempotency-key
string
Optional unique identifier to prevent duplicate transactions. Use the same key when retrying failed requests.

Request Body

PropertyTypeDescription
invoiceNumberRequired
string
Unique invoice number from the PoS system.
Example: INV-2024-001234
invoiceDateRequired
string
Invoice date in ISO 8601 format. Must be today's date.
Example: 2024-01-15T10:30:00Z
totalAmountRequired
number
Total amount before VAT. Must be at least 1 SAR.
Example: 850
vatRequired
number
VAT amount. Must be exactly 15% of totalAmount.
Example: 127.5
grandTotalRequired
number
Grand total including VAT. Must equal totalAmount + vat.
Example: 977.5
currencyRequired
string
Currency code (ISO 4217). Only SAR is supported.
Default: SAR
customerIdentifierRequired
string
Customer phone number registered in GrandShift (shifter account). This is the primary identifier used to lookup the customer and credit their cashback.
Example: +966512345678
invoiceAttachmentUrl
string
URL to download the receipt/invoice attachment.
Example: https://pos.example.com/receipts/INV-2024-001234.pdf
metadata
object
Additional metadata from the PoS system.
Example: { "terminalId": "T001", "cashierId": "C123" }
Request Example
{
  "invoiceNumber": "INV-2024-001234",
  "invoiceDate": "2024-01-15T10:30:00Z",
  "totalAmount": 850,
  "vat": 127.5,
  "grandTotal": 977.5,
  "currency": "SAR",
  "customerIdentifier": "+966512345678",
  "invoiceAttachmentUrl": "https://pos.example.com/receipts/INV-2024-001234.pdf",
  "metadata": {
    "terminalId": "T001",
    "cashierId": "C123",
    "transactionType": "SALE"
  }
}

Example Request

cURL
curl -X 'POST' \
  'https://dev.api.grandshifts.com/pos/v1/invoices' \
  -H 'accept: application/json' \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'x-idempotency-key: unique-request-id-123' \
  -H 'Content-Type: application/json' \
  -d '{
    "invoiceNumber": "INV-2024-001234",
    "invoiceDate": "2024-01-15T10:30:00Z",
    "totalAmount": 850,
    "vat": 127.5,
    "grandTotal": 977.5,
    "currency": "SAR",
    "customerIdentifier": "+966512345678"
  }'

Response Schema

PropertyTypeDescription
invoiceIdRequired
number
Internal invoice ID in GrandShift system.
Example: 12345
invoiceNumberRequired
string
Invoice number from the PoS system.
statusRequired
string
Current status of the invoice.
Enum: PENDING, APPROVED, REJECTED, PAID, REFUNDED, CANCELLED, CASHBACK_PROCESSED
totalAmountRequired
number
Total amount before VAT.
vatRequired
number
VAT amount.
grandTotalRequired
number
Grand total including VAT.
currencyRequired
string
Currency code.
vendorCashbackAmount
number
Cashback amount for the customer (if calculated).
createdAtRequired
string
Timestamp when the invoice was created in GrandShift.
cashbackProcessedAt
string
Timestamp when cashback was processed.

Success Response (201 Created)

Transaction submitted successfully. Cashback has been credited to customer.

Response
{
  "invoiceId": 12345,
  "invoiceNumber": "INV-2024-001234",
  "status": "APPROVED",
  "totalAmount": 850,
  "vat": 127.5,
  "grandTotal": 977.5,
  "currency": "SAR",
  "vendorCashbackAmount": 48.88,
  "createdAt": "2024-01-15T10:30:00Z",
  "cashbackProcessedAt": "2024-01-15T10:30:05Z"
}

Error Responses

401Unauthorized

Invalid or missing API key.

429Too Many Requests

Rate limit exceeded.

Detailed Error Examples

400Invoice Date Mismatch
{
  "statusCode": 400,
  "message": "Invoice date must be today (2025-12-07). Received: 2024-12-07",
  "error": "Bad Request"
}
400Customer Not Found
{
  "statusCode": 400,
  "message": "Customer not found with identifier: +966512345678. Please ensure the customer is registered in the GrandShift system.",
  "error": "Bad Request"
}
400Invalid Currency
{
  "statusCode": 400,
  "message": ["Currency must be SAR"],
  "error": "Bad Request"
}
400Invalid Amount (Less than 1)
{
  "statusCode": 400,
  "message": ["totalAmount must not be less than 1"],
  "error": "Bad Request"
}
400Invalid VAT (Not 15%)
{
  "statusCode": 400,
  "message": ["VAT must be exactly 15% of total amount"],
  "error": "Bad Request"
}
400Invalid Grand Total
{
  "statusCode": 400,
  "message": ["Grand total must equal totalAmount + vat"],
  "error": "Bad Request"
}
400Insufficient Vendor Balance
{
  "statusCode": 400,
  "message": "Insufficient balance or wallet not eligible for cashback. Current balance: 43624.5, Required: 50000, Wallet active: true",
  "error": "Bad Request"
}
409Duplicate Invoice Number
{
  "statusCode": 409,
  "message": "Active invoice with number \"INV-2024-005555\" already exists for this branch",
  "error": "Conflict"
}