นักพัฒนา
API รับชำระคริปโตที่สร้างมาเพื่อการรับเงินโดยตรง
สร้างใบแจ้งหนี้ด้วยคำขอที่ยืนยันตัวตนเพียงครั้งเดียว แล้ว Unheld จะคืนที่อยู่ที่ต้องจ่าย จำนวนเงินที่แน่นอน และจำนวนการยืนยันที่ระบบจะรอ เงินเข้ากระเป๋าที่คุณควบคุมโดยตรง — API ไม่เคยถือครองสิ่งที่มันรายงานเลย
สร้างใบแจ้งหนี้
POST เดียว จำนวนเงินเขียนแบบที่คนเขียนกัน และถูกแปลงตามทศนิยมของสินทรัพย์นั้นที่ฝั่งเซิร์ฟเวอร์ คุณจึงไม่ต้องแปลงเป็นหน่วยฐานเองเลย
curl -X POST https://api.unheld.io/api/v1/invoices \
-H "Authorization: Bearer $UNHELD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chainId": "11155111",
"assetType": "native",
"amountDecimal": "0.05",
"expiresInSeconds": 900,
"metadata": { "orderId": "A-1043" }
}'การตอบกลับ
{
"id": "e2b0…",
"status": "CREATED",
"receiveAddress": "0x…",
"expectedAmount": "50000000000000000",
"minConfirmations": 3,
"expiresAt": "2026-08-10T14:15:00.000Z",
"instructions": {
"chainId": "11155111",
"to": "0x…",
"amount": "50000000000000000",
"assetType": "native"
}
}receiveAddress สร้างจากกระเป๋าเงินของคุณและผูกกับใบแจ้งหนี้นี้ ส่วน expectedAmount เป็นหน่วยฐาน และ minConfirmations คือเกณฑ์ของเครือข่ายเอง ไม่ใช่ค่าที่เราตั้งขึ้น
การยืนยันตัวตนและขอบเขตสิทธิ์
คีย์เป็น bearer token สร้างในแดชบอร์ดและแสดงเพียงครั้งเดียว ทุกคีย์มีรายการขอบเขตสิทธิ์ที่ชัดเจน และคำขอจะถูกปฏิเสธหากคีย์ไม่มีสิทธิ์สำหรับเส้นทางนั้น
ขอบเขตสิทธิ์ที่มี
- invoices:write
- invoices:read
- webhooks:write
- webhooks:read
- balances:read
- customers:write
- customers:read
- subscriptions:write
- subscriptions:read
ให้สิทธิ์แคบที่สุดเท่าที่ยังทำงานได้ คีย์ที่สร้างใบแจ้งหนี้อย่างเดียวจะอ่านข้อมูลลูกค้าไม่ได้ และคีย์อ่านที่หลุดออกไปก็ย้ายอะไรไม่ได้ เพราะไม่มีอะไรใน API นี้ที่ย้ายเงินได้
webhook ที่ตรวจสอบได้
ทุกการส่งมีลายเซ็น ลายเซ็นคือ HMAC-SHA256 ของ timestamp และเนื้อหาดิบต่อกันด้วยจุด โดยใช้ secret ของ webhook คุณ และส่งมาเป็นเลขฐานสิบหก
ตรวจสอบการส่งหนึ่งครั้ง
const signature = crypto
.createHmac("sha256", webhookSecret)
.update(`${req.headers["x-timestamp"]}.${rawBody}`)
.digest("hex");
crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(req.headers["x-signature"])
);เปรียบเทียบ digest แบบเวลาคงที่ ปฏิเสธ timestamp ที่อยู่นอกกรอบเวลาที่คุณยอมรับ และใช้ X-Request-Id เป็นคีย์กันซ้ำ เพราะการส่งซ้ำจะใช้ค่าเดิม ดังนั้นการที่เหตุการณ์เดียวกันมาถึงสองครั้งเป็นเรื่องปกติและต้องไม่ประมวลผลซ้ำ
เหตุการณ์ของใบแจ้งหนี้
การชำระเงินเคลื่อนผ่านสถานะต่าง ๆ แทนที่จะพลิกจากยังไม่จ่ายเป็นจ่ายแล้วทันที และทุกการเปลี่ยนสถานะคือ webhook การจ่ายขาดและจ่ายเกินเป็นเหตุการณ์ของตัวเอง ไม่ใช่ข้อผิดพลาด
| เหตุการณ์ | เกิดอะไรขึ้น |
|---|---|
| invoice.created | ใบแจ้งหนี้ถูกสร้างแล้วและที่อยู่รับเงินกำลังถูกเฝ้าดู |
| invoice.receiving | พบธุรกรรมการจ่ายบนเครือข่ายแล้วแต่ยังไม่ได้รับการยืนยัน |
| invoice.confirming | การชำระเงินกำลังได้รับการยืนยันและยังไม่ถึงเกณฑ์ของเครือข่าย |
| invoice.paid | ยืนยันครบตามความลึกที่เครือข่ายกำหนดแล้ว ส่งมอบได้อย่างปลอดภัย |
| invoice.underpaid | เงินเข้ามาน้อยกว่าที่คาด การจ่ายบางส่วนจะสะสมรวมกัน การโอนครั้งที่สองจึงทำให้ครบได้ |
| invoice.overpaid | เงินเข้ามามากกว่าที่คาด บันทึกไว้อย่างแม่นยำแทนที่จะปัดทิ้ง |
| invoice.expired | หมดเวลาโดยยังชำระไม่ครบ |
ทดสอบทั้งกระบวนการฟรี
ทดสอบใบแจ้งหนี้ การตรวจพบ การยืนยัน และ webhook โดยไม่ใช้เงินจริง โทเค็น testnet ไม่มีมูลค่า กิจกรรม testnet ไม่ใช่การชำระเงินจริง
ขอบเขต
- มันไม่เคยถือเงิน ไม่มี endpoint ยอดคงเหลือให้ถอน เพราะเงินเข้าที่อยู่ของคุณและอยู่ตรงนั้น
- มันไม่แปลงและไม่ชำระบัญชีเป็นเงินตราปกติ เงินมาถึงเป็นสินทรัพย์และบนเครือข่ายที่ส่งมา
- ยังไม่มี SDK อย่างเป็นทางการ ทุกอย่างที่นี่เป็น HTTP ล้วน และเราเผยแพร่ตัวอย่างแทนที่จะทำแพ็กเกจที่เราจะดูแลได้ไม่ดี
คำถามจากนักพัฒนา
มี sandbox ไหม
ทดสอบใบแจ้งหนี้ การตรวจพบ การยืนยัน และ webhook โดยไม่ใช้เงินจริง โทเค็น testnet ไม่มีมูลค่า กิจกรรม testnet ไม่ใช่การชำระเงินจริง
จะเลี่ยงการประมวลผล webhook เดิมซ้ำได้อย่างไร
ใช้ X-Request-Id เป็นคีย์กันซ้ำ การส่งซ้ำจะใช้ค่าเดิม ดังนั้นให้บันทึกไว้แล้วข้ามรายการที่ซ้ำ การส่งซ้ำเป็นเรื่องที่คาดหมายได้ เพราะการส่งที่ล้มเหลวจะถูกลองใหม่ตามกำหนดเวลาแทนที่จะถูกทิ้ง
ต้องแปลงจำนวนเงินเป็นหน่วยฐานเองไหม
ไม่ต้อง ส่ง amountDecimal แบบที่คนเขียน แล้ว API จะแปลงตามทศนิยมของสินทรัพย์เอง การตอบกลับจะคืน expectedAmount เป็นหน่วยฐาน ทั้งสองรูปแบบจึงชัดเจนและไม่มีทางคลาดเคลื่อนจากกัน
ตรวจสอบตัวอย่างกับ API จริงเมื่อ .
เริ่มพัฒนาบน testnet ก่อน
สร้างคีย์ ชี้ไปที่เครือข่าย testnet แล้วไล่ทั้งกระบวนการก่อนที่อะไรจริง ๆ จะเคลื่อนไหว
เริ่มใช้ฟรี