연동 안내

Nile 테스트넷대시보드

시작 순서

방식받는 곳준비
B·C 운영비 자체 부담B 0.35% · 최소 0.30 · C 0.3% · 최소 0.20 USDT선택 · 입금 주소 활성화·Energy 를 서명 프로그램이 모지갑 TRX 로 채움 · 서명 설정 gas.max_trx_day (하루 TRX 한도)
A 금액 매칭주소 1개, 주문마다 소수점 금액을 다르게받는 주소만
B 1회용 주소주문마다 새 주소서명 프로그램 → xpub
C 고객할당고객마다 고정 주소, 주문 없이 보내도 입금 처리서명 프로그램 → xpub
  1. B·C: 가맹점 서버에서 서명 프로그램 init → 출력된 xpub 를 운영자에게 전달 (A 는 받는 주소)
  2. 운영자가 가맹점 등록 → 담당자 이메일로 설정 링크 수신
  3. 링크에서 비밀번호·OTP 설정 → API 키·웹훅 시크릿·서명 프로그램 토큰 한 번 표시 (보관)
  4. 대시보드 › 웹훅 › 연동 설정: 웹훅 주소, 결제 팝업 사이트
  5. 서버에서 주문 만들기 → 팝업 → 웹훅으로 지급
  6. B·C: 서명 프로그램 run 상시 실행 (집금·이동·출금 서명)

인증

Authorization: Bearer sk_...
결제 서버: https://pay.usdtgate.net

API 키는 가맹점 서버에만. 브라우저·앱에 넣지 않음. 유출 시 대시보드 › 웹훅 › API 키 재발급 (기존 키 즉시 무효).

주문

요청내용
POST /v1/orders{order_id, amount, currency?, customer_ref?, ttl_min?} · 같은 order_id 재요청 = 같은 주문
GET /v1/orders/<id>주문 상태
GET /v1/rates1 USDT = 현지 화폐 (시세)
POST /v1/customers/<ref>/addressC: 고객 고정 주소
값설명
amountcurrency 없으면 USDT, 있으면 그 통화 금액 (KRW·JPY·USD 등) · 최소 1 USDT
customer_ref회원번호 등. C 는 필수 (고객 주소 결정)
ttl_min입금 기한(분), 기본 30

요청

curl -X POST https://pay.usdtgate.net/v1/orders \
  -H "Authorization: Bearer sk_..." -H "Content-Type: application/json" \
  -d '{"order_id":"chg-1001","amount":"50000","currency":"KRW","customer_ref":"user-77"}'

응답

{
  "id": "ord_...", "order_id": "chg-1001", "status": "pending",
  "network": "TRC20", "address": "T...", "address_index": 12,
  "amount": "36.24", "paid": "0", "remaining": "36.24",
  "currency": "KRW", "fiat_amount": "50000", "rate": "1379.7", "credit": "0",
  "result": null, "expires_at": "...Z",
  "pay_url": "https://pay.usdtgate.net/pay/ord_...", "tg_url": "..."
}
status
pending입금 대기
partial일부 입금
paid완료 (result: exact 정상 · over 초과)
expired만료 (result: under 부족 · null 미입금)

웹훅

POST (가맹점 웹훅 주소)
X-Gw-Timestamp: 1762650000
X-Gw-Signature: hex(HMAC-SHA256(whsec_..., timestamp + "." + body))

{"id": "evt_...", "type": "order.paid", "created": "...Z", "data": { ...주문 }}

서명·시각(5분) 확인 후 200 응답. 실패 시 2n분 간격 8회 재전송, 같은 id. 대시보드 › 웹훅에서 다시 보내기.

type
order.partial일부 입금 (credit_delta)
order.paid완료 (credit_delta)
order.expired만료
deposit.customerC: 주문 없이 고객 주소로 입금
deposit.late만료 주문 주소·금액으로 입금 → 대시보드에서 주문 연결
deposit.unknown연결 안 된 입금
deposit.other_tokenUSDT 아닌 스테이블코인 입금
job.updated집금·이동·출금 상태
wallet.permission_changed지갑 서명 권한 변경 감지

검증 (Python)

from gateway_sdk import verify_webhook
if not verify_webhook(WHSEC, request.headers, request.get_data()):
    abort(400)

받은 만큼 지급

order.partial·order.paid 마다 credit_delta(이번 입금분, 주문 통화)를 웹훅 id 당 한 번 더함. credit = 합계.

예 (5만 원, 1 USDT = 1,380원)credit_deltacredit
36.24 USDT 정확50,00050,000
20 USDT (부족)27,60027,600
이어서 17.24 USDT23,78051,380
덜 받고 만료없음그대로

주소 검증

주문 응답의 주소가 내 키에서 나온 것인지 고객에게 보여주기 전에 확인. 결제 서버가 털려도 고객 돈이 다른 곳으로 가지 않음.

from gateway_sdk import check_order
check_order(order, xpub=MY_XPUB)            # B·C
check_order(order, fixed_address=MY_ADDR)   # A
# 다르면 AddressMismatch → 주문 중단

업종별 흐름

업종요청웹훅에서 할 일
구매 (쇼핑몰·디지털 상품·구독 갱신)POST /v1/orders {order_id, amount, currency} → pay_url 또는 팝업order.paid → 주문 완료 · order.expired result=under → 덜 받음 처리
충전 (게임머니·포인트·지갑)C: POST /v1/customers/<회원>/address → 고정 주소 · 또는 금액 지정 주문고정 주소: deposit.customer 중 order_id 없는 것 → amount × 충전 비율 · 주문: credit_delta 만큼
환전 (게임머니 → USDT·판매자 정산)잔액 먼저 보류 → POST /v1/payouts {to, amount, ref, sig} (otp 생략 = 자동 출금)job.updated done → 확정 · rejected·failed·expired → 보류 돌려줌 · unknown → 보류 유지

모든 웹훅은 id 당 한 번만 반영. 충전 비율·게임머니 단위는 가맹점이 정함. 세 흐름 전부 들어 있는 예: server.js (Node.js), 충전 주문형: flask_shop.py.

집금·출금 (B·C)

요청내용
POST /v1/sweeps{address} 입금 주소 → 모지갑 (자동 집금도 됨)
POST /v1/moves{amount, otp} 모지갑 → 출금 지갑
POST /v1/payouts{to, amount, otp, ref} 출금 지갑 → 고객 · 같은 ref = 같은 작업 · 최소 5 USDT · otp 대신 sig = 자동 출금
GET /v1/jobs/<id>작업 상태, tx_id

otp = 서명 프로그램 OTP (대시보드 OTP 와 별개). 120초 안에 서명 프로그램이 가져가야 함.

자동 출금: 서명 설정 payout.auto_max_per_tx·auto_max_per_day 안에서만 OTP·텔레그램 승인 없이 서명 (기본 0 = 꺼짐, 넘으면 rejected). 출금 지갑 잔액은 내부 이동(OTP)으로 미리 채워 둘 것.

자동 출금 sig: HMAC-SHA256(auto_secret, ref + "|" + to + "|" + 금액×1000000) 16진수 소문자. 예: ref wd-1 · 12.5 USDT → "wd-1|T…|12500000". auto_secret 은 서명 프로그램 설정 payout.auto_secret 과 가맹점 서버에만 둠 (게이트웨이에 보내지 않음, agent.py init 이 만들어 줌). 서명 불일치·같은 ref 재사용은 rejected. API 키나 게이트웨이가 털려도 sig 없이는 자동 출금 불가.

서명 프로그램 (B·C)

가맹점 서버에서 실행. 키는 가맹점 서버에만 있고 결제 서버는 서명할 수 없음. 나가는 연결만 사용.

unzip signer.zip && cd signer
pip install -r requirements.txt
cp signer_config.example.json signer_config.json
python agent.py init signer_config.json   # 키 파일·OTP·xpub 출력 → xpub 운영자에게
# signer_config.json: gateway_url = https://pay.usdtgate.net, signer_token = st_...
python agent.py run signer_config.json    # 상시 실행
python selftest_signer.py
설정값
gateway_urlhttps://pay.usdtgate.net
tron_apihttps://nile.trongrid.io
usdt_contractTXYZopYRdj2D9XRtbG411XZZ3kM5VkAeBf
payout1건·하루 한도, confirm_over 넘으면 텔레그램 승인
fee_address대시보드 › 웹훅 › 수수료 받는 주소
fee.max_per_day수수료 송금 하루 한도 (기본 500 USDT)
telegram_token서명 전용 봇 새로 만들기 (다른 프로그램 봇 같이 쓰지 않음)

수수료

방식요율받는 방법
B 1회용 주소0.5% · 건당 최소 1.49 USDT모지갑 → 수수료 주소 자동 송금 · 미수 100 USDT 이상일 때 · 서명 프로그램이 fee_address·하루 한도 확인 후 서명
C 고객할당0.4% · 건당 최소 1.03 USDT
B·C 출금완료 1건당 실제 소각 TRX × 시세 × 1.3 · 최소 0.30 USDT (지금 약 1.03)위와 같이 합산 · 운영비 자체 부담이면 없음
A 금액 매칭월 50 USDT선납 · 기간 끝나고 3일 뒤 새 주문 402

대상: 완료 주문, 주문 없는 고객 입금, 만료 뒤 입금, 완료 출금. 내역은 대시보드 › 주문 › 수수료 내역 (CSV). 송금 기록은 작업 목록 kind=fee, 웹훅 job.updated.

오류

코드
400{"error": "..."} 값 오류
401API 키·토큰 틀림, 또는 사용 중지된 가맹점
402A: 이용료 기간 만료
404없는 주문·작업
429A: 같은 금액 대기 주문이 너무 많음, 잠시 후 다시
503환율 일시 불가 (현지 화폐 주문)

파일