Braintree Payments in Laravel: The Ultimate Guide
Founder of QuickAdminPanel
Braintree is one of the most popular ways to accept payments online, in this article we take a deep look how it works in Laravel framework.
In this tutorial we will create a few Braintree demos, so please create your testing account at Braintree, and let’s dive right in.
Preparation and Braintree Install
First, let’s create a new Laravel application
laravel new braintree-demo
Next – usual Laravel installation steps:
composer install cp .env.example .env php artisan key:generate php artisan migrate
And then we install a special Braintree package for PHP:
composer require braintree/braintree_php
Now we need to set up our Braintree API information in .env file
BRAINTREE_ENV=sandbox BRAINTREE_MERCHANT_ID= BRAINTREE_PUBLIC_KEY= BRAINTREE_PRIVATE_KEY=
Go to Braintree sandbox page and register an account. After account confirmation and login, just go to Settings -> API keys and there you’ll find all the needed information.
Now, fill in the data
BRAINTREE_ENV=sandbox BRAINTREE_MERCHANT_ID=pxsff7htd4xwwcgs BRAINTREE_PUBLIC_KEY=3m7dsyydgdz9nxcd BRAINTREE_PRIVATE_KEY=cc2632a6b244d16eabbbcb4d08105bab
To setup Braintree in Laravel, go to App/Providers/AppServiceProvider.php and add the following code to your boot() method
Braintree_Configuration::environment(env('BRAINTREE_ENV')); Braintree_Configuration::merchantId(env('BRAINTREE_MERCHANT_ID')); Braintree_Configuration::publicKey(env('BRAINTREE_PUBLIC_KEY')); Braintree_Configuration::privateKey(env('BRAINTREE_PRIVATE_KEY'));
Payment Routes and Forms
In our routes/web.php we need to add a new route for processing the payment
Route::get('/payment/process', 'PaymentsController@process')->name('payment.process');
Now we can add our application view in resources/views/welcome.blade.php
<!doctype html> <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Braintree-Demo</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://js.braintreegateway.com/web/dropin/1.8.1/js/dropin.min.js"></script> <link href="{{ asset('css/app.css') }}" rel="stylesheet"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div id="dropin-container"></div> <button id="submit-button">Request payment method</button> </div> </div> </div> <script> var button = document.querySelector('#submit-button'); braintree.dropin.create({ authorization: "{{ Braintree_ClientToken::generate() }}", container: '#dropin-container' }, function (createErr, instance) { button.addEventListener('click', function () { instance.requestPaymentMethod(function (err, payload) { $.get('{{ route('payment.process') }}', {payload}, function (response) { if (response.success) { alert('Payment successfull!'); } else { alert('Payment failed'); } }, 'json'); }); }); }); </script> </body> </html>
If the setup was successful, you should see Braintree “drop-in” appear – there you can enter your credit card information:
Processing Payment
To process the payment, we need to create a new payment controller
php artisan make:controller PaymentsController
And then we create process() method inside the controller
use Braintree_Transaction; public function process(Request $request) { $payload = $request->input('payload', false); $nonce = $payload['nonce']; $status = Braintree_Transaction::sale([ 'amount' => '10.00', 'paymentMethodNonce' => $nonce, 'options' => [ 'submitForSettlement' => True ] ]); return response()->json($status); }
And that’s it – our simple payment system is created!
To try it out, just go to your application and enter some fake credit card data:
- Braintree sandbox credit card number is 4111 1111 1111 1111
- Expiration date can be whatever you want
Then click on “Request payment method” button:
Our front-end part of the application will send a request to Braintree and ask for a payment method and a “nonce” that we will use to execute the payment in our controller.
After we get a response from Braintree, we send a request to our application’s backend with information provided by Braintree, and try to make a payment. PaymentsController will return the status of the payment, and if it’s successful – we should see an alert, informing us about that.
Subscription payments – Cashier
Another way to pay for services is subscriptions. And here with Braintree we can use official Laravel Cashier package.
First, let’s install the package:
composer require laravel/cashier-braintree
To track our subscriptions, we’ll need to update our database and add some fields:
php artisan make:migration add_braintree_fields
Fill the up method with the following code:
Schema::table('users', function ($table) { $table->string('braintree_id')->nullable(); $table->string('paypal_email')->nullable(); $table->string('card_brand')->nullable(); $table->string('card_last_four')->nullable(); $table->timestamp('trial_ends_at')->nullable(); }); Schema::create('subscriptions', function ($table) { $table->increments('id'); $table->integer('user_id'); $table->string('name'); $table->string('braintree_id'); $table->string('braintree_plan'); $table->integer('quantity'); $table->timestamp('trial_ends_at')->nullable(); $table->timestamp('ends_at')->nullable(); $table->timestamps(); });
Also, to test our app, we’ll need a user, so let’s create one in database/seeds/DatabaseSeeder.php
User::create([ 'name' => 'First user', 'email' => 'user@user.com', 'password' => bcrypt('password') ]);
At this point, we can run the migrations
php artisan migrate --seed
Now, add Billable trait to our User model:
use Laravel\Cashier\Billable; class User extends Authenticatable { use Billable; }
Next: add service configuration code in config/services.php:
'braintree' => [ 'model' => App\User::class, 'environment' => env('BRAINTREE_ENV'), 'merchant_id' => env('BRAINTREE_MERCHANT_ID'), 'public_key' => env('BRAINTREE_PUBLIC_KEY'), 'private_key' => env('BRAINTREE_PRIVATE_KEY'), ],
Notice: we added these env variables in .env file in the first part of the tutorial.
Now, routing: add a subscription route in routes/web.php:
Route::get('/payment/subscribe', 'PaymentsController@subscribe')->name('payment.subscribe');
And a subscribe() method in PaymentsController – the same that we created earlier:
public function subscribe(Request $request) { try { $payload = $request->input('payload', false); $nonce = $payload['nonce']; $user = User::first(); $user->newSubscription('main', 'bronze')->create($nonce); return response()->json(['success' => true]); } catch (\Exception $ex) { return response()->json(['success' => false]); } }
The view can stay the same, we just need to change the route from
{{ route('payment.process') }}
To
{{ route('payment.subscribe') }}
One last thing. In our PaymentsController we are subscribing to our ‘bronze’ subscription, but we haven’t created one in Braintree, so before we can make a payment – we need to go to our sandbox and find Plans at the end of the menu.
Go to plans and click New, create your plan there. Important thing: Plan ID has to be the same as $user->newSubscription(‘main’, ‘bronze’) second parameter.
Now that our backend is set up, we can add front-end subscription form.
It’s basically the same code as in single payment form, only difference being the route we are submitting to.
<!doctype html> <html lang="{{ app()->getLocale() }}"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Braintree-Demo</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script src="https://js.braintreegateway.com/web/dropin/1.8.1/js/dropin.min.js"></script> <link href="{{ asset('css/app.css') }}" rel="stylesheet"> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div id="dropin-container"></div> <button id="submit-button">Request payment method</button> </div> </div> </div> <script> var button = document.querySelector('#submit-button'); braintree.dropin.create({ authorization: "{{ Braintree_ClientToken::generate() }}", container: '#dropin-container' }, function (createErr, instance) { button.addEventListener('click', function () { instance.requestPaymentMethod(function (err, payload) { $.get('{{ route('payment.subscribe') }}', {payload}, function (response) { if (response.success) { alert('Payment successfull!'); } else { alert('Payment failed'); } }, 'json'); }); }); }); </script> </body> </html>
Enter dummy credit card data, click Subscribe, and that’s it – Braintree will now bill the user based on your subscription settings that you entered while setting up subscription plan in Braintree.
You can visit you Braintree Sandbox and you should find our subscription there.
So, that’s it! That was an overview of how you can use Braintree inside of Laravel. Was it helpful?
Read more: