Posted on 3 Comments

Create A Point Of Sales System With Vue/Laravel + Stripe

Point Of Sales In The Palm Of Your Hand

In today’s tutorial I will be creating a point of sales system utilizing Vue and Laravel with Stripe being our payment processor. The program will allow a stripe account holder to take payments and if on mobile will allow them to scan the card via the device’s camera. It will utilize Laravel Passport for secure API calls and Stripe to handle the payments.

Installing The Dependencies

The app uses two dependencies as of now and those are Stipe and Laravel Passport install them using composer
 

composer require laravel/passportstripe/stripe-php

Now run the migrations (I’m using Laravel 5.5 so the packages are auto-discovered)

php artisan migrate

Now open your app/User.php model and edit the following

<?php
namespace App;
use Laravel\Passport\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
    use HasApiTokens, Notifiable;
}

Next register the Passport routes in your AuthServiceProvider

<?php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
    ];
    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        Passport::routes();
    }
}

Register the api driver in config/auth.php

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

Lastly set the web middleware group

'web' => [
    // Other middleware...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],

Controller

This application only needs one external controller

php artisan make:controller StripeController

This controller will only contain 2 methods __construct() and charge(). The __construct method will set the StripeApiKey and the charge method actually makes the charge

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class StripeController extends Controller
{
 //
 public function __construct(){
 \Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
 }
public function charge(Request $request){
 try {
 // Use Stripe's library to make requests...
 $token = \Stripe\Token::create(array(
 "card" => array(
 "number" => $request->card['card_number'],
 "exp_month" => $request->card['expiry_month'],
 "exp_year" => $request->card['expiry_year'],
 "cvc" => $request->card['cvv']
 )
 ));
 \Stripe\Charge::create(array(
 "amount" => $request->amount * 100,
 "currency" => "usd",
 "source" => $token, // obtained with Stripe.js
 "description" => $request->description,
 "receipt_email" => $request->email
 ));
 return response()->json([
 'success' => true
 ]);
 } catch(\Stripe\Error\Card $e) {
 // Since it's a decline, \Stripe\Error\Card will be caught
 return response()->json($e->getJsonBody());
 } catch (\Stripe\Error\RateLimit $e) {
 // Too many requests made to the API too quickly
 return response()->json($e->getJsonBody());
 } catch (\Stripe\Error\InvalidRequest $e) {
 // Invalid parameters were supplied to Stripe's API
 return response()->json($e->getJsonBody());
 } catch (\Stripe\Error\Authentication $e) {
 // Authentication with Stripe's API failed
 // (maybe you changed API keys recently)
 return response()->json($e->getJsonBody());
 } catch (\Stripe\Error\ApiConnection $e) {
 // Network communication with Stripe failed
 return response()->json($e->getJsonBody());
 } catch (\Stripe\Error\Base $e) {
 // Display a very generic error to the user, and maybe send
 // yourself an email
 return response()->json($e->getJsonBody());
 } catch (Exception $e) {
 // Something else happened, completely unrelated to Stripe
 return response()->json($e->getJsonBody());
 }
 }
}

The controller is now finished let’s create the API routes

API Routes

Open the routes/api.php file and add the following routes

<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
 return $request->user();
});
Route::middleware('auth:api')->post('/charge','StripeController@charge');

The backend is now complete now for the front end.

Vue Component

Get rid of the example component and create a new one called ChargeComponent and add the following content

<template>
 <div class="container">
 <div class="row">
 <div class="col-md-8 col-md-offset-2">
 <div class="panel panel-default">
 <div class="panel-heading">Make A Charge</div>
