I'm developing my first test Django Stripe project, but I'm currently stuck at the point because the redirect on success page is not working.
This is my views.py file
import stripe
from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.views import View
from django.views.generic import TemplateView
from .models import Item
stripe.api_key = settings.STRIPE_SECRET_KEY
class ProductLandingPageView(TemplateView):
template_name = 'landing.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
item_id = self.kwargs["id"]
item = get_object_or_404(Item, id=item_id)
context['item'] = item
return context
class CreateCheckoutSessionView(View):
def get(self, request, *args, **kwargs):
item_id = self.kwargs["id"]
DOMAIN: str = 'http://127.0.0.1:8000'
item = Item.objects.get(id=item_id)
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[
{
'price_data': {
'currency': 'usd',
'unit_amount': item.price * 100,
'product_data': {
'name': item.name,
},
},
'quantity': 1,
},
],
payment_intent_data={
'metadata': {
'item_id': item.id,
},
},
mode='payment',
success_url=DOMAIN + '/success/',
cancel_url=DOMAIN + '/cancel/',
)
return HttpResponse(session.id)
class SuccessView(TemplateView):
template_name = "success.html"
class CancelView(TemplateView):
template_name = "cancel.html"
And this is my template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Homepage</title>
<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<div class="description">
<h3>{{ item.name }}</h3>
<h5>{{ item.display_price }} USD.</h5>
</div>
<button id="buy-button" data-item-id="{{ item.id }}">Buy</button>
<script>
document.getElementById('buy-button').addEventListener('click', function() {
var itemId = this.getAttribute('data-item-id');
fetch('/buy/' + itemId)
.then(function(response) {
return response.json();
})
.then(function(data) {
var stripe = Stripe(data.stripe_public_key);
stripe.redirectToCheckout({ sessionId: data.session_id });
})
.catch(function(error) {
console.error('Ошибка:', error);
});
});
</script>
</body>
</html>
I'm using env variables for keys so added these lines in settings
STRIPE_PUBLISHABLE_KEY = os.getenv('STRIPE_PUBLISHABLE_KEY')
STRIPE_SECRET_KEY = os.getenv('STRIPE_SECRET_KEY')
And my urls.py is set this way
from api.views import CancelView, SuccessView, CreateCheckoutSessionView, ProductLandingPageView
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
path('item/<int:id>', ProductLandingPageView.as_view(), name='item'),
path('buy/<int:id>', CreateCheckoutSessionView.as_view(), name='buy'),
path('cancel/', CancelView.as_view(), name='cancel'),
path('success/', SuccessView.as_view(), name='success'),]
Project structure
Do you have any suggestions on how to solve the issue? BTW if you notice any other thing to improve - please feel free to comment it. I'm very new to stripe service and still learning how it works.
UPD:
Problem solved by modifying JS code as follows
<script>
document.getElementById('buy-button').addEventListener('click', function() {
var itemId = this.getAttribute('data-item-id');
var stripe = Stripe("{{ STRIPE_PUBLIC_KEY }}");
fetch('/buy/' + itemId)
.then(function(response) {
return response.json();
})
.then(function (session) {
return stripe.redirectToCheckout({ sessionId: session.id });
})
.catch(function(error) {
console.error('Ошибка:', error);
});
});
</script>
In general you have two options to do the Checkout Session redirect.
Option 1:
checkout.url
to your frontendwindow.location.href
Option 2:
<form action="/checkout-session" method="POST"> <button type="submit" /> </form>
/checkout-session
creates a Checkout Session and return a 303 redirect with the Checkout Session url