API tương thích Coinbase Commerce

Mở trong ChatGPTMở trong Claude

Các endpoint charge, header X-CC-Api-Key, đối tượng charge và webhook ký bằng X-CC-Webhook-Signature đều theo tài liệu của Coinbase Commerce, nên các SDK chính thức hoạt động sau khi đổi một dòng. Coinbase Commerce đã ngừng phục vụ người bán ngoài Hoa Kỳ và Singapore từ ngày 2026-03-31. Đến từ nơi khác? Xem tổng quan chuyển đổi.

Bên dưới đó là một hóa đơn blockwallets bình thường: địa chỉ nhận tiền là của bạn, trang thanh toán là trang thanh toán do chúng tôi lưu trữ, và một khoản thanh toán chỉ được tính khi đã được xác nhận trên chuỗi và đối chiếu với node thứ hai. Phần dưới gồm: ba bước, rồi từng API hỗ trợ gì và khác bản gốc ở đâu — tham số chúng tôi không triển khai sẽ trả về lỗi chứ không bị bỏ qua âm thầm.

Ba bước

  1. Có tài khoản người bán (đăng ký dùng ở trang chủ) và thêm tên miền của bạn trong “Tên miền website” ở “Nhà phát triển › Tích hợp & khóa” trong trang quản trị. URL callback (ipn_callback_url) và URL chuyển hướng (success_url / cancel_url / redirect_url) phải thuộc các tên miền đó hoặc tên miền của URL callback của bạn — khóa bị lộ cũng không thể trỏ webhook sang nơi khác.
  2. Tạo thông tin xác thực tương thích trong trang quản trị ở mục “Nhà phát triển › Tích hợp & khóa”, một bộ cho live và một bộ cho thử nghiệm: NOWPayments dùng API key + IPN secret, Coinbase Commerce dùng API key + webhook shared secret. Chúng chỉ hiển thị một lần; chúng tôi chỉ lưu giá trị băm / bản mã hóa.
  3. Trỏ code của bạn đến URL gốc bên dưới và dùng khóa mới. Chạy thử trên testnet bằng thông tin xác thực thử nghiệm trước, rồi mới chuyển sang live.
TrướcSauHeader xác thựcChữ ký webhook
https://api.commerce.coinbase.comhttps://blockwallets.io/coinbase/X-CC-Api-KeyX-CC-Webhook-Signature (HMAC-SHA256)

Coinbase Commerce

Mọi SDK chính thức đều nhận một URL gốc — chỉ đổi một dòng (chú ý dấu / ở cuối):

SDK
// Node(coinbase-commerce-node)
const { Client } = require("coinbase-commerce-node");
- Client.init(process.env.COINBASE_COMMERCE_API_KEY);
+ Client.init(process.env.COINBASE_COMMERCE_API_KEY, "https://blockwallets.io/coinbase/");

# Python(coinbase-commerce)
- client = Client(api_key=API_KEY)
+ client = Client(api_key=API_KEY, base_api_uri="https://blockwallets.io/coinbase/")

// PHP(coinbase/coinbase-commerce)
- ApiClient::init($apiKey);
+ ApiClient::init($apiKey, 'https://blockwallets.io/coinbase/');
curl
curl -X POST https://blockwallets.io/coinbase/charges \
  -H "X-CC-Api-Key: $COINBASE_COMMERCE_API_KEY" -H "X-CC-Version: 2018-03-22" \
  -H "content-type: application/json" \
  -d '{"name":"Order #12345","description":"Pro plan","pricing_type":"fixed_price",
       "local_price":{"amount":"100.00","currency":"USD"},
       "redirect_url":"https://shop.example/success","cancel_url":"https://shop.example/cancel",
       "metadata":{"order_id":"12345"}}'
# → 201 {"data": {"id": "…", "code": "7C7V5ECK", "hosted_url": "https://blockwallets.io/pay/inv_…", "timeline": [{"status": "NEW", …}], …}}

Endpoint được hỗ trợ

EndpointGhi chú
POST /chargesTạo charge; hosted_url là trang thanh toán do chúng tôi lưu trữ; có hiệu lực 1 giờ
GET /charges/:code_or_idTra cứu theo mã 8 ký tự hoặc id
GET /chargesDanh sách: limit (≤100) / starting_after / ending_before / order, với cùng đối tượng pagination
POST /charges/:code_or_id/cancelHủy charge chưa thấy khoản thanh toán nào

Không có: /charges/:code/resolve (400 — hãy xử lý charge trả thiếu trong trang quản trị), /checkouts, /events, /invoices (404).

Webhook

Webhook của Coinbase ở cấp tài khoản, và của chúng tôi cũng vậy: chúng đến URL callback đặt trong trang quản trị của bạn (charge tạo bằng thông tin xác thực thử nghiệm đến URL callback thử nghiệm). Nội dung là {id, scheduled_for, attempt_number, event: {id, type, api_version, created_at, data}} của Coinbase, với charge đầy đủ trong data; X-CC-Webhook-Signature = HMAC-SHA256(shared secret, nội dung thô), nên Webhook.verifyEventBody của các SDK dùng được nguyên trạng. Khi thử lại, event.id giữ nguyên còn attempt_number tăng lên — hãy loại trùng theo event.id.

Node.js
import crypto from "node:crypto";

// Same as the SDK's Webhook.verifySigHeader: HMAC-SHA256(shared secret, raw body)
function verifyWebhook(rawBody, sig, sharedSecret) {
  const hmac = crypto.createHmac("sha256", sharedSecret).update(rawBody, "utf8").digest("hex");
  return crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(sig || ""));
}
// verifyWebhook(rawBody, req.headers["x-cc-webhook-signature"], process.env.COINBASE_WEBHOOK_SECRET)
// or with the official SDK:Webhook.verifyEventBody(rawBody, signature, sharedSecret)
Sự kiệnKhi nàoMục cuối trong timeline
charge:confirmedĐã thanh toán (được xác nhận trên chuỗi và đối chiếu; trả dư vẫn tính)COMPLETED
charge:failedHết hạn chưa thanh toán / bạn đã hủy / hết hạn khi trả thiếuEXPIRED / CANCELED / UNRESOLVED (context UNDERPAID)

Khi truy vấn bạn còn thấy NEW (chờ thanh toán) và PENDING (đã thấy thanh toán trên chuỗi, đang xác nhận). Hãy giao hàng khi nhận charge:confirmed: chúng tôi không gửi charge:created, charge:pending, charge:delayed hay charge:resolved.

Khác biệt so với Coinbase Commerce

Chế độ thử nghiệm

Charge và thanh toán tạo bằng thông tin xác thực thử nghiệm chạy trên testnet của từng chuỗi và webhook của chúng được ký bằng IPN secret / shared secret thử nghiệm — tách biệt hoàn toàn với live: khóa thử nghiệm không thấy được các khoản thanh toán live.

Mọi thứ còn lại (trang thanh toán, xác nhận, mạng và mức tối thiểu, hoàn tiền) hoạt động như trong tài liệu chính.