# Astana POS API — Reference v1.0

> Dijana automatik dari registry `astana-mcp`. Base URL: `https://api.astanabiz.com/v1.0`

## Ringkasan

Astana API ialah REST API (HTTPS, JSON) untuk sistem POS Astana — POS, inventori, resit, pelanggan dan pembayaran.

- **Base URL:** `https://api.astanabiz.com/v1.0` (versi mesti ada dalam URL)
- **Authorization:** setiap request mesti sertakan header `Token: Bearer <ACCESS_TOKEN>`
- **Format tarikh/masa:** 24 jam, `Y-m-d H:i:s`
- **Had kadar:** 300 requests / 300 saat setiap akaun (lebih → HTTP 429)

## Authorization

Dua kaedah: **Personal Access Token** (dari Backoffice → Integrations → Access token) atau **OAuth 2.0**. Untuk akses akaun sendiri, PAT memadai.

```
Token : Bearer YOUR_ACCESS_TOKEN
```

> Nota: nama header ialah `Token` (bukan `Authorization`), dan nilainya ada awalan `Bearer `.

OAuth 2.0 — POST ke `/oauth/token` dengan `client_id`, `client_secret`, `grant_type=authorization_code`, `code`. Refresh guna `grant_type=refresh_token`.

## Pagination

Response senarai mengandungi field `cursor`. Hantar semula nilai `cursor` sebagai query parameter untuk set seterusnya. Bila `cursor` tiada, itu set terakhir. `limit` default 10, maksimum 250.

## Handling Errors

Request gagal memulangkan objek `errors`:

```json
{ "errors": { "code": "UNAUTHORIZED", "details": "Access token is not valid." } }
```

| Status | Kod | Maksud |
|---|---|---|
| 401 | UNAUTHORIZED | Data auth tiada, salah format atau tidak sah |
| 429 | — | Had kadar dilampaui |

## Webhooks

Notifikasi masa nyata via HTTP POST ke URL yang didaftarkan. Event disokong: `inventory_levels.update`, `products.update`, `customers.update`, `receipts.update`, `credit_note.update`. Satu langganan = satu event. Endpoint mesti pulang HTTP 2xx; cuba semula sehingga 200 kali dalam 48 jam sebelum status → Disabled.

> ⚠️ Setakat Julai 2026, sijil SSL `api.astanabiz.com` telah expired (isu server Astana). Client mungkin perlu langkau pengesahan TLS sementara.


---

# Rujukan Endpoint

## Webhooks

### `GET` /webhooks

Dapatkan satu webhook mengikut ID.

- **MCP tool:** `astana_get_webhook`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `id` | string | ✅ | Unique identifier webhook. |

**Response 200:** id, merchant_id, url, type, status, created_at, updated_at

### `POST` /webhooks

Cipta webhook baharu. _(mengubah data)_

- **MCP tool:** `astana_create_webhook`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `url` | string | ✅ | URL destinasi (uri). |
| `type` | enum | ✅ | inventory_levels.update \| products.update \| customers.update \| receipts.update \| credit_note.update |
| `status` | enum | ✅ | ENABLED \| DISABLED |
| `master_username` | string | ✅ | Master account username merchant (email). |

**Response 200:** Sama struktur seperti GET /webhooks

### `DELETE` /webhooks

Padam webhook mengikut ID. _(mengubah data)_

- **MCP tool:** `astana_delete_webhook`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `id` | string | ✅ |  |

**Response 200:** deleted_object_ids

## Categories

### `GET` /category

Senaraikan kategori item.

- **MCP tool:** `astana_list_categories`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `category_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  | Default 10, maksimum 250. |
| `cursor` | string |  | Cursor pagination dari response sebelumnya. |

**Response 200:** categories[]: id, category_name, item_classification_code, created_at, updated_date

### `POST` /category

Cipta atau kemaskini kategori. _(mengubah data)_

- **MCP tool:** `astana_upsert_category`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `category_name` | string | ✅ |  |
| `item_classification_code` | string |  |  |
| `created_at` | date-time | ✅ |  |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** id, name, item_classification_code, created_at

### `DELETE` /category

Padam kategori. _(mengubah data)_

- **MCP tool:** `astana_delete_category`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `category_id` | string | ✅ |  |

**Response 200:** success

## Sub categories

### `GET` /sub_category

Senaraikan sub-kategori.

- **MCP tool:** `astana_list_sub_categories`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `sub_category_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  | Default 10, maksimum 250. |
| `cursor` | string |  | Cursor pagination dari response sebelumnya. |

**Response 200:** sub_categories[]: id, category_name, sub_category_name, created_at, updated_date · cursor

### `POST` /sub_category

Cipta atau kemaskini sub-kategori. _(mengubah data)_

- **MCP tool:** `astana_upsert_sub_category`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `category_id` | string | ✅ |  |
| `sub_category_name` | string | ✅ |  |
| `created_at` | date-time | ✅ |  |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** id, category_name, sub_category_name, created_at

### `DELETE` /sub_category

Padam sub-kategori. _(mengubah data)_

- **MCP tool:** `astana_delete_sub_category`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `category_id` | string | ✅ |  |
| `sub_category_id` | string | ✅ |  |

**Response 200:** success

## Measurements

### `GET` /measurements

Senaraikan unit ukuran.

- **MCP tool:** `astana_list_measurements`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `measurement_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  | Default 10, maksimum 250. |
| `cursor` | string |  | Cursor pagination dari response sebelumnya. |

**Response 200:** measurements[]: id, measurement_name, weight_scale_enable, created_at, updated_date · cursor

### `POST` /measurements

Cipta atau kemaskini unit ukuran. _(mengubah data)_

- **MCP tool:** `astana_upsert_measurement`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `measurement_name` | string | ✅ |  |
| `weight_scale_enable` | int | ✅ | 0 atau 1. |
| `created_at` | date-time | ✅ |  |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** id, measurement_name, weight_scale_enable, created_at, updated_at

### `DELETE` /measurements

Padam unit ukuran. _(mengubah data)_

- **MCP tool:** `astana_delete_measurement`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `measurement_id` | string | ✅ |  |

**Response 200:** success

## Taxes

### `GET` /taxes

Senaraikan cukai dan caj.

- **MCP tool:** `astana_list_taxes`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `tax_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  | Default 10, maksimum 250. |
| `cursor` | string |  | Cursor pagination dari response sebelumnya. |

**Response 200:** taxes[]: id, tax_type, tax_code, tax_name, rate, shops[], created_at · cursor

### `POST` /taxes

Cipta atau kemaskini cukai/caj. _(mengubah data)_

- **MCP tool:** `astana_upsert_tax`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `tax_type` | enum | ✅ | TAX \| CHARGE |
| `calculation_method` | enum |  | ADDED \| INCLUDED \| FIXED |
| `tax_name` | string | ✅ |  |
| `rate` | int | ✅ |  |
| `apply_tax_after_other_taxes` | int |  | 0 atau 1. |
| `is_tax_price_change` | int |  | 0 atau 1. |
| `shops` | array | ✅ | Senarai uuid shop. |
| `created_at` | date-time | ✅ |  |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** id, tax_type, calculation_method, tax_code, tax_name, rate, shops, created_at

### `DELETE` /taxes

Padam cukai mengikut kod dan shops. _(mengubah data)_

- **MCP tool:** `astana_delete_tax`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `tax_code` | string | ✅ |  |
| `shops` | array | ✅ | Senarai shop id. |

**Response 200:** success

## Customers

### `GET` /customers

Senaraikan pelanggan.

- **MCP tool:** `astana_list_customers`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `customer_ids` | string |  |  |
| `email` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** customers[]: id, customer_code, name, email, phone_number, total_spent, total_points, credit_limit, membership_status … · cursor

### `POST` /customers

Cipta atau kemaskini pelanggan. Guna additional_fields untuk medan lain (address, city, id_type, dsb). _(mengubah data)_

- **MCP tool:** `astana_upsert_customer`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `first_name` | string | ✅ |  |
| `last_name` | string |  |  |
| `email` | string |  |  |
| `phone` | string |  |  |
| `id_type` | enum |  | NA \| NRIC \| PASSPORT \| ARMY \| MyPR \| MyKAS \| BRN |
| `id_number` | string |  |  |
| `credit_limit` | number |  |  |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** success

