Appearance
Quick start
This page takes you from nothing to a real order and its tracking number. It uses cURL, so any terminal will do. Each step links to the full reference for the call it makes.
1. Create an app in XSelly
A store owner, or anyone with access to the store's settings, does this once:
- In XSelly, open แอปภายนอก (API) in the store menu.
- Press + at the top right, name the app (for example ระบบ POS หน้าร้าน), read and accept ข้อควรรู้ก่อนเชื่อมต่อ, and press สร้างการเชื่อมต่อ.
- Open the new app. Its Client ID (
xs_...) is already there. - Press สร้าง Client Secret and copy the secret (
xss_...) now. It is shown once and cannot be read back, only replaced.
TIP
Each app counts toward the store's connection quota, together with its sales channels, accounting and CRM connections.
You also need your base URL, which is shown in the XSelly app.
Keep these values out of source control. The examples below read them from the environment:
bash
export BASE_URL=your_base_url
export CLIENT_ID=xs_your_client_id
export CLIENT_SECRET=xss_your_client_secret2. Get an access token
bash
curl -sS -X POST "$BASE_URL/oauth/token" \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET"json
{
"access_token": "eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 14400
}The token lasts four hours. In a real integration you cache it and reuse it until then (see Authentication). For now, keep it in a variable:
bash
export ACCESS_TOKEN=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...3. Find something to sell
List the store's products. You get an id, a name and a picture for each:
bash
curl -sS -X POST "$BASE_URL/v1/product/list" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"limit": 5}'Then read one of them in full, to get its variants:
bash
curl -sS -X POST "$BASE_URL/v1/product/detail" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"product_id": "569032"}'Each entry in product.variants[] has a product_variant_id. That is what an order line names. Note that it is a string: "1984307", not 1984307. Why ids are strings.
4. Create an order
bash
curl -sS -X POST "$BASE_URL/v1/order/create" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"external_order_id": "QUICKSTART-0001",
"shipping_type": "ems",
"recipient_address": {
"name": "คุณทดสอบ ระบบ",
"telephone": "0556789201",
"address1": "51/102 บางปะกง",
"sub_district": "บางปะกง",
"district": "บางปะกง",
"province": "ฉะเชิงเทรา",
"postal_code": 24130
},
"products": [{ "product_variant_id": "1984307", "qty": 1 }],
"shipping_fee": 30
}'A few things this call did for you:
- The sender address was left out, so the parcel ships from the store's primary address (ที่อยู่หลัก).
- The price was left out, so the store's own price for that variant was used.
- A tracking number will be requested from the courier as soon as the order is ready to ship (payment has been confirmed and completed or flag
ship_before_payis true), where the store has XShipping set up for it. Send"auto_request_xshipping": falseto opt out. external_order_idmakes the call safe to retry. Send the exact same request again and you get the same order back, not a second one.
The response is the full order object. Keep order.id.
5. Read it back
bash
curl -sS -X POST "$BASE_URL/v1/order/detail" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"external_order_id": "QUICKSTART-0001"}'A new order has no shipments yet. XShipping books the courier moments later, and then order.shipments[].tracking_number appears here.
Next steps
- Authentication: cache the token properly before you go further.
- Build a sale page or website: products, variants and stock.
- Create and track orders: COD, amounts, retries and order states.
- Receive webhooks: stay in sync with stock.
- Prefer clicking to typing? Import the Postman collection.
