Coinbase Commerce 호환 API
charge 엔드포인트, X-CC-Api-Key 헤더, charge 객체, X-CC-Webhook-Signature로 서명되는 웹훅이 Coinbase Commerce 문서를 따르므로 공식 SDK는 한 줄만 바꾸면 동작합니다. Coinbase Commerce는 2026-03-31부터 미국과 싱가포르 밖의 가맹점에 서비스를 제공하지 않습니다. 다른 곳에서 오셨나요? 이전 개요를 참고하세요.
내부적으로는 일반 blockwallets 청구서입니다. 수신 주소는 당신의 것이고, 결제 페이지는 저희가 호스팅하는 결제 페이지이며, 결제는 체인에서 컨펌되고 두 번째 노드와 교차 확인된 뒤에야 인정됩니다. 아래에서 세 단계를 설명하고, 이어서 각 API가 지원하는 범위와 원래 서비스와 어떻게 다른지를 설명합니다. 구현하지 않은 매개변수는 조용히 무시하지 않고 오류를 돌려줍니다.
세 단계
- 가맹점 계정을 만들고(홈페이지에서 신청) 관리 화면 “개발자 › 연동 및 키”의 “웹사이트 도메인”에 도메인을 추가합니다. 콜백 URL(
ipn_callback_url)과 리디렉션 URL(success_url/cancel_url/redirect_url)은 이 도메인이나 콜백 URL의 도메인에 속해야 합니다. 키가 유출되어도 웹훅을 다른 곳으로 보낼 수 없습니다. - 가맹점 관리 화면의 “개발자 › 연동 및 키”에서 호환 자격 증명을 만듭니다. 실서비스용 한 세트와 테스트용 한 세트입니다. NOWPayments는 API key + IPN secret, Coinbase Commerce는 API key + 웹훅 공유 시크릿을 받습니다. 한 번만 표시되며 저희는 해시 / 암호문만 보관합니다.
- 코드가 아래 기본 URL을 가리키게 하고 새 키를 사용합니다. 먼저 테스트 자격 증명으로 테스트넷에서 실행해 본 다음 실서비스로 전환하세요.
| 이전 | 이후 | 인증 헤더 | 웹훅 서명 |
|---|---|---|---|
https://api.commerce.coinbase.com | https://blockwallets.io/coinbase/ | X-CC-Api-Key | X-CC-Webhook-Signature (HMAC-SHA256) |
Coinbase Commerce
공식 SDK는 모두 기본 URL을 지정할 수 있으니 한 줄만 바꾸세요(끝의 /에 주의).
// 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 -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", …}], …}}지원하는 엔드포인트
| 엔드포인트 | 비고 |
|---|---|
POST /charges | charge 생성. hosted_url은 저희가 호스팅하는 결제 페이지이며 유효 시간 1시간 |
GET /charges/:code_or_id | 8자리 code 또는 id로 조회 |
GET /charges | 목록: limit (100 이하) / starting_after / ending_before / order, 같은 pagination 객체 포함 |
POST /charges/:code_or_id/cancel | 결제가 아직 감지되지 않은 charge 취소 |
제공하지 않음: /charges/:code/resolve(400 — 부족 결제된 charge는 관리 화면에서 처리), /checkouts, /events, /invoices(404).
웹훅
Coinbase 웹훅은 계정 단위이고 저희도 마찬가지입니다. 관리 화면에 설정한 콜백 URL로 갑니다(테스트 자격 증명으로 만든 charge는 테스트 콜백 URL로 감). 본문은 Coinbase 형식의 {id, scheduled_for, attempt_number, event: {id, type, api_version, created_at, data}}이며 data에 charge 전체가 들어 있습니다. X-CC-Webhook-Signature = HMAC-SHA256(공유 시크릿, 원문 본문)이므로 SDK의 Webhook.verifyEventBody를 그대로 쓸 수 있습니다. 재시도할 때 event.id는 그대로이고 attempt_number만 올라가니 event.id로 중복을 제거하세요.
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)| 이벤트 | 언제 | 마지막 타임라인 항목 |
|---|---|---|
charge:confirmed | 결제 완료(체인에서 컨펌되고 교차 확인됨. 초과 결제 포함) | COMPLETED |
charge:failed | 결제 없이 만료됨 / 당신이 취소함 / 부족 결제로 만료됨 | EXPIRED / CANCELED / UNRESOLVED (context UNDERPAID) |
조회하면 NEW(결제 대기)와 PENDING(체인에서 결제가 보이고 컨펌 중)도 볼 수 있습니다. charge:confirmed에서 이행하세요. charge:created, charge:pending, charge:delayed, charge:resolved는 보내지 않습니다.
Coinbase Commerce와의 차이점
pricing_type은fixed_price여야 하고local_price.currency는 USD여야 합니다(USDC / USDT는 1:1).no_price와 다른 법정화폐는 400을 돌려줍니다.- 주소는 고객이 결제 페이지에서 코인과 네트워크를 고른 뒤에 나타납니다.
addresses에는 그 네트워크만 들어가고,pricing에는 고른 뒤에만local과settlement이 들어갑니다.exchange_rates,checkout, 브랜딩 필드는 없습니다. metadata는 그대로 저장하고 돌려줍니다(최대 4 KB).- 환불은 타임라인에 나타나지 않으니 관리 화면에서 확인하세요.
테스트 모드
테스트 자격 증명으로 만든 charge와 결제는 각 체인의 테스트넷에서 동작하며 웹훅은 테스트 IPN secret / 공유 시크릿으로 서명됩니다. 실서비스와 완전히 분리되어 있어 테스트 키로는 실서비스 결제를 볼 수 없습니다.
나머지(결제 페이지, 컨펌, 네트워크와 최소 금액, 환불)는 메인 문서와 같습니다.