TL;DR; You can allow coupon codes on the Stripe checkout, you do currently have to do this by creating a session via backend, but it is very easy and only requires a few lines of JS and backend code.
To achieve this it requires:
- JS to AJAX call to backend to get a sessionID with
allow_promotion_codes: true
- JS to
redirectToCheckout() once got a sessionID from backend
(rather than the default of just using redirectToCheckout() directly in JS.)
Here's an example with Javascript and PHP:
Front end (Javascript):
(Be sure to change out 'YOUR STRIPE PRODUCT ID' and 'YOUR AJAX ENDPOINT' values, and initiate https://js.stripe.com/v3 with your Stripe key).
// bind the button
document.getElementById('checkout-button').addEventListener('click', function (e) {
// stop any normal action (if a link)
e.preventDefault();
// retrieve a session ID
ajax_checkoutsession('YOUR STRIPE PRODUCT ID',function (response) {
// got errors?
if (typeof response.checkoutSessionId == undefined){
// could fallback to sending with redirectToCheckout directly
// otherwise, backend error
}
stripe.redirectToCheckout({
sessionId: response.checkoutSessionId,
})
.then(function (result) {
// if error
if (result.error) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer.
// deal with error
}
})
.catch(function (err) {
// deal with non-network Stripe error
});
},function(err){
// deal with AJAX error
});
}
function ajax_checkoutsession(plan,cb,errcb){
var data = {
'action': 'retrieve_checkout_session',
'plan': plan
};
jQuery.ajax({
type: "POST",
url: 'YOUR AJAX ENDPOINT',
"data": data,
dataType: 'json',
timeout: 20000,
success: function(response) {
// callback
if (typeof cb == "function") cb(response);
return response;
},
error: function(response){
// callback
if (typeof errcb == "function") errcb(response);
}
});
}
And then the backend php is pretty simple... (Requires the Stripe library, your Stripe secret key, and your success/cancel URLs):
// load vendor files
require(dirname( __FILE__ ) . '/vendor/autoload.php');
// setup Stripe
\Stripe\Stripe::setApiKey('YOUR STRIPE SECRET KEY');
// retrieve plan / product
$plan = 'defaultplan'; if (isset($_POST['plan'])) $plan = sanitize_text_field( $_POST['plan'] );
// build any line items (for now, simply one)
$line_items = [[
'price' => $plan,
'quantity' => 1
]];
// Sign customer up for subscription
// Note we could use: `client_reference_id`, `customer`, or `customer_email` for returning customers
$checkout_session = \Stripe\Checkout\Session::create([
'success_url' => 'https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => 'https://yoursite.com/cancelled',
'payment_method_types' => ['card'],
'mode' => 'subscription',
'allow_promotion_codes' => true,
'line_items' => $line_items
]);
echo json_encode(['checkoutSessionId' => $checkout_session['id']]);
exit();
Caveats:
- If for some reason your AJAX sessionID generation breaks, your checkout won't work. (You can get around this by falling back to a raw
redirectToCheckout() call.
- The above example 100% works today for Subscriptions, (will need adapting for other modes of payment)
Useful links: