Sign in
결제 및 출금/Payout API

Payout API

가맹점 잔액에서 임의의 블록체인 주소로 출금을 전송합니다.

Payout API를 사용하면 가맹점 잔액에서 임의의 블록체인 주소로 프로그래밍 방식으로 자금을 출금할 수 있습니다.

모든 Payout endpoint에서는 sign 서명을 생성할 때 별도의 Payout API key를 사용해야 합니다. 이 키는 일반 API key와 다르며 프로젝트 설정에서 별도로 생성해야 합니다.

출금 생성

가맹점 잔액으로부터 출금 요청을 생성합니다.

POST/v1/payout

요청 매개변수

필드타입필수설명
currencystringyes출금 통화 (References 참고)
networkstringyes네트워크 코드 (References 참고)
amountstringyes출금 금액
to_addressstringyes수신자 블록체인 주소
order_idstringno멱등성 키 — 프로젝트 내에서 고유. 동일한 order_idPOST 요청을 반복해도 새로운 출금은 생성되지 않으며, 기존 출금이 반환됩니다
url_callbackstringno출금 webhook URL. 이 출금에 대해 webhook을 비활성화하려면 생략하세요
memostring | nullno목적지 태그 / memo. 현재 TONSOL 네트워크에서만 사용됩니다. 최대 255자
from_currencystringno출금 시점에 차감하여 currency로 자동 변환할 원천 잔액. USDT 같은 스테이블코인으로 잔액을 유지하면서 변동성 자산(BTC, ETH, …)으로 출금할 수 있게 해줍니다 — 변동성 암호화폐를 직접 보유할 필요가 없습니다. "USDT"를 전달하면 USDT 잔액에서 차감합니다
fee_optionstringno수수료 부과 방식. deduct(기본) — 네트워크 + 플랫폼 수수료가 amount에서 차감되며 수신자는 amount - fees를 받음. add — 수수료가 추가로 부과되어 가맹점 측에서는 amount + fees가 차감되고 수신자는 정확히 amount를 받음

멱등성. 프로젝트 내에서 출금은 order_id로 고유하게 식별됩니다. 동일한 order_id로 동일한 POST를 다시 보내도 안전합니다 — API는 중복을 만들지 않고 기존 출금을 반환합니다. 프로덕션 출금에서는 항상 order_id를 전달하세요.

요청 예시

Shell
curl -X POST https://api.2328.io/api/v1/payout \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE" \
  -d '{"currency":"TRX","network":"TRX-TRC20","amount":"1.00","to_address":"TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t","order_id":"9ed25264-8be4-439f-acf5-2a8732538d27","url_callback":"https://your-site.com/webhook/payout","memo":null,"fee_option":"deduct"}'

응답 예시

JSON
{
  "state": 0,
  "result": {
    "uuid": "019dea62-1727-72aa-ac2c-eaf2ade193ef",
    "order_id": "9ed25264-8be4-439f-acf5-2a8732538d27",
    "status": "pending",
    "currency": "TRX",
    "network": "TRX-TRC20",
    "amount": "1.00",
    "merchant_amount": "1",
    "network_amount": "0.89",
    "amount_usd": "0.33",
    "to_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "memo": null,
    "txid": null,
    "block_number": null,
    "error_type": null,
    "created_at": "2026-05-02T23:29:50+03:00",
    "updated_at": "2026-05-02T23:29:50+03:00"
  }
}

수수료. 기본값 fee_option: deduct — 네트워크 + 플랫폼 수수료가 amount에서 차감되어 수신자는 amount - fees를 받습니다. 수수료를 추가로 부과하려면 fee_option: add를 전달하세요. 이 경우 수신자는 정확히 amount를 받고 가맹점 측에서는 amount + fees가 차감됩니다.

출금 계산

출금을 생성하지 않고 잔액 차감도 없이 출금 금액과 수수료를 추정합니다. 확인 전에 사용자에게 실제로 받을(또는 지불할) 정확한 금액을 보여줄 때 사용합니다.

POST/v1/payout/calc

요청 매개변수

출금 생성 과 동일합니다 — 동일한 필드, 동일한 서명. order_id, url_callback, to_address, memo 도 허용되지만 무시됩니다: 출금은 저장되지 않으며 callback 도 전송되지 않습니다.

요청 예시

Shell
curl -X POST https://api.2328.io/api/v1/payout/calc \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE" \
  -d '{"currency":"USDT","network":"TRX-TRC20","amount":"100","fee_option":"add"}'

응답 예시

JSON
{
  "state": 0,
  "result": {
    "currency": "USDT",
    "network": "TRX-TRC20",
    "amount": "100",
    "fee_option": "add",
    "merchant_amount": "103.00000000",
    "network_amount": "100",
    "total_fee": "3.00000000",
    "total_fee_usd": "3.00000000"
  }
}

미리보기 전용. 이 엔드포인트는 읽기 전용입니다 — 잔액이 차감되지 않으며 출금 레코드도 생성되지 않습니다. UI 에 수수료 내역을 표시하기 위해 필요한 만큼 호출해도 됩니다.

출금 상태

출금 요청의 상태를 조회합니다.

GET/v1/payout/status/{uuid}

Path 매개변수

