Example #1
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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 item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    isinstance(item_data, int)
                    order_line_item = OrderLineItem(
                        order=order,
                        product=product,
                        quantity=item_data,
                    )
                    order_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request, (
                        "We couldn't find on of the products in your bag."
                        "Please call us for assistance!")
                    )
                    order.delete()
                    return redirect(reverse('view_bag'))

            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "Your bag is still empty")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = "sk_test_51IGnAWFmJAyuyKG9aAPOPeDhZ3jnti8PaeAFHtMUxqrMhE2JxkzkV05VGfeNE29EU7asylsGF55QRvVqTNLvy24Y00CbXDc9sf"
        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.user.get_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()

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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 checkout(request):
    """ View to checkout """
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        """ Saves the order """
        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 item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                except Product.DoesNotExist:
                    order.delete()
                    return redirect(reverse('view_bag'))

            # Updates the order total then sends a confirmation email to the user
            order.update_total()
            subject = 'Thank you for your purchase! - Order No: ' + order.order_number
            body = render_to_string(
                'checkout/confirmation_email/confirmation_email_body.txt', {
                    'order': order,
                    'contact_email': settings.DEFAULT_FROM_EMAIL
                })

            send_mail(subject, body, settings.DEFAULT_FROM_EMAIL,
                      [order.email])

            # Save the info to the user's profile if all is well
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
    else:
        """ Creates Stripe payment intent when arriving on the checkout page """
        bag = request.session.get('bag', {})
        if not bag:
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any info the user maintains in their profile
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_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)
Example #3
0
def checkout_order(request):
    """ A view to handle the ability to process an order
    with Stripe's built-in functionality """
    stripe_publishable_key = settings.STRIPE_PUBLISHABLE_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        shopping_bag = request.session.get('bag', {})
        form_data = {
            'full_name': request.POST['full_name'],
            'email_address': request.POST['email_address'],
            'phone_number': request.POST['phone_number'],
            'country': request.POST['country'],
            'address_line1': request.POST['address_line1'],
            'address_line2': request.POST['address_line2'],
            'city_or_town': request.POST['city_or_town'],
            'postcode': request.POST['postcode'],
        }
        checkout_order_form = CheckoutOrderForm(form_data)
        if checkout_order_form.is_valid():
            # Prevent multiple save events by disallowing the first one
            order = checkout_order_form.save(commit=False)
            pi_id = request.POST.get('client_secret').split('_secret')[0]
            order.original_bag = json.dumps(shopping_bag)
            order.stripe_pi_id = pi_id
            order.save()
            for product_id, product_data in shopping_bag.items():
                try:
                    product = Product.objects.get(id=product_id)
                    each_line_order = EachLineOrder(
                        order=order,
                        product=product,
                        quantity=product_data,
                    )
                    each_line_order.save()
                except Product.DoesNotExist:
                    messages.error(request, (
                        "We were unable to find one of the products in your bag. \
                            Please contact us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_shopping_bag'))
            request.session['save_contact'] = 'save-contact' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(
                request, 'Error processing your order. \
                Please recheck the information you have provided.')

    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "You have not added an item to your bag yet!")
            return redirect(reverse('shop'))

        user_bag = bag_contents(request)
        total_price = user_bag['grand_total']
        # Stripe works with whole numbers so it's easier to convert to pence
        stripe_charge = round(total_price * 100)
        stripe.api_key = stripe_secret_key
        stripePaymentIntent = stripe.PaymentIntent.create(
            amount=stripe_charge,
            currency=settings.STRIPE_CURRENCY,
        )
        """ A conditional statement to handle prefilling the form
        with the contact details that the user updated from their
        user profile. """
        if request.user.is_authenticated:
            try:
                user_profile = UserProfile.objects.get(user=request.user)
                checkout_order_form = CheckoutOrderForm(
                    initial={
                        'full_name': user_profile.default_full_name,
                        'email_address': user_profile.default_email_address,
                        'phone_number': user_profile.default_phone_number,
                        'country': user_profile.default_country,
                        'postcode': user_profile.default_postcode,
                        'city_or_town': user_profile.default_city_or_town,
                        'address_line1': user_profile.default_address_line1,
                        'address_line2': user_profile.default_address_line2,
                    })
            except UserProfile.DoesNotExist:
                checkout_order_form = CheckoutOrderForm()
        else:
            checkout_order_form = CheckoutOrderForm()

    # Incase no Stripe publishable key is in environment
    if not stripe_publishable_key:
        messages.warning(
            request, 'No Stripe Publishable Key was detected \
                in your environment variables')

    template = 'checkout/checkout.html'
    context = {
        'form': checkout_order_form,
        'stripe_publishable_key': stripe_publishable_key,
        'client_secret_key': stripePaymentIntent.client_secret,
    }

    return render(request, template, context)
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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()
            for item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    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 Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database. "
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))
            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        """ Multiply by a hundred and round it to zero decimal places,
        since stripe will require the amount to charge as an integer. """
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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 checkout(request):
    """
    render the checkout page. Willl also process the checkout post request & fullfill this. 
    If information is rendered incorrectly, it will redirect the user back to the bag 
    and displays an error message prompting users to try again.
    If all completed successfully this will direct the user to the checkout success view.
    """

    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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'],
            '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()
            for item_id, item_data in bag.items():
                try:
                    item = CurrentItem.objects.get(id=item_id)
                    order_line_item = OrderLineItem(
                        order=order,
                        item=item,
                        quantity=item_data,
                    )
                    order_line_item.save()

                except CurrentItem.DoesNotExist:
                    messages.error(
                        request, ("One of the products in your bag wasn't found in our database. "
                                  "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('bag.html'))

            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(
                request, "There's nothing in your bag at the moment")
            return redirect(reverse('shop'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        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)
Example #6
0
def checkout(request):
    """View to display checkout page"""
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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'],
            'street_address': request.POST['street_address'],
            'post_code': request.POST['post_code'],
            'town_or_city': request.POST['town_or_city'],
            'country': request.POST['country'],
        }
        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 item_id, item_data in bag.items():
                try:
                    product = get_object_or_404(Product, pk=item_id)
                    if isinstance(item_data, int):
                        order_item = OrderItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_item.save()
                    else:
                        for (flavour, quantity) in (
                                item_data['items_by_flavour'].items()):

                            order_item = OrderItem(
                                order=order,
                                product=product,
                                quantity=quantity,
                                product_flavour=flavour,
                            )
                            order_item.save()

                except Product.DoesNotExist:
                    messages.error(request,
                                   ("One of the products you were trying to \
                            buy was not found. "
                                    "Please contact us for assistance."))
                    order.delete()
                    return redirect(reverse('view_bag'))

            request.session['save_order'] = 'save_order'
            return redirect(
                reverse('checkout_success', args=[order.order_number]))

        else:
            messages.error(
                request, "There was an error with your form. \
                Please double check your information.")

    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(
                request, "There's nothing in your bag at \
                the moment")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['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.user.get_full_name(),
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'street_address': profile.default_street_address,
                        'post_code': profile.default_post_code,
                        'town_or_city': profile.default_town_or_city,
                        'country': profile.default_country,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is missing.')

    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)
Example #7
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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 item_id, item_data in bag.items():
                try:
                    # 1. get product id
                    product = Product.objects.get(id=item_id)
                    # if int, product with no size
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        # iterate each size, create line item
                        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()
                # if product not found
                except Product.DoesNotExist:
                    messages.error(request,
                                   ("One of the products in your bag wasn't "
                                    "found in our database. "
                                    "Please call us for assistance!"))
                    # delete empty order
                    order.delete()
                    # return to shopping bag page
                    return redirect(reverse('view_bag'))

            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 \
                Please double check your list.')

    else:
        bag = request.session.get('bag', {})

        if not bag:
            messages.error(
                request, "There's \
                nothing in your bag at the moment")
            return redirect(reverse('products'))

        # not to overwrite existing bag variable
        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        order_form = OrderForm()

        if not stripe_public_key:
            messages.warning(
                request, 'Stripe public key is missing. \
                    Did you forget to set it in your environment?')

        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 checkout(request):
    # payment intent variables
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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)
        # add in the data from our form to the dictionary
        if order_form.is_valid():
            order = order_form.save(commit=False)
            # to check we're using the right one
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_bag = json.dumps(bag)
            order.save()
            # iterate through the line items to add them separately
            for item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    # get the product out of the bag
                    if isinstance(item_data, int):
                        # we know there aren't any sizes if it's just an integer
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                        print(order_line_item)
                    else:
                        # item has sizes, so iterate through
                        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 Product.DoesNotExist:
                    # just in case it doesn't exist on the database - unlikely
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database. "
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))

            request.session['save_info'] = 'save-info' in request.POST
            # did user want to save to session?
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        # get it from the calculated context file
        stripe_total = round(total * 100)
        # stripe needs an integer format
        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.user.get_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:
                # render an empty form
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)
Example #9
0
def checkout(request):
    """
    render checkout page and does not allow checkout
    in case of delivery issue,
    handle POST requests (Stripe and PayPal)
    """
    if request.method == 'POST':
        payment_choice = request.POST['payment-choice']
        bag = request.session.get('bag', {})
        # collect data from the form
        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'],
        }
        # stripe
        if payment_choice == "stripe":
            # validate form
            order_form = OrderForm(form_data)
            if order_form.is_valid():
                order = order_form.save()
                # add pid and original bag to order
                pid = request.POST.get('client_secret').split('_secret')[0]
                order.stripe_pid = pid
                order.original_bag = json.dumps(bag)
                # add line items to order
                for item_id, item_quantity in bag.items():
                    try:
                        product = Product.objects.get(id=item_id)
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_quantity,
                        )
                        order_line_item.save()
                    except Product.DoesNotExist:
                        messages.error(request,
                                       ("One of the products in your bag"
                                        "wasn't found in our database. "
                                        "Contact us for assistance!"))
                        order.delete()
                        return redirect(reverse('view_bag'))
            else:
                messages.error(
                    request, 'There was an error with your form. \
                    Please double check your information.')
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        # paypal
        if payment_choice == 'paypal':
            # validate form
            pre_order_form = PreOrderForm(form_data)
            if pre_order_form.is_valid():
                pre_order = pre_order_form.save()
                # add line items to preorder
                for item_id, item_quantity in bag.items():
                    try:
                        product = Product.objects.get(id=item_id)
                        pre_order_line_item = PreOrderLineItem(
                            order=pre_order,
                            product=product,
                            quantity=item_quantity,
                        )
                        pre_order_line_item.save()
                    except Product.DoesNotExist:
                        messages.error(request,
                                       ("One of the products in your bag"
                                        "wasn't found in our database."
                                        "Contact us for assistance!"))
                        pre_order.delete()
                        return redirect(reverse('view_bag'))
            else:
                messages.error(
                    request, 'There was an error with your form. \
                Please double check your information.')
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('invoice_confirmation', args=[pre_order.order_number]))

    # GET request
    else:
        change_country = False
        # check if user amended the country
        if "country" in request.GET:
            change_country = True
            chosen_country = request.session.get('chosen_country')
            request.session['chosen_country'] = request.GET['country']

        # check if there is some delivery problem
        context = bag_contents(request)
        delivery_problem = context["delivery_problem"]
        if delivery_problem:
            messages.error(
                request, "Some items in your bag cannot be delivered"
                "to your shipping destination."
                "Go back to you bag and delete them"
                "or change your shipping address to Ireland.")
        stripe_public_key = settings.STRIPE_PUBLIC_KEY
        stripe_secret_key = settings.STRIPE_SECRET_KEY
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "There's nothing in your bag")
            return redirect(reverse('products'))
        current_bag = bag_contents(request)
        grand_total = current_bag['grand_total']

        # Stripe intent
        stripe_total = round(grand_total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )
        client_secret = intent.client_secret
        # generate form
        # request comes from change country
        if change_country:
            new_data = request.GET
            order_form = OrderForm({
                'full_name':
                new_data['full_name'],
                'email':
                new_data['email'],
                'phone_number':
                new_data['phone_number'],
                'country':
                new_data['country'],
                'postcode':
                new_data['postcode'],
                'town_or_city':
                new_data['town_or_city'],
                'street_address1':
                new_data['street_address1'],
                'street_address2':
                new_data['street_address2'],
                'county':
                new_data['county'],
            })
        # request does not come from change country
        else:
            if request.user.is_authenticated:
                try:
                    profile = UserProfile.objects.get(user=request.user)
                    order_form = OrderForm(
                        initial={
                            'full_name': profile.user.get_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': client_secret,
            'change_country': change_country,
        }
        return render(request, template, context)
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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 product_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=product_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request, (
                        "Something went wrong! Please email us and we'll try to help!"
                    ))
                    order.delete()
                    return redirect(reverse('view_bag'))

                    request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_confirm', args=[order.order_number]))
        else:
            messages.error(
                request,
                'Something went wrong - please double check your information')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "Your bag is empty!")
            return redirect(reverse('products'))
        else:
            bag = request.session.get('bag', {})
            if not bag:
                messages.error.request, "Your bag is empty"
                return redirect(reverse('products'))

        user_bag = bag_contents(request)
        total = user_bag['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.user.get_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()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)
Example #11
0
def checkout(request):
    """ View to view checkout and form.
    Stops users checking out with an empty bag.
    Creates an order with all the order items and saves them to the
    database.
    """

    # Gets variable from os for stripe
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    # POST
    if request.method == 'POST':
        bag = request.session.get('bag', {})

        # Get order form data
        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'town_or_city': request.POST['town_or_city'],
            'county': request.POST['county'],
            'postcode': request.POST['postcode'],
            'country': request.POST['country'],
        }
        order_form = OrderForm(form_data)

        # Check if the order form is valid and save it if it is
        if order_form.is_valid():

            # Commit False stops multiple save events on database.
            order = order_form.save(commit=False)

            payment_id = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = payment_id
            order.original_bag = json.dumps(bag)
            order.save()

            # Cycle through bag items and create an Order Item for each
            for product_id, product_data in bag.items():
                try:
                    product = Product.objects.get(id=product_id)
                    if isinstance(product_data, int):
                        order_item = OrderItem(
                            order=order,
                            product=product,
                            quantity=product_data,
                        )
                        order_item.save()
                    else:
                        if 'product_by_variant' in product_data:
                            varis = product_data['product_by_variant'].items()
                            for variant_id, quantity in varis:
                                variant = Variant.objects.get(id=variant_id)
                                order_item = OrderItem(
                                    order=order,
                                    product=product,
                                    variant=variant,
                                    quantity=quantity,
                                )
                                order_item.save()

                        elif 'product_by_size' in product_data:
                            sizes = product_data['product_by_size'].items()
                            for size, quantity in sizes:
                                order_item = OrderItem(
                                    order=order,
                                    product=product,
                                    quantity=quantity,
                                    product_size=size,
                                )
                                order_item.save()

                # If Product doesn't exist give feeback and redirect to bag
                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't \
                            found in our database."
                        "Please call us for assistance!")
                    )
                    order.delete()
                    return redirect(reverse('view_bag'))

            # On successful Orders redirect user to Checkout Success Page
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number])
            )

        # If form is invalid tell user their is an error and reload checkout
        else:
            messages.error(request, 'There was an error with your form. \
                Please double check your information.')
            return redirect(reverse('checkout'))

    # GET
    else:
        bag = request.session.get('bag', {})
        # Stops users accessing checkout via url with an empty bag
        if not bag:
            messages.error(request, "Can't Checkout: Your Bag is Empty")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        bag_total = current_bag['bag_grand_total']

        # Round total as Stripe charges in pennies
        # ie. £23.51 is equal to 2351p
        stripe_total = round(bag_total * 100)
        stripe.api_key = stripe_secret_key

        # Create Payment Intent
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Try prefilling delivery form with profile delivery form data
        if request.user.is_authenticated:
            try:
                profile = Profile.objects.get(user=request.user)
                order_form = OrderForm(initial={
                    'full_name': profile.user.get_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 Profile.DoesNotExist:
                order_form = OrderForm()
        else:
            order_form = OrderForm()

    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
    }

    return render(request, 'checkout/checkout.html', context)
Example #12
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        user = request.user
        user_profile = RegisteredUserProfile.objects.get(user=user)
        bag = request.session.get('bag', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'street_address_1': request.POST['street_address_1'],
            'street_address_2': request.POST['street_address_2'],
            'town': request.POST['town'],
            'country': request.POST['country'],
            'postcode': request.POST['postcode'],
        }
        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.customer = user_profile
            order.save()
            for print_id, item_data in bag.items():
                try:
                    print_details = Print.objects.get(id=print_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            print_details=print_details,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        for quantity in item_data.items():
                            order_line_item = OrderLineItem(
                                order=order,
                                print_details=print_details,
                                quantity=quantity,
                            )
                except Print.DoesNotExist:
                    messages.error(
                        request,
                        ("Sorry, one of these prints isn't on Plan Chest. "
                         "Please send us an email and we'll look into it."))
                    order.delete()
                    return redirect(reverse('bag_contents'))

            request.session['safe_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.\
            Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('all_prints'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
                         Did you forget to set it in your environment?')

    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)
Example #13
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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 item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    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 Product.DoesNotExist:
                    messages.error(
                        request,
                        ("One of the products in your bag wasn't found in our database. "
                         "Please call us for assistance!"),
                    )
                    order.delete()
                    return redirect(reverse("view_bag"))

            # Save the info to the user's profile if all is well
            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. \
                Please double check your information.",
            )
    else:
        bag = request.session.get("bag", {})
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse("products"))

        current_bag = bag_contents(request)
        total = current_bag["grand_total"]
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any info the user maintains in their profile
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        "full_name": profile.user.get_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()

    if not stripe_public_key:
        messages.warning(
            request,
            "Stripe public key is missing. \
            Did you forget to set it in your environment?",
        )

    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)
