Computer Programming/AI

TIL_장바구니 비움과 주문 내역 저장

JYCoder 2023. 12. 8. 09:44

목적

결제 시스템에서 상품이 성공적으로 결제된 후, 장바구니는 비워주고 결제 내역을 따로 기록해 두려고 함

 

가능한 방법들

1) 해당 장바구니의 DB 값을 비우고, 같은 내용을 order이라는 entity로 이동하여 저장CartItem(장바구니) entity의 값 중 status(상태)가 ‘paid’일 경우, 해당 user의 장바구니 값들을 for문으로 하나 씩 가져와서 OrderItem(결제 내역) entity에 저장

2) 1)의 내용과 같지만 추가적으로 ‘transaction.atomic()’으로 감싸주어 어떠한 예외가 발생하게 된다면 rollback을 하고, 예외가 발생하지 않는다면 커밋을 하도록 함

 

선택한 방법

  • 2)의 ‘transaction.atomic()’ 방법을 선택하여 데이터베이스 작업이 안전하게 수행되고, 데이터의 일관성이 유지되도록 코드를 작성
  • 장바구니 내역 중 결제 상태가 ‘paid’인 데이터 값들을 그대로 결제 내역 DB로 저장함에 있어서 어떠한 문제로 값들이 부분적으로만 저장되거나 하는 일을 방지할 수 있음

 

Code

try:
	response = requests.get(iamport_url, headers=headers)
	response_data = response.json()
	
	# 결제 검증
	amount_to_be_paid = payment.amount
	paid_amount = response_data.get("response", {}).get("amount")
	
	if paid_amount == amount_to_be_paid:
	    payment.status = response_data.get("response", {}).get(
	        "status"
	    )  # Update the status based on the PortOne response
	    payment.paid_amount = paid_amount
	    payment.save()
	print("payment.user: ", payment.user)
	
	# 장바구니 속 상품들의 payment_id의 상태 값이 'paid'일 경우,
	# 장바구니 비워주고, Order 테이블에 상품 내역 저장
	if payment.status == "paid":
	    cart_items = CartItem.objects.filter(user=payment.user)
	
	    # To ensure consistency
	    with transaction.atomic():
	        order_items = []
	        num_purchased_coin = 0
	        for cart_item in cart_items:
	            order_item = OrderItem.objects.create(
	                user=payment.user,
	                product=cart_item.product,
	                quantity=cart_item.quantity,
	            )
	            order_items.append(order_item)
	
	            # 구입한 coin 개수만큼 해당 user에 coin 지급
	            quantity = order_item.quantity
	            product_name = order_item.product.product_name
	            match = re.search(r"\b\d+\b", product_name)
	
	            if match:
	                num_coin = int(match.group())
	                print("num_coin: ", num_coin)
	                num_purchased_coin += num_coin * quantity
	            else:
	                print("No number found in the string.")
	
	        print("num_purchased_coin: ", num_purchased_coin)
	
	        cart_items.delete()
	
	    user = get_user_model().objects.get(pk=payment.user.pk)
	    user.coin += num_purchased_coin
	    user.save()
	
	return Response({"detail": "결제 완료"}, status=response.status_code)
	
except Exception as ex:
	logging.error(f"Error: {ex}")
	return Response(
	    {"error": str(ex)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR
	)
LIST

'Computer Programming > AI' 카테고리의 다른 글

TIL_Channels  (0) 2023.12.08
TIL_PortOne을 이용한 결제 시스템  (1) 2023.12.06
TIL_Process Flow  (1) 2023.11.23
TIL_Decorator in Python  (1) 2023.11.21
TIL_When to use Redis?  (1) 2023.11.20