필드타입필수설명
uuidstringyes출금 UUID (생성 시 result.uuid)

응답 예시

JSON
{
  "state": 0,
  "result": {
    "uuid": "019dff1f-0dbd-7277-8d45-271e7775388f",
    "order_id": "4dfdcc84402b1185b71cbe399321533e",
    "status": "completed",
    "currency": "TRX",
    "network": "TRX-TRC20",
    "amount": "3.00",
    "merchant_amount": "3.00",
    "network_amount": "3.00",
    "amount_usd": "1.04",
    "to_address": "THauRv5tcucQRohXg8NiyGTk16DX1XQG5x",
    "memo": null,
    "txid": "9242e533703704ef3eaba840f70b4a26333e72c943377ee375fea17badb53def",
    "block_number": null,
    "error_type": null,
    "created_at": "2026-05-07T00:08:38+03:00",
    "updated_at": "2026-05-07T00:08:54+03:00",
    "from_currency": "USDT",
    "debited_amount": "1.050735",
    "debited_currency": "USDT"
  }
}

이 GET 요청에서는 빈 본문에 대해 서명을 계산합니다: hash_hmac('sha256', base64_encode(''), $apiKey)

응답 필드

POST /v1/payoutGET /v1/payout/status/{uuid}result에서 반환되는 필드:

필드타입설명
uuidstring시스템이 부여한 출금 UUID
order_idstring가맹점 측 내부 출금 식별자 (프로젝트 내 고유)
statusstring현재 출금 상태 (아래 참고)
currencystring출금 통화
networkstring네트워크 코드
amountstring요청한 출금 금액
merchant_amountstring가맹점 잔액에서 차감된 금액
network_amountstring실제로 온체인에 전송된 금액 (네트워크 + 플랫폼 수수료 차감 후)
amount_usdstring출금 금액의 USD 환산
to_addressstring수신자 블록체인 주소
memostring | null목적지 태그 / memo (TON, SOL). 그 외에는 null
txidstring | null블록체인 트랜잭션 해시. 트랜잭션이 전송되기 전까지 null
block_numberint | null트랜잭션이 포함된 블록 번호. 포함 전까지 null
error_typestring | nullstatus = failed일 때 실패 사유 (아래 Error types 참고). 그 외에는 null
created_atstring (ISO 8601)출금 생성 시각
updated_atstring (ISO 8601)마지막 상태 변경 시각
from_currencystring | null자동 변환이 사용된 경우 출금이 차감된 원천 잔액 (예: BTC 출금에 대한 USDT). 변환이 발생하지 않은 경우 null
debited_amountstring | null변환 후 원천 잔액에서 실제로 차감된 금액. 자동 변환을 사용한 경우에만 존재
debited_currencystring | nulldebited_amount의 통화 — 자금이 차감된 잔액의 통화

출금 상태

status 필드는 다음 값을 가질 수 있습니다:

Status설명
pending생성됨, 처리 대기 중
completed정상적으로 완료됨 — txid가 설정됨
failed전송 오류 — error_type 참조
cancelled취소됨

오류 유형

status = failed일 때 error_type 필드는 사유를 설명합니다:

Code설명
aml_riskAML 리스크 검사로 인해 출금이 차단됨 (수신자 주소가 고위험으로 표시됨)

Webhook 알림

출금의 상태가 변경되면 시스템은 출금 생성 시 전달된 url_callback URL로 POST webhook을 보냅니다. url_callback을 제공하지 않은 경우 해당 출금에 대한 webhook은 전송되지 않습니다.

  • Method: POST
  • Content-Type: application/json
  • Signature: 요청 본문의 sign 필드. 출금 요청을 서명할 때 사용한 동일한 Payout API key로 계산됩니다.

payload는 GET /v1/payout/status/{uuid}result 객체에 검증용 sign 필드를 더한 것과 동일합니다.

Payload

JSON
{
  "uuid": "019dff1f-0dbd-7277-8d45-271e7775388f",
  "order_id": "4dfdcc84402b1185b71cbe399321533e",
  "status": "completed",
  "currency": "TRX",
  "network": "TRX-TRC20",
  "amount": "3.00",
  "merchant_amount": "3.00",
  "network_amount": "3.00",
  "amount_usd": "1.04",
  "to_address": "THauRv5tcucQRohXg8NiyGTk16DX1XQG5x",
  "memo": null,
  "txid": "9242e533703704ef3eaba840f70b4a26333e72c943377ee375fea17badb53def",
  "block_number": null,
  "error_type": null,
  "created_at": "2026-05-07T00:08:38+03:00",
  "updated_at": "2026-05-07T00:08:54+03:00",
  "from_currency": "USDT",
  "debited_amount": "1.050735",
  "debited_currency": "USDT",
  "sign": "925ad7bf3d6841864101f7cc2c7e30652e70a06cdb04dbe07a0129480000ce4a"
}

서명 검증. 결제 webhook과 동일한 알고리즘을 사용하되 일반 API key 대신 Payout API key로 서명합니다. sign 필드를 제거하고 나머지 payload를 JSON으로 인코딩한 뒤 base64로 인코딩하고 hash_hmac('sha256', $base64, $payoutApiKey)를 계산해 수신한 sign과 비교하세요.