Example #14
0
def checkout(request):
    """
     Handle the data from checkout form, return an error if there is an issue
    """
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == "POST":
        bag = request.session.get('bag', {})

        # save info is not added here as it does not exist on the model
        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 item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)

                    order_line_item = OrderLineItem(
                        order=order,
                        product=product,
                        quantity=item_data,
                    )

                    order_line_item.save()

                    ammended_stock_level = product.stock - item_data

                    # The code below is a workaround for my stock system
                    # A stock needs to be a positive int
                    if ammended_stock_level <= 0:
                        product.stock = 0
                    else:
                        product.stock = ammended_stock_level

                    product.save()

                except Product.DoesNotExist:
                    messages.error(request,
                                   ("One of the products in your bag\
                            wasn't found in our database."
                                    "Please contact us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))

            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. \
                Please check your information")
    else:
        bag = request.session.get('bag', {})

        if not bag:
            messages.error(request,
                           "Oops, there's nothing in your bag to checkout")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['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={
                        'email': profile.user.email,
                        'phone_number': profile.default_phone_number,
                        'street_address1': profile.default_street_address1,
                        'street_address2': profile.default_street_address2,
                        'town_or_city': profile.default_town_or_city,
                        'county': profile.default_county,
                        'postcode': profile.default_postcode,
                        'country': profile.default_country,
                    })
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        else:

            order_form = OrderForm()

    if not stripe_public_key:
        messages.warning('Stripe public key is missing')

    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)
Example #15
0
def checkout(request):
    """ Collect the checkout information """
    # Collect the Stipe config variables
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        # The user has asked to checkout, so collect bag information
        bag = request.session.get('bag', {})

        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'street_address1': request.POST['street_address1'],
            'street_address2': request.POST['street_address2'],
            'town': request.POST['town'],
            'postcode': request.POST['postcode'],
            'country': request.POST['country'],
            'county': request.POST['county'],
        }

        # Create an order form instance
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            order = order_form.save(commit=False)
            # commit=False to stop it saving twice
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_bag = json.dumps(bag)
            order.save()
            for item_id, item_data in bag.items():
                # For each item in the bag
                try:
                    product = Product.objects.get(id=item_id)
                    # Collect the product information
                    for size, quantity in item_data['items_by_size'].items():
                        # Save each item to the order line item model
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=quantity,
                            product_size=size,
                        )
                        order_line_item.save()
                except Product.DoesNotExist:
                    # Product is non existent in database
                    messages.error(request, (
                        "One of the products in your bag was\
                            not found in our database. "
                        "Please call us for assistance."
                    ))
                    # Delete the order
                    order.delete()
                    return redirect(reverse('view_bag'))
            # See if the user has asked to save user information to profile
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(reverse('checkout_success',
                            args=[order.order_number]))
        else:
            # Form entry was invalid
            messages.error(request, "There was an error with your form. \
                Please double check your information.")
    else:
        # Collect the bag information
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('collections'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Prefill the form with any user info saved on the user's profile
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(initial={
                    'full_name': profile.user.get_full_name(),
                    'email': profile.user.email,
                    'phone_number': profile.default_phone_number,
                    'street_address1': profile.default_street_address1,
                    'street_address2': profile.default_street_address2,
                    'town': profile.default_town,
                    'county': profile.default_county,
                    'postcode': profile.default_postcode,
                    'country': profile.default_country,
                })
            except UserProfile.DoesNotExist:
                # Render an empty form as no user profile exists
                order_form = OrderForm()
        else:
            # Render an empty form as no user profile exists
            order_form = OrderForm()

        if not stripe_public_key:
            messages.warning(request, 'Stripe public key is missing. \
                Did you forget to set it in your environment?')

        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)
