From f2003a711f1f4fa15c97e47122e9ddec712340e5 Mon Sep 17 00:00:00 2001 From: Nathan Chapman Date: Sun, 1 May 2022 10:29:59 -0600 Subject: [PATCH 1/2] Update USPS shipping handling --- src/storefront/cart.py | 14 +++++++++----- .../templates/storefront/cart_detail.html | 2 +- src/storefront/views.py | 19 ++++++++++++++++--- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/storefront/cart.py b/src/storefront/cart.py index b2eb9f0..e05afe6 100644 --- a/src/storefront/cart.py +++ b/src/storefront/cart.py @@ -115,17 +115,21 @@ class Cart: return ShippingContainer.VARIABLE def get_shipping_cost(self): - if len(self) > 0: - usps_rate_request = self.build_usps_rate_request() + if len(self) > 0 and self.session.get("shipping_address"): + try: + usps_rate_request = self.build_usps_rate_request() + except TypeError as e: + return Decimal('0.00') usps = USPSApiWithRate(settings.USPS_USER_ID, test=True) validation = usps.get_rate(usps_rate_request) logger.info(validation.result) try: - rate = Decimal(validation.result['RateV4Response']['Package']['Postage']['CommercialRate']) - return rate + rate = validation.result['RateV4Response']['Package']['Postage']['CommercialRate'] + rate = '0.00' except KeyError as e: raise e("USPS Result has no 'Postage'") - return Decimal('0.00') + rate = '0.00' + return Decimal(rate) else: return Decimal('0.00') diff --git a/src/storefront/templates/storefront/cart_detail.html b/src/storefront/templates/storefront/cart_detail.html index 555e307..2b107d2 100644 --- a/src/storefront/templates/storefront/cart_detail.html +++ b/src/storefront/templates/storefront/cart_detail.html @@ -16,7 +16,7 @@

{{product.name}}

-

Grind: {{item.grind}}

+

Grind:

{% for key, value in item.variations.items %}

{{key}}

