Docs Sandbox API

API 샌드박스

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

HMAC 인증

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

1 필수 요청 헤더

X-API-Key

Unifi Pay에서 발급받은 apiKey

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/v1/payment/{transactionId}

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

요청 파라미터

Path Parameter

필수 헤더

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

응답 필드

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

요청 샘플

curl --request GET \
  --url 'https://unifi.me/pay/api/seller/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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 안내

결제의 최종 처리 결과를 비동기로 수신합니다

동작 방식

결제의 최종 처리 결과는 결제 링크 발급 시 지정한 callbackUrl비동기 Webhook이 전송됩니다.

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

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

결제 Webhook 상태값

status type 설명
CONFIRMED PURCHASE 결제 성공 및 확정
FAILED PURCHASE 결제 실패
CANCELED PURCHASE 결제 취소 (이탈 또는 30분 경과)