Example #16
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        bag = request.session.get('bag', {})
        # put the form data into a dictionary.
        # I'm doing this manually in order to skip the save infobox
        # which doesn't have a field on the order model.
        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'],
        }
        # instance of the form using the form data
        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 item_id, item_data in bag.items():
                try:
                    # get product id
                    product = Product.objects.get(id=item_id)
                    # if the item does not have size
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        # if the item has sizes
                        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()
                # if the product was not found
                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database. "
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))

            # whether or not the user wanted to save their profile information to the session.
            # Save the info to the user's profile if all is well
            request.session['save_info'] = 'save-info' in request.POST
            # url at the end of this python code pass order number as argument
            return redirect(
                reverse('checkout_success', args=[order.order_number]))

        else:  # if order_form is not valid
            messages.error(request, ('There was an error with your form. '
                                     'Please double check your information.'))
    else:
        bag = request.session.get('bag', {})
        # And if there's nothing in the bag just add a simple error message.
        # And redirect back to the products page.
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('products'))

        # We can pass it the request and get the same dictionary here in the view.
        # I'll store that in a variable called current bag.
        # Making sure not to overwrite the bag variable that already exists
        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(
            total * 100
        )  # Since stripe will require the amount to charge as an integer.
        # set the secret key on stripe and create payment intent
        # the payment intent is like a dictionary that came back from stripe with a whole bunch of keys.
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any info the user maintains in their profile
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_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()

    # a convenient message here that alerts you if you forget to set your public key.
    if not stripe_public_key:
        messages.warning(
            request,
            'Stripe public key is missing. Did you forget to set it in your environment?'
        )

    # we just need to create an instance of our order form. Which will be empty for now.
    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)
