핵심 요약
AI에게 결제 기능을 맡길 때 가장 위험한 프롬프트는 단순히 ‘결제 붙여줘’라고 요청하는 것입니다. 결제는 돈을 받는 코드가 아니라 돈의 흐름을 책임지는 운영·회계·고객지원 시스템입니다.
기술적으로는 결제창 연동, 승인 API 호출, 웹훅 수신, 주문 저장을 AI가 빠르게 구현할 수 있습니다. 그러나 다음 정책이 정해져 있지 않으면 실제 서비스에서는 유령 주문, 이중 결제, 환불 지연, 고객센터 폭주, 법적 고지 누락 문제가 발생할 수 있습니다.
| 결정 영역 | 미리 정해야 할 질문 | 실패 시 위험 |
|---|---|---|
| 주문 상태 | 주문은 어떤 상태를 순서대로 거치는가? | 결제는 됐지만 주문이 없는 유령 주문 발생 |
| 환불 기한 | 청약철회와 환불 처리 기한을 어떻게 반영할 것인가? | 법정 기한 위반, 지연 이자, 분쟁 위험 |
| 부분 환불 | 일부 상품 반품, 쿠폰, 배송비를 어떻게 계산할 것인가? | 운영자가 매번 수동 계산, 고객 불신 |
| 이중 결제 | 같은 주문에 결제가 두 번 잡히지 않게 어떻게 막을 것인가? | 카드 명세서 기준 고객 불만, 신뢰 하락 |
| 실패 안내 | 한도 초과, 잔액 부족, 인증 실패를 어떻게 안내할 것인가? | 재시도 전환율 하락, 불필요한 문의 증가 |
| 결제 내역 | 고객이 결제와 환불 상태를 어디서 확인하는가? | 고객센터 문의 증가, 상태 불투명 |
| 환불 고지 | 환불 규정과 취소 버튼을 어디에 배치하는가? | 다크패턴 논란, 규제 리스크 |
1. 주문 상태 설계: 상태가 곧 운영 언어다
결제 기능을 만들 때 주문 상태를 ‘주문 완료’ 하나로만 두면 안 됩니다. 실제 주문은 결제 시도, 승인, 취소, 환불, 실패, 만료 같은 여러 단계를 거칩니다.
권장 상태 예시
| 상태 코드 예시 | 고객에게 보이는 상태 | 의미 |
|---|---|---|
payment_pending |
결제 대기 | 주문은 생성됐지만 결제가 끝나지 않음 |
paid |
결제 완료 | 결제 승인이 완료되어 주문이 유효함 |
payment_failed |
결제 실패 | 결제 시도가 실패했고 재시도 가능 여부를 판단해야 함 |
cancel_requested |
취소 요청 | 고객이 취소를 신청했고 처리 대기 중임 |
cancelled |
취소 완료 | 결제 전 주문 취소 또는 승인 취소가 완료됨 |
refund_requested |
환불 요청 | 결제 후 환불 신청이 접수됨 |
refund_processing |
환불 진행 중 | 환불 승인 또는 결제수단 환급 처리 중임 |
partially_refunded |
부분 환불 완료 | 주문 금액 중 일부만 환불됨 |
refunded |
환불 완료 | 환불 처리가 완료됨 |
expired |
주문 만료 | 결제 대기 시간이 지나 주문이 무효화됨 |
상태 설계 원칙
- 주문 상태와 결제 상태를 완전히 같은 것으로 보지 않습니다. 주문은 존재하지만 결제가 실패할 수 있고, 결제는 승인됐지만 주문 저장이 실패할 수도 있습니다.
- 모든 상태 변경에는 발생 시각, 처리자, 사유, 결제 거래 식별자, 환불 거래 식별자를 남깁니다.
- 고객 화면, 관리자 화면, 고객센터 응대 문구가 같은 상태 정의를 사용해야 합니다.
- 상태 전이는 일방향으로 설계하고, 예외 복구는 별도 관리자 권한으로 기록을 남겨 처리합니다.
2. 청약철회와 법정 환불 기한: 정책이 아니라 법적 요구사항이다
한국에서 소비자 대상 전자상거래를 운영한다면 전자상거래 등에서의 소비자보호에 관한 법률을 고려해야 합니다. 일반적으로 소비자는 일정 기간 안에 청약철회를 할 수 있고, 사업자는 환불 요청 또는 반환 절차 이후 정해진 기한 안에 대금을 환급해야 합니다.
실무에서 특히 중요한 기준은 다음과 같습니다.
- 소비자는 원칙적으로 재화 등을 공급받은 날 등 법이 정한 기준일부터 7일 이내에 청약철회를 할 수 있습니다.
- 사업자는 환급 사유가 발생한 뒤 법정 기한 안에 대금을 환급해야 하며, 지연되는 경우 지연 배상금 또는 지연 이자 문제가 생길 수 있습니다.
- 디지털 콘텐츠, 맞춤 제작 상품, 사용으로 가치가 현저히 감소하는 상품 등은 예외가 될 수 있지만, 예외를 적용하려면 사전 고지와 동의 등 요건을 신중히 확인해야 합니다.
- 실제 적용은 상품 유형, 계약 방식, 소비자에게 제공한 고지, 사용 개시 여부에 따라 달라질 수 있으므로 법무 검토가 필요합니다.
개발 요구사항으로 바꾸는 방법
법적 기준은 약관 문구에만 적어두면 부족합니다. 시스템 요구사항으로도 바꿔야 합니다.
| 법·정책 요구 | 시스템 요구사항 |
|---|---|
| 7일 내 청약철회 가능 여부 판단 | 주문 수령일 또는 서비스 제공일 기준으로 환불 가능 기간 자동 계산 |
| 3영업일 내 환급 처리 필요 | 관리자 화면에 환불 신청일과 처리 마감일 표시 |
| 환급 지연 위험 | 마감 임박, 마감 초과 알림 표시 |
| 예외 상품 고지 필요 | 결제 전 환불 제한 상품임을 명확히 표시하고 동의 로그 저장 |
| 분쟁 대응 필요 | 약관 버전, 고지 시각, 동의 시각, 고객 IP 또는 계정 로그 보관 |
3. 부분 환불 규칙: 쿠폰, 배송비, 세금을 미리 정의한다
부분 환불은 전체 취소보다 훨씬 복잡합니다. 여러 상품을 한 번에 주문한 뒤 일부만 반품하면, 원래 적용된 할인과 배송비를 어떻게 나눌지 결정해야 합니다.
반드시 정해야 할 항목
- 상품별 결제 금액을 어떻게 배분할 것인가
- 주문 전체 쿠폰을 상품별로 비례 배분할 것인가
- 특정 상품 쿠폰은 해당 상품에만 적용할 것인가
- 무료배송 조건이 깨졌을 때 배송비를 차감할 것인가
- 단순 변심 반품 배송비와 상품 하자 반품 배송비를 어떻게 구분할 것인가
- 포인트, 적립금, 기프트카드 결제분을 어떤 순서로 환급할 것인가
- 부분 환불 후 세금계산서, 현금영수증, 영수증 표기를 어떻게 바꿀 것인가
부분 환불 계산 예시
| 항목 | 금액 |
|---|---|
| A 상품 | 30,000원 |
| B 상품 | 70,000원 |
| 주문 전체 쿠폰 | -10,000원 |
| 실제 결제 금액 | 90,000원 |
쿠폰을 상품 금액 비율로 배분하면 A 상품에는 3,000원, B 상품에는 7,000원의 할인이 배분됩니다. 이때 A 상품만 환불하면 환불 기준 금액은 30,000원이 아니라 27,000원입니다. 무료배송 조건, 반품 배송비, 결제수단별 환급 제한이 있다면 최종 환불액은 더 달라질 수 있습니다.
정답은 하나가 아닙니다. 중요한 것은 일관된 규칙을 사전에 정하고, 고객이 결제 전 또는 환불 신청 전에 이해할 수 있게 고지하는 것입니다.
4. 이중 결제 방지: 버튼 비활성화만으로는 부족하다
이중 결제는 고객이 가장 빠르게 발견하는 결제 사고입니다. 고객은 서비스 내부 주문 상태보다 카드 승인 문자와 카드 명세서를 먼저 봅니다. 같은 주문이 두 번 결제되면 신뢰가 크게 떨어집니다.
발생 원인
- 고객이 결제 버튼을 연속 클릭함
- 결제 직후 새로고침하거나 뒤로 가기를 누름
- 모바일 네트워크 지연으로 같은 요청이 재전송됨
- 결제 승인 응답은 성공했지만 서비스 서버 저장이 실패함
- 웹훅과 클라이언트 리다이렉트가 동시에 주문 상태를 변경함
방어 설계
| 방어 장치 | 설명 |
|---|---|
| 클라이언트 버튼 잠금 | 결제 버튼 클릭 후 재클릭을 막지만 보조 수단으로만 사용 |
| 서버 단 주문 잠금 | 같은 주문 ID에 대해 동시에 결제 승인 요청이 실행되지 않게 처리 |
| 멱등성 키 | 같은 결제 요청을 여러 번 보내도 결과가 한 번만 생성되게 하는 식별자 사용 |
| 고유 거래번호 | 주문 번호와 결제 거래번호의 중복 저장을 데이터베이스 제약조건으로 방지 |
| 상태 기반 검증 | 이미 paid인 주문에는 추가 승인 요청을 막음 |
| 웹훅 중복 처리 | 같은 웹훅 이벤트가 여러 번 와도 상태 변경이 한 번만 일어나게 처리 |
AI에게 결제 코드를 요청할 때는 ‘중복 클릭 방지’가 아니라 ‘동일 주문에 대해 결제 승인과 결제 완료 처리는 멱등하게 동작해야 한다’고 명시하는 것이 좋습니다.
5. 결제 실패 안내 문구: 실패는 사고가 아니라 정상 흐름이다
결제 실패는 매일 발생하는 정상 상황입니다. 한도 초과, 잔액 부족, 카드 인증 실패, 비밀번호 오류, 3D Secure 인증 실패, 간편결제 앱 미응답, 네트워크 오류는 모두 흔한 케이스입니다.
나쁜 안내는 ‘오류가 발생했습니다’로 끝나는 문구입니다. 고객은 결제가 된 것인지, 다시 눌러도 되는지, 주문이 사라지는지 알 수 없습니다.
안내 문구 예시
| 상황 | 권장 안내 |
|---|---|
| 잔액 부족 | 결제수단의 잔액이 부족해 결제가 완료되지 않았습니다. 다른 결제수단을 선택하거나 잔액을 확인한 뒤 다시 시도해 주세요. |
| 한도 초과 | 카드 한도 또는 1회 결제 한도를 초과해 결제가 실패했습니다. 카드사 앱에서 한도를 확인하거나 다른 카드로 결제해 주세요. |
| 인증 실패 | 결제 인증이 완료되지 않아 주문이 결제 대기 상태로 유지됩니다. 30분 안에 다시 결제할 수 있습니다. |
| 네트워크 오류 | 결제 결과 확인이 지연되고 있습니다. 중복 결제를 막기 위해 잠시 후 결제 내역을 확인해 주세요. |
| 주문 만료 | 결제 대기 시간이 지나 주문이 만료되었습니다. 상품을 다시 선택해 주문해 주세요. |
실패 안내의 핵심 요소
- 결제가 실제로 완료되지 않았는지 명확히 말합니다.
- 주문이 유지되는 시간을 알려줍니다.
- 다시 시도해도 되는지, 다른 결제수단을 써야 하는지 안내합니다.
- 고객센터에 문의할 때 필요한 주문번호를 보여줍니다.
- 결제 결과가 불확실한 경우 무조건 재결제를 유도하지 말고 확인 중 상태를 제공합니다.