เอกสาร API

หน้าแรก/เอกสาร API
API CHARGING V2

คู่มือเชื่อมต่อส่งบัตรเติมเงิน

เอกสารสำหรับ Merchant เพื่อส่งบัตร ตรวจสอบสถานะธุรกรรม และรับตารางค่าธรรมเนียมตามบัญชี

ENDPOINT หลักhttps://toctoico.com/chargingws/v2

1. ภาพรวมการเชื่อมต่อ

ข้อมูลค่า
Endpoint หลักhttps://toctoico.com/chargingws/v2
API ตารางค่าธรรมเนียมhttps://toctoico.com/chargingws/v2/getfee?partner_id=YOUR_PARTNER_ID
MethodPOST
รูปแบบข้อมูลapplication/json หรือ application/x-www-form-urlencoded
คำสั่งที่รองรับcharging, check

2. เงื่อนไขก่อนเรียก API

รองรับโปรโตคอล Nappay: เปลี่ยน URL เป็นเว็บไซต์นี้ และใช้ Partner ID/Key กับรหัสกระเป๋าของ Merchant ที่นี่ รายการสินค้า ราคา และเงื่อนไขดำเนินการมาจากระบบนี้

เชื่อมต่อกับระบบนี้โดยตรงด้วย Merchant ของบัญชีคุณ จำนวนเงินทั้งหมดเป็นดองเวียดนาม (VND) ให้ส่งเป็นจำนวนเต็มไม่มีเครื่องหมายคั่น

  1. เข้าสู่ระบบ → เชื่อมต่อ API / Merchant, สร้าง Merchant ให้ตรงบริการแล้วเปิดใช้งาน
  2. รับ Partner ID, Partner Key และรหัสกระเป๋าจาก Merchant นั้น หากตั้งค่า IP ที่อนุญาต ให้ระบุ IP สาธารณะของเซิร์ฟเวอร์ที่ส่งคำขอ
  3. ตั้งค่า URL Callback HTTPS ของระบบรับผล เลือก POST JSON หรือ GET ตาม Merchant
  4. ดึงหมวดหมู่/ค่าธรรมเนียมและตรวจสอบยอดก่อน จากนั้นจึงเชื่อมต่อการสร้างคำสั่งซื้อ การค้นหา และการกระทบยอด

Partner Key ใช้บนเซิร์ฟเวอร์ของคุณเท่านั้น อย่าใส่คีย์ใน JavaScript เบราว์เซอร์ แอปสาธารณะ หรือ URL ค่า YOUR_PARTNER_ID, YOUR_PARTNER_KEY, YOUR_WALLET ด้านล่างเป็นช่องสำหรับข้อมูล Merchant ของคุณบนเว็บนี้

Endpoint แลกบัตร Topup และซื้อรหัสบัตร
บริการEndpointรูปแบบ
แลกบัตรเติมเงินhttps://toctoico.com/chargingws/v2POST JSON หรือ form-urlencoded
เติมเงิน Topuphttps://toctoico.com/api/rechargewsPOST JSON หรือ form-urlencoded
ซื้อรหัสบัตรhttps://toctoico.com/api/cardwsPOST JSON หรือ form-urlencoded
ตารางค่าธรรมเนียมแลกบัตรhttps://toctoico.com/chargingws/v2/getfee?partner_id=YOUR_PARTNER_IDGET
หมวดหมู่รหัสบัตรhttps://toctoico.com/api/cardws/products?partner_id=YOUR_PARTNER_IDGET

3. ลายเซ็นยืนยันตัวตน

ลงนาม MD5 ด้วยสตริง UTF-8 ที่ต่อกันตามลำดับด้านล่าง โดยไม่เพิ่มจุด ช่องว่าง หรืออักขระคั่น ส่งสตริง MD5 แบบ hex และใช้ command ตัวพิมพ์เล็กตามเอกสาร

