diff --git a/payments/mixins.py b/payments/mixins.py index c0cfbe8..6378e8d 100644 --- a/payments/mixins.py +++ b/payments/mixins.py @@ -141,12 +141,17 @@ def validate_order(self, order): raise ValidationError("결제 가능한 상태의 주문이 아닙니다.") if order.get_total_price() > 50000: raise ValidationError("결제 금액이 50,000원을 초과할 수 없습니다.") - if order.payments.filter(payment_status__in=["completed", "pending"]).exists(): - raise ValidationError("이미 결제가 완료되었거나 진행 중인 주문입니다.") def create_payment(self, order, user): self.validate_order(order) + existing_payments = Payment.objects.filter( + order=order, payment_status="pending" + ) + if existing_payments.exists(): + # 모든 기존 pending payment를 취소 처리 + existing_payments.update(payment_status="cancelled") + try: kakao_response = self.kakao_pay_service.request_payment(order) except Exception as e: diff --git a/payments/views.py b/payments/views.py index 5db952a..b37f78e 100644 --- a/payments/views.py +++ b/payments/views.py @@ -265,7 +265,12 @@ def get_queryset(self): @transaction.atomic def post(self, request): - order = self.get_queryset().filter(order_status="pending").select_for_update().first() + order = ( + self.get_queryset() + .filter(order_status="pending") + .select_for_update() + .first() + ) if not order: return Response( {"detail": "진행 중인 주문이 없습니다."}, @@ -302,23 +307,16 @@ def get(self, request): status=status.HTTP_404_NOT_FOUND, ) - # 가장 최근의 pending payment를 가져오고 나머지는 취소 처리 - payments = list( - Payment.objects.filter(order=order, payment_status="pending").order_by( - "-created_at" - ) + payment = ( + Payment.objects.filter(order=order, payment_status="pending") + .order_by("-created_at") + .first() ) - if not payments: + if not payment: return Response( {"detail": "해당 주문에 대한 대기 중인 결제를 찾을 수 없습니다."}, status=status.HTTP_404_NOT_FOUND, ) - payment = payments[0] - # 가장 최근의 pending payment를 제외한 나머지 payment를 취소 처리 - if len(payments) > 1: - Payment.objects.filter(id__in=[p.id for p in payments[1:]]).update( - payment_status="cancelled" - ) result = request.GET.get("result") pg_token = request.GET.get("pg_token")