Skip to content

Commit b5bdb6f

Browse files
zemekenengvikalpj
authored andcommitted
Add view to accept card token instead of full card details. (Fueled#2)
* Add view to accept card token instead of full card details. * Use generic error handling for non-present tokens case.
1 parent cc851c9 commit b5bdb6f

File tree

4 files changed

+44
-1
lines changed

4 files changed

+44
-1
lines changed

README.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ Endpoints
1818
* current-user/ (GET)
1919
* subscription/ (GET/POST)
2020
* change-card/ (GET/POST)
21+
* change-card-token/ (POST)
2122
* charges/ (GET)
2223
* invoices/ (GET)
2324
* plans/ (GET)
2425
* events/ (GET)
2526
* webhook/ (POST)
2627
* cancel/ (POST)
2728

28-
**ALL TEMPLATES AND AJAX VIEWS HAS BEEN REMOVED, USE ADDED ENDPOINTS**
29+
**ALL TEMPLATES AND AJAX VIEWS HAVE BEEN REMOVED, USE ADDED ENDPOINTS**
2930

3031
Documentation can be found at http://django-stripe-payments.readthedocs.org

payments/api/serializers.py

+4
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ class CardSerializer(Serializer):
9797
address_country = serializers.CharField(required=False, allow_null=True)
9898

9999

100+
class CardTokenSerializer(Serializer):
101+
token = serializers.CharField(required=True, help_text=u'Card token generated by stripe.js, or other api call.')
102+
103+
100104
class CancelSerializer(Serializer):
101105
confirm = serializers.BooleanField(required=True)
102106

payments/api/urls.py

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
url(r'^current-user/$', views.CurrentCustomerDetailView.as_view(), name='stripe-current-customer-detail'),
77
url(r'^subscription/$', views.SubscriptionView.as_view(), name='stripe-subscription'),
88
url(r'^change-card/$', views.ChangeCardView.as_view(), name='stripe-change-card'),
9+
url(r'^change-card-token/$', views.ChangeCardTokenView.as_view(), name='stripe-change-card-token'),
910
url(r'^charges/$', views.ChargeListView.as_view(), name='stripe-charges'),
1011
url(r'^invoices/$', views.InvoiceListView.as_view(), name='stripe-invoices'),
1112
url(r'^plans/$', views.PlanListView.as_view(), name='stripe-plans'),

payments/api/views.py

+37
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
CurrentCustomerSerializer,
1616
SubscriptionSerializer,
1717
CardSerializer,
18+
CardTokenSerializer,
1819
CancelSerializer,
1920
ChargeSerializer,
2021
InvoiceSerializer,
@@ -120,6 +121,42 @@ def post(self, request, *args, **kwargs):
120121
return Response(error_data, status=status.HTTP_400_BAD_REQUEST)
121122

122123

124+
class ChangeCardTokenView(StripeView):
125+
"""
126+
Add or update customer card token
127+
128+
This is useful if you are planing to use strip.js to
129+
retrieve the card token. This isolates the full credit
130+
card number from your server.
131+
"""
132+
serializer_class = CardTokenSerializer
133+
134+
def post(self, request, *args, **kwargs):
135+
try:
136+
serializer = self.serializer_class(data=request.data)
137+
138+
if serializer.is_valid():
139+
validated_data = serializer.validated_data
140+
141+
customer = self.get_customer()
142+
143+
token = validated_data['token']
144+
customer.update_card(token)
145+
send_invoice = customer.card_fingerprint == ""
146+
147+
if send_invoice:
148+
customer.send_invoice()
149+
customer.retry_unpaid_invoices()
150+
151+
return Response(validated_data, status=status.HTTP_201_CREATED)
152+
else:
153+
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
154+
155+
except stripe.StripeError as e:
156+
error_data = {u'error': smart_str(e) or u'Unknown error'}
157+
return Response(error_data, status=status.HTTP_400_BAD_REQUEST)
158+
159+
123160
class CancelView(StripeView):
124161
""" Cancel customer subscription """
125162
serializer_class = CancelSerializer

0 commit comments

Comments
 (0)