DPT Learn — 가맹점 결제

USDC 체크아웃 연동

체크아웃에 USDC 결제를 연동하기 위한 실무 중심 엔지니어링 가이드입니다. API 패턴, 네트워크 선택, 웹훅 멱등성, 그리고 프로덕션에서 마주치게 될 장애 유형을 다룹니다.

요약

USDC 체크아웃 연동은 익숙한 패턴을 따릅니다. 서버에서 결제 인텐트(금액, 통화, 네트워크 선호)를 생성하고, 매입사로부터 호스팅 결제 페이지 URL 또는 위젯 설정을 받아, 구매자가 자신의 지갑에서 결제하게 한 다음, 확인 웹훅을 멱등하게 처리합니다. 가장 중요한 엔지니어링 결정은 네트워크 선택(1센트 미만 수수료를 위해 Solana 또는 Base를 기본값으로), 웹훅 멱등성(주문 ID + 트랜잭션 해시 사용), 환불 흐름(결제 시 지갑 주소를 수집하고 환불 API 제공), 그리고 지갑 서명 단계의 매끄러운 사용자 경험(모바일 지갑은 딥링크, 데스크톱은 QR 코드로 대체)입니다. 제대로 구현하면 USDC 결제는 처음부터 끝까지 30초 안에 완료되며, 가맹점 비용은 매입사에 따라 0.3%–1%입니다.

표준 API 구조

USDC 결제 매입 API는 대체로 Stripe가 널리 알린 결제 인텐트 패턴을 따릅니다. 최소한의 구성은 다음과 같습니다.

  1. 서버에서 결제 인텐트 생성

    POST /v1/payments를 호출하고 본문에 amount, currency(법정화폐로 가격을 제시하면 USD, 스테이블코인으로 제시하면 USDC), settlement_preference(USDC 또는 법정화폐), networks(허용 목록), order_id(멱등성 키), success_url, cancel_url, 그리고 자체 대사(reconciliation)용 metadata 블롭을 담습니다.

  2. 매입사가 결제 페이지 URL 또는 위젯 설정 반환

    호스팅 결제 방식이라면 구매자를 리디렉션할 URL을, 임베디드 위젯 방식이라면 위젯이 불러올 클라이언트 측 설정(공개 키, 인텐트 ID)을 반환합니다. 두 방식 모두 지갑 감지, 네트워크 선택, 견적 표시를 처리합니다.

  3. 구매자가 지갑에서 서명하고 온체인 이체가 전파됨

    모바일에서는 MetaMask, Phantom, Trust 등으로 딥링크하고, 데스크톱에서는 WalletConnect QR 코드나 브라우저 확장 프로그램 팝업을 사용합니다. 구매자가 금액을 확인하고 서명합니다.

  4. 매입사가 블록 확인을 기다린 뒤 웹훅 발송

    POST your_webhook_url로 event_type: “payment.succeeded”, order_id, amount, tx_hash, network, 그리고 매입사의 웹훅 시크릿으로 검증할 서명을 담은 페이로드를 보냅니다.

  5. 서버가 멱등하게 주문을 결제 완료로 표시

    웹훅 서명을 검증하고, DB에서 (order_id, tx_hash)를 조회해 아직 표시되지 않았다면 결제 완료로 표시한 뒤 주문 이행을 시작합니다.

네트워크 선택

어떤 네트워크를 받을지는 사용자 경험과 비용 사이의 절충입니다.

  • Solana: 네트워크 수수료 1센트 미만, 확인 1초 미만. 평균 주문 금액(AOV)이 작다면 가장 좋은 기본값입니다.
  • Base: 네트워크 수수료 몇 센트, 확인 몇 초. 지갑 지원이 탄탄하며, 암호화폐에 익숙한 고객층에 적합한 기본값입니다.
  • Polygon, Arbitrum: 수수료와 속도가 Base와 비슷합니다. 추가해도 좋지만 꼭 필요하지는 않습니다.
  • Ethereum 메인넷: 가스 상황에 따라 네트워크 수수료가 $1–$8+입니다. 소액 주문에서는 구매자에게 부담이 큽니다. 평균 주문 금액이 높은 경우($500 초과)나 대안으로만 받으십시오.
  • Tron: 아시아/아프리카의 USDT 흐름을 겨냥한다면 USDC와 함께 USDT-TRON 지원을 검토할 만합니다.

