NOWPayments 호환 API

ChatGPT에서 열기Claude에서 열기

경로, x-api-key 헤더, 요청과 응답 필드, 상태, x-nowpayments-sig IPN 서명이 NOWPayments 문서를 따르므로 기존 코드는 대개 새 기본 URL, API key, IPN secret만 있으면 됩니다. 다른 곳에서 오셨나요? 이전 개요를 참고하세요.

내부적으로는 일반 blockwallets 청구서입니다. 수신 주소는 당신의 것이고, 결제 페이지는 저희가 호스팅하는 결제 페이지이며, 결제는 체인에서 컨펌되고 두 번째 노드와 교차 확인된 뒤에야 인정됩니다. 아래에서 세 단계를 설명하고, 이어서 각 API가 지원하는 범위와 원래 서비스와 어떻게 다른지를 설명합니다. 구현하지 않은 매개변수는 조용히 무시하지 않고 오류를 돌려줍니다.

세 단계

  1. 가맹점 계정을 만들고(홈페이지에서 신청) 관리 화면 “개발자 › 연동 및 키”의 “웹사이트 도메인”에 도메인을 추가합니다. 콜백 URL(ipn_callback_url)과 리디렉션 URL(success_url / cancel_url / redirect_url)은 이 도메인이나 콜백 URL의 도메인에 속해야 합니다. 키가 유출되어도 웹훅을 다른 곳으로 보낼 수 없습니다.
  2. 가맹점 관리 화면의 “개발자 › 연동 및 키”에서 호환 자격 증명을 만듭니다. 실서비스용 한 세트와 테스트용 한 세트입니다. NOWPayments는 API key + IPN secret, Coinbase Commerce는 API key + 웹훅 공유 시크릿을 받습니다. 한 번만 표시되며 저희는 해시 / 암호문만 보관합니다.
  3. 코드가 아래 기본 URL을 가리키게 하고 새 키를 사용합니다. 먼저 테스트 자격 증명으로 테스트넷에서 실행해 본 다음 실서비스로 전환하세요.
이전이후인증 헤더웹훅 서명
https://api.nowpayments.io/v1https://blockwallets.io/nowpayments/v1x-api-keyx-nowpayments-sig (HMAC-SHA512)

NOWPayments

JavaScript
- const NP = "https://api.nowpayments.io/v1";
+ const NP = "https://blockwallets.io/nowpayments/v1";

const res = await fetch(`${NP}/payment`, {
  method: "POST",
  headers: { "x-api-key": process.env.NOWPAYMENTS_API_KEY, "content-type": "application/json" },
  body: JSON.stringify({
    price_amount: 49.9, price_currency: "usd", pay_currency: "usdttrc20",
    order_id: "A-1001", order_description: "Pro plan",
    ipn_callback_url: "https://shop.example/ipn/nowpayments",
  }),
});
const { payment_id, pay_address, pay_amount } = await res.json();

지원하는 엔드포인트

엔드포인트비고
GET /status{"message":"OK"}, 키 불필요
GET /currencies · /merchant/coins · /full-currencies지금 받을 수 있는 코인(아래 티커). fixed_rate는 무시됨
GET /min-amount · GET /estimate최소 금액과 견적. USD 가격만 지원(USDT / USDC는 1:1)
POST /payment결제 생성. pay_address / pay_amount를 바로 돌려줌(화이트 라벨)
POST /invoice인보이스 생성. invoice_url은 저희가 호스팅하는 결제 페이지이며 고객이 코인과 네트워크를 고름
POST /invoice-payment인보이스에 쓸 코인을 정하고 결제를 돌려줌
GET /payment/:id결제 상태
GET /payment/목록: limit (1–500) / page / orderBy / dateFrom / dateTo / invoiceId. sortBy는 created_at만
POST /auth목록 조회에는 x-api-key만 필요하고 JWT는 필요 없습니다. 이 엔드포인트는 검증하지 않는 자리표시자 토큰을 돌려주어 “로그인 후 목록 조회” 코드가 계속 동작하게 합니다(이메일 / 비밀번호는 검사하지 않음)

제공하지 않음: 지급(payout), 환전, 수탁 하위 파트너, 구독, update-merchant-estimate, 법정화폐 결제. 이 경로는 404를 돌려줍니다.

IPN 콜백

결제가 최종 상태에 도달하면 생성할 때 지정한 ipn_callback_url로 POST하며, x-nowpayments-sig = HMAC-SHA512(IPN secret, 키 기준으로 재귀 정렬한 JSON)입니다. NOWPayments의 검증 코드와 똑같습니다. 저희가 보내는 본문은 이미 정렬된 compact JSON이므로 원문 본문에 대한 HMAC도 통합니다(아주 작은 소수를 다시 인코딩하면 JS와 결과가 다를 수 있는 PHP / Python에서는 이쪽이 가장 안전합니다). 실패한 콜백은 1분, 5분, 30분, … 뒤에 재시도하며 총 8번 시도합니다.

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

