Practical Laravel – payment integration – Stripe

Update! I have posted a tutorial for Laravel 4 as well, please check it after reading this post:
maxoffsky.com/code-blog/integrating-stripe-into-laravel-4-application/

Hello there, Laravel developers!

In this blog post I’ll describe in detail how you can integrate payment system into your Laravel 3 applications and charge people some real money! Specifically I’ll describe how to use Stripe. In future posts I may also write about Balanced and others but this one is focused on Stripe.

What is Stripe? Simply it is a payment gateway for developers. Something like Paypal but a whole lot more developer friendly. As a developer you will love how easy it is to charge money and how easily it integrates into your application. In fact, you will love it so much that you will want to come up with something to charge people money just to see it working so well =)

Stripe works this way: there are two parts to make Stripe work, the client side Stripe.js (really small) and the server side library. the Stripe.js javascript creates an invisible single-use token that is appended to the checkout form on submittal and then you feed that token into the server side library that creates the actual financial charge. This way the user never leaves your site, you are totally in control of the look and feel of your site but Stripe also provides a get-started-quickly javascript that handles a lot of client side validation before the form is processed.

Stripe accepts the following credit and debit cards :

  • United States businesses can accept Visa, MasterCard, American Express, JCB, Discover, and Diners Club.
  • Canada businesses can accept Visa, MasterCard, and American Express.

Does this sound good? Ok , let’s start integrating stripe into your application.

Step 1) If you don’t have a Stripe account, create one right now here: https://manage.stripe.com/register

Step 2) Download the stripe PHP library here, unpack it and place the contents of the “lib” folder into your “application/libraries” folder :

Step 3) Make sure that your production PHP server has CURL extension enabled. For example on Pagodabox I had to add curl to the list of PHP extensions in the Boxfile.

Step 4) Integrate Stripe.js into your checkout form. Let’s say you are asking for user’s shipping information on the checkout form, you will want to omit the “Submit” button, and instead put in Stripe.js code, something like this (I am using Former bundle to create my  beautiful Forms in Laravel) :

{{ Former::open('checkout') }}
{{ Former::legend('Shipping information:')}}
{{ Former::text('address_1','Address 1')->required()->min(3)}}
{{ Former::text('address_2','Address 2')}}
{{ Former::text('phone','Phone')}}
{{ Former::text('city','City')->required()->min(2)}}
{{ Former::select('state','State')->options(array('CA'=>'California'))->required()}}
{{ Former::text('zip','Zip')->required()->min(4)}}
<div class="control-group">
  <label for="payment" class="control-label">Payment*</label>
  <div class="controls">
    <script
      src="https://checkout.stripe.com/v2/checkout.js" class="stripe-button"
      data-key="your_test_or_live_key_from_stripe_account"
      data-amount="1000"
      data-name="Myshop"
      data-description="Quadcopter"
      data-image="{{url('img/stripe-128x128.png')}}">
    </script>
  </div>
</div>
{{ Former::close() }}

Now, when this form will be displayed, you will see it looking like this :

This form will be POSTed to ‘checkout’ route.

Let’s create that route in the routes.php:

Route::post('checkout', function()
{
	//
});

Now, we need to process this form inside this POST route, first let’s do some basic Laravel validation for the checkout form :

$formInput = Input::all();

	$rules = array(
	    'address_1' 	=> 'required|min:3',
	    'city' 		=> 'required|min:3',
	    'state' 		=> 'required',
	    'zip' 		=> 'required|min:4',
	);

	$v = Validator::make($formInput, $rules);

	if ( $v -> fails() )
	{   
	    return Redirect::to('/')
	    	->with_errors($v)
	    	->with_input();
	} else {

	}

Now, let the Stripe magic begin.

If the validation passes, let’s charge this person some money.

// Set up Stripe private api key
		Stripe::setApiKey('YourStripeSecretKey');

		// Get the credit card details submitted by the form
		$token = Input::get('stripeToken');

		// Create the charge on Stripe's servers - this will charge the user's card
		try {
			$charge = Stripe_Charge::create(array(
			  "amount" => 1000, 
			  "currency" => "usd",
			  "card"  => $token,
			  "description" => 'Charge for my product')
			);

		} catch(Stripe_CardError $e) {
			$e_json = $e->getJsonBody();
			$error = $e_json['error'];
		  	// The card has been declined
		  	// redirect back to checkout page

			return Redirect::to('/')
				->with_input()
				->with('card_errors'=>$error);
		}

		// Stripe charge was successfull, continue 
		return 'Charge successfull';

		/* or 
		create an order in orders table to record this order
		create an account for the user if doesn't exist
		etc...
		*/

