주요 콘텐츠로 건너뛰기

결제 및 주문 상태 모델

이 페이지는 Aghanim 플랫폼에서 결제와 주문의 수명 주기를 설명합니다: 모든 상태, 모든 전환, 그리고 결제 상태 변경이 주문 상태를 어떻게 이끄는지를 다룹니다. 어떤 웹훅이 언제 발생하는지, 플레이어가 언제 재시도할 수 있는지, 그리고 중복 청구나 조기 권한 회수를 어떻게 피할 수 있는지 이해하는 데 사용하세요.

무엇이 안정적이고 무엇이 그렇지 않은가

여기에 설명된 웹훅 이벤트와 API 상태 값은 공개 통합 계약의 일부입니다. 이 페이지에 설명된 상태 간의 구체적인 중간 전환은 기술적 명확성을 위해 문서화되었지만 구현 세부 사항입니다. 이는 플랫폼이 성장함에 따라 변경될 수 있습니다. 특정 전환 그래프가 아니라 웹훅 이벤트와 API 상태 값을 기준으로 통합을 구축하세요.

개요

Aghanim은 구매 수명 주기에서 두 가지 엔티티를 구분합니다:

  • 결제(Payment) — 결제 제공업체를 통해 플레이어에게 청구하려는 단일 시도입니다. 하나의 주문은 여러 번의 결제 시도를 가질 수 있습니다(예: 카드 거절 이후). 각 시도는 별도의 결제 기록입니다.
  • 주문(Order) — 논리적인 구매 기록입니다(플레이어가 아이템, 번들 또는 구독을 구매하는 것). 플랫폼은 결제 전환에 대응하여 주문 상태를 업데이트합니다.

주문은 해당 결제 중 하나가 성공하거나, 환불이 완료되거나, 분쟁이 플레이어에게 불리하게 해결될 때에만 종료됩니다.

새 결제 기록이 생성되기 전에 플랫폼은 주문을 created(또는 reattempted)에서 captured로 이동시켜 주문을 잠급니다. 이 잠금은 동일한 주문에 대한 두 개의 동시 결제 시도를 방지합니다.

결제 수명 주기

결제 상태

상태종료웹훅 이벤트의미
created아니오payment.pending결제가 시작되었습니다. 플레이어가 거래를 시작했으며 Aghanim은 결제 제공업체가 결과를 확인하기를 기다리고 있습니다. 이 시점에 payment.pending이 발생합니다.
done아니오payment.succeeded결제가 성공적으로 캡처되었습니다. 이후 dispute 또는 refund_requested로 이동할 수 있습니다. 분쟁 해결 또는 실패한 환불 복구를 통해 done으로 진입할 때에도 payment.succeeded 웹훅이 발생하므로, 페이로드를 검사하여 구분하세요.
dispute아니오payment.dispute이전에 성공한 결제에 대해 차지백이 제기되었습니다. 해결되면 done(판매자 승소, 차지백 철회) 또는 chargeback(플레이어 승소, 차지백 인정)으로 다시 이동합니다.
refund_requested아니오환불이 접수되었지만 결제 제공업체가 아직 확인하지 않았습니다. 이 상태로 진입할 때는 웹훅이 발생하지 않습니다. payment.refunded(환불 완료) 또는 payment.succeeded(환불을 처리할 수 없어 결제가 done으로 돌아감)를 기다리세요.
refundedpayment.refunded결제 제공업체가 환불을 확인했지만, 자금이 아직 플레이어의 계좌로 반환되지 않았을 수 있습니다.
failedpayment.declined처리 중 결제가 거절되었거나 오류가 발생했습니다.
expiredpayment.expired결제가 제시간에 완료되지 않아 결제 제공업체가 결제를 만료된 것으로 보고했습니다. Aghanim은 제공업체가 보고할 때(웹훅 또는 상태 폴링을 통해)에만 결제를 expired로 이동시키며, 그렇지 않으면 결제는 created 상태로 유지됩니다.
voidedpayment.voided결제가 승인되었지만 캡처 전에 무효화되었으며, 일반적으로 승인 후 검사(국가 불일치, 이상 거래 방지) 때문입니다.
rejectedpayment.rejected제출 전에 결제가 거부되었으며, 일반적으로 이상 거래 방지 시스템에 의한 것입니다.
abandonedpayment.abandoned플레이어가 명시적으로 결제 절차를 중단했습니다(페이지를 닫거나, 취소하거나, 뒤로 가기를 눌렀습니다). 결제가 제시간에 완료되지 않았을 때 결제 제공업체가 보고하는 expired와는 구별됩니다.
chargebackpayment.chargeback플레이어가 차지백 분쟁에서 승소하여 결제가 취소되었습니다. 자금은 플레이어의 은행에 의해 플레이어에게 반환되었거나 반환될 예정입니다.