Example #17
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    # check whether the method is post.
    if request.method == 'POST':
        # get the bag from the session.then put the form data in a dictionary
        bag = request.session.get('bag', {})

        form_data = {
            # we can create an instance of the form using the 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'],
        }
        # If the form is valid we'll save the order.
        # then we iterate through the bag items to create each line item.
        order_form = OrderForm(form_data)
        if order_form.is_valid():
            # prevent multiple save events from being executed on the database
            # by adding commit=false to prevent the 1st one from happening.
            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 item_id, item_data in bag.items():
                try:
                    # we get the Product ID out of the bag
                    product = Product.objects.get(id=item_id)
                    # if its value is integer we know is an item that doesn't
                    # have sizes.So quantity will be the item data.
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    else:
                        # if the item has sizes iterate through each size
                        # and create a line item accordingly.
                        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()
                # in case a product isn't found add error message Delete empty
                # order and return the user to the shopping bag page.
                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database. "
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))
            # We'll attach whether or not the user wanted to save their profile
            # information to the session.
            request.session['save_info'] = 'save-info' in request.POST
            # redirect them to a new page and pass the order number as argument
            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(
                request, 'There was an error with your form. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})

        # if there's nothing in the bag just add error message and redirect
        # back to products page
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('products'))

    # We can pass the request and get the same dictionary here in the view.
    # store that in a variable called current bag.Making sure not to overwrite
    # the bag variable that already exists
        current_bag = bag_contents(request)
        # get the grand_total key out of the current bag.
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )
        # Since users now have profiles we can use their default delivery info
        #  to pre-fill the form on the checkout page by checking whether user
        # is authenticated,if so, get their profile and use the initial
        # parameter on the order form to pre-fill all its fields
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_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()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)
Example #18
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY
    has_address = False

    if request.method == 'POST':
        bag = request.session.get('bag', {})

        form_data = {
            'username': request.user,
            'full_name': request.POST['full_name'],
            '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 item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()

                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database. "
                        "Please call us for assistance!")
                    )
                    order.delete()
                    return redirect(reverse('view_bag'))

            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "There doesn't seem to be anyhing in your bag right now")
            return redirect(reverse('games'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # To get user address data if there is any
        profile = None
        try:
            profile = UserProfile.objects.get(user=request.user)
        except (UserProfile.DoesNotExist, TypeError, ValueError) as e:
            print("Cannot get user address:", e)

        order_form = OrderForm(instance=profile)
        has_address = not order_form.errors

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key': stripe_public_key,
        'client_secret': intent.client_secret,
        'has_address': has_address
    }

    return render(request, template, context)
Example #19
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    test_if_bag_is_empty = request.session.get('bag', {})
    product_count = 0

    for product_id, product_data in test_if_bag_is_empty.items():
        for size, quantity in product_data['product_size'].items():
            product_count += quantity

    if product_count == 0:
        messages.error(request, 'You cannot checkout with an empty bag.')
        return redirect(reverse('home'))

    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 product_id, item_data in bag.items():
                try:
                    product = Product.objects.get(product_id=product_id)
                    for size, qty in item_data['product_size'].items():
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=qty,
                            product_size=size,
                        )
                        order_line_item.save()

                except Product.DoesNotExist:
                    messages.error(request,
                                   'Product does not exist in database.')
                    order.delete()
                    return redirect(reverse('view_bag'))

            request.session['save_info'] = 'save-info' in request.POST

            _send_confirmation_email(order)

            return redirect(
                reverse('checkout_success', args=[order.order_number]))
        else:
            messages.error(request, 'Sorry, your form is invalid.')

    else:
        current_bag = bag_contents(request)
        total = current_bag['total'] + settings.DEFAULT_DELIVERY_CHARGE
        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.default_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)
