Skip to content

결제

SoloPay 결제의 전체 API를 설명합니다.

결제 생성

결제를 생성하고 고유 ID를 발급받습니다.

개요

SoloPay 위젯을 사용하면 결제 생성은 위젯이 자동으로 처리합니다. 이 페이지는 내부 동작을 이해하거나 커스텀 구현을 위한 참고용 API 명세입니다.

생성된 결제는 5분 후 자동 만료됩니다.

  • 인증: x-public-key 헤더 필수 (pk_xxx)
  • 체인 및 수령 주소는 가맹점 설정에서 자동 결정
  • tokenAddress는 화이트리스트 등록 및 가맹점 활성화가 필수

결제 플로우

┌─────────────┐         ┌─────────────┐         ┌─────────────┐
│  SoloPay 위젯│         │  SoloPay API │         │   블록체인   │
└──────┬──────┘         └──────┬──────┘         └──────┬──────┘
       │                       │                       │
       │  POST /payments       │                       │
       │──────────────────────▶│                       │
       │                       │                       │
       │  { paymentId, deadline, ... }                  │
       │◀──────────────────────│                       │
       │                       │                       │
       │     (사용자가 지갑에서 결제)                   │
       │                       │                       │
       │                       │    TX 전송            │
       │                       │──────────────────────▶│

REST API

bash
curl -X POST https://gateway.dev.solonetwork.io/api/v1/payments \
  -H "x-public-key: pk_xxxxx" \
  -H "Origin: https://yourshop.com" \
  -H "Content-Type: application/json" \
  -d '{
    "orderId": "order-001",
    "amount": 10.5,
    "tokenAddress": "0xE4C687167705Abf55d709395f92e254bdF5825a2",
    "successUrl": "https://example.com/success",
    "failUrl": "https://example.com/fail"
  }'

요청 파라미터

필드타입필수설명
orderIdstring가맹점 주문 식별자 (같은 가맹점 내 중복 불가)
amountnumber결제 금액 (토큰 단위 또는 법정화폐 단위). 소수점 이하 최대 2자리
tokenAddressaddressERC-20 토큰 컨트랙트 주소 (화이트리스트 & 가맹점 활성화 필수)
successUrlstring결제 성공 시 리다이렉트 URL
failUrlstring결제 실패 시 리다이렉트 URL
currencystring법정화폐 코드 (예: USD, KRW). 입력 시 가격 변환 적용

currency 옵션

currency를 입력하면 amount는 법정화폐 기준으로 해석되며, 서버가 최근 1시간 평균 가격(TWAP)으로 자동 환산하여 토큰 수량을 결정합니다. 예: amount: 10, currency: "USD" → 직전 1시간 평균 토큰 가격을 기준으로 USD 10에 해당하는 토큰 수량으로 결제

순간 시세 변동에 휘둘리지 않도록 1시간 평균가를 사용합니다. 응답의 tokenPrice 필드에 환산에 사용된 1시간 평균가가 포함됩니다.

amount 소수점 제한

amount는 소수점 이하 최대 2자리까지만 허용됩니다 (예: 10.50 ✓, 10.123 ✗). currency 없이 전달하면 토큰 수량으로 직접 사용되며, currency가 있으면 법정화폐 금액에서 토큰 수량으로 변환 후 소수 둘째자리로 절삭됩니다. 최소 토큰 수량은 0.01입니다.

응답

성공 (201 Created)

json
{
  "success": true,
  "data": {
    "paymentId": "0xabc123def456...",
    "orderId": "order-001",
    "chainId": 80002,
    "tokenAddress": "0xE4C687167705Abf55d709395f92e254bdF5825a2",
    "tokenSymbol": "SUT",
    "tokenDecimals": 18,
    "gatewayAddress": "0x...",
    "forwarderAddress": "0x...",
    "amount": "10500000000000000000",
    "recipientAddress": "0xMerchantWallet...",
    "merchantId": "0x...",
    "deadline": "1706281200",
    "successUrl": "https://example.com/success",
    "failUrl": "https://example.com/fail",
    "expiresAt": "2024-01-26T12:35:00.000Z",
    "tokenPermitSupported": true,
    "currency": "USD",
    "fiatAmount": 10.5,
    "tokenPrice": 1.0
  }
}

에러 응답

HTTP코드원인
400TOKEN_NOT_ENABLED해당 토큰이 가맹점에서 비활성화됨
404TOKEN_NOT_FOUND화이트리스트에 없는 토큰
400UNSUPPORTED_CHAIN지원하지 않는 체인
400CHAIN_NOT_CONFIGURED가맹점에 체인이 설정되지 않음
400RECIPIENT_NOT_CONFIGURED가맹점 수령 주소 미설정
400CHAIN_MISMATCH토큰이 가맹점 체인에 속하지 않음
400UNSUPPORTED_TOKEN해당 체인에서 지원되지 않는 토큰
400PRICE_SERVICE_NOT_CONFIGURED통화 변환 서비스 사용 불가
400VALIDATION_ERROR입력값 검증 실패
409DUPLICATE_ORDER이미 사용된 orderId

응답 필드 설명

필드타입설명
paymentIdstring결제 고유 식별자 (bytes32 해시)
amountstringwei 단위로 변환된 금액
gatewayAddressaddressPaymentGateway 컨트랙트 주소
forwarderAddressaddressERC2771 Forwarder 주소 (Gasless용)
merchantIdstringbytes32 형태의 가맹점 ID
deadlinestring결제 기한 (Unix timestamp); 이 시각 전에 pay()를 호출해야 합니다. 기본: 5분(300초)
expiresAtdatetime결제 만료 시각 (생성 후 5분)
tokenPermitSupportedbooleanEIP-2612 Permit 지원 여부
currencystring법정화폐 통화 코드 (요청 시에만 포함)
fiatAmountnumber원래 법정화폐 금액 (요청 시에만 포함)
tokenPricenumber환산에 사용된 최근 1시간 평균 토큰 가격(TWAP) (요청 시에만 포함)

위젯 사용 시

위젯(@solo-pay/widget-js / @solo-pay/widget-react)을 사용하면 이 API를 직접 호출할 필요 없이 위젯이 자동으로 처리합니다.

위젯 연동 가이드 참고


결제 상태 조회

결제의 현재 상태를 조회합니다.

  • 인증: x-public-key 헤더 필수
  • GET 요청 시 Origin 헤더 대신 x-origin 헤더 사용 가능 (프록시 환경)

REST API

bash
curl https://gateway.dev.solonetwork.io/api/v1/payments/0xabc123... \
  -H "x-public-key: pk_xxxxx"

응답

성공 (200 OK)

json
{
  "success": true,
  "data": {
    "paymentId": "0xabc123...",
    "orderId": "order-001",
    "status": "PAID",
    "chainId": 80002,
    "tokenAddress": "0xE4C687167705Abf55d709395f92e254bdF5825a2",
    "tokenSymbol": "SUT",
    "tokenDecimals": 18,
    "tokenPermitSupported": true,
    "gatewayAddress": "0x...",
    "forwarderAddress": "0x...",
    "amount": "10500000000000000000",
    "recipientAddress": "0xMerchantWallet...",
    "merchantId": "0x...",
    "deadline": "1706281200",
    "successUrl": "https://example.com/success",
    "failUrl": "https://example.com/fail",
    "expiresAt": "2024-01-26T12:35:00.000Z",
    "txHash": "0xdef789...",
    "payerAddress": "0x...",
    "createdAt": "2024-01-26T12:30:00Z",
    "currency": "USD",
    "fiatAmount": 10.5,
    "tokenPrice": 1.0
  }
}
  • txHash — 결제 트랜잭션 해시. PAID 이후 상태에서 존재합니다.

상태 흐름

CREATED ──► PAID ──► REFUND_SUBMITTED ──► REFUNDED
CREATED ──► EXPIRED
CREATED ──► FAILED
CREATED ──► INVALID

상태 설명

상태설명다음 액션
CREATED결제 생성됨, 온체인 트랜잭션 대기사용자가 결제 진행
PAID결제가 온체인에서 확인됨없음 (정상 플로우의 종료)
REFUND_SUBMITTED환불 트랜잭션 제출됨REFUNDED 대기
REFUNDED환불 완료, 자금 구매자에게 반환없음 (종료)
INVALID결제 검증 실패새 결제 생성
FAILED트랜잭션 실패새 결제 생성
EXPIRED만료 (5분 초과)새 결제 생성

온체인 동기화

GET /payments/:id 호출 시 블록체인과 DB 상태를 실시간으로 동기화합니다. 결제 성공 시 상태는 PAID(온체인 결제 확인, 자금이 가맹점으로 직접 전송)입니다.


결제 내역

가맹점의 결제 내역을 조회합니다. API Key 인증이 필요합니다.

현재 두 가지 엔드포인트를 모두 사용할 수 있습니다. /merchants/me/payments를 권장하며, /merchant/payments는 레거시 엔드포인트로 향후 제거될 수 있습니다.

REST API

bash
# orderId로 조회 (권장)
curl "https://gateway.dev.solonetwork.io/api/v1/merchants/me/payments?orderId=order-001" \
  -H "x-api-key: sk_xxxxx"

# orderId로 조회 (레거시)
curl "https://gateway.dev.solonetwork.io/api/v1/merchant/payments?orderId=order-001" \
  -H "x-api-key: sk_xxxxx"

# paymentId로 조회 (권장)
curl "https://gateway.dev.solonetwork.io/api/v1/merchants/me/payments/0xabc123..." \
  -H "x-api-key: sk_xxxxx"

# paymentId로 조회 (레거시)
curl "https://gateway.dev.solonetwork.io/api/v1/merchant/payments/0xabc123..." \
  -H "x-api-key: sk_xxxxx"

응답

json
{
  "success": true,
  "data": {
    "paymentId": "0xabc123...",
    "orderId": "order-001",
    "status": "PAID",
    "amount": "10500000000000000000",
    "tokenSymbol": "SUT",
    "tokenDecimals": 18,
    "txHash": "0xdef789...",
    "payerAddress": "0x1234...",
    "createdAt": "2024-01-26T12:30:00Z",
    "confirmedAt": "2024-01-26T12:35:42Z",
    "expiresAt": "2024-01-26T12:35:00Z"
  }
}

응답 필드

필드타입설명
paymentIdstring결제 고유 식별자 (bytes32 해시)
orderIdstring가맹점 주문 ID
statusstringCREATED, PAID, REFUND_SUBMITTED, REFUNDED, INVALID, EXPIRED, FAILED
amountstringwei 단위 금액
tokenSymbolstring토큰 심볼
tokenDecimalsnumber토큰 소수점
txHashstring온체인 트랜잭션 해시 (확정 후 존재)
payerAddressstring결제자 지갑 주소 (확정 후 존재)
confirmedAtstring결제 확정 시각
expiresAtstring결제 만료 시각

가격 조회

토큰의 현재 가격 또는 1시간 평균 가격을 조회합니다. API Key 인증이 필요합니다.

type 파라미터로 조회 방식을 선택할 수 있으며, typehourly-average인 경우 응답의 price는 직전 정시 1시간 구간의 평균 가격입니다.

REST API

bash
# 현재 가격 조회
curl "https://gateway.dev.solonetwork.io/api/v1/prices?chainId=80002&tokenAddress=0xE4C687167705Abf55d709395f92e254bdF5825a2&type=current&currency=USD" \
  -H "x-api-key: sk_xxxxx"

# 1시간 평균 가격 조회
curl "https://gateway.dev.solonetwork.io/api/v1/prices?chainId=80002&tokenAddress=0xE4C687167705Abf55d709395f92e254bdF5825a2&type=hourly-average&currency=USD" \
  -H "x-api-key: sk_xxxxx"

요청 파라미터

필드타입필수설명
chainIdstringEIP-155 체인 ID (예: 80002)
tokenAddressstring토큰 컨트랙트 주소
typestringcurrent (기본값) 또는 hourly-average
currencystring법정화폐 코드 (기본값: USD)

응답

json
{
  "success": true,
  "data": {
    "type": "current",
    "chain_id": 80002,
    "token_address": "0xE4C687167705Abf55d709395f92e254bdF5825a2",
    "currency": "USD",
    "price": 1.0002,
    "symbol": "SUT"
  }
}

응답 필드

필드타입설명
typestringcurrent 또는 hourly-average
chain_idnumber체인 ID
token_addressstring토큰 컨트랙트 주소
currencystring법정화폐 코드
pricenumber토큰 가격. typehourly-average인 경우 직전 정시 1시간 구간의 평균 가격
symbolstring토큰 심볼

type별 price 차이

  • current: 가장 최근 수집된 토큰 가격 (5분 간격으로 갱신)
  • hourly-average: 직전 정시 기준 1시간 평균 가격. 예를 들어 현재 4시 20분이면 3시~4시 사이 수집된 가격의 평균입니다.

에러 응답

HTTP코드원인
401UNAUTHORIZEDAPI Key 누락 또는 유효하지 않음
404TOKEN_NOT_FOUND토큰이 없거나 가격 데이터 없음
500INTERNAL_ERROR서버 내부 오류

Non-custodial Web3 payment infrastructure for ERC-20 checkout, sponsored gas, and wallet-to-wallet settlement.