กลุ่มคำสั่งสตริงสำหรับแฮช MD5
แลกบัตร: chargingpartner_key + code + command + partner_id + request_id + serial + telco
แลกบัตร: checkpartner_key + command + partner_id + request_id
แลกบัตร: ยังรองรับลายเซ็นเดิมpartner_key + code + serial
Topup: topup, getstatuspartner_key + partner_id + command + request_id
Topup: productlist, getbalance, feetopup, canceltopuppartner_key + partner_id + command
รหัสบัตร: buycard, redownloadpartner_key + partner_id + command + request_id
รหัสบัตร: getbalance, checkavailablepartner_key + partner_id + command
หมวดหมู่รหัสบัตร, getfeeยืนยัน Merchant/IP ผ่าน partner_id ขณะนี้ endpoint ไม่ต้องใช้ sign
ตรวจสอบ serial /api/checkcardpartner_key + serial
Python
hashlib.md5((partner_key + partner_id + command + request_id).encode("utf-8")).hexdigest()

Merchant แต่ละรายใช้ได้เฉพาะประเภท API ที่ลงทะเบียนไว้ (Charging, Recharge, Softcard หรือ All) ข้อผิดพลาดการยืนยันตัวตน/IP อาจปรากฏใน JSON แม้ HTTP เป็น 200

4. พารามิเตอร์และการตอบกลับสำหรับแลกบัตร

POST /chargingws/v2

ส่งบัตรด้วย command=charging ตรวจสอบด้วย command=check พร้อม partner_id, request_id และ sign ตามตารางด้านบน โดยไม่ต้องส่งข้อมูลบัตรใหม่ ลายเซ็นเดิม MD5(partner_key + code + serial) ยังรองรับเมื่อส่ง code และ serial มาด้วย

พารามิเตอร์คำขอความหมาย / ค่า
partner_id, signจำเป็นMerchant และลายเซ็นของบริการแลกบัตร
commandจำเป็นcharging หรือ check
request_idจำเป็นรหัสคำขอไม่ซ้ำต่อ Merchant; check ใช้รหัสเดิม
telcoKhi chargingรหัสเครือข่ายตัวพิมพ์ใหญ่ ดึงจาก getfee
amountKhi chargingมูลค่าบัตรที่ระบุ สามารถไม่ส่งเมื่อ check
code, serialKhi chargingสตริงรหัสบัตร/ซีเรียล ต้องคงเลข 0 ด้านหน้า เมื่อ check ให้ส่งสตริงเดิมกลับให้ตรงทุกตัว
json
{
  "partner_id": "YOUR_PARTNER_ID",
  "command": "charging",
  "request_id": "CHARGE_DEMO_001",
  "telco": "VIETTEL",
  "amount": 100000,
  "code": "YOUR_CARD_CODE",
  "serial": "YOUR_CARD_SERIAL",
  "sign": "MD5_THEO_CONG_THUC_CHARGING"
}

ตรวจสอบธุรกรรมอีกครั้ง

json
{
  "partner_id": "YOUR_PARTNER_ID",
  "command": "check",
  "request_id": "CHARGE_DEMO_001",
  "sign": "MD5_PARTNER_KEY_CHECK_PARTNER_ID_REQUEST_ID"
}

คำตอบธุรกรรม

json
{
  "trans_id": 123,
  "request_id": "CHARGE_DEMO_001",
  "status": 99,
  "message": "PENDING",
  "declared_value": 100000,
  "value": 0,
  "amount": 0,
  "telco": "VIETTEL",
  "code": "YOUR_CARD_CODE",
  "serial": "YOUR_CARD_SERIAL",
  "callback_sign": "MD5_PARTNER_KEY_CODE_SERIAL"
}
พารามิเตอร์คำขอความหมาย / ค่า
trans_id, request_idได้รับรหัสธุรกรรมระบบและรหัสคำขอของคุณ
declared_valueได้รับมูลค่าบัตรที่ระบุไว้
valueได้รับมูลค่าบัตรจริงที่ยืนยันแล้ว
amountได้รับยอดสุทธิเข้ากระเป๋าหลังประมวลผล
status, messageได้รับสถานะบัตรหรือข้อผิดพลาด ให้ตรวจทั้งสองค่าเสมอ
statusความหมาย
99รออยู่ ยังไม่เพิ่มเงินเหมือนคำสั่งซื้อที่สำเร็จ
1บัตรใช้ได้ สำเร็จ
2บัตรใช้ได้แต่มูลค่าไม่ตรง
3บัตรผิดพลาด / ไม่ถูกต้อง
4ข้าม / บำรุงรักษาตามผลการประมวลผล
100ข้อผิดพลาดคำขอ
101ไม่พบธุรกรรม
102การยืนยันตัวตน IP หรือข้อมูลไม่ถูกต้อง
104คำสั่งไม่ถูกต้อง

