PoCs

HTTP 402 는 쉬운 부분이다 — 재시도는 정산의 책임이다

x402 는 결제를 HTTP 미들웨어로 만들지만, 제품의 경계는 검증이 성공하고 정산이 타임아웃된 뒤 클라이언트가 이미 결제한 요청을 재시도할 때 드러납니다.

어떻게 보나

`@x402/express` 로 멱등한 API 경로 하나를 보호하고, 단계마다 — 검증, 온체인 제출, 정산, 리소스 생성 직후 — 타임아웃을 주입합니다. 동일한 서명 요청을 재시도하며 두 불변식을 확인합니다: 정산은 최대 한 번, 정산된 결제 하나에 지속성 있는 사용 권한 하나.

기술 노트

각 항목이 실제로 무엇을 보여주고 어떻게 동작하는지 — 위 카드보다 자세한 기술 설명입니다.

HTTP 402 는 쉬운 부분이다 — 재시도는 정산의 책임이다완료

목적: Facilitator 는 판매자에게서 블록체인 배관을 없애 주지만, 분산 시스템의 의미론까지 없애 주지는 않습니다. 유료 API 에는 멱등성 키와 결제→리소스의 지속성 있는 상태 머신이 필요합니다. x402 는 스테이블코인 결제를 평범한 HTTP 미들웨어처럼 보이게 합니다: 서버가 결제 조건을 돌려주고, 클라이언트가 서명하고, facilitator 가 검증하고 정산합니다. 어려운 경계는 한 단계가 성공한 뒤 다음 응답이 사라질 때 나타납니다.

동작 방식: 멱등한 API 하나를 `@x402/express` 뒤에 두고, 검증·정산·이행 사이에 실패를 주입한 뒤, 서명된 결제 하나가 최대 한 번의 청구와 하나의 응답 권한만 만든다는 것을 증명합니다. ### PoC `@x402/express` 로 멱등한 API 경로 하나를 보호합니다. 검증 직후, 온체인 제출 직후, 정산 직후, 리소스 생성 직후에 각각 타임아웃을 주입합니다. 동일한 서명 요청을 다시 보내면서 두 불변식을 확인합니다: 결제는 최대 한 번만 정산되고, 정산된 결제 하나는 항상 지속성 있는 사용 권한 하나에 연결됩니다. ### 무엇을 증명하나 Facilitator 는 판매자가 노드를 운영하고 정산 트랜잭션을 제출하는 일을 없애 주지만, 분산 워크플로를 원자적으로 만들지는 못합니다. 애플리케이션에는 여전히 결제 식별자, 지속성 있는 상태, 재생 처리, facilitator 결과와 정규 체인 receipt 사이의 대사가 필요합니다. 참고: [x402 facilitator](https://docs.cdp.coinbase.com/x402/core-concepts/facilitator), [x402 v2 SDK](https://docs.cdp.coinbase.com/x402/migration-guide).

검토 후 보완: ### 데모가 끝나는 곳에서 제품이 시작된다 HTTP 402 와 결제 조건을 돌려주는 것은 한 시간짜리 일이고, 미들웨어는 데모를 거의 공짜로 만들어 줍니다. 미들웨어가 못 주는 것이 이것을 제품으로 만드는 부분입니다: 돈이 한 시스템(체인)에서 움직이고 상품이 다른 시스템(내 API)에서 전달되는 순간 분산 트랜잭션이 생기고, 분산 트랜잭션은 원자적으로 만들 수 없습니다. 진짜 일은 정확히 데모가 끝나는 자리 — 재시도 — 에 있습니다. ### 실패의 창은 단계 사이에 있다 "유료 요청" 하나는 네 단계 — **verify → submit → settle → fulfill** — 이고, 각 단계 사이의 네트워크 경계가 응답을 삼킬 수 있습니다. 그래서 PoC 는 단계를 실패시키는 게 아니라 각 단계 *직후*에 타임아웃을 주입합니다: 단계는 전부 성공했고 응답만 사라졌으며, 클라이언트는 합리적으로 동일한 서명 요청을 재시도합니다. | 창 | 무엇이 사실인가 | 재시도가 해야 할 일 | | --- | --- | --- | | 검증 직후 | 정산 없음, 돈 안 움직임 | 다시 검증하고 진행 — 가장 싼 창 | | 제출 직후 | 위험한 창: 전송이 실렸나? | 인가의 논스 덕에 체인이 두 번째 정산을 거부한다 — 그러니 "already used" 를 **이 결제는 이미 성공했다**로 읽어야지, 사용자에게 보여줄 에러로 읽으면 안 된다 | | 정산 직후 | 돈은 움직였는데 상품이 아직 없음 | 그 부채는 내 DB 에만 존재한다 — 크래시 *전에* 지속성 있게 기록돼 있어야 한다 | | 이행 직후 | 리소스는 있는데 전달이 유실됨 | *같은* 리소스를 돌려준다, 절대 다시 생성하지 않는다 | 두 번째 창을 오분류하는 것이, 결제가 성공한 고객이 에러 화면을 보는 경로입니다. ### 두 불변식이 제품의 전부다 서명 요청당 정산은 최대 한 번; 정산된 결제당 지속성 있는 사용 권한 정확히 하나. 나머지 — 미들웨어, facilitator, SDK — 는 교체 가능한 배관입니다. 이것은 정확히 Web2 결제의 교과서입니다: Stripe 의 `Idempotency-Key` 와, 결제 논스를 키로 삼는 지속성 있는 상태 머신(`received → verified → submitted → settled → fulfilled`). x402 가 바꾸는 것은 레일이지 의미론이 아닙니다. "재시도는 정산의 책임"이라는 말은 재시도 처리가 일반 HTTP 재시도 로직에 살 수 없다는 뜻입니다 — 재시도는 먼저 **기존 결제에 대한 조회**이고, 그 조회가 허락할 때에만 새 시도입니다. ### 주시가 산출물이 아니다 이중 청구는 지켜봐서 막을 수 없습니다 — 눈에 보였을 때는 이미 돈이 두 번 움직인 뒤입니다. 보장은 구조적이어야 합니다: 모든 응답은 사라질 수 있다고 가정하고, 재시도를 정상 경로로 취급하고, 설계 리뷰에서 플로우의 화살표 하나하나에 "이 화살표 직후의 응답이 사라지고 같은 요청이 다시 오면 무슨 일이 생기는가?"를 묻습니다. 어느 화살표든 답이 "또 청구된다"거나 "아무것도 전달 안 된다"면, 코드를 쓰기 전에 그 화살표가 버그입니다. 마지막의 대사(reconciliation) 줄은 `receipt-is-not-settlement` 의 반복입니다: facilitator 의 "정산됨"은 한 서비스의 주장이고, 권위는 체인 위의 정규 receipt 에 있습니다. 그리고 x402 가 애초에 중요한 이유는 에이전트 커머스입니다 — 계정도 API 키도 없는 요청당 결제는 AI 에이전트가 쓸 레일입니다.