From 62279cc3900dd4d2891a1a5bef5dd1e71f1f1bd3 Mon Sep 17 00:00:00 2001 From: James Kachel Date: Tue, 7 Jan 2025 10:03:08 -0600 Subject: [PATCH] Fix country code assignment on checkout (#192) --- payments/models.py | 12 ++++++++++-- payments/views/v0/__init__.py | 12 +++++++++--- payments/views/v0/urls.py | 10 +++++----- .../management/commands/generate_test_data.py | 6 ++++++ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/payments/models.py b/payments/models.py index 4cc1a5ee..1ca22b7f 100644 --- a/payments/models.py +++ b/payments/models.py @@ -919,11 +919,19 @@ def _get_or_create(self, basket: Basket): # (this re-uses a PendingOrder if it exists, so it might now be wrong) order.tax_rate = basket.tax_rate order.purchaser_ip = basket.user_ip - order.purchaser_taxable_country_code = basket.user_taxable_country_code + order.purchaser_taxable_country_code = ( + basket.user_taxable_country_code + if basket.user_taxable_country_code + else "" + ) order.purchaser_taxable_geolocation_type = ( basket.user_taxable_geolocation_type ) - order.purchaser_blockable_country_code = basket.user_blockable_country_code + order.purchaser_blockable_country_code = ( + basket.user_blockable_country_code + if basket.user_blockable_country_code + else "" + ) order.purchaser_blockable_geolocation_type = ( basket.user_blockable_geolocation_type ) diff --git a/payments/views/v0/__init__.py b/payments/views/v0/__init__.py index 078d3935..4456c2d6 100644 --- a/payments/views/v0/__init__.py +++ b/payments/views/v0/__init__.py @@ -8,7 +8,6 @@ from django.shortcuts import redirect from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt -from django.views.generic import View from django_filters import rest_framework as filters from drf_spectacular.utils import ( OpenApiParameter, @@ -20,7 +19,7 @@ from mitol.payment_gateway.api import PaymentGateway from rest_framework import status from rest_framework.decorators import api_view, permission_classes -from rest_framework.permissions import IsAuthenticated +from rest_framework.permissions import AllowAny, IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView from rest_framework.viewsets import ReadOnlyModelViewSet @@ -272,7 +271,7 @@ def start_checkout(request, system_slug: str): @method_decorator(csrf_exempt, name="dispatch") -class CheckoutCallbackView(View): +class CheckoutCallbackView(APIView): """ Handles the redirect from the payment gateway after the user has completed checkout. This may not always happen as the redirect back to the app @@ -280,6 +279,9 @@ class CheckoutCallbackView(View): things via the backoffice webhook. """ + authentication_classes = [] # disables authentication + permission_classes = [AllowAny] # disables permission + def _get_payment_process_redirect_url_from_line_items(self, request): """ Returns the payment process redirect URL @@ -354,6 +356,7 @@ def post_checkout_redirect(self, order_state, request): {"type": USER_MSG_TYPE_PAYMENT_ERROR_UNKNOWN}, ) + @extend_schema(exclude=True) def post(self, request): """ Handle successfully completed transactions. @@ -364,6 +367,9 @@ def post(self, request): 2. Finds and fulfills the order in the system (which should also then clear out the stored basket) 3. Perform any enrollments, account status changes, etc. + + Excluded from the OpenAPI schema because it's not a public API - only + CyberSource should be generating the payload for this request. """ with transaction.atomic(): diff --git a/payments/views/v0/urls.py b/payments/views/v0/urls.py index 354c5c8e..4334ec6a 100644 --- a/payments/views/v0/urls.py +++ b/payments/views/v0/urls.py @@ -48,6 +48,11 @@ BackofficeCallbackView.as_view(), name="checkout-callback", ), + path( + "checkout/result/", + CheckoutCallbackView.as_view(), + name="checkout-result-callback", + ), path( "checkout//", start_checkout, @@ -64,9 +69,4 @@ router.urls, ), ), - path( - "checkout/result/", - CheckoutCallbackView.as_view(), - name="checkout-result-callback", - ), ] diff --git a/system_meta/management/commands/generate_test_data.py b/system_meta/management/commands/generate_test_data.py index 58f051a9..99c16b66 100644 --- a/system_meta/management/commands/generate_test_data.py +++ b/system_meta/management/commands/generate_test_data.py @@ -16,6 +16,7 @@ from django.core.management import BaseCommand from django.core.management.base import CommandParser from django.db import transaction +from django.urls import reverse from system_meta.models import IntegratedSystem, Product @@ -111,6 +112,11 @@ def add_test_systems(self) -> None: description=f"Test System {i} description.", api_key=uuid.uuid4(), ) + system.payment_process_redirect_url = reverse( + "cart", kwargs={"system_slug": system.slug} + ) + system.save() + self.stdout.write(f"Created system {system.name} - {system.slug}") def add_test_products(self, system_slug: str) -> None: