So you don't trust yourself enough to build your own payment method page for your E-commerce website? WELL… NEITHER DO I!
In this blog post, I am going to teach you geeks how to set one up for your web applications. I have been troubleshooting for weeks on end, reading Stripe's extensive documentation, and chugging lots of Rockstar (sponser me plz) – so that you don’t have to. Just follow these five easy steps that even a Neanderthal like me could follow:
composer create-project laravel/laravel StripeTurtorial
Now, go into your newly created Laravel project:
cd StripeTurtorial
Next, install the libraries to use the Stripe API in your project:
composer require stripe/stripe-php
Then, check if your project is working correctly:
php artisan serve
If you haven't created a Stripe account already, go ahead and do so here. You must have a user account to use the Stripe API. In Stripe's dashboard go to the home tab, and click on "Get your test API keys." If you are using Linux, use vi (or whatever barbaric text editor that isn't vi) to add your keys in the .env file in your project’s main directory:
vi .env
Then, add these lines at the end of the .env file and the corresponding keys shown in the "Get your test API keys:"
STRIPE_KEY=pk_test*****
STRIPE_SECRET=sk_test*****
Now, we are going to create a controller. This allows our users go to the premade Stripe checkout page when they click on the JavaScript button.
php artisan make:controller StripePaymentController
Next, we are going to open this file with our text editor:
vi app/Http/Controllers/StripePaymentController.php
In this file, we will create a function called payment() in which we create a Stripe Checkout session. Then, we return the session ID in JSON format so that in the frontend the JavaScript fetch can redirect the user with their session ID to Stripe's checkout page.
<?php
namespace App\Http\Controllers;
// Add the response in so we can return the session as JSON
use Illuminate\Http\Response;
use Illuminate\Http\Request;
// To use Stripe PHP API
use Session;
use Stripe;
class StripePaymentController extends Controller
{
/* Creates the checkout session and returns the session id in JSON format */
public function payment() {
// We grab the Stripe key information we added in the .env file
\Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
// Creates the Stripe session
$session = \Stripe\Checkout\Session::create ([
'payment_method_types' => ['card'],
'billing_address_collection' => 'required',
'shipping_address_collection' => ['allowed_countries' => ['US', 'CA'],],
'line_items' => [[
'price_data' => [
'currency' => 'usd',
'product_data' => [
'name' => 'T-shirt',
],
'unit_amount' => 2000,
],
'quantity' => 1,
]],
'mode' => 'payment',
'allow_promotion_codes' => true,
'success_url' => 'http://127.0.0.1:8000/',
'cancel_url' => 'http://127.0.0.1:8000/',
]);
// Return the Stripe Session id so the fetch command in our frontend redirects users to Stripe's checkout page
return response()->json(['id' => $session->id]);
}
}
Okay. Now that we have created your controller with the payment function, we now need Laravel to grab that controller and use the function we created in Step 3. For that, we are going to open our web.php file in the routes folder.
vi routes/web.php
Then, we are going to add two elements in this folder: First, a path to where our controller is located (because we are using Laravel 8); and second, we add a POST route method in the same web.php file.
<?php
use Illuminate\Support\Facades\Route; // This line came with the web.php file
use App\Http\Controllers\StripePaymentController; // ADD! Tells Laravel where our controller is located at
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () { // This function came with the web.php file as well
return view('welcome');
});
/******************************Stripe******************************/
Route::post('/payment', [StripePaymentController::class, 'payment']); // ADD! Tells Laravel what function to use in the controller and what type of route method we are using
Let me start by saying this part was difficult for me when I first tried to use the Stripe API for an e-commerce website during my Senior Project. I kept running into an issue where the web application only returns a JSON string that looked like this:
{ id: random session number }
…among many other similar issues. So I did what any good programmer does: I headed over to stackoverflow and asked this question, hoping someone would help me figure out why my web application was returning only the JSON string! It was because JavaScript needed to access the CSRF token that was created. JavaScript simply needed to grab that token to redirect the user to the checkout page. Here is the original post if you are interested in seeing Donkarnash teach a Neanderthal like me how to use JavaScript.
I suggest editing the welcome.blade.php file in the resources/view folder in your Laravel project. From Stripe's documentation, we add a button to the HTML part of the welcome.blade.php file, and also add a <script> tag in the welcome.blade.php file. Stripe's documentation requires us to use fetch in the frontend.
vi resources/views/welcome.blade.php
Add this line in the <head> part of the .blade.php file:
<!-- For Stripe Checkout --!>
<script src="https://js.stripe.com/v3/"></script>
You can add this part of the code anywhere in the body tag for learning purposes:
<form action="/payment" method="POST">
@csrf
<button id="checkout-button">Proceed to Checkout</button>
</form>
<script type="text/javascript">
// Create an instance of the Stripe object with your publishable API key
var stripe = Stripe('pk_test_******');
var checkoutButton = document.getElementById('checkout-button');
checkoutButton.addEventListener('click', function() {
// Create a new Checkout Session using the server-side endpoint you
// created in step 3.
fetch('/payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'url': '/payment',
"X-CSRF-Token": document.querySelector('input[name=_token]').value
},
})
.then(function(response) {
return response.json();
})
.then(function(session) {
return stripe.redirectToCheckout({ sessionId: session.id });
})
.then(function(result) {
// If `redirectToCheckout` fails due to a browser or network
// error, you should display the localized error message to your
// customer using `error.message`.
if (result.error) {
alert(result.error.message);
}
})
.catch(function(error) {
console.error('Error:', error);
});
});
</script>
If you want to test the payment, stripe has a bunch of test cards you can use. Head over to your stripe dashboard where you can see if the test card payment goes through.
If you want the github repo of this project, then here it is!
Now go out there and make something great, you wonderful geeks!
I was kidding about the vi stuff plz monetize me gogole