def test_product_detail_view(self): new_user = User.objects.create_user('testuser', '*****@*****.**', 'password') self.client.login(username='******', password='******') product1 = Product.objects.create(name='test1', description='p1', price=1) product1.save() order = Order.objects.create(full_name='John Doe', phone_number='123456789', country='Netherlands', postcode='1234', town_or_city='Amsterdam', street_address1='Street', street_address2='22', county='North', date='2020-06-09') order_line_item1 = OrderLineItem(user=new_user, order=order, product=product1, quantity=1) order_line_item1.save() response = self.client.get('/products/1', content_type="html/text", follow=True) check_product = Product.objects.get(pk=1) self.assertEqual(check_product.view_count, 1) self.assertEqual(get_user_purchases(new_user), ['test1'])
def handle_payment_intent_succeeded(self, event): """ Handle payment_intent.succeeded webhook """ intent = event.data.object payment_intent_id = intent.id basket = intent.metadata.basket username = intent.metadata.user order_exists = False attempt = 1 while attempt <= 5: try: order = Order.objects.get( stripe_id=payment_intent_id, original_basket=basket, ) order_exists = True break except Order.DoesNotExist: attempt += 1 time.sleep(1) if order_exists: self._send_confirmation_email(order) return HttpResponse( content=f'Webhook received: {event["type"]} | SUCCESS: \ Order already in database', status=200) else: order = None try: user = get_object_or_404(User, username=username) profile = get_object_or_404(UserProfile, user=user) order = Order.objects.create( profile=profile, stripe_id=payment_intent_id, original_basket=basket, full_name=( intent.charges.data[0]['billing_details']['name']), email=intent.charges.data[0]['billing_details']['email'], ) for lesson_id, value in json.loads(basket).items(): lesson = get_object_or_404(Lesson, lesson_id=lesson_id) order_line_item = OrderLineItem( order=order, lesson=lesson, profile=profile, ) order_line_item.save() except Exception as e: if order: order.delete() return HttpResponse( content=f'Webhook received: {event["type"]} | \ Error: {e}', status=500) self._send_confirmation_email(order) return HttpResponse(content=f'Webhook received: {event["type"]} | \ Success: Created order in webhook', status=200)
def test_can_create_a_order_line_item(self): orderlineitem = OrderLineItem(order_id=3, product_id=1, quantity=2, size='Large') orderlineitem.save() self.assertEqual(orderlineitem.order_id, 3) self.assertEqual(orderlineitem.product_id, 1) self.assertEqual(orderlineitem.quantity, 2) self.assertEqual(orderlineitem.size, 'Large')
def save_order_items(userid, order, cart): for id, quantity in cart.items(): print(userid) print(f"Typeis: {type(userid)}") product = get_object_or_404(BaseProduct, pk=id) shopper = get_object_or_404(User, pk=userid) order_line_item = OrderLineItem(order=order, product=product, quantity=quantity, shopper=shopper) order_line_item.save()
def checkout(request): if request.method == 'POST': order_form = OrderForm(request.POST) payment_form = MakePaymentForm(request.POST) if order_form.is_valid() and payment_form.is_valid(): order = order_form.save(commit=False) order.date = timezone.now() order.save() cart = request.session.get('cart', {}) total = 0 for id, quantity in cart.items(): product = get_object_or_404(Product, pk=id) total += quantity * product.price order_line_item = OrderLineItem(order=order, product=product, quantity=quantity) order_line_item.save() try: customer = stripe.Charge.create( amount=int(total * 100), # as it is in pence currency="gbp", description=request.user.email, card=payment_form.cleaned_data['stripe_id'], ) except: messages.error(request, "Your card was declined") if customer.paid: messages.error(request, "You have successfully paid") request.session['cart'] = {} return redirect(reverse('products')) else: messages.error(request, "Unable to take payment at this time") else: print(payment_form.errors) messages.error(request, "We are unable to take a payment with that card") else: payment_form = MakePaymentForm() order_form = OrderForm() return render( request, "checkout.html", { 'order_form': order_form, 'payment_form': payment_form, 'publishable': settings.STRIPE_PUBLISHABLE })
def test_get_all_products_as_logged_in_user(self): product1 = Product.objects.create(name='test1', description='p1', price=1) product2 = Product.objects.create(name='test2', description='p2', price=2) product3 = Product.objects.create(name='test3', description='p3', price=3) product4 = Product.objects.create(name='test4', description='p4', price=4) new_user = User.objects.create_user('testuser', '*****@*****.**', 'password') self.client.login(username='******', password='******') order = Order.objects.create(full_name='John Doe', phone_number='123456789', country='Netherlands', postcode='1234', town_or_city='Amsterdam', street_address1='Street', street_address2='22', county='North', date='2020-06-09') order_line_item1 = OrderLineItem(user=new_user, order=order, product=product1, quantity=1) order_line_item2 = OrderLineItem(user=new_user, order=order, product=product2, quantity=2) order_line_item3 = OrderLineItem(user=new_user, order=order, product=product3, quantity=3) response = self.client.get("/products/", content_type="html/text", follow=True) self.assertEqual(response.status_code, 200) self.assertIn(b'test1', response.content) self.assertIn(b'test2', response.content) self.assertIn(b'test3', response.content) self.assertIn(b'test4', response.content)
def confirm_pre_order(request, order_number): """ view upgrading preorder and creating a corresponding order """ if not request.user.is_superuser: messages.error(request, 'Sorry, only store owners can see that.') return redirect(reverse('home')) pre_order = get_object_or_404(PreOrder, order_number=order_number) pp_transaction_id = request.POST['pp_transaction_id'] order = Order(user_profile=pre_order.user_profile, full_name=pre_order.full_name, email=pre_order.email, phone_number=pre_order.phone_number, country=pre_order.country, postcode=pre_order.postcode, town_or_city=pre_order.town_or_city, street_address1=pre_order.street_address1, street_address2=pre_order.street_address2, county=pre_order.county, delivery_cost=pre_order.delivery_cost, order_total=pre_order.order_total, grand_total=pre_order.grand_total, pp_transaction_id=pp_transaction_id) # save order order.save() # copy line items from preorder to order for li in pre_order.lineitems.all(): order_line_item = OrderLineItem( order=order, product=li.product, quantity=li.quantity, ) order_line_item.save() # update product reserved, sold product = li.product quantity = li.quantity product.sold = product.sold + quantity product.reserved = product.reserved - quantity product.save() # update preorder pre_order.upgraded_order = order pre_order.status = "UPG" pre_order.save() # success message messages.success(request, (f'Preorder {pre_order.order_number} upgraded.' f'New order {order.order_number} confirmed.')) return redirect(reverse('products_management'))
class OrderTests(TestCase): """ Testing order line item total calculation """ def test_subtotal_calculation(self): self.product = Product(name='test_name', price=11, description='test_description', ) self.product.save() self.order = Order( full_name="Test User", email="*****@*****.**", phone_number="12345", country="gb", postcode="e114dr", town_or_city="london", street_address1="40 test road", original_bag="", stripe_pid="", ) self.order.save() self.order_line_item = OrderLineItem( order=self.order, product=self.product, quantity=2, ) self.order_line_item.save() ''' Testing product and order is created ''' self.assertEqual(str(self.product.name), 'test_name') self.assertEqual(str(self.order.full_name), 'Test User') ''' Testing order line item ''' self.assertEqual(str(self.order_line_item.lineitem_total), '22') ''' Testing order total ''' self.assertEqual(str(self.order.order_total), '22')
def test_total_contributions(self): user = User.objects.create_user(username='******', password='******') feature = Feature(title="Test Post", author=user, content="Test Content") feature.save() order = Order(full_name = "Patrick Doherty", phone_number = "02871774646", country = "Ireland", postcode = "BT829DE", town_or_city = "Strabane", street_address1 = "5 Lasts Lane", street_address2 = "Urney Road", county = "Tyrone", date = timezone.now()) order.save() contribution = OrderLineItem(order=order, feature=feature, user=user, contribution =50) contribution.save() page = self.client.get("/features/{0}/{1}/".format(feature.id, feature.slug)) self.assertEqual(page.status_code, 200) self.assertTemplateUsed(page, "features/feature_detail.html") self.assertEqual(page.context["total_contributions"], 50) self.assertContains(page, 'Test Content') self.assertEqual(str(order), "{0}-{1}-{2}".format(order.id, order.date, order.full_name)) self.assertEqual(str(contribution), "{0}-{1}-{2}".format(contribution.contribution, feature.title, user.username))
def submit_payment(request): cart = request.session.get('cart', {}) cart_items_and_total = get_cart_items_and_total(cart) payment_form = MakePaymentForm(request.POST) order_form = OrderForm(request.POST) if order_form.is_valid() and payment_form.is_valid(): # save the order to the database order = order_form.save() cart = request.session.get('cart', {}) for product_id, quantity in cart.items(): line_item = OrderLineItem() line_item.product_id = product_id line_item.quantity = quantity line_item.order = order line_item.save() #Grab the money and run! total = cart_items_and_total['cart_total'] stripe_token=payment_form.cleaned_data['stripe_id'] try: total_in_cent = int(total*100) customer = stripe.Charge.create( amount=total_in_cent, currency="EUR", description="Dummy Transaction", card=stripe_token, ) except stripe.error.CardError: print("Declined") messages.error(request, "Your card was declined!") if customer.paid: print("Paid") messages.error(request, "You have successfully paid") # clear the cart del request.session['cart'] #redirect to home return redirect("/")
def checkout(request): stripe_public_key = settings.STRIPE_PUBLIC_KEY stripe_secret_key = settings.STRIPE_SECRET_KEY if request.method == 'POST': cart = request.session.get('cart', {}) form_data = { 'full_name': request.POST['full_name'], 'email': request.POST['email'], 'phone_number': request.POST['phone_number'], 'country': request.POST['country'], 'postcode': request.POST['postcode'], 'town_or_city': request.POST['town_or_city'], 'street_address1': request.POST['street_address1'], 'street_address2': request.POST['street_address2'], 'county': request.POST['county'], } order_form = OrderForm(form_data) if order_form.is_valid(): order = order_form.save(commit=False) pid = request.POST.get('client_secret').split('_secret')[0] order.stripe_pid = pid order.original_cart = json.dumps(cart) order.save() for item_id, quantity in cart.items(): try: product = Album.objects.get(id=item_id) order_line_item = OrderLineItem(order=order, product=product, quantity=quantity) order_line_item.save() except Album.DoesNotExist: messages.error( request, (f'Album with title {product.title} could' ' not be processed. Please contact us for details.')) order.delete() return redirect(reverse('view_cart')) request.session['save_info'] = 'save-info' in request.POST return redirect( reverse('checkout_success', args=[order.order_number])) else: cart = request.session.get('cart', {}) if not cart: messages.error(request, 'Your cart is empty') return redirect(reverse('products')) current_cart = cart_contents(request) total = current_cart['grand_total'] stripe_total = round(total * 100) stripe.api_key = stripe_secret_key intent = stripe.PaymentIntent.create( amount=stripe_total, currency=settings.STRIPE_CURRENCY, ) if request.user.is_authenticated: try: profile = UserProfile.objects.get(user=request.user) order_form = OrderForm( initial={ 'full_name': profile.default_full_name, 'email': profile.user.email, 'phone_number': profile.default_phone_number, 'country': profile.default_country, 'postcode': profile.default_postcode, 'town_or_city': profile.default_town_or_city, 'street_address1': profile.default_street_address1, 'street_address2': profile.default_street_address2, 'county': profile.default_county, }) except UserProfile.DoesNotExist: order_form = OrderForm() else: order_form = OrderForm() template = 'checkout/checkout.html' context = { 'order_form': order_form, 'stripe_public_key': stripe_public_key, 'client_secret': intent.client_secret } return render(request, template, context)
def handle_payment_intent_succeeded(self, event): """ Handle the payment_intent.succeeded webhook from Stripe """ intent = event.data.object pid = intent.id customer = intent.get('customer') # Bypass if subscription purchase if customer: return HttpResponse( content=f'Webhook received: {event["type"]} | SUCCESS: \ Stripe Subscription Customer', status=200) else: basket = intent.metadata.basket save_info = intent.metadata.save_info billing_details = intent.charges.data[0].billing_details shipping_details = intent.shipping grand_total = round(intent.charges.data[0].amount / 100, 2) # Set empty strings to null for field, value in shipping_details.address.items(): if value == "": shipping_details.address[field] = None # Update profile information if save_info was checked profile = None username = intent.metadata.username if username != 'AnonymousUser': profile = UserProfile.objects.get(user__username=username) if save_info: profile.default_phone_number = shipping_details.phone profile.default_street_address1 = shipping_details.address.line1 profile.default_street_address2 = shipping_details.address.line2 profile.default_town_or_city = shipping_details.address.city profile.default_county = shipping_details.address.state profile.default_country = shipping_details.address.country profile.default_postcode = shipping_details.address.postal_code profile.save() order_exists = False attempt = 1 while attempt <= 5: try: order = Order.objects.get( full_name__iexact=shipping_details.name, email__iexact=billing_details.email, phone_number__iexact=shipping_details.phone, street_address1__iexact=shipping_details.address.line1, street_address2__iexact=shipping_details.address.line2, town_or_city__iexact=shipping_details.address.city, county__iexact=shipping_details.address.state, country__iexact=shipping_details.address.country, postcode__iexact=shipping_details.address.postal_code, grand_total=grand_total, original_basket=basket, stripe_pid=pid, ) order_exists = True break except Order.DoesNotExist: attempt += 1 time.sleep(1) if order_exists: self._send_confirmation_email(order) return HttpResponse( content=f'Webhook received: {event["type"]} | SUCCESS: \ Verified order already in database', status=200) else: order = None try: order = Order.objects.create( full_name=shipping_details.name, user_profile=profile, email=billing_details.email, phone_number=shipping_details.phone, street_address1=shipping_details.address.line1, street_address2=shipping_details.address.line2, town_or_city=shipping_details.address.city, county=shipping_details.address.state, country=shipping_details.address.country, postcode=shipping_details.address.postal_code, original_basket=basket, stripe_pid=pid, ) for item_id, item_data in json.loads(basket).items(): product = get_object_or_404(Product, id=item_id) order_line_item = OrderLineItem( order=order, product=product, quantity=item_data, ) order_line_item.save() if not product.inventory_updated: product.remove_items_from_inventory( count=item_data, save=True) except Exception as e: if order: order.delete() return HttpResponse( content=f'Webhook received: {event["type"]} \ | ERROR: {e}', status=500) self._send_confirmation_email(order) return HttpResponse( content=f'Webhook received: {event["type"]} | SUCCESS: \ Created order in webhook', status=200)
def checkout(request): """ A view to render checkout page """ public_key = settings.STRIPE_PUBLIC_KEY secret_key = settings.STRIPE_SECRET_KEY if request.method == 'POST': bag = request.session.get('bag', {}) form_data = { 'full_name': request.POST['full_name'], 'email': request.POST['email'], 'phone_number': request.POST['phone_number'], 'country': request.POST['country'], 'postcode': request.POST['postcode'], 'town_or_city': request.POST['town_or_city'], 'street_address1': request.POST['street_address1'], 'street_address2': request.POST['street_address2'], 'county': request.POST['county'], } order_form = OrderForm(form_data) if order_form.is_valid(): order = order_form.save(commit=False) pid = request.POST.get('client_secret').split('_secret')[0] order.stripe_pid = pid order.original_bag = json.dumps(bag) order.save() for workshop_id, quantity in bag.items(): try: workshop = Workshop.objects.get(id=workshop_id) if isinstance(quantity, int): order_line_item = OrderLineItem( order=order, workshop=workshop, quantity=quantity, ) order_line_item.save() except Workshop.DoesNotExist: messages.error(request, ( "One of the products in your bag wasn't" "found in our database." "Please message us for assistance!") ) order.delete() return redirect(reverse('booking')) request.session['save_info'] = 'save-info' in request.POST return redirect(reverse('checkout_success', args=[order.order_number])) else: messages.error(request, "There was an error with your form. \ Check your information, please.") else: bag = request.session.get('bag', {}) if not bag: messages.info(request, "Your booking is empty") return redirect(reverse('workshops')) current_bag = booking_contents(request) total = current_bag['grand_total'] stripe_total = round(total * 100) stripe.api_key = secret_key intent = stripe.PaymentIntent.create( amount=stripe_total, currency=settings.STRIPE_CURRENCY, ) if request.user.is_authenticated: try: profile = UserProfile.objects.get(user=request.user) order_form = OrderForm(initial={ 'full_name': profile.full_name, 'email': profile.email_address, 'phone_number': profile.phone_number, 'street_address1': profile.street_address1, 'street_address2': profile.street_address2, 'postcode': profile.postcode, 'town_or_city': profile.town_or_city, 'county': profile.county, 'country': profile.country, }) except UserProfile.DoesNotExist: order_form = OrderForm() else: order_form = OrderForm() if not public_key: messages.warning(request, 'Stripe public key is missing. \ Check your environment, maybe it is there sleeping.') template = 'checkout/checkout.html' context = { 'order_form': order_form, 'stripe_public_key': public_key, 'client_secret': intent.client_secret, } return render(request, template, context)
def handle_payment_intent_succeeded(self, event): """ Handle the payment_intent.succeeded webhook from Stripe """ intent = event.data.object pid = intent.id bag = intent.metadata.bag billing_details = intent.charges.data[0].billing_details grand_total = round(intent.charges.data[0].amount / 100, 2) order_exists = False attempt = 1 while attempt <= 5: try: order = Order.objects.get( full_name__iexact=billing_details.name, email__iexact=billing_details.email, phone_number__iexact=billing_details.phone, street_address1__iexact=( billing_details.address.line1), street_address2__iexact=( billing_details.address.line2), town_or_city__iexact=billing_details.address.city, county__iexact=billing_details.address.state, country__iexact=billing_details.address.country, grand_total=grand_total, original_bag=bag, stripe_pid=pid, ) order_exists = True break except Order.DoesNotExist: attempt += 1 time.sleep(1) if order_exists: return HttpResponse( content=f'Webhook received: ({event["type"]}' '| SUCCESS: Verified order already in database', status=200) else: order = None try: order = Order.objects.create( full_name=billing_details.name, email=billing_details.email, phone_number=billing_details.phone, street_address1=billing_details.address.line1, street_address2=billing_details.address.line2, town_or_city=billing_details.address.city, county=billing_details.state, country=billing_details.country, original_bag=bag, stripe_pid=pid, ) for workshop_id, quantity in json.loads(bag).items(): workshop = Workshop.objects.get(id=workshop_id) if isinstance(quantity, int): order_line_item = OrderLineItem( order=order, workshop=workshop, quantity=quantity, ) order_line_item.save() except Exception as e: if order: order.delete() return HttpResponse( content=f'Webhook received: {event["type"]} | ERROR: {e}', status=500) return HttpResponse( content=f'Webhook received: {event["type"]}' '| SUCCESS: Created order in webhook', status=200)
def test_get_user_purchases(self): new_user = User.objects.create_user('testuser', '*****@*****.**', 'password') self.client.login(username='******', password='******') product1 = Product.objects.create(name='test1', description='p1', price=1) product2 = Product.objects.create(name='test2', description='p2', price=2) product3 = Product.objects.create(name='test3', description='p3', price=3) product1.save() product2.save() product3.save() order = Order.objects.create(full_name='John Doe', phone_number='123456789', country='Netherlands', postcode='1234', town_or_city='Amsterdam', street_address1='Street', street_address2='22', county='North', date='2020-06-09') order_line_item1 = OrderLineItem(user=new_user, order=order, product=product1, quantity=1) order_line_item1.save() order_line_item2 = OrderLineItem(user=new_user, order=order, product=product2, quantity=2) order_line_item2.save() order_line_item3 = OrderLineItem(user=new_user, order=order, product=product3, quantity=3) order_line_item3.save() self.assertEqual(get_user_purchases(new_user), ['test1', 'test2', 'test3'])
def test_place_order_products(self): order_line_item = OrderLineItem() self.assertFalse(order_line_item.quantity)
def checkout(request): """Renders checkout page with form for user to purchase prodcuts using Stripe API""" cart = request.session.get('cart', {}) total = 0 for id, quantity in cart.items(): product = get_object_or_404(Product, pk=id) total += quantity * product.price delivery = 0 if total > 30: delivery = 0 else: delivery = 3.95 new_total = round(float(total) + delivery, 2) if request.method == "POST": order_form = OrderForm(request.POST) payment_form = MakePaymentForm(request.POST) if order_form.is_valid() and payment_form.is_valid(): order = order_form.save(commit=False) order.purchased_by = request.user order.date = timezone.now() order.save() cart = request.session.get('cart', {}) total = 0 for id, quantity in cart.items(): product = get_object_or_404(Product, pk=id) total += quantity * product.price order_line_item = OrderLineItem(order=order, product=product, quantity=quantity) order_line_item.save() try: customer = stripe.Charge.create( amount=int(new_total * 100), currency="GBP", description=request.user.email, card=payment_form.cleaned_data['stripe_id'], ) except stripe.error.CardError: messages.error(request, "Your card was declined!") if customer.paid: messages.error(request, "You have successfully paid!") request.session['cart'] = {} return redirect(reverse('confirmation', args=(order.id, ))) else: messages.error(request, "Unable to take payment") else: print(payment_form.errors) messages.error(request, "We were unable to take a payment with that card!") else: payment_form = MakePaymentForm() order_form = OrderForm() return render( request, "checkout.html", { "order_form": order_form, "payment_form": payment_form, "delivery": delivery, "new_total": new_total, "publishable": settings.STRIPE_PUBLISHABLE })
def handle_payment_intent_succeeded(self, event): # Get order data from payment intent intent = event.data.object payment_intent_id = intent.id bag = json.loads(intent.metadata.bag ) if intent.metadata and intent.metadata.bag else None billing_details = intent.charges.data[ 0].billing_details if intent.charges.data[ 0].billing_details else None shipping_details = intent.shipping if intent.shipping else None grand_total = round(intent.charges.data[0].amount / 100, 2) # If no bag in metadata if not bag: return HttpResponse( content='No bag or items associated with this order | {}'. format(intent), status=400) # If no billing details if not billing_details: return HttpResponse( content='No billing details associated with this order | {}'. format(intent), status=400) # If no shipping details if not shipping_details: return HttpResponse( content='No shipping details associated with this order | {}'. format(intent), status=400) # Replace empty strings with Null for db compatibility for field, value in shipping_details.address.items(): if value == '': shipping_details.address[field] = None order_exists = False attempt = 1 # Attempt to find order in database 5 times while attempt <= 5: # Check if order already exists in database try: order = get_object_or_404( Order, stripe_payment_id=payment_intent_id, ) order_exists = True break # Increase attempt, sleep 1 second except Order.DoesNotExist: attempt += 1 time.sleep(1) if order_exists: # Send confirmation email self._send_confirmation_email(order) return HttpResponse( content= 'Webhook received: {} | SUCCESS: Verified order already in database' .format(event.type), status=200, ) else: order = None try: # Create order order = Order.objects.create( Order, full_name=shipping_details.name, address_1=shipping_details.line1, address_2=shipping_details.line2, city=shipping_details.city, postcode=shipping_details.postcode, email=billing_details.email, phone_number=billing_details.phone_number, grand_total=grand_total, original_bag=bag, stripe_payment_id=payment_intent_id, ) # Create line items (taken from contexts.py) if bag: forloop_count = 0 for restaurant, food_items in bag.items(): list_of_food_keys_in_bag = list(food_items.keys()) food_id = list_of_food_keys_in_bag[forloop_count] food_object = get_object_or_404(FoodItem, pk=food_id) quantity = bag[restaurant][food_id]['quantity'] for food in bag[restaurant]: order_line_item = OrderLineItem( order=order, food_item=food_object, quantity=bag[restaurant][food_id]['quantity'], ) order_line_item.save() forloop_count += 1 else: return HttpResponse(content='Bag does not exist', status=400) except Exception as e: if order: order.delete() return HttpResponse( content='Webhook received: {} | ERROR: {}'.format( event.type, e), status=500) # Send confirmation email self._send_confirmation_email(order) return HttpResponse( content= 'Webhook received: {} | SUCCESS: Created order via Webhook handler' .format(event.type), status=200, )
def handle_payment_intent_succeeded(self, event): """ Handle the "payment_intent.succeeded" webhook from Stripe """ # Get the payment intent and metadata intent = event.data.object pid = intent.id bag = intent.metadata.bag save_info = intent.metadata.save_info billing_details = intent.charges.data[0].billing_details shipping_details = intent.shipping grand_total = round(intent.charges.data[0].amount / 100, 2) # Clean/strip form data and set empty values to None for field, value in shipping_details.address.items(): if value == "": shipping_details.address[field] = None # Update profile information if save_info was checked profile = None username = intent.metadata.username if username != "AnonymousUser": profile = UserProfile.objects.get(user__username=username) if save_info: profile.default_phone_number = shipping_details.phone profile.default_country = shipping_details.address.country profile.default_postcode = shipping_details.address.postal_code profile.default_town_or_city = shipping_details.address.city profile.default_street_address1 = shipping_details.address.line1 profile.default_street_address2 = shipping_details.address.line2 profile.default_county = shipping_details.address.state profile.save() # Try to get the order in the database using the form data attempt = 1 order_exists = False while attempt <= 5: try: order = Order.objects.get( full_name__iexact=shipping_details.name, email__iexact=billing_details.email, phone_number__iexact=shipping_details.phone, country__iexact=shipping_details.address.country, postcode__iexact=shipping_details.address.postal_code, town_or_city__iexact=shipping_details.address.city, street_address1__iexact=shipping_details.address.line1, street_address2__iexact=shipping_details.address.line2, county__iexact=shipping_details.address.state, grand_total=grand_total, original_bag=bag, stripe_pid=pid, ) order_exists = True # Nothing else to do if order is already created break except Order.DoesNotExist: attempt += 1 time.sleep(1) # Sleep for a second and then try again if order_exists: # Send a confirmation email self._send_confirmation_email(order) return HttpResponse( content=f'Webhook received: {event["type"]} | SUCCESS: Verified order already in database', status=200) else: order = None # If somehow the form didn't create the order, try to create it here try: order = Order.objects.create( full_name=shipping_details.name, user_profile=profile, email=billing_details.email, phone_number=shipping_details.phone, country=shipping_details.address.country, postcode=shipping_details.address.postal_code, town_or_city=shipping_details.address.city, street_address1=shipping_details.address.line1, street_address2=shipping_details.address.line2, county=shipping_details.address.state, original_bag=bag, stripe_pid=pid, ) for item_id, item_data in json.loads(bag).items(): product = Product.objects.get(id=item_id) # If we're working w/ an item with no sizes, item_data will be the quantity if isinstance(item_data, int): order_line_item = OrderLineItem( order=order, product=product, quantity=item_data ) order_line_item.save() # Otherwise we need to add order lineitems for each size else: for size, quantity in item_data['items_by_size'].items(): order_line_item = OrderLineItem( order=order, product=product, quantity=quantity, product_size=size ) order_line_item.save() except Exception as e: if order: order.delete() # Delete it if anything went wrong. Stripe will try again later. return HttpResponse( content=f'Webhook received: {event["type"]} | ERROR: {e}', status=500) # Send a confirmation email self._send_confirmation_email(order) return HttpResponse( content=f'Webhook received: {event["type"]} | SUCCESS: Created order in webhook', status=200)