Skip to content

Instantly share code, notes, and snippets.

@johndellavecchia
Last active June 15, 2018 10:09
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johndellavecchia/b2ecab4a33701e6b9020 to your computer and use it in GitHub Desktop.
Save johndellavecchia/b2ecab4a33701e6b9020 to your computer and use it in GitHub Desktop.
Stripe Checkout v2 PHP donation example
<?php
require_once('path/to/stripe-php-library/init.php');
// set up messaging
$error = '';
$success = '';
if ($_POST) {
// Set your secret key: remember to change this to your live secret key in production
// See your keys here https://dashboard.stripe.com/account
\Stripe\Stripe::setApiKey("sk_test_your_secret_key");
// Get the credit card and customer interaction details submitted by the form
$token = $_POST['stripeToken'];
$custemail = $_POST['stripeEmail'];
$donation = $_POST['donationAmt'];
// Create the customer
$customer = \Stripe\Customer::create(array(
"source" => $token,
"description" => $custemail,
"email" => $custemail
));
// Create the charge on Stripe's servers - this will charge the user's card
try {
$charge = \Stripe\Charge::create(array(
"amount" => $donation,
"currency" => "usd",
"customer" => $customer->id,
"receipt_email" => $custemail,
"description" => "Online Donation - $custemail"
));
$success = 'Your payment was successful.';
} catch(\Stripe\Error\Card $e) {
// The card has been declined from some reason
$error = $e->getMessage();
}
// send back messaging json
$arr = array(
'success'=>$success,
'error'=>$error
);
echo json_encode($arr);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta charset="utf-8">
<title>Donate</title>
<style>
.donate-process,
.donate-thanks,
.donate-alert {
font-size: 1.2em;
-webkit-transition: all .3s ease-out;
-moz-transition: all .3s ease-out;
-o-transition: all .3s ease-out;
transition: all .3s ease-out;
visibility: hidden;
opacity: 0;
height: 0;
display: block;
}
.donate-process.show,
.donate-thanks.show,
.donate-alert.show {
opacity: 1;
height: auto;
visibility: visible;
padding: 1em;
}
.donate-alert.show {
background: #f6cfcf;
}
.donate-thanks.show {
background: #39d1b4;
color: #fff;
}
</style>
</head>
<body>
<div id="main" role="main">
<section>
<span class="donate-alert" aria-expanded="false"></span>
<span class="donate-process" aria-expanded="false">processing your donation...</span>
<span class="donate-thanks" aria-expanded="false"></span>
<h1>Donate</h1>
<p><em>Enter an amount below, or use the quick links for a specific amount.</em></p>
<form method="post" action="/" id="donate-form">
<input type="text" id="amt" value="">
<button id="donateNow">Donate</button>
</form>
<button data-amt="25">+$25</button>
<button data-amt="50">+$50</button>
<button data-amt="100">+$100</button>
<button data-amt="150">+$150</button>
</section>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
$(document).ready(function(){
// scroll to top for processing
function scrollTo() {
var hash = '#main';
var destination = $(hash).offset().top;
stopAnimatedScroll();
$('html, body').stop().animate({
scrollTop: destination
}, 400, function() { window.location.hash = hash; });
return false;
}
function stopAnimatedScroll(){
if ( $('*:animated').length > 0 ) {$('*:animated').stop();}
}
if(window.addEventListener) {
document.addEventListener('DOMMouseScroll', stopAnimatedScroll, false);
}
document.onmousewheel = stopAnimatedScroll;
// prevent decimal in donation input
$('#amt').keypress(function(event){
preventDot(event);
});
function preventDot(event){
var key = event.charCode ? event.charCode : event.keyCode;
if (key == 46){
event.preventDefault();
return false;
}
}
function showProcessing() {
scrollTo();
$('.donate-process').addClass('show').attr('aria-expanded', 'true');
$('.donate-thanks, .donate-alert').removeClass('show').attr('aria-expanded', 'false');
}
function hideProcessing() {
$('.donate-process').removeClass('show').attr('aria-expanded', 'false');
}
// set up Stripe config, ajax post to charge
var handler = StripeCheckout.configure({
key: 'pk_test_your_secret_key',
image: 'path/to/img',
closed: function(){document.getElementById('donateNow').removeAttribute('disabled');},
token: function(token) {
$.ajax({
url: 'path/to/charge.php',
type: 'POST',
dataType: 'json',
beforeSend: showProcessing,
data: {stripeToken: token.id, stripeEmail: token.email, donationAmt: donationAmt},
success: function(data) {
hideProcessing();
$('#amt').val('');
if (data.error!='') {
$('.donate-alert').addClass('show').text(data.error).attr('aria-expanded', 'true');
} else {
$('.donate-thanks').addClass('show').text(data.success).attr('aria-expanded', 'true');
}
},
error: function(data) {
$('.donate-alert').show().text(data).attr('aria-expanded', 'true');
}
});
}
});
// donate now button, open Checkout
$('#donateNow').click(function(e) {
// strip non-numbers from amount and convert to cents
donationAmt = document.getElementById('amt').value.replace(/\D/g,'') + '00';
// make sure there is an amount
if (donationAmt < 1) {
$('#amt').val('').focus();
e.preventDefault();
} else {
$('#donateNow').attr('disabled', 'disabled');
// Open Checkout
handler.open({
name: 'Your Org Name',
description: 'Online Donation',
amount: donationAmt,
billingAddress: true
});
e.preventDefault();
}
});
// quick-add amount buttons
$('.btn-amt').click(function() {
var insert = $.parseJSON($(this).attr('data-amt'));
$('#amt').val(insert);
});
// Close Checkout on page navigation
$(window).on('popstate', function() {
handler.close();
});
});
</script>
</body>
</html>

Stripe Checkout with Variable Donation Amount

This example uses techniques to implement a donation page with Stripe Checkout and PHP. It includes a variable amount input, quick-add amount buttons, basic form validation, ajax card charge, error handling on the response, UI for processing during submission, and ARIA accessibility enhancements.

ExpressionEngine Notes

If you use ExpressionEngine, make sure to include CSRF in your form and ajax post:

Add a hidden input to the form:

<input type="hidden" name="csrf_token" value="{csrf_token}">

Also, include the variable in the token ajax data array:

csrf_token: '{csrf_token}'

Requirements

Download the Stripe PHP library and place in a directory on your server.

Browser Support

Tested in IE8+ and all other major/modern browsers.

@mikeydiamonds
Copy link

mikeydiamonds commented Jul 9, 2016

Hey John,
I came across your gist while trying to implement a stripe checkout button for our non-profit. I cannot get it to work. Just pops up "processing your donation ..." and never finishes.

Also, I'm getting this error in the Console:
ReferenceError: event is not defined
$('#amt').keypress(function(){preventDot(event)});
index.html (line 88, col 33)

Any Ideas? Thanks for any help you can provide.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment