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

The following two tabs change content below.

Maks Surguy

Full stack web developer, speaker and writer.
Maks is young and energetic breakdancer turned into web developer who lives in Seattle area with his wife. He is well-versed in three languages (English, Russian, Ukrainian) and a dozen of programming languages.