Example #20
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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 key in bag.keys():
                print(key)
                item_first_part = key.split("_")[0]
                for k, v in bag[key].items():
                    print(k)
                    if item_first_part == "item":
                        try:
                            ingredient = Ingredients.objects.get(id=k)
                            if isinstance(v, int):
                                order_item = OrderItem(
                                    order=order,
                                    ingredient=ingredient,
                                    quantity=v,
                                )
                                order_item.save()
                        except Ingredients.DoesNotExist:
                            messages.error(request, (
                                "One of the products in your bag wasn't found in our database. "
                                "Please call us for assistance!"))
                            order.delete()
                            return redirect(reverse('view_bag'))
                    else:
                        try:
                            drink_side = SidesAndDrinks.objects.get(id=k)
                            if isinstance(v, int):
                                order_item = OrderSideItem(
                                    order=order,
                                    drink_side=drink_side,
                                    quantity=v,
                                )
                                order_item.save()
                        except SidesAndDrinks.DoesNotExist:
                            messages.error(request, (
                                "One of the products in your bag wasn't found in our database. "
                                "Please call us for assistance!"))
                            order.delete()
                            return redirect(reverse('view_bag'))
                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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, 'There is nothing in your bag right now!')
            return redirect(reverse('ingredients'))

        current_bag = bag_contents(request)
        total = current_bag['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.user.get_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()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)
Example #21
0
def checkout(request):
    """
    render checkout page and does not allow checkout
    in case of delivery issue,
    handle POST requests (Stripe and PayPal)
    """
    if request.method == 'POST':
        payment_choice = request.POST['payment-choice']
        bag = request.session.get('bag', {})
        # collect data from the form
        form_data = {
            'full_name': request.POST['full_name'],
            'email': request.POST['email'],
            'phone_number': request.POST['phone_number'],
            'country': 'MX',
            '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'],
        }
        # stripe
        if payment_choice == "stripe" or payment_choice == "oxxo":
            # validate form
            if payment_choice == "stripe":
                order_form = OrderForm(form_data)
            else:
                order_form = OxxoOrderForm(form_data)
            if order_form.is_valid():
                pid = request.POST.get('client_secret').split('_secret')[0]
                #avoid order duplication if user does leave the oxxo voucher modal open for too long
                if payment_choice == "oxxo":
                    attempt = 1
                    while attempt <= 10:
                        try:
                            # order already created by Webhook
                            order = OxxoOrder.objects.get(stripe_pid=pid)
                            break
                        except OxxoOrder.DoesNotExist:
                            attempt += 1
                            time.sleep(1)
                            if attempt == 10:
                                order = order_form.save()
                                # add pid and original bag to order
                                order.stripe_pid = pid
                                order.original_bag = json.dumps(bag)
                else:
                    order = order_form.save()
                    # add pid and original bag to order
                    order.stripe_pid = pid
                    order.original_bag = json.dumps(bag)
                # add line items to order
                for item_id, item_quantity in bag.items():
                    try:
                        product = Product.objects.get(id=item_id)
                        if payment_choice == "stripe":
                            order_line_item = OrderLineItem(
                                order=order,
                                product=product,
                                quantity=item_quantity,
                            )
                        else:
                            order_line_item = OxxoOrderLineItem(
                                order=order,
                                product=product,
                                quantity=item_quantity,
                            )
                        order_line_item.save()
                    except Product.DoesNotExist:
                        messages.error(request,
                                       ("One of the products in your bag"
                                        "wasn't found in our database. "
                                        "Contact us for assistance!"))
                        order.delete()
                        return redirect(reverse('view_bag'))
            else:
                messages.error(
                    request, 'There was an error with your form. \
                    Please double check your information.')
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('checkout_success',
                        args=[payment_choice, order.order_number]))
        # paypal
        if payment_choice == 'paypal':
            # validate form
            pre_order_form = PreOrderForm(form_data)
            if pre_order_form.is_valid():
                pre_order = pre_order_form.save()
                # add line items to preorder
                for item_id, item_quantity in bag.items():
                    try:
                        product = Product.objects.get(id=item_id)
                        pre_order_line_item = PreOrderLineItem(
                            order=pre_order,
                            product=product,
                            quantity=item_quantity,
                        )
                        pre_order_line_item.save()
                    except Product.DoesNotExist:
                        messages.error(request,
                                       ("One of the products in your bag"
                                        "wasn't found in our database."
                                        "Contact us for assistance!"))
                        pre_order.delete()
                        return redirect(reverse('view_bag'))
            else:
                messages.error(
                    request, 'There was an error with your form. \
                Please double check your information.')
            request.session['save_info'] = 'save-info' in request.POST
            return redirect(
                reverse('invoice_confirmation', args=[pre_order.order_number]))

    # GET request
    else:
        context = bag_contents(request)
        stripe_public_key = settings.STRIPE_PUBLIC_KEY
        stripe_secret_key = settings.STRIPE_SECRET_KEY
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "There's nothing in your bag")
            return redirect(reverse('products'))
        current_bag = bag_contents(request)
        grand_total = current_bag['grand_total']

        # Stripe intent
        stripe_total = round(grand_total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
            payment_method_types=['card', 'oxxo'])
        client_secret = intent.client_secret
        # generate form
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_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': client_secret
        }
        return render(request, template, context)
