I'm building an ecommerce store with Django and I want that when the user selects a payment, he gets redirected to that specific payment option. Meaning that when someone clicks Stripe, it should go to the Stripe's checkout and when he clicks Paypal, it should direct them tothat option. But as for now, when the user clicks the button to proceed it does nothing. I've alread made all the form validations and the payment_option's so that it redirects correctly.
views.py:
class CheckoutView(View):
def get(self, *args, **kwargs):
try:
order = Order.objects.get(user=self.request.user, ordered=False)
form = checkoutForm()
context = {
'form': form,
'order': order,
}
shipping_address_qs = Address.objects.filter(
user=self.request.user,
address_type='S',
default=True
)
if shipping_address_qs.exists():
context.update(
{'default_shipping_address': shipping_address_qs[0]})
except ObjectDoesNotExist:
messages.info(self.request, "You do not have an active order")
return redirect("core:checkout")
return render(self.request, "ecommerceapp/checkout.html", context)
def post(self, *args, **kwargs):
form = checkoutForm(self.request.POST or None)
try:
order = Order.objects.get(user=self.request.user, ordered=False)
if form.is_valid():
use_default_shipping = form.cleaned_data.get(
'use_default_shipping')
if use_default_shipping:
print("Using the defualt shipping address")
address_qs = Address.objects.filter(
user=self.request.user,
address_type='S',
default=True
)
if address_qs.exists():
shipping_address = address_qs[0]
order.shipping_address = shipping_address
order.save()
else:
messages.info(
self.request, "No default shipping address available")
return redirect('core:checkout')
else:
print("User is entering a new shipping address")
street_address = form.cleaned_data.get(
'street_address')
appartment_suite = form.cleaned_data.get(
'appartment_suite')
town_city = form.cleaned_data.get(
'town_city')
post_code = form.cleaned_data.get('post_code')
if is_valid_form([street_address, town_city, post_code]):
shipping_address = Address(
user=self.request.user,
street_address=street_address,
appartment_suite=appartment_suite,
town_city=town_city,
post_code=post_code,
)
shipping_address.save()
order.shipping_address = shipping_address
order.save()
set_default_shipping = form.cleaned_data.get(
'set_default_shipping')
if set_default_shipping:
shipping_address.default = True
shipping_address.save()
else:
messages.info(
self.request, "Please fill in the required shipping address fields")
payment_option = form.cleaned_data.get('payment_option')
if payment_option == 'S':
return redirect('core:payment', payment_option='Stripe')
elif payment_option == 'P':
return redirect('core:payment', payment_option='Paypal')
else:
messages.warning(
self.request, "Invalid payment option selected")
return redirect('core:checkout')
return render(self.request, "ecommerceapp/checkout.html", context)
except ObjectDoesNotExist:
messages.warning(self.request, "You do not have an active order")
return redirect("core:shop")
urls.py:
urlpatterns = [
path('', views.index, name='index'),
path('shop/', views.shop, name="shop"),
path('about/', views.about, name="about"),
path('blog/', views.blog, name="blog"),
path('contact/', views.contact, name="contact"),
path('checkout/', CheckoutView.as_view(), name="checkout"),
path('cart/', views.cart, name="cart"),
path('product-single/<slug:slug>/', views.productpage, name="productpage"),
path('add-to-cart/<slug:slug>/', views.add_to_cart, name="addtocart"),
path('remove-from-cart/<slug:slug>/', views.remove_from_cart, name="removefromcart"),
path('payment/<payment_option>/', PaymentView.as_view(), name='payment')
]
checkout.html:
<form action="#" class="billing-form">
{% csrf_token %}
<h3 class="mb-4 billing-heading">Billing Details</h3>
<div class="row align-items-end">
<div class="col-md-6">
<div class="form-group">
<label for="firstname">First Name</label>
{{ form.first_name }}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="lastname">Last Name</label>
{{ form.second_name }}
</div>
</div>
<div class="w-100"></div>
<div class="col-md-12">
<div class="form-group">
<label for="country">State / Country</label>
{{ form.state_country }}
<script>
var image_x = document.getElementById('flag_id_state_country');
image_x.parentNode.removeChild(image_x);
</script>
</div>
</div>
<div class="w-100"></div>
<div class="col-md-6">
<div class="form-group">
<label for="streetaddress">Street Address</label>
{{ form.street_address }}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
{{ form.appartment_suite }}
</div>
</div>
<div class="w-100"></div>
<div class="col-md-6">
<div class="form-group">
<label for="towncity">Town / City</label>
{{ form.town_city }}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="postcodezip">Postcode / ZIP *</label>
{{ form.post_code }}
</div>
</div>
<div class="w-100"></div>
<div class="col-md-6">
<div class="form-group">
<label for="phone">Phone</label>
{{ form.phone_number }}
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="emailaddress">Email Address</label>
{{ form.email_address }}
</div>
</div>
<div class="w-100"></div>
<div class="col-md-12">
<div class="form-group mt-4">
<div class="radio">
<label class="mr-3"><input type="radio" name="optradio"> Create an Account? </label>
<label><input type="radio" name="optradio"> Ship to different address</label>
</div>
</div>
</div>
</div>
{% for object in orders %}
<div class="row mt-5 pt-3 d-flex">
<div class="col-md-6 d-flex">
<div class="cart-detail cart-total bg-light p-3 p-md-4">
<h3 class="billing-heading mb-4">Cart Total</h3>
<p class="d-flex">
<span>Subtotal</span>
<span>${{ object.get_total }}</span>
</p>
<hr>
<p class="d-flex total-price">
<span>Total</span>
<span>${{ object.get_total }}</span>
</p>
</div>
</div>
{% endfor %}
<div class="col-md-6">
<div class="cart-detail bg-light p-3 p-md-4">
<h3 class="billing-heading mb-4">Payment Method</h3>
<div class="form-group">
<div class="col-md-12">
{% for value, name in form.fields.payment_option.choices %}
<div class="radio">
<input id="{{ name }}" name="payment_option" value="{{ value }}" type="radio" class="custom-control-input" required>
<label class="custom-control-label" for="{{ name }}">{{ name }}</label>
</div>
{% endfor %}
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<div class="checkbox">
<label><input type="checkbox" value="" class="mr-2"> I have read and accept the terms and conditions</label>
</div>
</div>
</div>
<button class="btn btn-primary py-3 px-4" type="submit">Continue to checkout</button>
forms.py:
class checkoutForm(forms.Form):
COUNTRY = (('France', 'France'),
('Italy', 'Italy'),
('Philippines', 'Philippines'),
('Hongkong', 'Hongkong'),
('Japan', 'Japan'))
PAYMENT_CHOICES = (
('S', 'Stripe'),
('P', 'Paypal'),
('BT', 'Bank Transfer'),
)
first_name = forms.CharField(widget=forms.TextInput(attrs={
'class': 'form-control',
}))
second_name = forms.CharField(widget=forms.TextInput(attrs={
'class': 'form-control',
}))
state_country = CountryField().formfield(widget=CountrySelectWidget(
attrs={'class': 'form-control',}
))
street_address = forms.CharField(widget=forms.TextInput(attrs={
'class': 'form-control',
}))
appartment_suite = forms.CharField(required=False, widget=forms.TextInput(attrs={
'class': 'form-control',
'placeholder': 'Appartment, suite, unit etc: (optional)'
}))
town_city = forms.CharField(widget=forms.TextInput(attrs={
'class': 'form-control',
}))
post_code = forms.IntegerField(widget=forms.NumberInput(attrs={
'class': 'form-control',
}))
phone_number = forms.IntegerField(widget=forms.NumberInput(attrs={
'class': 'form-control',
}))
email_address = forms.EmailField(widget=forms.TextInput(attrs={
'class': 'form-control',
}))
payment_option = forms.ChoiceField(choices=
PAYMENT_CHOICES)
set_default_shipping = forms.BooleanField(required=False)
use_default_shipping = forms.BooleanField(requi
red=False)
Add method="post"
to your html form.
<form action="#" class="billing-form" method="post">
The default method of form is GET