웹훅 멱등성

웹훅은 재시도됩니다. 핸들러는 반드시 멱등해야 합니다. 표준 패턴은 다음과 같습니다.

  1. 매입사의 시크릿으로 HMAC-SHA256을 사용해 웹훅 서명을 검증합니다.
  2. 페이로드에서 (order_id, tx_hash)를 추출합니다.
  3. processed_payments 테이블에서 해당 쌍을 조회합니다.
  4. 있으면 다른 작업 없이 200 OK를 반환합니다.
  5. 없으면 행을 삽입하고(해당 쌍에 UNIQUE 제약 조건 적용), 주 주문 테이블에서 주문을 결제 완료로 표시한 다음, 주문 이행을 시작합니다.
  6. 5단계를 하나의 DB 트랜잭션으로 묶어, 처리 도중 장애가 나도 주문이 이중으로 이행되지 않게 합니다.

대부분의 결제 매입 웹훅에는 전송 ID가 포함됩니다. 디버깅을 위해 기록해 두되, 멱등성 키로 의존해서는 안 됩니다. 네트워크 확인과 매입사의 재시도로 인해 전송 ID는 다르지만 tx_hash는 같은 payment.succeeded 이벤트가 중복으로 생길 수 있습니다. 중복 제거는 전송 기준이 아니라 온체인 식별자 기준이어야 합니다.

환불 흐름

주로 두 가지 패턴이 쓰입니다.

  • 송금인에게 환불: 매입사가 구매자가 원래 결제한 주소로 USDC를 돌려보냅니다. 사용자 경험이 가장 깔끔하며, 온체인 결제 기록에 출금 주소가 담겨 있기 때문에 가능합니다.
  • 지정 주소로 환불: 구매자가 환불받을 주소를 지정합니다(거래소나 핫 월렛에서 결제했다면 출금 주소와 다를 수 있습니다). 대부분의 매입사는 destination_address를 담은 POST /v1/refunds로 이를 지원합니다.

환불 구간의 네트워크 수수료는 가맹점이 부담합니다. 전액 환불과 부분 환불이 모두 지원됩니다. 환불 자체에도 원래 결제와 같은 온체인 확인 시간이 걸립니다.

프로덕션 장애 유형

  • 구매자가 서명 후 이탈하는 경우. 온체인 이체는 전파되었지만 웹훅이 발송되기 전에 구매자가 탭을 닫습니다. 매입사는 온체인 모니터링으로 결제를 여전히 감지하고 확인합니다. 주문 이행은 리디렉션이 아니라 웹훅을 기준으로 실행됩니다.
  • 구매자가 잘못된 금액을 결제하는 경우. 대부분의 매입사는 온체인 감지 시점에 금액이 일치하지 않는 결제를 거부합니다. 일부는 허용 오차 범위 안의 근사 일치를 허용하고 그 차이를 웹훅에 표시합니다.
  • 구매자가 잘못된 네트워크에서 결제하는 경우. Solana만 받는데 구매자가 Ethereum에서 서명하면, 그 결제는 매입사의 모니터링에 아예 잡히지 않습니다. 대부분의 제공업체는 복구 절차를 통해 자금을 돌려주지만, 일부는 자금을 잃습니다. 결제 화면에서 네트워크 선택을 명확히 보여 주십시오.
  • 구매자가 거래소 주소에서 결제하는 경우. 출금 주소로 보낸 환불이 반송되거나 엉뚱한 계정에 입금될 수 있습니다. 환불 가능성이 있는 상품이라면 결제 시 환불받을 주소를 명시적으로 수집하십시오.
  • 스테이블코인 디페깅. 드물지만 실제로 일어납니다. 견적과 온체인 정산 사이의 짧은 시간 동안 USDC가 크게 디페깅되면, 계약 내용에 따라 가맹점이나 매입사가 그 차이를 부담합니다.

DPT Acquiring으로 USDC 결제 추가하기

거래당 0.3%부터. USDC 또는 법정화폐로 당일 정산. 호스팅 결제 페이지 URL 또는 임베드형 위젯. SDK와 웹훅 문서는 merchant.dpt.xyz에서 확인할 수 있습니다.

DPT Acquiring · Shopify 및 WooCommerce 연동 방법