Docs Sandbox API

API 샌드박스

Unifi Pay API를 탐색하고 테스트해보세요. 요청 파라미터를 수정한 뒤 요청 전송 버튼을 클릭하면 Mock 응답을 확인할 수 있습니다.

문서 버전 안내: 이 페이지는 최신 API v2 기준 문서입니다. API v1으로 연동 중인 파트너를 위한 기존 문서도 계속 제공됩니다. V1 문서 보기

HMAC 인증

API 요청(Server-to-Server) 시 필수 적용

1 필수 요청 헤더

X-API-Key

Unifi Pay 온보딩을 통해 발급받은 API Key

X-Timestamp

현재 Unix 타임스탬프 (밀리초 단위). 서버 시각과 ±5분 이상 차이 시 요청 거부

X-Authorization-Hmac

Base64로 인코딩된 HMAC-SHA256 서명값

2 서명 생성 공식

// HMAC 생성

BASE64(
  HMACSHA256(
    appSecret,
    {HTTP_METHOD}
    + {URI}
    + {X-API-Key}
    + {X-Timestamp}
    + {REQUEST_BODY}
  )
)

참고: 모든 필드를 구분자 없이 순서대로 연결합니다. GET 요청의 REQUEST_BODY는 빈 문자열("")을 사용합니다.

3 서명 생성기

GET /api/seller/v2/payment/{transactionId}

생성된 결제 건의 현재 상태를 조회합니다

요청 파라미터

Path Parameter

필수 헤더

X-API-KeyAPI Key
X-TimestampUnix ms 타임스탬프
X-Authorization-HmacHMAC 서명값
파라미터 위치 필수
transactionIdpathY

응답 필드

transactionId트랜잭션 ID
orderId주문 식별자
storeId가맹점 ID
serviceName서비스 명칭
items결제 상품 목록
statusCREATEDPENDINGPAIDCONFIRMEDFAILEDCANCELED
failType실패 유형 (FAILED 시)
countryCode국가 코드
payAmount실제 결제 금액
payCurrencyCode결제 통화
orderAmount주문 금액
orderCurrencyCode주문 통화

요청 샘플

curl --request GET \
  --url 'https://unifi.me/pay/api/seller/v2/payment/txn_abc123' \
  --header 'X-API-Key: {YOUR_API_KEY}' \
  --header 'X-Timestamp: 1773017787000' \
  --header 'X-Authorization-Hmac: {HMAC}'
const txnId    = 'txn_abc123';
const timestamp = Date.now().toString();
const appId     = 'YOUR_APP_ID';
const uri       = `/api/seller/v2/payment/${txnId}`;

// GET 요청은 body 없음
const hmac = generateHmac(
  'YOUR_APP_SECRET',
  'GET' + uri + appId + timestamp
);

const res = await fetch(
  `https://unifi.me/pay${uri}`,
  {
    headers: {
      'X-API-Key': apiKey,
      'X-Timestamp': timestamp,
      'X-Authorization-Hmac': hmac
    }
  }
);
const data = await res.json();
import requests, hmac, hashlib, base64, time

txn_id     = "txn_abc123"
app_id     = "YOUR_APP_ID"
app_secret = "YOUR_APP_SECRET"
timestamp  = str(int(time.time() * 1000))
uri        = f"/api/seller/v2/payment/{txn_id}"

# GET 요청은 REQUEST_BODY가 빈 문자열
msg = "GET" + uri + app_id + timestamp + ""
sig = base64.b64encode(
    hmac.new(
        app_secret.encode(),
        msg.encode(),
        hashlib.sha256
    ).digest()
).decode()

res = requests.get(
    f"https://unifi.me/pay{uri}",
    headers={
        "X-API-Key": api_key,
        "X-Timestamp": timestamp,
        "X-Authorization-Hmac": sig
    }
)
print(res.json())

응답

200 OK
"transactionId": "txn_abc123",
"orderId": "order_12345",
"storeId": "store_001",
"serviceName": "naver",
"items": [
  { "name": "ITEM-GAME-001", "price": 50000 }
],
"status": "CONFIRMED",
"failType": null,
"countryCode": "KOR",
"payAmount": 49000,
"payCurrencyCode": "USDT",
"orderAmount": 50000,
"orderCurrencyCode": "USD",
"blockchainTxId": "0x4fce0d72ff7f4b9f4ba0cf58d30119924bea3811d85a830c762e1d87b3e1ee17",
"blockchainNetworkFee": 0.00253778
404 Not Found
"code": "PAYMENT_TRANSACTION_NOT_FOUND",
"message": "Transaction not found"
GET /api/seller/v2/payment/settlement/transaction

결제, 환불 내역을 확인합니다

요청 파라미터

Query Parameter

필수 헤더

X-API-KeyAPI Key
X-TimestampUnix ms 타임스탬프
X-Authorization-HmacHMAC 서명값
파라미터 위치 필수
fromquery조건부
toquery조건부
paymentTypequeryN
transactionIdqueryN
settlementIdqueryN
pagequeryN
sizequeryN

응답 필드

content[]결제 데이터 목록
totalElements전체 건수
totalPages전체 페이지수
pageNumber현재 페이지 번호
first첫 페이지 여부
last마지막 페이지 여부

요청 샘플

curl --request GET \
  --url 'https://unifi.me/pay/api/seller/v2/payment/settlement/transaction?from=2026-03-01T00:00:00Z&to=2026-03-31T23:59:59Z&page=0&size=20' \
  --header 'X-API-Key: {YOUR_API_KEY}' \
  --header 'X-Timestamp: 1773017787000' \
  --header 'X-Authorization-Hmac: {HMAC}'
const from      = '2026-03-01T00:00:00Z';
const to        = '2026-03-31T23:59:59Z';
const timestamp = Date.now().toString();
const appId     = 'YOUR_APP_ID';
const uri       = `/api/seller/v2/payment/settlement/transaction?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}&page=0&size=20`;

const hmac = generateHmac(
  'YOUR_APP_SECRET',
  'GET' + uri + appId + timestamp
);

const res = await fetch(
  `https://unifi.me/pay${uri}`,
  {
    headers: {
      'X-API-Key': apiKey,
      'X-Timestamp': timestamp,
      'X-Authorization-Hmac': hmac
    }
  }
);
const data = await res.json();
import requests, hmac, hashlib, base64, time
from urllib.parse import urlencode

from_date  = "2026-03-01T00:00:00Z"
to_date    = "2026-03-31T23:59:59Z"
app_id     = "YOUR_APP_ID"
app_secret = "YOUR_APP_SECRET"
timestamp  = str(int(time.time() * 1000))
params     = urlencode({"from": from_date, "to": to_date, "page": 0, "size": 20})
uri        = f"/api/seller/v2/payment/settlement/transaction?{params}"

msg = "GET" + uri + app_id + timestamp
sig = base64.b64encode(
    hmac.new(
        app_secret.encode(),
        msg.encode(),
        hashlib.sha256
    ).digest()
).decode()

res = requests.get(
    f"https://unifi.me/pay{uri}",
    headers={
        "X-API-Key": api_key,
        "X-Timestamp": timestamp,
        "X-Authorization-Hmac": sig
    }
)
print(res.json())

응답

200 OK
"content": [
  {
    "partnerCorpName": "ABC Corporation",
    "storeId": "store_001",
    "orderId": "ORD-20260301-0001",
    "itemName": "Premium Subscription",
    "serviceName": "ABC Service",
    "orderCountryCode": "KR",
    "orderCurrencyCode": "USD",
    "orderAmount": 50000,
    "createdAt": "2026-03-01T10:00:00Z",
    "transactionId": "txn_abc123def456",
    "blockchainTxId": "0xabcdef1234567890abcdef1234567890abcdef12",
    "paymentType": "PURCHASE",
    "originTransactionId": null,
    "status": "CONFIRMED",
    "finalizedAt": "2026-03-01T10:01:30Z",
    "capturedAt": "2026-03-01T10:01:25Z",
    "failType": null,
    "payCurrencyCode": "USDT",
    "payAmount": 10.87,
    "paymentExchangeRate": 1.0,
    "buyerWalletAddress": "0x1234567890abcdef1234567890abcdef12345678",
    "variableFeeRate": 1.5,
    "settlementId": "stl_xyz789",
    "settlementCurrencyCode": "USDT",
    "settlementExchangeRate": 1.0
  }
],
"totalElements": 1,
"totalPages": 1,
"pageNumber": 0,
"first": true,
"last": true
406 Not Acceptable
"code": "PAYMENT_INVALID_REQUEST",
"message": "Date range must not exceed 90 days"

Webhook 안내

결제의 처리 결과를 비동기 Webhook으로 2회에 걸쳐 수신합니다

동작 방식

결제의 처리 결과는 결제 링크 발급 시 지정한 callbackUrl비동기 Webhook이 전송됩니다. Webhook은 PAID 시점에 1차, CONFIRMED 시점에 2차로 총 2회 발송되므로, 중복 수신에 대비해 멱등하게 처리해 주십시오.

서버는 Webhook 수신 후 반드시 HTTP 200을 반환해야 합니다. 응답하지 않을 경우 재전송될 수 있습니다.

Webhook은 최소한의 정보(transactionId, status, type)만 전송합니다. 상세 정보는 결제 상태 확인 API를 호출하여 조회하세요.

결제 Webhook 상태값

status type 설명
PAID PURCHASE 결제 성공 (1차 Webhook)
CONFIRMED PURCHASE 정산 완료 (2차 Webhook)
FAILED PURCHASE 결제 실패
CANCELED PURCHASE 결제 취소 (이탈 또는 30분 경과)