Example #22
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    # To confirm it we verified that the form on the checkout page was submitted.
    # However, at the moment the form data doesn't actually go anywhere
    # since the checkout view doesn't have any handling for the post method.
    # Let's fix that in this video. So that when a user submits their payment
    # information. We also create the order in the database.
    # And redirect them to a success page.
    # The first thing to do is obviously check whether the method is post.
    # That means we should also wrap the current code into an else block to
    # handle the get requests.
    # In the post method code we will need the shopping bag.
    # And then we'll put the form data into a dictionary.
    # I'm doing this manually in order to skip the save infobox
    # which doesn't have a field on the order model.
    # All the other fields can come directly from the form though.
    # And then we can create an instance of the form using the form data.
    # If the form is valid we'll save the order.
    # And then we need to iterate through the bag items to create each line item.
    # This code is pretty similar to what we used in the context processor.
    # So I'll just paste it in and review it briefly.
    # First we get the Product ID out of the bag.
    # Then if its value is an integer we
    # know we're working with an item that doesn't have sizes.
    # So the quantity will just be the item data.
    # Otherwise, if the item has sizes. we'll iterate through each size and
    # create a line item accordingly.
    # Finally this should theoretically never happen but just in case a
    # product isn't found we'll add an error message.
    # Delete the empty order and return the user to the shopping bag page.
    # At the bottom here at the same indentation level as the for-loop.
    # We'll attach whether or not the user wanted to save their profile
    # information to the session.
    # And then redirect them to a new page which we'll create in just a moment.
    # We'll name the new URL check out success.
    # And pass it the order number as an argument.
    # Also to get that we'll need to save the order here on line 31 so
    # I'll add that. If the order form isn't valid let's just attach a message
    # letting them know and they'll be sent back to the checkout page at the
    # bottom of this view with the form errors shown.

    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 item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    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 Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database. "
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))

            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. \
                Please double check your information.')

    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any info the user maintains in their profile
        # All we need to do is check whether the user is authenticated.
        # And if so we'll get their profile and use the initial parameter on the order form
        # to pre-fill all its fields with the relevant information.
        # For example, we can fill in the full_name with the built in get_full_name method on their user account.
        # Their email from their user account.
        # And everything else from the default information in their profile.
        # If the user is not authenticated we'll just render an empty form.

        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_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()

        order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)
Example #23
0
def checkout(request):
    """
    Gets stripe keys and bag from session, requests form data,
    if form is valid gets pid, original bag from json dump and
    saves form. Determines if item is a product or programme then
    iterates through bag items, gets sizes if any, and saves to
    order_line_item. If except occurs, user receives error message
    and is redirected to bag view. If checkout successful, session is
    saved and user is directed to checkout success view. If user is
    authenicated, looks for saved data in profile and fills form
    accordingly.
    [Code taken from Code Institute and modified for personal use]
    """
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        bag = request.session.get('bag', {'product': {}, 'programme': {}})

        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 category, category_items in bag.items():
                for item_id, item_data in category_items.items():

                    if category == "product":
                        try:
                            product = get_object_or_404(Product, pk=item_id)
                            if isinstance(item_data, int):
                                order_line_item = OrderLineItem(
                                    order=order,
                                    product=product,
                                    quantity=item_data,
                                )
                                order_line_item.save()
                            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 Product.DoesNotExist:
                            messages.error(request, (
                                "One of the products in your bag wasn't found \
                                     in our database. "
                                "Please call us for assistance!"))
                            order.delete()
                            return redirect(reverse('view_bag'))

                    elif category == "programme":
                        try:
                            programme = get_object_or_404(Programme,
                                                          pk=item_id)
                            if isinstance(item_data, int):
                                order_line_item = ProgOrderLineItem(
                                    order=order,
                                    programme=programme,
                                    quantity=item_data,
                                )
                                order_line_item.save()
                        except Product.DoesNotExist:
                            messages.error(request, (
                                "One of the products in your bag wasn't found \
                                    in our database. "
                                "Please call us for assistance!"))
                            order.delete()
                            return redirect(reverse('view_bag'))

            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {'product': {}, 'programme': {}})
        if not bag:
            messages.error(
                request, "There's nothing in your bag at the \
                moment")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['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.default_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()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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 checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        bag = request.session.get('bag', [])

        order_form = OrderForm(request.POST)
        if order_form.is_valid():
            total = 0
            order = order_form.save()
            for item_data in bag:
                try:
                    product = Product.objects.get(id=item_data['product'])
                    order_line_item = OrderLineItem(
                        sub_total=item_data['sub_total'],
                        order=order,
                        product=product,
                        quantity=item_data['quantity'],
                        background=item_data['background'],
                        text_color=item_data['text_color'],
                        text_content=item_data['text_content'],
                        extra_requirements=item_data['extra_requirements'],
                    )
                    total += item_data['sub_total']
                    order_line_item.save()
                except Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database. "
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))
            grand_total = total
            discount = 0
            if total >= settings.BUNDLE_DISCOUNT_THRESHOLD:
                grand_total = float(total) * 0.8
                discount = total - grand_total

            order.order_total = total
            order.grand_total = grand_total
            order.discount = discount
            order.save()
            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "There's nothing here yet")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        current_total = current_bag['grand_total']
        stripe_total = round(current_total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)
Example #25
0
def checkout(request):
    stripe_public_key = "pk_test_51HX5u6A1fnSIB3Km43MupzPhDdzE3QyyAOUnwsbTnovphUUDBuyIEDZDXo3rNw5SQHBkDuqo3keliCWShvZ3PGdN00gKgCOG4V"
    stripe_secret_key = "sk_test_51HX5u6A1fnSIB3Kmi9YWFTtgVrcE0bOv5zNYToTO4aAqCY4aYD6LPAhAwxvyGC7LIxYG5S402ylsKkrjWnonqmCH00Oq6E6YtR"

    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 item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    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 Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database. "
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))

            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = "sk_test_51HX5u6A1fnSIB3Kmi9YWFTtgVrcE0bOv5zNYToTO4aAqCY4aYD6LPAhAwxvyGC7LIxYG5S402ylsKkrjWnonqmCH00Oq6E6YtR"
        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.user.get_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()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    template = 'checkout/checkout.html'
    context = {
        'order_form': order_form,
        'stripe_public_key':
        "pk_test_51HX5u6A1fnSIB3Km43MupzPhDdzE3QyyAOUnwsbTnovphUUDBuyIEDZDXo3rNw5SQHBkDuqo3keliCWShvZ3PGdN00gKgCOG4V",
        'client_secret': intent.client_secret,
    }

    return render(request, template, context)
