I will divide this tutorial into following steps:
- Creating the necessary tables and models
- Defining the routes and creating the controllers
- Creating checkout form
- Front-end validation with Parsley.js
- Stripe configuration
- Back-end validation
- Creating Stripe Customer and charging the customer, storing data in the database
Creating tables and models
For this project we will need two tables: users and purchases. To create these tables we first need to create migrations for them. For the users table we will use create_users_table migration with slight modifications. Because our project does not have authentication we will modify it to look like this:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->string('stripe_customer_id')->unique();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down()
{
Schema::drop('users');
}
}
Next we need a purchases table so we will create a migration called create_purchases_table. We can do this using the console command:php artisan make:migration create_purchases_table --create=”purchases”
This will create a migration called create_purchases_table with the table name “purchases” predefined. We will add some more fields to the table so it looks like on the picture below:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePurchasesTable extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::create('purchases', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->string('product');
$table->integer('amount');
$table->string('stripe_transaction_id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down()
{
Schema::drop('purchases');
}
}
As you can see we are referencing an id on the users table so
we can keep track of which customer bought the product. Also if we
delete the user we will delete all of his purchases. Besides this we are
keeping record of the product name, cost amount and Stripe transaction
id.Now lets create the tables using the console command
php artisan migrate
.The tables should now exist and we can now create a model for our purchases table. In the console type
php artisan make:model Purchase
. Also, we will make the fields fillable (for both users and purchases tables) so we can create table entries using User::create()
and Purchase::create()
methods.
<?php
namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['first_name', 'last_name', 'email', 'stripe_customer_id'];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [];
}
and
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Purchase extends Model
{
protected $fillable = ['user_id', 'product', 'amount', 'stripe_transaction_id'];
}
Now that we have our tables and models ready we can start defining the routes and building our form.
Defining routes and creating controllers
For our project we will have only 3 routes: the home (or "root") route which will redirect to our "order" page, the GET order route and the POST order route. The code below will make things more clear...
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the controller to call when that URI is requested.
|
*/
Route::get('/', function () {
return redirect()->route('order');
});
Route::get('order', ['as' => 'order', 'uses' => 'PagesController@getOrder']);
Route::post('order', ['as' => 'order-post', 'uses' => 'PagesController@postOrder']);
We named our routes so we don't have to think about their paths. This is
not necessary for such a small project, but its a good practice. Our
routes are managed by the PagesController so we have to create it now. We can do this with php artisan make:controller PagesController --plain
(--plain
because we want an empty PagesController
class). We will add two methods to the class, one for handling the
GET request and the other for handling the POST request. We will later
return to the POST method logic, for now lets just handle the GET
request so it shows the "order" view. Your PagesController should look
like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PagesController extends Controller
{
public function getOrder()
{
return view('pages.order');
}
public function postOrder(Request $request)
{
//
}
}
We did not create views yet so our application will not work correctly if we try to open it. We will do this in the next step...
Creating checkout form
Our checkout form will look like the one shown on the following picture:
<!DOCTYPE html>
<html>
<head>
<title>Stripe Tutorial</title>
<!-- Latest compiled and minified Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- Including the jQuery libraries -->
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<!-- Latest compiled and minified Bootstrap JavaScript library -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
@yield('content')
</div>
</body>
</html>
Next, in your resources/views folder create a new folder called pages.
In this folder we will keep all our pages (for this project we will
have only one). Lets create a new view for our purchasing form, we will
call the view order.blade.php and place it in our pages folder. The initial view should look like this and if we run our application now we should see "Hello!" printed in our browser.
@extends('app')
@section('content')
Hello!
@endsection
Because we will be using Laravel Collective HTML, before we start
creating our purchasing form we will have to install this package
and add it to our Service Providers and Facades. Instructions on how to
do this can be found here.
Now we can start building... Our order.blade.php view should look like this:
@extends('app')
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-primary" style="text-align: center;">Create order</h1>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
{!! Form::open(['url' => route('order-post')]) !!}
<div class="form-group">
{!! Form::label('firstName', 'First Name:') !!}
{!! Form::text('first_name', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('lastName', 'Last Name:') !!}
{!! Form::text('last_name', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('email', 'Email address:') !!}
{!! Form::email('email', null, ['class' => 'form-control', 'placeholder' => 'email@example.com']) !!}
</div>
<div class="form-group">
{!! Form::label('product', 'Select product:') !!}
{!! Form::select('product', ['book' => 'Book ($10)', 'game' => 'Game ($20)', 'movie' => 'Movie ($15)'], 'Book', ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label(null, 'Credit card number:') !!}
{!! Form::text(null, null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label(null, 'Card Validation Code (3 or 4 digit number):') !!}
{!! Form::text(null, null, ['class' => 'form-control']) !!}
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
{!! Form::label(null, 'Ex. Month') !!}
{!! Form::selectMonth(null, null, ['class' => 'form-control'], '%m') !!}
</div>
</div>
<div class="col-md-4">
<div class="form-group">
{!! Form::label(null, 'Ex. Year') !!}
{!! Form::selectYear(null, date('Y'), date('Y') + 10, null, ['class' => 'form-control']) !!}
</div>
</div>
</div>
<div class="form-group">
{!! Form::submit('Place order!', ['class' => 'btn btn-primary btn-order', 'id' => 'submitBtn', 'style' => 'margin-bottom: 10px;']) !!}
</div>
{!! Form::close() !!}
</div>
</div>
@endsection
You can check now how the purchasing form looks like. I added 3 products
to the select field, you can create some other ones if you like.
Front-end validation with Parsley.js
Next step is to add Parsley.js (front-end) validation and format the error messages. For more details you can check http://parsleyjs.org/doc/index.html#installation.We will add Parsley.js to the bottom of our app.blade.php file, just before the ending
</body>
tag:
<!-- PARSLEY -->
<script>
window.ParsleyConfig = {
errorsWrapper: '<div></div>',
errorTemplate: '<div class="alert alert-danger parsley" role="alert"></div>',
errorClass: 'has-error',
successClass: 'has-success'
};
</script>
<script src="http://parsleyjs.org/dist/parsley.js"></script>
</body>
</html>
First we added the Parsley configuration script so that error messages
are displayed in the template we specified and also we defined the
classes which are to be assigned to the input fields in case of error or
success. After that we included the Parsley.js library. Also, we will
add some styling to the error message template. Just add this in the app.blade.php header under the Bootstrap CSS:
<!-- PARSLEY CSS config -->
<style>
.alert.parsley {
margin-top: 5px;
margin-bottom: 0px;
padding: 10px 15px 10px 15px;
}
.check .alert {
margin-top: 20px;
}
</style>
Next we will add Parsley validators to our HTML Form. Our order.blade.php should now look like this:
@extends('app')
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-primary" style="text-align: center;">Create order</h1>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
{!! Form::open(['url' => route('order-post'), 'data-parsley-validate']) !!}
<div class="form-group" id="first-name-group">
{!! Form::label('firstName', 'First Name:') !!}
{!! Form::text('first_name', null, [
'class' => 'form-control',
'required' => 'required',
'data-parsley-required-message' => 'First name is required',
'data-parsley-trigger' => 'change focusout',
'data-parsley-pattern' => '/^[a-zA-Z]*$/',
'data-parsley-minlength' => '2',
'data-parsley-maxlength' => '32',
'data-parsley-class-handler' => '#first-name-group'
]) !!}
</div>
<div class="form-group" id="last-name-group">
{!! Form::label('lastName', 'Last Name:') !!}
{!! Form::text('last_name', null, [
'class' => 'form-control',
'required' => 'required',
'data-parsley-required-message' => 'Last name is required',
'data-parsley-trigger' => 'change focusout',
'data-parsley-pattern' => '/^[a-zA-Z]*$/',
'data-parsley-minlength' => '2',
'data-parsley-maxlength' => '32',
'data-parsley-class-handler' => '#last-name-group'
]) !!}
</div>
<div class="form-group" id="email-group">
{!! Form::label('email', 'Email address:') !!}
{!! Form::email('email', null, [
'class' => 'form-control',
'placeholder' => 'email@example.com',
'required' => 'required',
'data-parsley-required-message' => 'Email name is required',
'data-parsley-trigger' => 'change focusout',
'data-parsley-class-handler' => '#email-group'
]) !!}
</div>
<div class="form-group" id="product-group">
{!! Form::label('product', 'Select product:') !!}
{!! Form::select('product', ['book' => 'Book ($10)', 'game' => 'Game ($20)', 'movie' => 'Movie ($15)'], 'Book', [
'class' => 'form-control',
'required' => 'required',
'data-parsley-class-handler' => '#product-group'
]) !!}
</div>
<div class="form-group" id="cc-group">
{!! Form::label(null, 'Credit card number:') !!}
{!! Form::text(null, null, [
'class' => 'form-control',
'required' => 'required',
'data-parsley-type' => 'number',
'maxlength' => '16',
'data-parsley-trigger' => 'change focusout',
'data-parsley-class-handler' => '#cc-group'
]) !!}
</div>
<div class="form-group" id="ccv-group">
{!! Form::label(null, 'Card Validation Code (3 or 4 digit number):') !!}
{!! Form::text(null, null, [
'class' => 'form-control',
'required' => 'required',
'data-parsley-type' => 'number',
'data-parsley-trigger' => 'change focusout',
'maxlength' => '4',
'data-parsley-class-handler' => '#ccv-group'
]) !!}
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group" id="exp-m-group">
{!! Form::label(null, 'Ex. Month') !!}
{!! Form::selectMonth(null, null, [
'class' => 'form-control',
'required' => 'required'
], '%m') !!}
</div>
</div>
<div class="col-md-4">
<div class="form-group" id="exp-y-group">
{!! Form::label(null, 'Ex. Year') !!}
{!! Form::selectYear(null, date('Y'), date('Y') + 10, null, [
'class' => 'form-control',
'required' => 'required'
]) !!}
</div>
</div>
</div>
<div class="form-group">
{!! Form::submit('Place order!', ['class' => 'btn btn-primary btn-order', 'id' => 'submitBtn', 'style' => 'margin-bottom: 10px;']) !!}
</div>
{!! Form::close() !!}
</div>
</div>
@endsection
We can now test our ordering form for front-end validation errors, it should all work correctly.
Stripe configuration
Finally we arrived to the step which is about Stripe, that is what this tutorial is about :)Stripe is developer friendly and their documentation is very clean and understandable, so checkout their site if you need more details. There is also an embedded form which can be added to your website, it makes using Stripe much easier. But that is not our goal in this tutorial, we are making a custom purchasing form.
You will have to register a Stripe account in order to get your API keys. There are 2 keys, one which is publishable and which you include in your client-side application (this is used for data checking and generating a Stripe token) and the other one which is a secret key (used for server to server communication). You can find these keys in Account Settings -> API keys. We will explain this after we configure and include the Stripe scripts.
So, first we have to include and configure Stripe. Lets add Stripe library and scripts to our app.blade.php file (we will do this right under our Parsley.js scripts):
<!DOCTYPE html>
<html>
<head>
<title>Stripe Tutorial</title>
<!-- Latest compiled and minified Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<!-- STRIPE CSS config -->
<style>
.alert.parsley {
margin-top: 5px;
margin-bottom: 0px;
padding: 10px 15px 10px 15px;
}
.check .alert {
margin-top: 20px;
}
</style>
<!-- Including the jQuery libraries -->
<script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
<!-- Latest compiled and minified Bootstrap JavaScript library -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
@yield('content')
</div>
<!-- PARSLEY -->
<script>
window.ParsleyConfig = {
errorsWrapper: '<div></div>',
errorTemplate: '<div class="alert alert-danger parsley" role="alert"></div>',
errorClass: 'has-error',
successClass: 'has-success'
};
</script>
<script src="http://parsleyjs.org/dist/parsley.js"></script>
<!-- Inlude Stripe.js -->
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script>
// This identifies your website in the createToken call below
Stripe.setPublishableKey('{!! env('STRIPE_PK') !!}');
jQuery(function($) {
$('#payment-form').submit(function(event) {
var $form = $(this);
// Before passing data to Stripe, trigger Parsley Client side validation
$form.parsley().subscribe('parsley:form:validate', function(formInstance) {
formInstance.submitEvent.preventDefault();
return false;
});
// Disable the submit button to prevent repeated clicks
$form.find('#submitBtn').prop('disabled', true);
Stripe.card.createToken($form, stripeResponseHandler);
// Prevent the form from submitting with the default action
return false;
});
});
function stripeResponseHandler(status, response) {
var $form = $('#payment-form');
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('.payment-errors').addClass('alert alert-danger');
$form.find('#submitBtn').prop('disabled', false);
$('#submitBtn').button('reset');
} else {
// response contains id and card, which contains additional card details
var token = response.id;
// Insert the token into the form so it gets submitted to the server
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// and submit
$form.get(0).submit();
}
};
</script>
</body>
</html>
Notice: Stripe keys are configured in .env file as STRIPE_PK and STRIPE_SK.
Now we have to make some changes to our order.blade.php file and add fields which the Stripe scripts will check for. Also we will add a Stripe response error message to appear at the bottom of our page. After this I will provide explanation of what exactly is happening and what we did so far. This is how our order.blade.php should look like:
@extends('app')
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1 class="text-primary" style="text-align: center;">Create order</h1>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
{!! Form::open(['url' => route('order-post'), 'data-parsley-validate', 'id' => 'payment-form']) !!}
<div class="form-group" id="first-name-group">
{!! Form::label('firstName', 'First Name:') !!}
{!! Form::text('first_name', null, [
'class' => 'form-control',
'required' => 'required',
'data-parsley-required-message' => 'First name is required',
'data-parsley-trigger' => 'change focusout',
'data-parsley-pattern' => '/^[a-zA-Z]*$/',
'data-parsley-minlength' => '2',
'data-parsley-maxlength' => '32',
'data-parsley-class-handler' => '#first-name-group'
]) !!}
</div>
<div class="form-group" id="last-name-group">
{!! Form::label('lastName', 'Last Name:') !!}
{!! Form::text('last_name', null, [
'class' => 'form-control',
'required' => 'required',
'data-parsley-required-message' => 'Last name is required',
'data-parsley-trigger' => 'change focusout',
'data-parsley-pattern' => '/^[a-zA-Z]*$/',
'data-parsley-minlength' => '2',
'data-parsley-maxlength' => '32',
'data-parsley-class-handler' => '#last-name-group'
]) !!}
</div>
<div class="form-group" id="email-group">
{!! Form::label('email', 'Email address:') !!}
{!! Form::email('email', null, [
'class' => 'form-control',
'placeholder' => 'email@example.com',
'required' => 'required',
'data-parsley-required-message' => 'Email name is required',
'data-parsley-trigger' => 'change focusout',
'data-parsley-class-handler' => '#email-group'
]) !!}
</div>
<div class="form-group" id="product-group">
{!! Form::label('product', 'Select product:') !!}
{!! Form::select('product', ['book' => 'Book ($10)', 'game' => 'Game ($20)', 'movie' => 'Movie ($15)'], 'Book', [
'class' => 'form-control',
'required' => 'required',
'data-parsley-class-handler' => '#product-group'
]) !!}
</div>
<div class="form-group" id="cc-group">
{!! Form::label(null, 'Credit card number:') !!}
{!! Form::text(null, null, [
'class' => 'form-control',
'required' => 'required',
'data-stripe' => 'number',
'data-parsley-type' => 'number',
'maxlength' => '16',
'data-parsley-trigger' => 'change focusout',
'data-parsley-class-handler' => '#cc-group'
]) !!}
</div>
<div class="form-group" id="ccv-group">
{!! Form::label(null, 'Card Validation Code (3 or 4 digit number):') !!}
{!! Form::text(null, null, [
'class' => 'form-control',
'required' => 'required',
'data-stripe' => 'cvc',
'data-parsley-type' => 'number',
'data-parsley-trigger' => 'change focusout',
'maxlength' => '4',
'data-parsley-class-handler' => '#ccv-group'
]) !!}
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group" id="exp-m-group">
{!! Form::label(null, 'Ex. Month') !!}
{!! Form::selectMonth(null, null, [
'class' => 'form-control',
'required' => 'required',
'data-stripe' => 'exp-month'
], '%m') !!}
</div>
</div>
<div class="col-md-4">
<div class="form-group" id="exp-y-group">
{!! Form::label(null, 'Ex. Year') !!}
{!! Form::selectYear(null, date('Y'), date('Y') + 10, null, [
'class' => 'form-control',
'required' => 'required',
'data-stripe' => 'exp-year'
]) !!}
</div>
</div>
</div>
<div class="form-group">
{!! Form::submit('Place order!', ['class' => 'btn btn-primary btn-order', 'id' => 'submitBtn', 'style' => 'margin-bottom: 10px;']) !!}
</div>
<div class="row">
<div class="col-md-12">
<span class="payment-errors" style="color: red;margin-top:10px;"></span>
</div>
</div>
{!! Form::close() !!}
</div>
</div>
@endsection
So, the submit button will trigger the Stripe script which will disable
the default action of the submit button and make the button
unclickable until a response from Stripe is received. The response is
handled by the function stripeResponseHandler()
and if verification is successful we will receive a stripeToken, which will be added to the form. If the verification failed we will receive an error response which will be printed to the user.
After the correct response has been received the POST request will be sent to our server. With this step, we have finished most of our front-end work. Now it is time to handle the back-end programming.
Back-end validation
Before we can create our Stripe customer and charge him with the selected amount we will quickly validate the request which we got. Lets check our PagesController@postOrder method:
public function postOrder(Request $request)
{
/*
* Validation of the $request
*/
$validator = \Validator::make(\Input::all(), [
'first_name' => 'required|string|min:2|max:32',
'last_name' => 'required|string|min:2|max:32',
'email' => 'required|email',
'product' => 'required|string',
]);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator);
}
}
If the request fails to validate it will return to our order page with
validation error messages. Lets show these messages right under our
form:
{!! Form::close() !!}
</div>
{{-- Show $request errors after back-end validation --}}
<div class="col-md-6 col-md-offset-3">
@if($errors->has())
<div class="alert alert-danger fade in">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<h4>The following errors occurred</h4>
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
</div>
</div>
@endsection
Creating Stripe customer and charging the client. Storing data in the database
To make our life easier we will use a Stripe library for PHP. Just add"stripe/stripe-php": "3.*"
to your composer.json file and type composer update
in the console. If you have trouble doing this check the Stripe API libraries page https://stripe.com/docs/libraries#php-library.
Now we have everything set up for the creation of Stripe Customer and charging the customer with the amount which corresponds to the selected product. We will add the following code to the PagesController@postOrder method:
public function postOrder(Request $request)
{
$validator = \Validator::make(\Input::all(), [
'first_name' => 'required|string|min:2|max:32',
'last_name' => 'required|string|min:2|max:32',
'email' => 'required|email',
'product' => 'required|string',
]);
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
->withInput();
}
// Checking is product valid
$product = $request->input('product');
switch ($product) {
case 'book':
$amount = 1000;
break;
case 'game':
$amount = 2000;
break;
case 'movie':
$amount = 1500;
break;
default:
return redirect()->route('order')
->withErrors('Product not valid!')
->withInput();
}
$token = $request->input('stripeToken');
$first_name = $request->input('first_name');
$last_name = $request->input('last_name');
$email = $request->input('email');
$emailCheck = User::where('email', $email)->value('email');
\Stripe\Stripe::setApiKey(env('STRIPE_SK'));
// If the email doesn't exist in the database create new customer and user record
if (!isset($emailCheck)) {
// Create a new Stripe customer
try {
$customer = \Stripe\Customer::create([
'source' => $token,
'email' => $email,
'metadata' => [
"First Name" => $first_name,
"Last Name" => $last_name
]
]);
} catch (\Stripe\Error\Card $e) {
return redirect()->route('order')
->withErrors($e->getMessage())
->withInput();
}
$customerID = $customer->id;
// Create a new user in the database with Stripe
$user = User::create([
'first_name' => $first_name,
'last_name' => $last_name,
'email' => $email,
'stripe_customer_id' => $customerID,
]);
} else {
$customerID = User::where('email', $email)->value('stripe_customer_id');
$user = User::where('email', $email)->first();
}
// Charging the Customer with the selected amount
try {
$charge = \Stripe\Charge::create([
'amount' => $amount,
'currency' => 'usd',
'customer' => $customerID,
'metadata' => [
'product_name' => $product
]
]);
} catch (\Stripe\Error\Card $e) {
return redirect()->route('order')
->withErrors($e->getMessage())
->withInput();
}
// Create purchase record in the database
Purchase::create([
'user_id' => $user->id,
'product' => $product,
'amount' => $amount,
'stripe_transaction_id' => $charge->id,
]);
return redirect()->route('order')
->with('successful', 'Your purchase was successful!');
}
Because this is a lot of code and we did add several things I will
explain it step by step. So after the back-end validation we are
handling the request inputs. First of all, we are checking the product
which was selected and add the correct amount to it (ex: 10$ = 1000 ,
because the amount we are passing to Stripe is in cents). After that we
are handling the other inputs and putting them into variables. Next is
the Stripe API key setting, here we provide the secret API key we got.
Next we are checking if the user with that email already exists in our database. If it is a new user we will create Stripe customer and at the same time create a new user in our database (with all the data stored, including the Stripe customer ID which we can then reuse without creating the customer again). If an error occurred during the customer creation process we will redirect the user back to the ordering page and display the error.
If the user exists in our database we will not create a new user nor Stripe customer. We will just pull the Stripe customer ID and user ID from our database, because we will need them in the next step.
Next we are charging the user with the cost amount of the product. If an error occurs during this process we are catching it and redirecting the user to the ordering page with a proper error message.
Finally, if everything goes well a purchase record is created in the database and we are redirected back to the ordering page with a "purchase successful" message.
How To Validate Password With Pattern Using Jquery In Laravel
ReplyDeleteUsing Jquery is another way to validate Password in Laravel. Here we make one function like CheckPassword which was check the password and match with Regular Expression(Pattern)..
For More Info:- How To Validate Password With Pattern Using Jquery In Laravel