// Same as the NOWPayments docs (our body is already sorted, so hashing the raw body works too)
function sortObject(obj) {
  return Object.keys(obj).sort().reduce((r, k) => {
    r[k] = obj[k] && typeof obj[k] === "object" ? sortObject(obj[k]) : obj[k];
    return r;
  }, {});
}
function verifyIpn(params, sig, ipnSecret) {
  const hmac = crypto.createHmac("sha512", ipnSecret).update(JSON.stringify(sortObject(params))).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(hmac), Buffer.from(sig || ""));
}
// verifyIpn(req.body, req.headers["x-nowpayments-sig"], process.env.NOWPAYMENTS_IPN_SECRET)
PHP
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
tksort($data);  // the recursive ksort from the NOWPayments docs
$hmac = hash_hmac('sha512', json_encode($data, JSON_UNESCAPED_SLASHES), trim($ipnSecret));
$ok = hash_equals($hmac, $_SERVER['HTTP_X_NOWPAYMENTS_SIG'] ?? '');
payment_status언제보내는 IPN
waiting결제 대기(코인을 아직 고르지 않은 인보이스 포함)—
confirming체인에서 결제가 보이고 컨펌을 기다리는 중— (조회할 때 보임)
finished결제 완료(초과 결제 포함. actually_paid는 도착한 금액)✓
partially_paid부족: 고객이 만료 전에 같은 주소로 추가 송금할 수 있음(처음 부족하게 송금했을 때 한 번 전송), 만료 시점에도 부족하면 다시 전송✓
expired결제 없이 만료됨✓
refunded관리 화면에서 결제 전액을 환불하고 송금까지 끝남— (조회할 때 보임)

confirmed, sending, failed는 나타나지 않습니다. 컨펌되면 finished가 되어 잔액에 입금되며 다른 곳으로 전달하지 않습니다.

통화 티커

코인네트워크pay_currencynetwork최소 금액
USDTTRONusdttrc20trx$1
USDTBNB Chainusdtbsc usdtbep20bsc$1
USDCBNB Chainusdcbsc usdcbep20bsc$1
USDTEthereumusdterc20eth$5
USDCEthereumusdc usdcerc20eth$5
USDCBaseusdcbasebase$1
USDTPolygonusdtmatic usdtpolygonmatic$1
USDCPolygonusdcmatic usdcpolygonmatic$1
USDTArbitrumusdtarbarbitrum$1
USDCArbitrumusdcarbarbitrum$1
USDTOptimismusdtopop$1
USDCOptimismusdcopop$1
USDTAvalancheusdtarc20 usdtavax / usdtavaxcavaxc$1
USDCAvalancheusdcarc20 usdcavax / usdcavaxcavaxc$1
USDTX Layerusdtxlayerxlayer$1
USDCX Layerusdcxlayerxlayer$1
USD1BNB Chainusd1bscbsc$1
FDUSDBNB Chainfdusdbscbsc$1
DAIEthereumdai daierc20eth$5
DAIArbitrumdaiarbarbitrum$1
DAIBasedaibasebase$1
BTCBitcoinbtcbtc$5
LTCLitecoinltcltc$1
DOGEDogecoindogedoge$1
BCHBitcoin Cashbchbch$1
TRXTRONtrxtrx$1
BNBBNB Chainbnbbsc bnbbsc$1
ETHEthereumetheth$5
ETHBaseethbasebase$1
ETHArbitrumetharbarbitrum$1
ETHOptimismethopop$1
POLPolygonmaticmainnet pol / polmainnet / maticmatic$1
AVAXAvalancheavaxc avaxavaxc$1
OKBX Layerokbxlayerxlayer$1
USDTSolanausdtsolsol$1
USDCSolanausdcsolsol$1
SOLSolanasolsol$1
USDTTONusdttonton$1
TONTONtonton$1

NOWPayments와의 차이점

테스트 모드

테스트 자격 증명으로 만든 charge와 결제는 각 체인의 테스트넷에서 동작하며 웹훅은 테스트 IPN secret / 공유 시크릿으로 서명됩니다. 실서비스와 완전히 분리되어 있어 테스트 키로는 실서비스 결제를 볼 수 없습니다.

나머지(결제 페이지, 컨펌, 네트워크와 최소 금액, 환불)는 메인 문서와 같습니다.