diff --git a/src/storefront/views.py b/src/storefront/views.py index f3a9b76..625ac6d 100644 --- a/src/storefront/views.py +++ b/src/storefront/views.py @@ -7,7 +7,7 @@ from django.shortcuts import render, reverse, redirect, get_object_or_404 from django.urls import reverse_lazy from django.core.mail import EmailMessage from django.core.exceptions import ObjectDoesNotExist -from django.http import JsonResponse +from django.http import JsonResponse, HttpResponseRedirect from django.views.generic.base import RedirectView, TemplateView from django.views.generic.edit import FormView, CreateView, UpdateView, DeleteView, FormMixin from django.views.generic.detail import DetailView, SingleObjectMixin @@ -15,6 +15,7 @@ from django.views.generic.list import ListView from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.messages.views import SuccessMessageMixin +from django.contrib import messages from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST from django.forms.models import model_to_dict @@ -193,13 +194,25 @@ class OrderCreateView(CreateView): form_class = OrderCreateForm success_url = reverse_lazy('storefront:payment-done') + def get(self, request, *args, **kwargs): + if not self.request.session.get("shipping_address"): + messages.warning(request, 'Please add a shipping address.') + return HttpResponseRedirect(reverse('storefront:checkout-address')) + else: + return super().get(request, *args, **kwargs) + def get_initial(self): cart = Cart(self.request) + try: + shipping_cost = cart.get_shipping_cost() + except Exception as e: + raise e('Could not get shipping information') + shipping_cost = Decimal('0.00') + initial = { 'total_net_amount': cart.get_total_price(), - 'shipping_total': cart.get_shipping_cost() + 'shipping_total': shipping_cost } - if self.request.session.get('shipping_address'): a = self.request.session.get('shipping_address') user_info = { From b3c75bdb7d30552a77c7d27d604f8f7646707034 Mon Sep 17 00:00:00 2001 From: Nathan Chapman Date: Sun, 1 May 2022 10:47:08 -0600 Subject: [PATCH 2/2] Fix paypal same-site origin opener policy --- src/ptcoffee/config.py | 2 ++ src/static/scripts/payment.js | 21 ++++++++++++--------- src/storefront/payments.py | 6 +++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/ptcoffee/config.py b/src/ptcoffee/config.py index 733a86f..f57381e 100644 --- a/src/ptcoffee/config.py +++ b/src/ptcoffee/config.py @@ -20,6 +20,7 @@ CACHE_CONFIG = { PAYPAL_CLIENT_ID = os.environ.get('PAYPAL_CLIENT_ID', '') PAYPAL_SECRET_ID = os.environ.get('PAYPAL_SECRET_ID', '') +PAYPAL_ENVIRONMENT = os.environ.get('PAYPAL_ENVIRONMENT', 'SANDBOX') USPS_USER_ID = os.environ.get('USPS_USER_ID', '639NATHA3105') DEFAULT_ZIP_ORIGINATION = os.environ.get('DEFAULT_ZIP_ORIGINATION', '98368') @@ -37,3 +38,4 @@ SECURE_HSTS_SECONDS = os.environ.get('SECURE_HSTS_SECONDS', 3600) SECURE_SSL_REDIRECT = os.environ.get('SECURE_SSL_REDIRECT', 'False') == 'True' SESSION_COOKIE_SECURE = os.environ.get('SESSION_COOKIE_SECURE', 'False') == 'True' CSRF_COOKIE_SECURE = os.environ.get('CSRF_COOKIE_SECURE', 'False') == 'True' +SECURE_CROSS_ORIGIN_OPENER_POLICY = 'same-origin-allow-popups' diff --git a/src/static/scripts/payment.js b/src/static/scripts/payment.js index 52ffeef..39c0a50 100644 --- a/src/static/scripts/payment.js +++ b/src/static/scripts/payment.js @@ -5,6 +5,12 @@ let form = document.querySelector('.order-create-form') // Render the PayPal button into #paypal-button-container paypal.Buttons({ + style: { + color: "gold", + shape: "rect", + layout: "vertical" + }, + // Call your server to set up the transaction createOrder: function(data, actions) { const formData = new FormData(form) @@ -24,22 +30,19 @@ paypal.Buttons({ }) return fetch(request, options) - .then(function(res) { - return res.json(); - }).then(function(orderData) { - return orderData.id; - }); + .then((response) => response.json()) + .then((order) => order.id) }, // Call your server to finalize the transaction - onApprove: function(data, actions) { + onApprove: (data, actions) => { const csrftoken = getCookie("csrftoken") return fetch('/paypal/order/' + data.orderID + '/capture/', { method: 'post', headers: {'X-CSRFToken': csrftoken} - }).then(function(res) { - return res.json(); - }).then(function(orderData) { + }) + .then((response) => response.json()) + .then((orderData) => { var errorDetail = Array.isArray(orderData.details) && orderData.details[0]; if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') { diff --git a/src/storefront/payments.py b/src/storefront/payments.py index 6a26ec2..85ab92d 100644 --- a/src/storefront/payments.py +++ b/src/storefront/payments.py @@ -23,10 +23,10 @@ class PayPalClient: """Setting up and Returns PayPal SDK environment with PayPal Access credentials. For demo purpose, we are using SandboxEnvironment. In production this will be LiveEnvironment.""" - if settings.DEBUG: - self.environment = SandboxEnvironment(client_id=self.client_id, client_secret=self.client_secret) - else: + if settings.PAYPAL_ENVIRONMENT == 'LIVE': self.environment = LiveEnvironment(client_id=self.client_id, client_secret=self.client_secret) + else: + self.environment = SandboxEnvironment(client_id=self.client_id, client_secret=self.client_secret) """ Returns PayPal HTTP client instance with environment which has access credentials context. This can be used invoke PayPal API's provided the