결제 전환

시작대상원인종료
createddone결제 제공업체가 성공적인 캡처를 확인함아니오
createdfailed결제 제공업체가 결제를 거절하거나 오류를 반환함
createdrejected이상 거래 방지 시스템이 결제를 거부함
createdexpired결제 제공업체가 결제를 만료된 것으로 보고함(웹훅 또는 상태 폴링을 통해)
createdvoided승인 후 검사 실패(국가 불일치, 이상 거래 방지)
createdabandoned플레이어가 명시적으로 결제 절차를 중단함
donedispute성공한 결제에 대해 차지백이 제기되거나 환불이 요청됨아니오
donerefund_requested환불이 접수되었으나 결제 제공업체의 확인 대기 중아니오
donerefunded결제 제공업체가 환불을 즉시 확인함
refund_requestedrefunded결제 제공업체가 보류 중인 환불을 확인함
refund_requesteddone환불을 처리할 수 없었음아니오
disputedone차지백 철회(판매자가 분쟁을 방어함)아니오
disputechargeback은행이 차지백을 인정함

결제 상태 다이어그램

created에서 done을 거쳐 종료 상태로 전환되는 과정을 보여주는 결제 상태 다이어그램.
created에서 done을 거쳐 종료 상태로 전환되는 과정을 보여주는 결제 상태 다이어그램.

주문 수명 주기

통합에서 확인할 수 있는 주문 상태 값:

상태종료의미
created아니오주문이 생성되었습니다. 아직 결제 시도가 시작되지 않았습니다.
captured아니오결제 시도가 진행 중입니다. 주문이 병렬 결제 시도에 대해 잠겨 있습니다.
reattempted아니오이전 결제 시도가 비종료 방식으로 실패했습니다. 주문이 새로운 결제 시도를 위해 열려 있습니다.
paid아니오이 주문에 대한 결제가 성공했습니다. 주문이 전달 단계로 진행됩니다.
disputed아니오이 주문에 대한 결제가 분쟁 중입니다.
refund_requested아니오환불이 접수되었습니다.
refunded환불이 완료되었습니다.
canceled해결된 분쟁을 통해 도달합니다.

결제 상태가 주문 상태를 이끄는 방식

주문 상태 변경은 결제 전환에 의해 트리거됩니다:

결제 전환주문 상태효과
(결제 기록 생성 전)created 또는 reattemptedcaptured주문이 동시 결제 시도에 대해 잠김
createddonecapturedpaiditem.add 발생
createdfailedcapturedreattempted플레이어가 재시도 가능
createdrejectedcapturedreattempted플레이어가 재시도 가능
createdexpiredcapturedreattempted플레이어가 재시도 가능
createdvoidedcapturedreattempted플레이어가 재시도 가능
createdabandonedcapturedreattempted플레이어가 재시도 가능
donedisputepaiddisputed분쟁 워크플로
donerefund_requestedpaidrefund_requested환불 보류 중
done / refund_requestedrefundedrefunded종료; item.remove 발생
disputechargebackdisputedcanceled종료; item.remove 발생
disputedonedisputedpaid분쟁 해결됨; 권한 유지

주문 상태 다이어그램

created에서 paid를 거쳐 refunded 또는 canceled로 전환되는 과정을 보여주는 주문 상태 다이어그램.
created에서 paid를 거쳐 refunded 또는 canceled로 전환되는 과정을 보여주는 주문 상태 다이어그램.

수명 주기 동안 발생하는 웹훅

위의 전환은 통합에 전달되는 웹훅을 이끕니다:

  • payment.pending — 결제가 created에 진입할 때(플레이어가 거래를 시작할 때) 발생합니다.
  • payment.succeeded — 세 가지 서로 다른 전환에서 발생합니다: 정상적인 성공 경로(created → done), 플레이어에게 불리하게 해결된 분쟁(dispute → done), 그리고 처리할 수 없었던 환불(refund_requested → done). 이 이벤트에서 수익을 집계하는 통합은 복구를 이중 계산하지 않도록 페이로드를 검사해야 합니다.
  • payment.chargeback — 플레이어가 차지백 분쟁에서 승소할 때 dispute → chargeback에서 발생합니다. 자금은 플레이어의 은행에 의해 플레이어에게 반환되었거나 반환될 예정입니다.
  • payment.abandoned — 결제가 abandoned에 진입할 때(플레이어가 명시적으로 결제 절차를 중단할 때) 발생합니다. 결제가 제시간에 완료되지 않았을 때 결제 제공업체가 보고하는 payment.expired와는 구별됩니다.
  • 결제가 refund_requested에 진입할 때는 웹훅이 발생하지 않습니다. 최종 해결을 수신 대기하세요: 환불이 완료되면 payment.refunded, 처리할 수 없으면 payment.succeeded.
  • item.add — 성공 경로에서만 발생합니다: 결제가 created → done으로 전환되고 주문이 paid로 이동할 때.
  • item.remove — 두 가지 종료 주문 결과에서 발생합니다: 주문이 refunded에 도달할 때(refund_requested → refunded 포함) 및 disputed → canceled일 때(차지백 인정). 분쟁을 제기(paid → disputed)하거나 환불을 접수(paid → refund_requested)하는 것은 item.remove를 발생시키지 않습니다 — 최종 해결만이 발생시킵니다.
  • failed, rejected, expired 또는 voided로 종료되는 결제는 item.add를 생성하지 않습니다. 주문은 reattempted로 돌아가고 플레이어는 재시도할 수 있습니다.

플레이어가 구매를 완료하려면 해당 결제 시도 중 하나가 done에 도달해야 합니다. 다른 모든 종료 상태는 주문을 또 다른 시도를 위해 열어 둡니다. 결제가 done이 되면 → refunded 또는 disputed → canceled만이 item.remove를 통해 권한을 회수합니다.

실무 지침

일부 결제 수단 — 통신사 청구, 특정 지갑, 그리고 특정 흐름의 PayPal — 은 결제 제공업체가 결과를 확인하기 전까지 결제를 몇 분 이상 created 상태로 유지할 수 있습니다. 이러한 흐름을 올바르게 처리하고 중복 청구나 조기 권한 회수를 피하려면, 통합은 다음을 수행해야 합니다:

  1. payment.pending을 플레이어에게 구매가 진행 중임을 표시하고 클라이언트에서 동일한 아이템에 대한 반복 구매 시도를 차단하는 신호로 취급하세요.
  2. 합리적인 시간 내에(대부분의 수단의 경우 10~20분) item.add가 도착하지 않으면, 결제 시 반환된 order_idGet Order를 호출하여 현재 주문 상태를 검사하세요.
  3. 다음 중 하나가 발생하면 차단을 해제하세요:
    • item.add가 도착함 — 결제가 성공했습니다.
    • 실패 웹훅이 도착함 — payment.declined, payment.expired, payment.voided, payment.rejected 또는 payment.abandoned. 시도가 종료되고 주문이 reattempted로 돌아가므로 플레이어가 재시도할 수 있습니다.
    • 주문이 종료 상태(refunded 또는 canceled)에 도달함.
  4. item.remove를 권한을 회수하는 유일한 신호로 취급하세요. paid → disputed 또는 paid → refund_requested에서는 회수하지 마세요 — 둘 다 되돌릴 수 있으며(분쟁에서 승소할 수 있고, 환불이 거부될 수 있음) 플레이어는 아이템을 유지합니다.
  5. 모든 Aghanim 웹훅 전달에는 idempotency_key가 포함됩니다. 이를 사용하여 사용자 측에서 반복된 전달을 중복 제거하세요. 전체 계약은 Idempotency를 참조하세요.

도움이 필요하세요?
통합팀에 문의하십시오 integration@aghanim.com