That’s it! After putting in my test API keys in both client side and server side scripts, I made a test charge with one of the fake card numbers(listed below) and here is the details from Stripe about it:

You can try a test charge with one of the following credit card numbers (found here):

Number Card type
4242424242424242 Visa
4012888888881881 Visa
5555555555554444 MasterCard
5105105105105100 MasterCard
378282246310005 American Express
371449635398431 American Express
6011111111111117 Discover
6011000990139424 Discover
30569309025904 Diner’s Club
38520000023237 Diner’s Club
3530111333300000 JCB
3566002020360505 JCB

Here is the complete source code for routes.php (with the API key stripped out) :

Route::get('/', function()
{
	return View::make('home.index');
});

Route::post('checkout', function()
{
	$formInput = Input::all();

	$rules = array(
	    'address_1' 	=> 'required|min:3',
	    'city' 		=> 'required|min:3',
	    'state' 		=> 'required',
	    'zip' 		=> 'required|min:4',
	);

	$v = Validator::make($formInput, $rules);

	if ( $v -> fails() )
	{   
	    return Redirect::to('/')
	    	->with_errors($v)
	    	->with_input();
	} else {

		// Set up Stripe private api key
		Stripe::setApiKey('your_stripe_private_key');

		// Get the credit card details submitted by the form
		$token = Input::get('stripeToken');

		// Create the charge on Stripe's servers - this will charge the user's card
		try {
			$charge = Stripe_Charge::create(array(
			  "amount" => 1000, 
			  "currency" => "usd",
			  "card"  => $token,
			  "description" => 'Charge for my product'
			));

		} catch(Stripe_CardError $e) {
			$e_json = $e->getJsonBody();
			$error = $e_json['error'];
		  	// The card has been declined
		  	// redirect back to checkout page or just display error message

			dd($error);
			//return Redirect::to('/')->with_input()->with('card_errors',$error);
		}

		// Stripe charge was successfull, continue 
		return 'Charge successfull';

		/* or 
		create an order in orders table to record this order
		create an account for the user if doesn't exist
		etc...
		*/
	}

});

This is the basics of charging money with Stripe.

From here you can go further, you can create customers on Stripe servers, you can link customers to a token that you save in your database and that way you can set up recurring charges and much more!

Please let me know if you have any questions! Have fun Stripe-ing in Laravel

Liked it? Take a second to support Maks Surguy on Patreon!
Become a patron at Patreon!

You may also like

17 comments

  • aditya menon April 20, 2013  

    It’s posts like this that make it worthwhile to get your articles delivered straight to my inbox! Thanks. Too bad I’m not in North America, so I can’t use Stripe personally. But it was pleasant to see how you can just drop libraries into laravel and then call LibraryName::staticfunction and it just works (gets autoloaded transparently).

  • Sinan Eldem April 20, 2013  

    Thanks Maks.

    Good work.

  • Maks Surguy April 21, 2013  

    Yep! Love the autoloading functionality!
    Yeah, that is one of the drawback of most payment systems, they don’t allow you to process payments without setting up a business in the US. One way around that is to ask somebody from USA or Canada to set it up, in exchange for a percentage of payments. They will pay taxes from the income as well so your share will be around 60% of all sales which is still pretty good in the goods are digital or have a good profit margin.

  • Bastian Hofmann May 20, 2013  

    The else statement is not necessary since you return the redirect.

  • Maks Surguy May 24, 2013  

    Where ?

  • Rob June 6, 2013  

    Awesome Tutorial! Stripe is such a great tool to use. And with Laravel…Even better. I would love to see an update for this in Laravel 4!

  • Daryl June 9, 2013  

    Thanks Maks, you write a great Tutorial. You wouldn’t know of a link to a guide Implementing Paypal Express into L4 would you?

  • Rob June 15, 2013  

    Hey Maks, I was able to get the stripe library as a package. So the stripe folder is in my vendor folder. Using laravel 4, how would I autoload that lib? What would I need to put in my app.php to make it work?

  • Maks Surguy June 15, 2013  
  • Sadi June 20, 2013  

    I think he means line #24.

Leave a comment