Integrating Stripe into Laravel 4 application

In this short post I will explain how you can get the basic Stripe checkout to work inside of Laravel 4 application. Stripe allows you to take credit card payments painlessly and integration cannot be simpler than this.

I have previously posted on Stripe integration into Laravel 3 application, to understand more how Stripe payments work I would like to ask you to please read that post first .

Without further ado, let’s imagine you have an already working Laravel 4 application and you just need to be able to take credit card payments, Stripe will be perfect for that and here is how you can integrate it quickly in Laravel 4 web application.

First add the stripe-php to composer.json by running “Composer require” command in the terminal and then specify the version of the package:

composer require stripe/stripe-php

Please provide a version constraint for the stripe/stripe-php requirement: dev-master

Running “composer require” command should download the stripe library and place it in the “vendor” folder. Believe it or not, at this point you can already use Stripe in your application. Don’t you love the beauty of Composer – based frameworks? Plug in play a package in just a few seconds.

We can optimize some things though to make them Laravel friendly. For example Laravel provides us with ability to store and access config variables easy. We can set different API keys for different environments – local and production using Laravel’s simple concept of environments. Also we can use Laravel’s Input and Redirect functionality to simplify the application flow.

Let’s create a config file that will store the Stripe keys (you need to get the API keys here). Let’s place the following contents in app/config/stripe.php , replacing the words with underscores with your actual Stripe keys (for now let’s use test keys):

<?php

return array(
	// Stripe keys
	'stripe' => array(
		'secret' => 'your_test_secret_key_here',
		'public' => 'your_test_public_key_here'
	),

);

Then, in your page where you want the “Pay with Stripe”  button to appear, create a form that will hold user’s checkout information, and that will implement the “Pay with Stripe” button:

<form action="{{url('pay')}}" method="POST">
  <script
    src="https://checkout.stripe.com/v2/checkout.js" class="stripe-button"
    data-key="{{Config::get('stripe.stripe.public')}}"
    data-amount="2000"
    data-name="Demo Laravel Site"
    data-description="2 scoops of ice cream ($20.00)"
    data-image="/128x128.png">
  </script>
</form>

You can adjust the attributes to customize the informational text and image that appears in the Stripe popup by modifying contents of “data-something” attributes. The data-amount attribute is the amount that will be shown to the user (in cents). The actual amount will be set in the backend of the application which we will get to.

Now let’s imagine your page where the customer is paying for something is located at “myapp.com/pay” route, in that case you will have 2 routes for your checkout, a “get” route to show the “Pay with Stripe” button (and possibly additional form fields) and a “post” route to process the Stripe payment (and/or additional form fields). Take a look at these complete routes below:

Route::get('pay', function(){
	return View::make('stripe');
});

Route::post('pay', function(){
	// Use the config for the stripe secret key
	Stripe::setApiKey(Config::get('stripe.stripe.secret'));

	// 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" => 2000, // amount in cents
	      "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('pay')
	        ->withInput()->with('stripe_errors',$error['message']);
	}
	// Maybe add an entry to your DB that the charge was successful, or at least Log the charge or errors
	// Stripe charge was successfull, continue by redirecting to a page with a thank you message
	return Redirect::to('pay/success');
});

This is pretty much it, you can now charge credit cards with Stripe and Laravel 4. Did you expect more? =) Let me know in the comments if you have any suggestions or improvements to this article!

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

You may also like

14 comments

  • Jake Toolson September 10, 2013  

    Hey! I think you want to add more of Stripe’s exception handling because a CardError is only one of the exceptions thrown.

    I have a catchall that re-throws a basic exception to the parent method.

    [code]
    catch(Stripe_CardError $e)
    {
    $body = $e->getJsonBody();
    $err = $body[‘error’];
    Log::write(‘error’, ‘Stripe: ‘ . $err[‘type’] . ‘: ‘ . $err[‘code’] . ‘: ‘ . $err[‘message’]);
    $error = $err[‘message’];
    }
    catch (Stripe_InvalidRequestError $e)
    {
    $body = $e->getJsonBody();
    $err = $body[‘error’];
    Log::write(‘error’, ‘Stripe: ‘ . $err[‘type’] . ‘: ‘ . $err[‘message’]);
    $error = $err[‘message’];
    }
    catch (Stripe_ApiConnectionError $e)
    {
    // Network communication with Stripe failed
    $error = ‘A network error occurred.’;
    }
    catch (Stripe_AuthenticationError $e)
    {
    Log::write(‘error’,’Stripe: API key rejected!’, ‘stripe’);
    $error = ‘Payment processor API key error.’;
    }
    catch (Stripe_Error $e)
    {
    Log::write(‘error’, ‘Stripe: Stripe_Error – Stripe could be down.’);
    $error = ‘Payment processor error, try again later.’;

    }
    catch (Exception $e)
    {
    Log::write(‘error’, ‘Stripe: Unknown error.’);
    $error = ‘There was an error, try again later.’;
    }

    if ($error !== null)
    {
    throw new Stripe_Exception( (string) $error);
    }
    [/code]

  • Evan Schoepke October 18, 2013  

    How about for subscription style building?

  • Jason February 9, 2014  

    I think you missed something in your code. I figured out after a little while that the first segment of the config variable is the file name. Mine looks like this: Config::get(‘stripe.stripe.secret’)

  • Maks Surguy February 9, 2014  

    Thanks for the catch! Updated the post with correct info.

  • Alex Crawford June 17, 2014  

    I was going to come back to follow along later, but then I barely scrolled down and learned in seconds. Too easy, thanks Laravel and Maks and nice site!

  • maxsurguy June 18, 2014  

    You’re welcome! Glad you found it useful. Also if you need subscription billing (recurring) make sure to check out Laravel Cashier, native package for Laravel to make that extremely simple.

  • Ravi September 30, 2014  

    All is working good but getting error Call to undefined method IlluminateDatabaseQueryBuilder::setApiKey(). Any help!!

  • Shamim Ullah December 31, 2014  

    I have an issue after successfully submitting the form it shows an error after redirection Illuminate Session TokenMismatchException.
    Please help.

  • A. Arsalan February 4, 2015  

    You need to set the package name in app configuration.

  • Sylar March 23, 2015  

    @maxsurguy:disqus Can you do an integration with an actual product?

  • Gokul October 6, 2015  

    I have tried this,its throwing error like this,FatalErrorException in routes.php line 29:Class ‘Stripe’ not found

Leave a comment