ตารางค่าธรรมเนียมตาม Merchant

GET /chargingws/v2/getfee?partner_id=YOUR_PARTNER_ID. การตอบกลับเป็นรายการแบบแบนที่มี telco, value, fees และ penalty ซึ่งเข้ากันได้กับ Nappay ระบบเดิมที่ต้องการ object แบบจัดกลุ่มสามารถเพิ่ม format=grouped ได้ fees คือค่าธรรมเนียมลูกค้าตามกลุ่มบัญชี โดยคืนเฉพาะประเภทบัตร/มูลค่าบัตรที่เปิดใช้งาน อย่ากำหนดหมวดหมู่หรือค่าธรรมเนียมตายตัวตามตัวอย่างเอกสาร

json
[
  {
    "telco": "VIETTEL",
    "value": 100000,
    "fees": "18.5",
    "penalty": "50"
  }
]

ค่าธรรมเนียมกลุ่มถูกกำหนดตอนรับบัตร หากมูลค่าผิด (status=2) จะปรับ 50% จากยอดรับหลังหักค่าธรรมเนียมกลุ่ม: ยอดรับ = มูลค่าที่ต้นทางยืนยัน × (100 − ค่าธรรมเนียมกลุ่ม)% × 50% ปัดลงเป็นหน่วย ดอง ตัวอย่าง 10.000đ ค่าธรรมเนียมกลุ่ม 26,8% รับ 3.660đ ใช้ amount ของผลลัพธ์สุดท้ายบันทึกยอด อย่าคำนวณใหม่จากมูลค่าที่แจ้ง รายการแบบทำเองอาจยังเป็นสถานะ 99 จนผู้ดำเนินการยืนยัน; การค้นหา/callback เป็นหลักฐานอัปเดตสุดท้าย

5. Callback และการกระทบยอด

ลงทะเบียน URL callback ของคุณใน Merchant บนเว็บนี้ ระบบส่งผลแลกบัตร/Topup ผ่าน POST JSON หรือ GET ตามการตั้งค่า Merchant อาจส่ง callback ซ้ำได้ จึงต้องจัดการรายการซ้ำอย่างปลอดภัยตามรหัสคำสั่งซื้อและสถานะ

บริการตรวจสอบ callback_signฟิลด์หลัก
แลกบัตรMD5(partner_key + code + serial)status, message, request_id, trans_id, declared_value, value, amount, telco, code, serial
TopupMD5(partner_key + order_code)status, request_id, order_code, request_value, amount, account

Callback Topup ใช้ status=completed เมื่อรายการสำเร็จ; request_value คือยอดที่ต้องการเติม และ amount คือยอดชำระหากมีราคาเสนอที่สรุปไว้ การค้นหาอาจคืน data.status=success สำหรับผลเดียวกัน Callback GET แลกบัตรมี card_value เพิ่มด้วย

json
{
  "status": "completed",
  "request_id": "TOPUP_DEMO_001",
  "order_code": "R_DEMO_ORDER",
  "request_value": 100000,
  "amount": 92500,
  "account": {
    "game_id": "PLAYER_ID"
  },
  "callback_sign": "MD5_PARTNER_KEY_ORDER_CODE"
}
  1. ตรวจลายเซ็นด้วยคีย์ Merchant ที่ตรงกัน เปรียบเทียบอย่างปลอดภัย และตรวจว่ารหัสคำสั่งซื้ออยู่ในระบบของคุณ
  2. เรียก check/getstatus เพื่อยืนยันสถานะและเทียบมูลค่าบัตร/จำนวนเงินก่อนบันทึกผล ลายเซ็นที่รองรับย้อนหลังไม่ได้ลงนามครอบคลุมทุกฟิลด์สถานะ
  3. บันทึกภายในธุรกรรมฐานข้อมูล ป้องกันการบันทึก/เพิ่มเงินซ้ำ จากนั้นตอบ HTTP 2xx อย่างรวดเร็ว
  4. หาก callback ล่าช้าหรือสูญหาย ให้ค้นหาตามรอบ อย่าถือว่าการเชื่อมต่อขาดคือความล้มเหลว และอย่าสร้างคำสั่งซื้อใหม่