### `DELETE` /customers

Padam pelanggan. _(mengubah data)_

- **MCP tool:** `astana_delete_customer`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `customer_id` | string | ✅ |  |

**Response 200:** success

## Employee

### `GET` /employee

Senaraikan pekerja.

- **MCP tool:** `astana_list_employees`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `employee_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  | Default 10, maksimum 250. |
| `cursor` | string |  | Cursor pagination dari response sebelumnya. |

**Response 200:** employees[]: id, Name, User_Role, POS_Login_PIN, POS_user_name, Backoffice_login_email, Phone, shops · cursor

## Suppliers

### `GET` /suppliers

Senaraikan pembekal.

- **MCP tool:** `astana_list_suppliers`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `supplier_ids` | string |  |  |
| `updated_at_min` | date-time |  |  |
| `updated_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** suppliers[]: id, supplier_name, supplier_id, phone_number, email, type, address, created_at · cursor

### `POST` /suppliers

Cipta atau kemaskini pembekal. _(mengubah data)_

- **MCP tool:** `astana_upsert_supplier`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `supplier_name` | string | ✅ |  |
| `supplier_id` | string | ✅ |  |
| `type` | enum | ✅ | Cash \| Credit \| N/A |
| `created_at` | date-time | ✅ |  |
| `phone_number` | string |  |  |
| `email` | string |  |  |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** id, supplier_name, supplier_id, phone_number, email, type, address, created_at

### `DELETE` /suppliers

Padam pembekal. _(mengubah data)_

- **MCP tool:** `astana_delete_supplier`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `supplier_id` | string | ✅ |  |

**Response 200:** success

## Product

### `GET` /products

Senaraikan produk dengan field penuh.

- **MCP tool:** `astana_list_products`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `product_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `updated_at_min` | date-time |  |  |
| `updated_at_max` | date-time |  |  |
| `limit` | int |  | 1-100, default 10. |
| `cursor` | string |  |  |

**Response 200:** products[]: id, product_code, product_name, category, cost, barcode, measurement, tax_codes, variants, shops, components …

### `POST` /products

Cipta atau kemaskini produk. Guna additional_fields untuk medan penuh (components, modifiers_ids, option names, dsb). _(mengubah data)_

- **MCP tool:** `astana_upsert_product`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `product_code` | string | ✅ |  |
| `product_name` | string | ✅ |  |
| `cost` | number | ✅ |  |
| `stock_control` | bool | ✅ |  |
| `is_variant` | bool | ✅ |  |
| `shops` | array | ✅ |  |
| `variants` | array |  |  |
| `tax_ids` | array |  |  |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

## Product Image

### `POST` /product_image

Muat naik imej produk (multipart). `image` ialah path fail tempatan .png/.jpg/.jpeg. _(mengubah data)_

- **MCP tool:** `astana_upload_product_image`

**Form Fields (multipart):**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `product_code` | string | ✅ |  |
| `image` | file | ✅ | Path fail tempatan pada mesin yang menjalankan server MCP. |

**Response 200:** success

### `DELETE` /product_image

Padam imej produk. _(mengubah data)_

- **MCP tool:** `astana_delete_product_image`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `product_code` | string | ✅ |  |

**Response 200:** success

## Receipts

### `GET` /receipts

Senaraikan resit / invois.

- **MCP tool:** `astana_list_receipts`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `receipt_numbers` | string |  |  |
| `shop_id` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** receipts[]: receipt_number, receipt_type, total_money, customer_id, line_products, payments …

### `GET` /void_receipts

Senaraikan resit yang di-void.

- **MCP tool:** `astana_list_void_receipts`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `receipt_numbers` | string |  |  |
| `shop_id` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** receipts[] + deleted_by, deleted_date · cursor

### `GET` /credit_note_and_refund

Senaraikan nota kredit dan bayaran balik tunai.

- **MCP tool:** `astana_list_credit_notes`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `receipt_numbers` | string |  |  |
| `shop_id` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** receipts[] · cursor

### `POST` /credit_note_and_refund

Cipta nota kredit atau bayaran balik tunai. _(mengubah data)_

- **MCP tool:** `astana_create_credit_note`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `receipt_number` | string | ✅ |  |
| `shop_id` | string | ✅ |  |
| `pos_device_id` | string | ✅ |  |
| `receipt_type` | enum | ✅ | CASH_REFUND \| CREDIT_NOTE |
| `transaction_date` | date-time | ✅ |  |
| `line_products` | array | ✅ | [{product_id, product_line_no, quantity, comment}] |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** success

## Orders

### `GET` /orders

Senaraikan pesanan. Julat tarikh wajib.

- **MCP tool:** `astana_list_orders`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `order_numbers` | string |  |  |
| `shop_id` | string |  |  |
| `created_at_min` | date-time | ✅ |  |
| `created_at_max` | date-time | ✅ |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** orders[]: order_number, order_date_time, total_money, customer_id, line_products, payments, order_status …

## Shops

### `GET` /shops

Senaraikan kedai merchant.

- **MCP tool:** `astana_list_shops`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `shop_ids` | string |  |  |
| `updated_at_min` | date-time |  |  |
| `updated_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** shops[]: id, shop_name, address, phone_number, city, email, longitude, latitude, terminal_list, is_enable

