Skip to content

Commit 548ba5e

Browse files
committed
Add option to return dict from payment methods
1 parent e2edbb9 commit 548ba5e

File tree

5 files changed

+32
-16
lines changed

5 files changed

+32
-16
lines changed

docs/releases/dev.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
##############
2-
In Development
2+
In development
33
##############
44

55
*TBA*
6+
7+
Changed
8+
-------
9+
10+
- Payment methods can now optionally return a JSON serializable data dictionary.

docs/releases/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Release notes and upgrade information. This project adheres to
1818
:caption: v1.1
1919
:maxdepth: 1
2020

21+
dev
2122
1.1.2
2223
1.1.1
2324
1.1.0

salesman/checkout/payment.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, List, Optional
3+
from typing import TYPE_CHECKING, List, Optional, Union
44

55
from django.core.exceptions import ValidationError
66
from django.http import HttpRequest
@@ -74,12 +74,14 @@ def validate_order(self, order: BaseOrder, request: HttpRequest) -> None:
7474
msg = _("Payment for order with status '{status}' is not allowed.")
7575
raise ValidationError(msg.format(status=order.status_display))
7676

77-
def basket_payment(self, basket: BaseBasket, request: HttpRequest) -> str:
77+
def basket_payment(
78+
self,
79+
basket: BaseBasket,
80+
request: HttpRequest,
81+
) -> Union[str, dict]:
7882
"""
7983
This method gets called when new checkout is submitted and
8084
is responsible for creating a new order from given basket.
81-
Should return the redirect url to either the next payment step or
82-
the order success page. Raise ``PaymentError`` in case an issue appears.
8385
8486
Args:
8587
basket (Basket): Basket instance
@@ -89,15 +91,17 @@ def basket_payment(self, basket: BaseBasket, request: HttpRequest) -> str:
8991
PaymentError: If error with payment occurs
9092
9193
Returns:
92-
str: Redirect url to the next step
94+
Union[str, dict]: Redirect URL string or JSON serializable data dictionary
9395
"""
9496
raise NotImplementedError("Method `basket_payment()` is not implemented.")
9597

96-
def order_payment(self, order: BaseOrder, request: HttpRequest) -> str:
98+
def order_payment(
99+
self,
100+
order: BaseOrder,
101+
request: HttpRequest,
102+
) -> Union[str, dict]:
97103
"""
98104
This method gets called when payment for an existing order is requested.
99-
Should return the redirect url to either the next payment step or the
100-
order success page. Raise ``PaymentError`` in case an issue appears.
101105
102106
Args:
103107
order (Order): Order instance
@@ -107,7 +111,7 @@ def order_payment(self, order: BaseOrder, request: HttpRequest) -> str:
107111
PaymentError: If error with payment occurs
108112
109113
Returns:
110-
str: Redirect url to the next step
114+
Union[str, dict]: Redirect URL string or JSON serializable data dictionary
111115
"""
112116
raise NotImplementedError("Method `order_payment()` is not implemented.")
113117

salesman/checkout/serializers.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ class CheckoutSerializer(serializers.Serializer):
3838
Serializer for processing a basket payment.
3939
"""
4040

41-
url = serializers.CharField(read_only=True)
4241
email = serializers.EmailField(write_only=True)
4342
shipping_address = serializers.CharField(
4443
allow_blank=True,
@@ -98,5 +97,9 @@ def save(self):
9897
basket.save(update_fields=['extra'])
9998
# Process the payment.
10099
payment = self.validated_data['payment_method']
101-
url = payment.basket_payment(basket, request)
102-
self.validated_data['url'] = url # type: ignore
100+
data = payment.basket_payment(basket, request)
101+
# Returning string in payments converts to a URL data value.
102+
if isinstance(data, str):
103+
data = {'url': data}
104+
# Override the serializer data with the payment data.
105+
self._data = data

salesman/orders/serializers.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ class OrderPaySerializer(serializers.Serializer):
178178
Serializer used to pay for existing order via payment method.
179179
"""
180180

181-
url = serializers.CharField(read_only=True)
182181
payment_method = serializers.ChoiceField(
183182
choices=payment_methods_pool.get_choices('order'),
184183
write_only=True,
@@ -197,8 +196,12 @@ def save(self):
197196
# Process the payment.
198197
order, request = self.context['order'], self.context['request']
199198
payment = self.validated_data['payment_method']
200-
url = payment.order_payment(order, request)
201-
self.validated_data['url'] = url # type: ignore
199+
data = payment.order_payment(order, request)
200+
# Returning string in payments converts to a URL data value.
201+
if isinstance(data, str):
202+
data = {'url': data}
203+
# Override the serializer data with the payment data.
204+
self._data = data
202205

203206

204207
class OrderRefundSerializer(serializers.Serializer):

0 commit comments

Comments
 (0)