ກຳລັງຈັດກຽມຂໍ້ມູນ
ດຶງລາຄາສິນຄ້າ, ສົ່ງອໍເດີ ແລະຕິດຕາມການເຕີມຈາກເຊີບເວີຂອງຮ້ານ. ເລີ່ມຈາກບັນຊີຕົວແທນ ແລະສົ່ງຄຳຂໍເປີດ API ໃຫ້ແອັດມິນກວດສອບ.
ເປີດໃຊ້ເປັນລາຍຮ້ານ
ຖ້າຍັງບໍ່ມີບັນຊີຕົວແທນ ໃຫ້ຕິດຕໍ່ຮ້ານກ່ອນ. ຫຼັງອະນຸມັດຈຶ່ງສ້າງ Key ແລະເຕີມຍອດໃນສູນຕົວແທນ. API ນີ້ໃຊ້ Agent Balance ແຍກຈາກ MG Balance ຂອງລູກຄ້າທົ່ວໄປ.
pending ລໍຖ້າ · processing ກຳລັງເຕີມ · success ສຳເລັດ · cancelled ຍົກເລີກ · refunded ຄືນເງິນ
ໃຊ້ສິນຄ້າທີ່ມີໃນ catalog ຂອງບັນຊີ. ແພັກກົດມືຍັງໃຊ້ເວລາຈັດສົ່ງຕາມຮ້ານ. ເປີດ Webhook ເພື່ອຮັບສະຖານະອັດຕະໂນມັດ ແລະກວດ GET /orders ທຸກ 15–30 ວິນາທີເປັນທາງສຳຮອງ. ເກມທີ່ຕ້ອງກວດ ID ຕ້ອງສົ່ງຂໍ້ມູນຢືນຢັນຕາມລະບົບເດີມ.
ຂໍສິດ API ແລະລໍຖ້າອະນຸມັດ
ສ້າງ key ແລະເກັບໃນ server
ດຶງ catalog ມາສ້າງສິນຄ້າ
ສົ່ງອໍເດີດ້ວຍ key ບໍ່ຊ້ຳ
ຮັບ Webhook ແລະ sync updates
Base URL
https://megametopup.com/api/reseller/v1Header ທຸກ request
Authorization: Bearer YOUR_API_KEYໃຫ້ເອີ້ນ API ຈາກ backend ຂອງຮ້ານເທົ່ານັ້ນ. ຫ້າມຝັງ API key ໄວ້ໃນ HTML, JavaScript, mobile app ຫຼື repository ສາທາລະນະ.
ຈຳກັດຄຳຂໍທົ່ວໄປ 120 ຄັ້ງ/ນາທີຕໍ່ IP ແລະກວດບັນຊີ 20 ຄັ້ງ/ນາທີ. catalog ມີ cache ສັ້ນ 20 ວິນາທີແຍກແຕ່ລະບັນຊີ; ຕອນສັ່ງຊື້ຈະກວດລາຄາ/ສິດປັດຈຸບັນອີກຄັ້ງ.
/catalogດຶງເກມ, ແພັກ, ລາຄາ ແລະສະຖານະພ້ອມຂາຍ
/updatesກວດລາຄາປ່ຽນ ແລະສະຖານະສິນຄ້າ
/profileກວດຍອດສັ່ງຊື້ ແລະຂໍ້ມູນບັນຊີ
/ordersສັ່ງຊື້ແພັກ ແລະຫັກ Agent Balance
/player-checkກວດບັນຊີ ແລະເລືອກເຊີບ/ຕົວລະຄອນ
/orders?id=ORDER_IDກວດສະຖານະອໍເດີຂອງທ່ານ
/orders?idempotencyKey=REFERENCEຄົ້ນອໍເດີຈາກເລກອ້າງອີງຂອງຮ້ານ
ໃຊ້ inputFields[].id ຈາກ catalog ເປັນ Key ໃນ accountFields ແລະໃສ່ຄ່າໃຫ້ຄົບຊ່ອງທີ່ required=true. ຕົວຢ່າງ player_id ດ້ານລຸ່ມເປັນພຽງຕົວຢ່າງ; ໃຫ້ໃຊ້ ID ຕາມເກມຈິງ.
1. ດຶງ catalog ແລະສະຕັອກ
curl "https://megametopup.com/api/reseller/v1/catalog" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"ຕົວຢ່າງ catalog response
{
"catalogVersion": "c934707a89d07fcd8f6e020f156572ee7f8d3543239c8cd53a21ec835b113ffd",
"summary": { "availablePackages": 148, "unavailablePackages": 3 },
"updates": [{
"type": "price_down",
"gameName": "Example Game",
"packageName": "100 Diamonds",
"previousPrice": 25000,
"currentPrice": 24000,
"priceBasis": "agent_base_cost",
"currentRetailPrice": 25000,
"currentAgentCost": 24000
}],
"games": [{
"id": "game-id",
"name": "Example Game",
"inputFields": [{ "id": "player_id", "label": "User ID", "required": true }],
"packages": [{
"id": "package-id",
"price": 25000,
"retailPrice": 25000,
"agentCost": 24000,
"earningAmount": 1000,
"available": true,
"availabilityCode": "available"
}]
}]
}2. ສ້າງອໍເດີ
curl -X POST "https://megametopup.com/api/reseller/v1/orders" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: shop-order-10001" \
-d '{ "gameId": "game-id", "packageId": "package-id", "expectedPrice": 25000, "accountFields": { "player_id": "123456789" }, "selectedServer": "Asia", "idempotencyKey": "shop-order-10001" }'3. ກວດສະຖານະອໍເດີ
curl "https://megametopup.com/api/reseller/v1/orders?id=ORDER_ID" \
-H "Authorization: Bearer YOUR_API_KEY"ຖ້າ catalog.games[].verification.enabled=true ໃຫ້ເອີ້ນ POST /player-check ດ້ວຍ API key ດຽວກັບອໍເດີ. ສົ່ງ gameId ແລະ userId; ເພີ່ມ zoneId/serverId/selectedServer ຖ້າເກມນັ້ນຕ້ອງໃຊ້. ໃຫ້ລູກຄ້າຢືນຢັນຊື່ກ່ອນເຕີມ.
price / retailPrice
ລາຄາຂາຍ ແລະຍອດທີ່ຫັກຈາກ Agent Balance ຕອນສັ່ງຊື້.
agentCost
ຕົ້ນທຶນຕົວແທນ; ຍອດທີ່ຫັກຕອນສັ່ງແມ່ນ price.
earningAmount
ລາຍຮັບທີ່ເຂົ້າຍອດຖອນໄດ້ຫຼັງອໍເດີສຳເລັດ.
GET /updates ທຸກ 30-60 ວິນາທີ ຫຼືເມື່ອເປີດໜ້າຊຳລະ.catalogVersion ປ່ຽນ ໃຫ້ດຶງ GET /catalog ໃໝ່.available=false ໃຫ້ປິດປຸ່ມຊື້ ແຕ່ຍັງສະແດງແພັກພ້ອມເຫດຜົນ.updates[].type ແຍກ price_up, price_down, out_of_stock ແລະ back_in_stock.| HTTP | Code | ວິທີແກ້ |
|---|---|---|
| 400 | idempotency_key_is_required | ເພີ່ມ X-Idempotency-Key ຢ່າງໜ້ອຍ 8 ຕົວ |
| 401 | invalid_api_key | ກວດ API key ຫຼືສ້າງ key ໃໝ່ |
| 400/409 | price_changed | ດຶງ catalog ໃໝ່ ແລະຢືນຢັນລາຄາອີກຄັ້ງ |
| 400/409 | game_unavailable / provider_package_unavailable | ດຶງ catalog ໃໝ່ ແລະກວດ available ກ່ອນຊື້ |
| 400 | insufficient_agent_balance | ເຕີມຍອດສັ່ງຊື້ກ່ອນສ້າງອໍເດີ |
| 409 | idempotency_conflict | ໃຊ້ Key ເກົ່າສຳລັບອໍເດີເກົ່າເທົ່ານັ້ນ |
| 400 | idempotency_key_mismatch | ໃຊ້ເລກອ້າງອີງດຽວກັນໃນ Header ແລະ JSON |
| 409 | player_verification_required | ກວດ POST /player-check ແລ້ວສົ່ງ Token ໃນອໍເດີ |
| 409 | duplicate_order | ກວດອໍເດີທີ່ກຳລັງເຕີມກ່ອນ ບໍ່ສ້າງ Key ໃໝ່ເພື່ອລອງຊ້ຳ |
| 404 | order_not_found | ກວດ ORDER_ID ແລະ API key ຂອງບັນຊີ |
| 429 | HTTP 429 | ລໍຖ້າຕາມ Retry-After ແລ້ວລອງໃໝ່ |
ເປີດຢູ່ສູນຕົວແທນ → ເຊື່ອມ API. ໃສ່ URL HTTPS ໃນໂດເມນດຽວກັບເວັບທີ່ອະນຸມັດ ໂດຍບໍ່ໃສ່ query ຫຼືລະຫັດ. ເກັບ Secret ທີ່ສະແດງຄັ້ງດຽວ ແລະທົດສອບດ້ວຍປຸ່ມທົດສອບກ່ອນເປີດຮັບອໍເດີ.
ຕົວຢ່າງການແຈ້ງສະຖານະ
{
"id": "evt_123...",
"sequence": 42,
"createdAt": "2026-10-06 10:00:00",
"type": "order.status_changed",
"order": {
"id": "ORD-API-...",
"idempotencyKey": "shop-order-10001",
"status": "success",
"previousStatus": "processing",
"price": 25000,
"paidAmount": 25000,
"currency": "LAK"
}
}ກວດລາຍເຊັນດ້ວຍ Node.js
import { createHmac, timingSafeEqual } from 'node:crypto';
// rawBody: Buffer, headers: incoming HTTP headers
const timestamp = headers['x-megame-timestamp'];
const signature = headers['x-megame-signature'];
if (!/^\d{10}$/.test(timestamp ?? '') ||
Math.abs(Date.now() / 1000 - Number(timestamp)) > 300 ||
!/^v1=[a-f0-9]{64}$/.test(signature ?? '')) {
throw new Error('invalid_signature');
}
const expected = createHmac('sha256', process.env.WEBHOOK_SECRET)
.update(timestamp + '.').update(rawBody).digest();
const received = Buffer.from(signature.slice(3), 'hex');
if (!timingSafeEqual(expected, received)) {
throw new Error('invalid_signature');
}
// Parse JSON only after verifying its exact original bytes.
const event = JSON.parse(rawBody.toString('utf8'));
// Save event.id once in your DB; ignore lower order sequences.
// Return HTTP 2xx only after the event is durably saved.order.created ແຈ້ງອໍເດີໃໝ່; order.status_changed ແຈ້ງສະຖານະປ່ຽນ; webhook.test ເປັນການທົດສອບທີ່ບໍ່ສ້າງອໍເດີ ແລະບໍ່ຫັກເງິນ.X-MeGame-Signature ດ້ວຍ HMAC-SHA256 ຂອງ timestamp + "." + rawBody. ອ່ານ timestamp ຈາກ X-MeGame-Timestamp ແລະຮັບພາຍໃນ 5 ນາທີ.id ເພື່ອກັນແຈ້ງຊ້ຳ. ໃຊ້ sequence ເພື່ອບໍ່ໃຫ້ຂໍ້ຄວາມເກົ່າປ່ຽນສະຖານະຫຼ້າສຸດ. ສົ່ງຊ້ຳໃຊ້ Event ID ເດີມ ແຕ່ timestamp ແລະລາຍເຊັນໃໝ່.success ໃຫ້ດຶງ GET /orders?id=... ເພື່ອຮັບລະຫັດສິນຄ້າຖ້າມີ.