## Payment types

### `GET` /payment_types

Senaraikan jenis pembayaran.

- **MCP tool:** `astana_list_payment_types`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `payment_type_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `updated_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** payment_types[]: id, payment_type_name, shops, created_date, updated_date

### `POST` /payment_types

Cipta atau kemaskini jenis pembayaran. _(mengubah data)_

- **MCP tool:** `astana_upsert_payment_type`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `payment_type_code` | string | ✅ |  |
| `payment_type_name` | string | ✅ |  |
| `payment_type_category` | string | ✅ | cth: Cash, Card, Cheque. |
| `status` | int | ✅ | 0 atau 1. |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** success

### `DELETE` /payment_types

Padam jenis pembayaran. _(mengubah data)_

- **MCP tool:** `astana_delete_payment_type`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `payment_type_id` | string | ✅ |  |

**Response 200:** success

## Order types

### `GET` /order_types

Senaraikan jenis pesanan.

- **MCP tool:** `astana_list_order_types`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `order_type_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  | Default 10, maksimum 250. |
| `cursor` | string |  | Cursor pagination dari response sebelumnya. |

**Response 200:** order_type[]: id, order_type_name, is_enable, created_at, updated_date · cursor

### `POST` /order_types

Cipta atau kemaskini jenis pesanan. _(mengubah data)_

- **MCP tool:** `astana_upsert_order_type`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `order_type_name` | string | ✅ |  |
| `status` | int |  | 0 atau 1. |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** success

### `DELETE` /order_types

Padam jenis pesanan. _(mengubah data)_

- **MCP tool:** `astana_delete_order_type`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `order_type_id` | string | ✅ |  |

**Response 200:** success

## Modifiers

### `GET` /modifiers

Senaraikan kumpulan modifier.

- **MCP tool:** `astana_list_modifiers`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `modifier_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `updated_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** modifier_groups[]: id, modifier_group_name, modifiers, shops, created_date, updated_date

### `DELETE` /modifiers

Padam kumpulan modifier. _(mengubah data)_

- **MCP tool:** `astana_delete_modifier`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `modifier_group_id` | string | ✅ |  |

**Response 200:** success

## GRN

### `GET` /grn

Senaraikan Good Receive Notes.

- **MCP tool:** `astana_list_grn`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `shop_ids` | string |  |  |
| `grn_numbers` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** grn_list[]: grn_id, shop_id, supplier_id, grn_number, grn_amount, grn_date, grn_status, items, additional_cost · cursor

### `POST` /grn

Cipta Good Receive Note. _(mengubah data)_

- **MCP tool:** `astana_create_grn`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `supplier_id` | string |  |  |
| `shop_id` | string |  |  |
| `grn_date` | date-time |  |  |
| `payment_method_id` | string |  |  |
| `grn_total` | number |  |  |
| `items` | array |  | [{product_id, qty, unit_cost, total_unit_cost, expire_mode, expire_date}] |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** success

## Inventory

### `GET` /inventory

Dapatkan paras stok produk.

- **MCP tool:** `astana_list_inventory`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `product_ids` | string |  |  |
| `shop_ids` | string | ✅ |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** inventory_levels[]: product_id, shop_id, product_code, in_stock · cursor

### `POST` /inventory

Kemaskini paras stok. _(mengubah data)_

- **MCP tool:** `astana_update_inventory`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `inventory_levels` | array | ✅ | [{shop_id, product_id, in_stock}] |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** code, details

## Merchant

### `GET` /merchant

Dapatkan maklumat merchant.

- **MCP tool:** `astana_get_merchant`

**Response 200:** merchant[]: id, business_name, email, country, currency, created_at

## Online orders

### `POST` /online_orders

Hantar pesanan dalam talian. Guna additional_fields untuk medan penuh (fixed_charges, order_total_discounts, dsb). _(mengubah data)_

- **MCP tool:** `astana_place_online_order`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `shop_id` | string |  |  |
| `order_reference_number` | string |  |  |
| `order_reference_id` | string |  |  |
| `order_total` | number |  |  |
| `channel_order_status_id` | int |  | Sepatutnya 0. |
| `channel_order_status_name` | string |  | Sepatutnya "pending". |
| `customer_phone` | string |  |  |
| `order_date_time` | date-time |  |  |
| `order_items` | array |  |  |
| `order_payments` | array |  |  |
| `additional_fields` | object | | Medan tambahan pass-through ke body |

**Response 200:** success · order_reference_id, order_reference_number, system_unique_id, order_date

### `GET` /online_order_status

Semak status pesanan dalam talian.

- **MCP tool:** `astana_get_online_order_status`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `system_unique_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  | Default 10, maksimum 250. |
| `cursor` | string |  | Cursor pagination dari response sebelumnya. |

