- หน้าแรก
- นักพัฒนา
เชื่อมต่อการรับชำระเงินด้วยคริปโตได้ในไม่กี่นาที
REST API ที่เข้ากันได้กับ NOWPayments v1: ใช้เอนด์พอยต์ ฟิลด์ ค่าสถานะ และรหัสสกุลเงินเดียวกัน ยืนยันตัวตนด้วย x-api-key และรับการอัปเดตสถานะผ่าน IPN ที่มีลายเซ็นกำกับ
https://omniwallet.ewin888.com/api/v1/https://omniwallet-dev.ewin888.com/api/v1/เริ่มต้นอย่างรวดเร็ว
- 01
รับคีย์ API
สมัครและเข้าสู่ระบบหลังบ้าน สร้างคีย์ที่เมนู “นักพัฒนา → คีย์ API” จากนั้นตั้งค่ารหัสลับ IPN ที่เมนู “IPN” เราแนะนำให้เชื่อมต่อระบบในสภาพแวดล้อมทดสอบก่อน
- 02
สร้างรายการชำระเงิน
เรียก
POST /v1/paymentพร้อมระบุยอดเงิน สกุลเงินที่ใช้ตั้งราคา และเหรียญที่ต้องการรับ ในข้อมูลที่ตอบกลับpay_addressคือที่อยู่เฉพาะของรายการนี้ และpay_amountคือยอดที่ต้องชำระPOST /v1/paymentcurlcurl -X POST "https://omniwallet.ewin888.com/api/v1/payment" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: order-A-1024" \ -d '{ "price_amount": 120, "price_currency": "usd", "pay_currency": "usdttrc20", "order_id": "A-1024", "order_description": "Pro plan, 12 months", "ipn_callback_url": "https://example.com/ipn" }'การตอบกลับJSON{ "payment_id": 355446374401130, "payment_status": "waiting", "pay_address": "TJ8nq3M5yVfQ9C2dWkPz7aH4sLrE6uXbGt", "price_amount": 120, "price_currency": "usd", "pay_amount": 120.02, "pay_currency": "usdttrc20", "order_id": "A-1024", "network": "TRC20", "expiration_estimate_date": "2026-10-02T09:15:00.000Z", "omni_payment_url": "https://omniwallet.ewin888.com/payment/4fKq9ZtR2mXcL8vBnW1pYs" } - 03
พาลูกค้าไปชำระเงิน
แสดงที่อยู่และยอดเงิน (หรือ QR) ให้ลูกค้า หรือจะใช้
POST /v1/invoiceสร้างหน้าใบแจ้งหนี้สำเร็จรูป แล้วพาลูกค้าไปยังinvoice_urlที่ได้จากการตอบกลับก็ได้POST /v1/invoicecurlcurl -X POST "https://omniwallet.ewin888.com/api/v1/invoice" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "price_amount": 49.9, "price_currency": "usd", "order_id": "A-1025", "order_description": "Starter plan", "ipn_callback_url": "https://example.com/ipn", "success_url": "https://example.com/thanks", "cancel_url": "https://example.com/cart" }'การตอบกลับJSON{ "id": "355447603200201", "order_id": "A-1025", "price_amount": "49.9", "price_currency": "usd", "pay_currency": null, "invoice_url": "https://omniwallet.ewin888.com/invoice/8hTz2QpLm4XwN7cVb1RkYe", "success_url": "https://example.com/thanks", "cancel_url": "https://example.com/cart", "created_at": "2026-10-01T09:20:00.000Z" } - 04
รับ IPN
ทุกครั้งที่สถานะการชำระเงินเปลี่ยน เราจะส่งคำขอ POST ไปยัง
ตรวจสอบ IPNipn_callback_urlของคุณ โปรดตรวจสอบลายเซ็นก่อน แล้วจึงอัปเดตคำสั่งซื้อตามpayment_status - 05
สลับไปใช้สภาพแวดล้อมจริง
เมื่อผ่านการยืนยันตัวตนธุรกิจแล้ว ให้สร้างคีย์ API และรหัสลับ IPN ใหม่ในสภาพแวดล้อมจริง แล้วเปลี่ยน URL หลักเป็นของสภาพแวดล้อมจริง
ตรวจสอบลายเซ็น IPN
เราใช้รหัสลับ IPN ของคุณคำนวณ HMAC-SHA512 จาก “JSON ที่เรียงคีย์ตามลำดับตัวอักษร” แล้วใส่ค่าเป็นสตริงเลขฐานสิบหกในเฮดเดอร์ x-omni-sig เนื้อหาคำขอที่เราส่งไปคือ JSON ที่เรียงลำดับแล้วนี้ คุณจึงตรวจสอบกับเนื้อหาดิบที่ได้รับได้โดยตรง
- เปรียบเทียบลายเซ็นด้วยวิธีที่ใช้เวลาคงที่
- IPN อาจถูกส่งซ้ำหรือมาถึงไม่ตามลำดับ: ให้ตัดรายการซ้ำโดยใช้
payment_idและสถานะ และเรียกGET /v1/payment/{id}เพื่อดูสถานะล่าสุดเมื่อจำเป็น - การตอบกลับด้วยรหัส 2xx ใด ๆ ถือว่าได้รับ IPN แล้ว ส่วนการตอบกลับอื่นหรือกรณีหมดเวลาจะมีการส่งใหม่โดยอัตโนมัติ
import crypto from 'node:crypto';
import express from 'express';
const app = express();
const IPN_SECRET = process.env.OMNI_IPN_SECRET;
// Keep the raw body: the signature covers the exact bytes we send.
app.post('/ipn', express.raw({ type: 'application/json' }), (req, res) => {
const received = String(req.get('x-omni-sig') || '');
const expected = crypto
.createHmac('sha512', IPN_SECRET)
.update(req.body)
.digest('hex');
const valid = received.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(received), Buffer.from(expected));
if (!valid) return res.status(401).send('invalid signature');
const payment = JSON.parse(req.body.toString('utf8'));
// Idempotent update: the same status can be delivered more than once.
// await orders.applyStatus(payment.order_id, payment.payment_status);
res.sendStatus(200);
});
app.listen(3000);<?php
$secret = getenv('OMNI_IPN_SECRET');
$raw = file_get_contents('php://input');
$received = $_SERVER['HTTP_X_OMNI_SIG'] ?? '';
// The signature covers the exact bytes we send.
$expected = hash_hmac('sha512', $raw, $secret);
if (!hash_equals($expected, $received)) {
http_response_code(401);
exit('invalid signature');
}
$payment = json_decode($raw, true);
// Idempotent update: the same status can be delivered more than once.
// apply_status($payment['order_id'], $payment['payment_status']);
http_response_code(200);import hashlib
import hmac
import json
import os
from flask import Flask, abort, request
app = Flask(__name__)
IPN_SECRET = os.environ["OMNI_IPN_SECRET"].encode()
@app.post("/ipn")
def ipn():
raw = request.get_data() # the exact bytes we signed
expected = hmac.new(IPN_SECRET, raw, hashlib.sha512).hexdigest()
received = request.headers.get("x-omni-sig", "")
if not hmac.compare_digest(expected, received):
abort(401)
payment = json.loads(raw)
# Idempotent update: the same status can be delivered more than once.
# apply_status(payment["order_id"], payment["payment_status"])
return "", 200{
"actually_paid": 120.02,
"actually_paid_at_fiat": 120,
"invoice_id": null,
"order_description": "Pro plan, 12 months",
"order_id": "A-1024",
"outcome_amount": 119.42,
"outcome_currency": "usdttrc20",
"parent_payment_id": null,
"pay_address": "TJ8nq3M5yVfQ9C2dWkPz7aH4sLrE6uXbGt",
"pay_amount": 120.02,
"pay_currency": "usdttrc20",
"payment_id": 355446374401130,
"payment_status": "finished",
"price_amount": 120,
"price_currency": "usd",
"purchase_id": null,
"updated_at": "2026-10-01T09:17:42.000Z"
}สถานะการชำระเงิน
ค่าสถานะเหมือนกับ NOWPayments
| สถานะ | ความหมาย |
|---|---|
waitingรอชำระเงิน | รอลูกค้าชำระเงิน |
confirmingกำลังยืนยัน | ตรวจพบธุรกรรมแล้ว กำลังรอการยืนยันบล็อก |
confirmedยืนยันแล้ว | ยืนยันยอดเงินเข้าแล้ว |
sendingกำลังชำระบัญชี | กำลังโอนเข้าวอลเล็ตของคุณ |
partially_paidชำระบางส่วน | ชำระไม่ครบ ลูกค้าสามารถชำระส่วนที่ขาดได้ก่อนหมดอายุ |
finishedเสร็จสมบูรณ์ | ชำระเงินเสร็จสมบูรณ์ |
failedไม่สำเร็จ | ชำระเงินไม่สำเร็จ เช่น ตรงกับรายชื่อผู้ถูกคว่ำบาตร |
refundedคืนเงินแล้ว | คืนเงินให้ผู้ชำระแล้ว |
expiredหมดอายุ | ไม่ได้ชำระภายในเวลาที่กำหนด |
ย้ายระบบจาก NOWPayments
API เข้ากันได้ โค้ดส่วนใหญ่จึงไม่ต้องแก้ไข
- เปลี่ยน URL หลักแทนที่
https://api.nowpayments.io/v1/ด้วย URL ของ OmniWallet ด้านล่าง - ใช้คีย์ API ของ OmniWalletชื่อเฮดเดอร์ยังคงเป็น
x-api-keyเหมือนเดิม - อัปเดตการตรวจสอบ IPNเปลี่ยนไปใช้รหัสลับ IPN ของ OmniWallet และเฮดเดอร์
x-omni-sigหากต้องการให้โค้ดเดิมทำงานต่อได้โดยไม่ต้องแก้ไขเลย สามารถเปิดใช้เฮดเดอร์x-nowpayments-sigเพื่อความเข้ากันได้ในระบบหลังบ้าน - ตรวจสอบเหรียญที่รองรับรหัสสกุลเงินเหมือนเดิม (เช่น
usdttrc20,usdcsol) แต่ใช้ได้เฉพาะเหรียญที่เรารองรับเท่านั้น โปรดตรวจสอบด้วยGET /v1/merchant/coinsหรือที่หน้า เหรียญที่รองรับ - ตรวจสอบการตั้งค่าการจ่ายเงินออกการจ่ายเงินออกยังคงใช้ JWT อายุ 5 นาทีที่ได้จาก
POST /v1/authเช่นเดิม นอกจากนี้ คีย์ API ที่มีสิทธิ์จ่ายเงินออกต้องตั้งค่าไวท์ลิสต์ IP และต้องเพิ่มที่อยู่ผู้รับเงินลงในไวท์ลิสต์ก่อน
- https://api.nowpayments.io/v1/
+ https://omniwallet.ewin888.com/api/v1/สิ่งที่เหมือนเดิม
- พาธของเอนด์พอยต์และเมธอด HTTP
- ชื่อฟิลด์ในคำขอและการตอบกลับ
- ค่าสถานะของการชำระเงินและการจ่ายเงินออก
- รหัสสกุลเงิน
- อัลกอริทึมลายเซ็น IPN
ความแตกต่างที่ควรทราบ
- เฮดเดอร์ลายเซ็น IPN คือ
x-omni-sig(เลือกให้ส่งx-nowpayments-sigมาพร้อมกันได้) - ฟิลด์ส่วนขยายของ OmniWallet ขึ้นต้นด้วย
omni_ - ไม่รองรับการจ่ายเงินออกเป็นสกุลเงินเฟียต (ตอบกลับด้วย HTTP 501)
- การชำระบัญชีจะโอนเข้าวอลเล็ตที่ผูกไว้ในระบบหลังบ้านเสมอ
- สภาพแวดล้อมทดสอบใช้เทสต์เน็ตจริงของบล็อกเชน
สภาพแวดล้อมทดสอบ (Sandbox)
สภาพแวดล้อมทดสอบเป็นระบบที่ติดตั้งแยกต่างหาก เชื่อมต่อกับเทสต์เน็ตของแต่ละเชน และมี API เหมือนกับสภาพแวดล้อมจริงทุกประการ
- บัญชี คีย์ API และข้อมูลแยกจากสภาพแวดล้อมจริง จึงต้องสมัครแยกต่างหาก และการยืนยันตัวตนธุรกิจจะได้รับการอนุมัติโดยอัตโนมัติ
- ชำระเงินด้วยเหรียญทดสอบของแต่ละเทสต์เน็ต และตรวจสอบธุรกรรมได้ในตัวสำรวจบล็อกของเทสต์เน็ตนั้น
- เหรียญทดสอบไม่มีมูลค่าจริง โปรดอย่าโอนสินทรัพย์บนเมนเน็ตมายังที่อยู่ในสภาพแวดล้อมทดสอบ
| เครือข่าย | เทสต์เน็ต | รหัสสกุลเงินที่ใช้ได้ |
|---|---|---|
| Ethereum | Ethereum Sepolia | eth usdc |
| BNB Smart Chain | BNB Smart Chain Testnet | bnbbsc usdtbsc |
| Polygon | Polygon Amoy | maticmainnet usdcmatic |
| Avalanche C-Chain | Avalanche Fuji | avax usdcavax |
| Arbitrum | Arbitrum Sepolia | etharb usdcarb |
| Base | Base Sepolia | ethbase usdcbase |
| Optimism | OP Sepolia | ethop usdcop |
| TRON | TRON Nile | trx usdttrc20 |
| Solana | Solana Devnet | sol usdcsol |
| Bitcoin | Bitcoin Testnet4 | btc |
การป้องกันรายการซ้ำและการลองใหม่
คำขอ POST ทุกรายการที่สร้างทรัพยากรสามารถแนบเฮดเดอร์ Idempotency-Key ได้ หากเครือข่ายหมดเวลา ให้ส่งซ้ำด้วยคีย์เดิม ระบบจะไม่สร้างรายการชำระเงินหรือรายการจ่ายเงินออกซ้ำ
- คีย์เดียวกัน เนื้อหาเดียวกัน: ส่งคืนผลลัพธ์ของคำขอครั้งแรก
- คีย์เดียวกัน แต่เนื้อหาต่างกัน: ตอบกลับด้วย 422
IDEMPOTENCY_KEY_REUSED - คำขอแรกยังประมวลผลอยู่: ตอบกลับด้วย 409
IDEMPOTENCY_IN_FLIGHTโปรดลองใหม่อีกครั้งในภายหลัง
POST /api/v1/payout HTTP/1.1
Host: omniwallet.ewin888.com
x-api-key: YOUR_API_KEY
Authorization: Bearer YOUR_JWT
Idempotency-Key: 6c0a8e6e-3f5b-4f7a-9a52-1f0c2d9b7e41
Content-Type: application/json