Example #26
0
def checkout(request):
    """
        "gets the stripe keys and opens get the cart with a empty dictionary"
        "grabs the form data, pid, original_cart from json dumps and"
         "saves order then iterates through cart.items. Then saves to"
        "order_line_item. If the except happens an error message happens"
        "and redirect back to cart. If the user is authenticated looks for"
         "saved data and initialise the form with saved data Redirect back
         to products"
    """

    #
    # See, Pretty Printed:  (
    # "https://www.youtube.com/watch?v=JwhEjEqG43M&list=PLXmMXHVSvS&ab_channel=PrettyPrinted)

    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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)

            if request.user.is_authenticated:
                order.is_registered = True

            order.save()

            for item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()

                except Product.DoesNotExist:
                    messages.error(request,
                                   ("One of the products in your bid"
                                    "wasn't found in our collection. "
                                    "Please call us as soon as possible"))
                    order.delete()
                    return redirect(reverse('view_bag'))

            # Save the info to the user's profile if all is well
            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "There's nothing to your bid at the moment")
            return redirect(reverse('artists'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any"
        # "info the user maintains in their profile
        if request.user.is_authenticated:

            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_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()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)
Example #27
0
                    order.delete()
                    return redirect(reverse('view_bag'))

    order_form = OrderForm()
            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "There's nothing in your bag at the moment")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is missing. \
    }

    return render(request, template, context)
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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()
            for item_id, item_data in bag.items():
                product = Product.objects.get(id=item_id)
                if isinstance(item_data, int):
                    order_line_item = OrderLineItem(
                        order=order,
                        product=product,
                        quantity=item_data,
                    )
                    order_line_item.save()
                else:
                    messages.error(request, (
                        "There's a problem with your order, wave your paw for assistance."
                    ))
                    return redirect(reverse, ('view_bag'))
            request.session['save_info'] = 'save_info' in request.POST
            return redirect(
                reverse('checkout_success', args=[order.order_number]))

    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "You haven't bought anything yet!")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        order_form = OrderForm()

    if not stripe_public_key:
        messages.warning(request, 'Stripe public key not found')

    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)
Example #29
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_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 item_id, item_data in bag.items():
                try:
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    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 Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our database."
                        "Please call us for assistance!"))
                    order.delete()
                    return redirect(reverse('view_bag'))

            # Save the info to the user's profile if all is well
            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. \
                Please double check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request,
                           "There's nothing in your bag at the moment")
            return redirect(reverse('products'))

        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        stripe_total = round(total * 100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )

        # Attempt to prefill the form with any info the user maintains in their profile
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(
                    initial={
                        'full_name': profile.user.get_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()

    if not stripe_public_key:
        messages.warning(
            request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)
Example #30
0
def checkout(request):
    stripe_public_key = settings.STRIPE_PUBLIC_KEY
    stripe_secret_key = settings.STRIPE_SECRET_KEY

    if request.method == 'POST':
        bag = request.session.get('bag', {})
        # Get the form data from the request
        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)
            # get stripe payment id in order to uniquely id for each
            # transaction so custoemrs can order the same things
            # multiple times and orders will not be confused.
            pid = request.POST.get('client_secret').split('_secret')[0]
            order.stripe_pid = pid
            order.original_bag = json.dumps(bag)
            order.save()
            # iterate through the bag items to create line items
            for item_id, item_data in bag.items():
                try:
                    # get product ID, if value is int = no size field
                    product = Product.objects.get(id=item_id)
                    if isinstance(item_data, int):
                        order_line_item = OrderLineItem(
                            order=order,
                            product=product,
                            quantity=item_data,
                        )
                        order_line_item.save()
                    # if product has size, iterate thoguht eace size and
                    # create line item accordingly
                    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 Product.DoesNotExist:
                    messages.error(request, (
                        "One of the products in your bag wasn't found in our \
                            database. "
                        "Please call us for assistance!")
                    )
                    order.delete()
                    # return user to shopping bag
                    return redirect(reverse('view_bag'))
            # if the user wanted to save their profile redirect to
            # checkout_success with the order number as an additional argument
            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 submission. \
                Please re-check your information.')
    else:
        bag = request.session.get('bag', {})
        if not bag:
            messages.error(request, "There's currently no items in your bag")
            # Reverse Redirect to prevent customers manually accessing URL
            return redirect(reverse('products'))
        current_bag = bag_contents(request)
        total = current_bag['grand_total']
        # prepare stripe payment intent
        stripe_total = round(total*100)
        stripe.api_key = stripe_secret_key
        intent = stripe.PaymentIntent.create(
            amount=stripe_total,
            currency=settings.STRIPE_CURRENCY,
        )
        # if user is authenticated, render form with details pre-filled
        if request.user.is_authenticated:
            try:
                profile = UserProfile.objects.get(user=request.user)
                order_form = OrderForm(initial={
                    'full_name': profile.user.get_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,
                })
            # if user doens't exist, render empty form
            except UserProfile.DoesNotExist:
                order_form = OrderForm()
        # if user is not authenticated, render empty form
        else:
            order_form = OrderForm()

    # alert in case the public key has not been set
    if not stripe_public_key:
        messages.warning(request, 'Stripe public key is missing. \
            Did you forget to set it in your environment?')

    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)