**Response 200:** order_status[]: system_unique_id, order_reference_id, order_reference_number, order_status, status_name · cursor

### `POST` /cancel_online_order

Batal pesanan dalam talian. _(mengubah data)_

- **MCP tool:** `astana_cancel_online_order`

**Request Body:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `system_unique_id` | string | ✅ |  |

**Response 200:** success · code, details, order_reference_id, order_reference_number

## Shifts

### `GET` /shifts

Senaraikan shift POS dengan ringkasan tunai dan jualan.

- **MCP tool:** `astana_list_shifts`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `shift_ids` | string |  |  |
| `pos_device_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** employees[] (kunci wrapper sebenar API Astana): id, store_id, opened_at, closed_at, starting_cash, expected_cash, gross_sales, net_sales, payments … · cursor

## POS Devices

### `GET` /pos_devices

Senaraikan terminal POS.

- **MCP tool:** `astana_list_pos_devices`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `pos_keys` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  | Default 10, maksimum 250. |
| `cursor` | string |  | Cursor pagination dari response sebelumnya. |

**Response 200:** terminals[]: Shop_name, POS_name, pos_key, status

## Timecards

### `GET` /timecards

Senaraikan timecards (clock-in / clock-out) pekerja.

- **MCP tool:** `astana_list_timecards`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `shop_ids` | string |  |  |
| `employee_ids` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** timecards[]: id, shop_id, employee_name, clock_in, clock_out, total_hours · cursor

## Purchase Orders

### `GET` /purchase_orders

Senaraikan purchase order.

- **MCP tool:** `astana_list_purchase_orders`

**Query Parameters:**

| Nama | Jenis | Wajib | Keterangan |
|---|---|---|---|
| `shop_ids` | string |  |  |
| `po_numbers` | string |  |  |
| `created_at_min` | date-time |  |  |
| `created_at_max` | date-time |  |  |
| `limit` | int |  |  |
| `cursor` | string |  |  |

**Response 200:** purchase_orders[]: po_id, shop_id, supplier_name, po_number, po_amount, po_date, po_status, items …
