I’ve built a Django view so that I can validate a Stripe coupon code via an AJAX call, but I haven't gotten the code quite right yet.
I know that the view is at least getting triggered because the print statement I’ve put in there is working, but unfortunately it shows that coupon_code is None. Also, when I click on the “Apply” button after typing in a coupon code (valid or not), I’m getting GET http://localhost:8000/payments/coupon 404 (NOT FOUND). I thought maybe I should change the AJAX to a POST request, but then I get 405 (METHOD NOT ALLOWED).
Should I be using GET or POST? How can I successfully get the coupon code to the view for validation? What do I need to do to get the Stripe results from the view back into the template so I can apply the percent or amount off during the checkout process?
Here is my view:
class StripeCouponView(generic.View):
def get(self, request):
stripe.api_key=settings.STRIPE_SECRET_KEY
if request.method == 'GET':
coupon_code = request.GET.get('coupon_code')
print "coupon_code IS", coupon_code
try:
coupon_response = stripe.Coupon.retrieve(coupon_code)
return HttpResponse(
json.dumps(coupon_response),
content_type="application/json"
)
except (requests.exceptions.HTTPError, Exception):
return HttpResponseNotFound('BAD request')
else:
return HttpResponseNotFound('No coupon?')
Here is the applicable code in my urls.py:
from .views import StripeCouponView
# ... a lot of URLs
url(r'^payments/coupon',
StripeCouponView.as_view(),
name='stripecoupon'),
Here is the HTML (built off of djstripe's subscribe_form.html):
{% extends "djstripe/base.html" %}
{% load static djstripe_tags %}
{% block title %}Subscribe{% endblock title %}
{% block content %}
<div class="row">
{% for plan in PLAN_LIST %}
{% with plan_count=PLAN_LIST|length %}
<div class="col-xs-{{ 6|djdiv:plan_count|floatformat }} col-xs-offset-3">
{% endwith %}
<form
{% if not customer.current_subscription or customer.current_subscription.status == CurrentSubscription.STATUS_CANCELLED %}
action="{% url 'djstripe:subscribe' %}" class="djstripe-subscribe"
data-key="{{ STRIPE_PUBLIC_KEY }}"
data-amount="{{ plan.price }}"
data-name="{{ plan.name }}"
data-description="{{ plan.description }}"
{% else %}
data-stripe-key="{{ STRIPE_PUBLIC_KEY }}"
action="{% url 'djstripe:change_plan' %}" class="djstripe-change-plan"
{% endif %}
method="POST">
{% csrf_token %}
<input type="hidden" name="plan" value="{{ plan.plan }}" />
<input name="stripe_token" type="hidden" />
<!-- disable this when clicked -->
<button style="width:100%; border-radius:4px;"
{% if customer.current_subscription.plan == plan.plan and customer.current_subscription.status != CurrentSubscription.STATUS_CANCELLED %}
disabled="true"
{% endif %}
type="submit" class="btn btn-primary">
{% comment %}
{% with image=plan.image|default:"img/default-plan-image.png" %}
<img src="{% static image %}" class="img-thumbnail" />
{% endwith %}
{% endcomment %}
<h3>{{ plan.name }}</h3>
<p>{{ plan.description }}</p>
</button>
{% if not customer.current_subscription or customer.current_subscription.status == CurrentSubscription.STATUS_CANCELLED %}
<!-- do nothing -->
{% elif customer.current_subscription.plan == plan.plan %}
<h4>Your Current Plan</h4>
{% endif %}
</form>
<span class="discount-span"><label>Discount Code:</label>
<input type="text" id="discount-field"/>
<button id="apply-coupon">Apply</button></span>
<div id="coupon-msg">
</div>
</div>
{% endfor %}
</div>
{% endblock content %}
Here's the JavaScript where the Stripe checkout action occurs:
{% block bottom_js %}
{{ block.super }}
<script src="https://checkout.stripe.com/v2/checkout.js"></script>
<script type="text/javascript">
$('#apply-coupon').on('click', function (e) {
$.ajax({
type: 'GET',
url: '{% url 'stripecoupon' %}',
data: { coupon_code : $('#discount-field').val() },
success: function(results){
$('#discount-field').val('');
if (results) {
$('#coupon-msg').html("Valid code.")
// Do something here to send results to StripeCheckout?
}
else {
$('#coupon-msg').html("Invalid code.")
}
}
});
});
$(function() {
$('body').on("click", '.djstripe-subscribe button[type=submit]', function(e) {
e.preventDefault();
// retrieve current $(".djstripe-subscribe")
var $form = $(e.target).parents('form'),
token = function(res) {
$form.find("input[name=stripe_token]").val(res.id);
$("button[type=submit]").attr("disabled", "true");
$('#in-progress').modal({"keyboard": false})
$('.progress-bar').animate({width:'+=100%'}, 2000);
$form.trigger("submit");
};
StripeCheckout.open({
key: '{{ STRIPE_PUBLIC_KEY }}',
email: '{{ user.email }}',
name: 'Premium Subscription',
description: 'Curated Monthly Content',
panelLabel: 'Subscribe',
// amount: whatever the coupon code's percent_off or amount_off is.
token: token,
// coupon: coupon
});
return false;
});
{% if PLAN_LIST|length > 1 %}
$('.djstripe-change-plan').click(function(e){
$("button[type=submit]").attr("disabled", "true");
$('#in-progress').modal({"keyboard": false})
$('.progress-bar').animate({width:'+=100%'}, 2000);
var $form = $(this);
$form.trigger("submit");
});
{% endif %}
});
</script>
{% endblock %}