This course is archived!
This tutorial uses an older version of Symfony of the stripe-php SDK. The majority of the concepts are still valid, though there *are* differences. We've done our best to add notes & comments that describe these changes.
Coupons! Adding the Form
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
Let's talk about something fun: coupon codes. When a user checks out, I want them to be able to add a coupon code. Fortunately Stripe totally supports this, and that makes our job easier.
In fact, in the Stripe dashboard, there's a Coupon section. Create a new coupon: you can choose either a percent off or an amount off. To make things simple, I'm only going to support coupons that are for a specific amount off.
Create one that saves us $50
. Oh, and in case this is used on an order with a
subscription, you can set the duration to once, multi-month or forever.
Then, give the code a creative, unique code: like CHEAP_SHEEP. Oh, and the coupon codes are case sensitive.
Tip
I'm choosing to create my coupons through Stripe's admin interface. If you want an admin section that does this on your site, that's totally possible! You can create new Coupons through Stripe's API.
Adding a Coupon During Checkout
Back on our site, before we get into any Stripe integration, we need to add a spot for adding coupons during checkout.
Open the template: order/checkout.html.twig
. Below the cart table, add a button,
give it some styling classes and a js-show-code-form
class. Say, "I have a coupon code":
// ... lines 1 - 19 | |
{% block body %} | |
<div class="nav-space-checkout"> | |
<div class="container"> | |
<div class="row"> | |
// ... lines 24 - 26 | |
<div class="col-xs-12 col-sm-6"> | |
// ... lines 28 - 57 | |
<button class="btn btn-xs btn-link pull-right js-show-code-form"> | |
I have a coupon code | |
</button> | |
// ... lines 61 - 75 | |
</div> | |
// ... lines 77 - 79 | |
</div> | |
</div> | |
</div> | |
{% endblock %} |
Instead of adding this form by hand, open your tutorial/
directory: this is
included in the code download. Open coupon-form.twig
, copy its code, then paste
it below the button:
// ... lines 1 - 19 | |
{% block body %} | |
<div class="nav-space-checkout"> | |
<div class="container"> | |
<div class="row"> | |
// ... lines 24 - 26 | |
<div class="col-xs-12 col-sm-6"> | |
// ... lines 28 - 57 | |
<button class="btn btn-xs btn-link pull-right js-show-code-form"> | |
I have a coupon code | |
</button> | |
<div class="js-code-form" style="display: none;"> | |
<form action="" method="POST" class="form-inline"> | |
<div class="form-group"> | |
<div class="input-group"> | |
<span class="input-group-addon"> | |
<i class="fa fa-terminal"></i> | |
</span> | |
<input type="text" name="code" autocomplete="off" class="form-control" placeholder="Coupon Code"/> | |
</div> | |
<button type="submit" class="btn btn-primary">Add</button> | |
</div> | |
</form> | |
</div> | |
</div> | |
// ... lines 77 - 79 | |
</div> | |
</div> | |
</div> | |
{% endblock %} |
This new div
is hidden by default and has a js-code-form
class that we'll use soon
via JavaScript. And, it has just one field named code
.
Copy the js-show-code-form
class and scroll up to the javascripts
block. Add
a new document.ready()
function:
// ... lines 1 - 3 | |
{% block javascripts %} | |
// ... lines 5 - 8 | |
<script> | |
jQuery(document).ready(function() { | |
// ... lines 11 - 15 | |
}); | |
</script> | |
{% endblock %} | |
// ... lines 19 - 84 |
Inside, find the .js-show-code-form
element and on click
, add a callback. Start
with our favorite e.preventDefault()
:
// ... lines 1 - 3 | |
{% block javascripts %} | |
// ... lines 5 - 8 | |
<script> | |
jQuery(document).ready(function() { | |
$('.js-show-code-form').on('click', function(e) { | |
e.preventDefault(); | |
// ... lines 13 - 14 | |
}) | |
}); | |
</script> | |
{% endblock %} | |
// ... lines 19 - 84 |
Then, scroll down to the form, copy the js-code-form
class, use jQuery to select this,
and... drumroll... show it!
// ... lines 1 - 3 | |
{% block javascripts %} | |
// ... lines 5 - 8 | |
<script> | |
jQuery(document).ready(function() { | |
$('.js-show-code-form').on('click', function(e) { | |
e.preventDefault(); | |
$('.js-code-form').show(); | |
}) | |
}); | |
</script> | |
{% endblock %} | |
// ... lines 19 - 84 |
Cool! Now when you refresh, we have a new link that shows the form.
Submitting the Coupon Form
So let's move to phase two: when we hit "Add", this should submit to a new endpoint that validates the code in Stripe and attaches it to our user's cart.
To create the new endpoint, open OrderController
. Near the bottom add a new public
function addCouponAction()
with @Route("/checkout/coupon")
. Name it order_add_coupon
.
And to be extra-hipster, add @Method("POST")
to guarantee that you can only POST
to this:
// ... lines 1 - 9 | |
use Symfony\Component\HttpFoundation\Request; | |
class OrderController extends BaseController | |
{ | |
// ... lines 14 - 79 | |
/** | |
* @Route("/checkout/coupon", name="order_add_coupon") | |
* @Method("POST") | |
*/ | |
public function addCouponAction(Request $request) | |
{ | |
// ... lines 86 - 97 | |
} | |
// ... lines 99 - 144 | |
} | |
// ... lines 146 - 147 |
Cool! Copy the route name, then find the coupon form in the checkout template. Update
the form's action
: add path()
and then paste the route name:
// ... lines 1 - 19 | |
{% block body %} | |
<div class="nav-space-checkout"> | |
<div class="container"> | |
<div class="row"> | |
// ... lines 24 - 26 | |
<div class="col-xs-12 col-sm-6"> | |
// ... lines 28 - 61 | |
<div class="js-code-form" style="display: none;"> | |
<form action="{{ path('order_add_coupon') }}" method="POST" class="form-inline"> | |
// ... lines 64 - 73 | |
</form> | |
</div> | |
</div> | |
// ... lines 77 - 79 | |
</div> | |
</div> | |
</div> | |
{% endblock %} |
Next, we'll read the submitted code and check with Stripe to make sure it's real, and not just someone trying to guess clever coupon codes. Come on, we've all tried it before.
Yo :)
It would be really handy if a user could remove a product from the cart :)
my cart looks like this: https://imgur.com/a/H6Y6l
now when someone clicks on the x the product should be removed from the cart and the cart should be updated.
my template looks like this:
https://imgur.com/a/H6Y6l
and i started the javascript like this:
i dont know how to send a request to the server and then remove the product or subscription.
a hint for me?
Thanks for anything :)