<div class="panel-body">
 <fieldset>
 <div class="form-group">
 <label class="col-sm-3 control-label" for="amount">Amount</label>
 <div class="col-sm-9">
 <input type="number" class="form-control" id="amount" placeholder="Amount To Charge" v-model="amount">
 </div>
 </div>
 <div class="form-group">
 <label class="col-sm-3 control-label" for="email">Email</label>
 <div class="col-sm-9">
 <input type="email" class="form-control" id="email" placeholder="Email Receipt" v-model="email">
 </div>
 </div>
 <div class="form-group">
 <label class="col-sm-3 control-label" for="description">Description</label>
 <div class="col-sm-9">
 <input type="text" class="form-control" id="description" placeholder="Credit Card Description" v-model="description">
 </div>
 </div>
 <div class="form-group">
 <label class="col-sm-3 control-label" for="card-number">Card Number</label>
 <div class="col-sm-9">
 <input type="text" class="form-control" name="card-number" id="card-number" placeholder="Debit/Credit Card Number" autocomplete="cc-number" v-model="card.card_number">
 </div>
 </div>
 <div class="form-group">
 <label class="col-sm-3 control-label" for="expiry-month">Expiration Date</label>
 <div class="col-sm-9">
 <div class="row">
 <div class="col-xs-3">
 <select class="form-control col-sm-2" name="expiry-month" id="expiry-month" autocomplete="cc-exp-month" v-model="card.expiry_month">
 <option>Month</option>
 <option value="01">Jan (01)</option>
 <option value="02">Feb (02)</option>
 <option value="03">Mar (03)</option>
 <option value="04">Apr (04)</option>
 <option value="05">May (05)</option>
 <option value="06">June (06)</option>
 <option value="07">July (07)</option>
 <option value="08">Aug (08)</option>
 <option value="09">Sep (09)</option>
 <option value="10">Oct (10)</option>
 <option value="11">Nov (11)</option>
 <option value="12">Dec (12)</option>
 </select>
 </div>
 <div class="col-xs-3">
 <select class="form-control" name="expiry-year" autocomplete="cc-exp-year" v-model="card.expiry_year">
 <option value="17">2017</option>
 <option value="18">2018</option>
 <option value="19">2019</option>
 <option value="20">2020</option>
 <option value="21">2021</option>
 <option value="22">2022</option>
 <option value="23">2023</option>
 </select>
 </div>
 </div>
 </div>
 </div>
 <div class="form-group">
 <label class="col-sm-3 control-label" for="cvv">Card CVV</label>
 <div class="col-sm-3">
 <input type="text" class="form-control" name="cvv" id="cvv" placeholder="Security Code" autocomplete="cvc" v-model="card.cvv">
 </div>
 </div>
 <div class="form-group">
 <div class="col-sm-offset-3 col-sm-9">
 <button type="button" class="btn btn-success" v-on:click="createCharge">Pay Now</button>
 </div>
 </div>
 </fieldset>
 </div>
 </div>
 </div>
 </div>
 </div>
</template>
<script>
 export default {
 mounted() {
 console.log('Component mounted.')
 },
 data(){
 return{
 card: {
 card_number: null,
 expiry_year: null,
 expiry_month: null,
 cvv: null
 },
 amount: 0,
 email: null,
 description: null
 }
 },
 methods: {
 createCharge: function(){
 axios.post('/api/charge',{card: this.card, amount: this.amount, description: this.description})
 .then(function(data){
 alert('Success!')
 }).catch(function(error){
 alert(error.message);
 });
 }
 }
 }
</script>

Edit the app.js file to match the following

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */
require('./bootstrap');
window.Vue = require('vue');
/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */
Vue.component('charge-component', require('./components/ChargeComponent.vue'));
const app = new Vue({
 el: '#app'
 });

now install the npm dependencies and run mix

npm install && npm run dev

Enjoy your new app! You can fork the source code here! Be sure to like/subscribe/share and if you want to show your support please check out the shop!

Posted on Leave a comment

Get Your Daily Stripe Balance Using Laravel Task Scheduler

[callaction url=”https://www.youtube.com/user/JPlaya01″ background_color=”#333333″ text_color=”#ffffff” button_text=”Go Now” button_background_color=”#e64429″]Subscribe To My Youtube Page[/callaction]

Laravel Task Scheduler

I create many apps that use the Uber business model for paying out contractors using Stripe, and I make money by using application fees. I like to get my daily account available and pending balances from Stripe. Using Laravel’s built in task scheduler this is trivial. Laravel provides a way to define all of your application’s scheduled jobs within Laravel itself, so that you only have to manage one cron tab * * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1 it’s pretty awesome!

Install Dependencies

I will assume you have created a new Laravel install. I  need the Stripe PHP composer module for this to work. Go to the root of your application and type the following command composer require stripe/stripe-php now you have all the necessary components installed.

Define Schedule

All schedules are defined in schedule() method of the App\Console\Kernel located at app/console/kernel.php. I want to make a stripe call to retrieve my balance, both available and pending.

<?php
namespace App\Console;
use Mail;
use Carbon\Carbon;
use DB;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        \App\Console\Commands\Inspire::class,
    ];
    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {
        \Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
       $balance = \Stripe\Balance::retrieve();
       $emailText = "As of {Carbon::today()->toDayDateTimeString()}  your available balance is {$balance->available->amount} and your pending balance is {$balance->pending->amount}";
Mail::raw('Text to e-mail', function ($message) {
    //
    
 $message->from('financial@app.com', 'Your Application');
            $message->to(env('EMAIL_ADDRESS'),env('EMAIL_NAME'))->subject('Your Daily Stripe Balance!');
}); })->daily();  } }

With this piece of code I am now getting daily emails with the date, my available balance, and my pending balance. If you liked this please share and subscribe to my blog posts via email to the right!