คิว Callback ลองใหม่ได้สูงสุด 12 ครั้ง โดยเพิ่มเวลารอแต่ละครั้ง Callback ของ Topup ยังขึ้นอยู่กับการตั้งค่า Callback ของสินค้า การซื้อรหัสบัตรรับผลผ่าน buycard/redownload

Python
import hashlib, hmac
expected = hashlib.md5((partner_key + payload["order_code"]).encode()).hexdigest()
valid = hmac.compare_digest(expected, str(payload.get("callback_sign", "")).lower())

6. รหัสข้อผิดพลาดและการแก้ปัญหา

อ่านทั้งรหัส HTTP, status, message และสถานะธุรกรรมภายใน data ห้ามใช้ตาราง status เดียวกับทุกบริการ เช่น Topup ใช้สตริง ส่วนรหัสบัตรใช้ตัวเลข

รหัสข้อผิดพลาดทั่วไปสาเหตุ
100ไม่พบสินค้าหรือคำขอแลกบัตรผิดพลาด; อ่าน message
101ไม่พบกระเป๋าอิเล็กทรอนิกส์
102ยอดกระเป๋าไม่พอ
103ข้อมูลไม่ครบ
104ข้อมูลที่ส่งไม่ถูกต้อง
108Merchant ไม่มีอยู่ ถูกปิด หรือไม่ถูกต้อง
109request_id มีอยู่แล้ว
110คำขอไม่ถูกต้อง ประเภท Merchant ไม่ตรง หรือไม่พบคำสั่งซื้อ
111wallet_number ไม่ตรงกันใน API รหัสบัตร
116ลายเซ็นไม่ถูกต้อง
117command ขาด/ผิด
118สินค้าหมดหรือยังไม่ให้บริการ
114IP ไม่ได้รับอนุญาต
129ไม่พบคำสั่งซื้อรหัสบัตร
130ข้อผิดพลาดผู้ให้บริการ
125จำนวนไม่ถูกต้อง
126จำนวนต้องเป็นจำนวนเต็มบวก
กรณีแนวทางดำเนินการ
HTTP 400ตรวจสอบข้อมูล ฟิลด์ลูกค้า ขีดจำกัดจำนวนเงิน และตัวเลือกสินค้า
HTTP 409 / request_id ซ้ำตรวจสอบคำสั่งซื้อเดิม ห้ามส่ง payload อื่นด้วยรหัสที่ใช้แล้ว
HTTP 503 / timeoutคงรหัสคำขอไว้ และกระทบยอดก่อนลองใหม่ สถานะการส่งให้ผู้ให้บริการอาจยังไม่ชัดเจน
มี API success แต่ยังเป็น pendingติดตามสถานะ/callback ต่อ; ธุรกรรมยังไม่เสร็จ
Sai signตรวจสอบคีย์บริการ ลำดับการต่อข้อความ request_id และ UTF-8 ให้ถูกต้อง
ราคาเปลี่ยนจากที่ดูก่อนหน้าดึงหมวดหมู่ตาม Merchant ใหม่ โดยกำหนดราคา ณ เวลารับคำสั่งซื้อ

ควรเว้นระยะค้นหาอย่างน้อยไม่กี่วินาที และเพิ่มเวลารอเมื่อยังไม่มีผลลัพธ์ เซิร์ฟเวอร์ของคุณต้องสร้างและบันทึก request_id ก่อนส่ง อย่าใช้การซื้อจริงทดสอบการเชื่อมต่อ; productlist/getbalance/getfee เป็นการตรวจสอบแบบอ่านอย่างเดียว

7. ตัวอย่างโค้ด

ตัวอย่าง Python เรียก getbalance อย่างปลอดภัยเพื่อตรวจการเชื่อมต่อ (ติดตั้ง requests ด้วย pip install requests) ใช้ตัวแปรสภาพแวดล้อมสำหรับข้อมูลส่วนตัว ห้ามเขียนคีย์ในซอร์สโค้ด

Python
import os, hashlib, requests
BASE = "https://toctoico.com"
partner_id = os.environ["GACHTHE_PARTNER_ID"]
partner_key = os.environ["GACHTHE_PARTNER_KEY"]

def recharge(command, **fields):
    request_id = str(fields.get("request_id", "")) if command in ("topup", "getstatus") else ""
    sign = hashlib.md5((partner_key + partner_id + command + request_id).encode()).hexdigest()
    payload = {**fields, "partner_id": partner_id, "command": command, "sign": sign}
    response = requests.post(BASE + "/api/rechargews", json=payload, timeout=20)
    result = response.json()
    response.raise_for_status()
    return result

print(recharge("getbalance"))
# Lưu request_id trước khi gọi topup. Sau đó lưu order_code trả về.
# Khi timeout: tra cứu/đối soát, không tạo request_id mới để mua lại.

PHP: ลายเซ็นและการส่ง JSON

PHP
<?php
$partnerId = getenv('GACHTHE_PARTNER_ID');
$partnerKey = getenv('GACHTHE_PARTNER_KEY');
$command = 'getbalance';
$payload = ['partner_id' => $partnerId, 'command' => $command,
    'sign' => md5($partnerKey . $partnerId . $command)];
$ch = curl_init('https://toctoico.com/api/rechargews');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS => json_encode($payload), CURLOPT_TIMEOUT => 20]);
$body = curl_exec($ch);
if ($body === false) { throw new RuntimeException('Chưa xác nhận được phản hồi API'); }
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
// Kiểm tra $status, $result['status'] và trạng thái đơn trong data nếu có.

cURL

cURL
curl --request POST 'https://toctoico.com/api/rechargews' \
  --header 'Content-Type: application/json' \
  --data '{"partner_id":"YOUR_PARTNER_ID","command":"getbalance","sign":"YOUR_COMPUTED_MD5"}' 

การแลกบัตรใช้สูตร charging/check แยกตามตารางลายเซ็น สูตรเดิม MD5(partner_key + code + serial) ยังใช้ได้ สำหรับซื้อรหัสบัตร ให้ใช้กฎต่อสตริงเดียวกับตารางลายเซ็นและ endpoint /api/cardws

8. ค้นหาซีเรียล

POST /api/checkcard. ใช้ได้เมื่อผู้ดูแลเปิดฟีเจอร์และอนุญาต Merchant แล้วเท่านั้น ความสามารถในการค้นหา วงเงิน และข้อมูลที่คืนขึ้นอยู่กับการตั้งค่าที่ได้รับอนุมัติ อย่าสรุปว่าบัตรยังไม่ได้ใช้จากการตอบกลับที่มีข้อมูลไม่ครบ

พารามิเตอร์คำขอความหมาย / ค่า
partner_idจำเป็นMerchant มีสิทธิ์
telcoKhi chargingรหัสประเภทบัตร
serialจำเป็นสตริงซีเรียล
signจำเป็นMD5(partner_key + serial)
json
{
  "partner_id": "YOUR_PARTNER_ID",
  "telco": "VIETTEL",
  "serial": "YOUR_CARD_SERIAL",
  "sign": "MD5_PARTNER_KEY_SERIAL"
}

ตรวจสอบ status, message และข้อมูลจริงที่คืนมา อย่าถือว่านี่เป็น API เติมบัตรหรือตรวจสอบ PIN ห้ามเปิดสิทธิ์เองหรือค้นหาเป็นจำนวนมาก

เอกสารตาม API ของระบบ · อัปเดต 30/10/2026 · โค้ดตัวอย่างและราคาใช้ประกอบคำอธิบายเท่านั้น