Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix to make shipping address from data passed from PayPal, per spec #153

Merged
merged 14 commits into from
May 1, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion paypal/express/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
url(r'^place-order/(?P<basket_id>\d+)/$', views.SuccessResponseView.as_view(),
name='paypal-place-order'),
# Callback for getting shipping options for a specific basket
url(r'^shipping-options/(?P<basket_id>\d+)/',
url(r'^shipping-options/(?P<basket_id>\d+)/(?P<country_code>\w+)?',
csrf_exempt(views.ShippingOptionsView.as_view()),
name='paypal-shipping-options'),
# View for using PayPal as a payment method
Expand Down
57 changes: 50 additions & 7 deletions paypal/express/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,46 @@ def get_shipping_method(self, basket, shipping_address=None, **kwargs):

class ShippingOptionsView(View):

def get(self, request, *args, **kwargs):
"""
We use the shipping address given to use by PayPal to
determine the available shipping method
"""
# Basket ID is passed within the URL path. We need to do this as some
# shipping options depend on the user and basket contents. PayPal do
# pass back details of the basket contents but it would be royal pain to
# reconstitute the basket based on those - easier to just to piggy-back
# the basket ID in the callback URL.
basket = get_object_or_404(Basket, id=kwargs['basket_id'])
user = basket.owner
if not user:
user = AnonymousUser()

logger.info(kwargs['country_code'])

# Create a shipping address instance using the data passed back
country_code = self.request.POST.get(
'SHIPTOCOUNTRY', None)
try:
country = Country.objects.get(iso_3166_1_a2=kwargs['country_code'])
except Country.DoesNotExist:
country = Country()

shipping_address = ShippingAddress(
line1=self.request.POST.get('SHIPTOSTREET', ''),
line2=self.request.POST.get('SHIPTOSTREET2', ''),
line4=self.request.POST.get('SHIPTOCITY', ''),
state=self.request.POST.get('SHIPTOSTATE', ''),
postcode=self.request.POST.get('SHIPTOZIP', ''),
country=country
)
methods = Repository().get_shipping_methods(
basket=basket, shipping_addr=shipping_address,
request=self.request, user=user)
return self.render_to_response(methods, basket)



def post(self, request, *args, **kwargs):
"""
We use the shipping address given to use by PayPal to
Expand All @@ -405,18 +445,18 @@ def post(self, request, *args, **kwargs):

# Create a shipping address instance using the data passed back
country_code = self.request.POST.get(
'PAYMENTREQUEST_0_SHIPTOCOUNTRY', None)
'SHIPTOCOUNTRY', None)
try:
country = Country.objects.get(iso_3166_1_a2=country_code)
except Country.DoesNotExist:
country = Country()

shipping_address = ShippingAddress(
line1=self.request.POST.get('PAYMENTREQUEST_0_SHIPTOSTREET', ''),
line2=self.request.POST.get('PAYMENTREQUEST_0_SHIPTOSTREET2', ''),
line4=self.request.POST.get('PAYMENTREQUEST_0_SHIPTOCITY', ''),
state=self.request.POST.get('PAYMENTREQUEST_0_SHIPTOSTATE', ''),
postcode=self.request.POST.get('PAYMENTREQUEST_0_SHIPTOZIP', ''),
line1=self.request.POST.get('SHIPTOSTREET', ''),
line2=self.request.POST.get('SHIPTOSTREET2', ''),
line4=self.request.POST.get('SHIPTOCITY', ''),
state=self.request.POST.get('SHIPTOSTATE', ''),
postcode=self.request.POST.get('SHIPTOZIP', ''),
country=country
)
methods = Repository().get_shipping_methods(
Expand All @@ -427,6 +467,7 @@ def post(self, request, *args, **kwargs):
def render_to_response(self, methods, basket):
pairs = [
('METHOD', 'CallbackResponse'),
('CALLBACKVERSION', '61.0'),
('CURRENCYCODE', self.request.POST.get('CURRENCYCODE', 'GBP')),
]
for index, method in enumerate(methods):
Expand All @@ -445,6 +486,8 @@ def render_to_response(self, methods, basket):
else:
# No shipping methods available - we flag this up to PayPal indicating that we
# do not ship to the shipping address.
pairs.append(('NO_SHIPPING_OPTION_DETAILS', 1))
pass
# pairs.append(('NO_SHIPPING_OPTION_DETAILS', 1))
payload = urlencode(pairs)
logger.info(payload)
return HttpResponse(payload)