Saturday, April 1, 2017

Account balance system with Stripe

For the past two days I've been trying to understand how Stripe works.. What I'm trying to build is a simple system that lets the user to add funds to his account on the site. I followed a tutorial I found on the internet that uses Laravel Cashier but as I've read on the laravel documentation if I need to perform single charges I should use directly Stripe. The thing is, there are not many tutorials on how this should be done with laravel..

Here's what I have so far:

VIEW:

    <form class="app-form" style="margin-bottom: 0px;" action="/add-funds" method="POST">
      

      <select id="funds-options" style="width: 20%; margin-bottom: 20px;" name="add-funds-select">
        <option value="30">$30</option>
        <option value="50">$50</option>
        <option value="100">$100</option>
        <option value="200">$200</option>
        <option value="300">$300</option>
        <option value="500">$500</option>
      </select>

      <p style="margin-bottom: 0px;">
        <script src="https://checkout.stripe.com/checkout.js"></script>

        <button id="customButton">Purchase</button>

        <script>
        var handler = StripeCheckout.configure({
          key: '',
          image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
          locale: 'auto',
          token: function(token) {
            // You can access the token ID with `token.id`.
            // Get the token ID to your server-side code for use.
          }
        });

        document.getElementById('customButton').addEventListener('click', function(e) {
          // Open Checkout with further options:
          var userAmount = $("#funds-options").val();

          handler.open({
            name: 'Demo Site',
            description: '2 widgets',
            amount: userAmount*100
          });
          e.preventDefault();
        });

        // Close Checkout on page navigation:
        window.addEventListener('popstate', function() {
          handler.close();
        });
        </script>
      </p>
    </form>

I have this select tag where the user can select the amount he wants to add to his account. Now, this opens the widget from Stripe but as soon as I hit pay, I'm getting that info: "You did not set a valid publishable key". I tried this using the publishable key directly and I'm able to pass this but as soon as it gets into the controller it throws pretty much the same error, something like API key was not set.

I set the keys in the env file and I also reference them in the services.php..

ENV:

STRIPE_KEY=pk_test_....
STRIPE_SECRET=sk_test_...

SERVICES:

'stripe' => [
    'model' => App\User::class,
    'key' => env('STRIPE_KEY'),
    'secret' => env('STRIPE_SECRET'),
],

Anyway, even if I pass this "error" I'm still not sure if I'm doing this right.

Controller:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Auth;

class WalletController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */

    public function index()
    {
        return view('user.wallet.index');
    }

     public function postPayWithStripe(Request $request)
     {
         return $this->chargeCustomer($request->input('add-funds-select'), $request->input('stripeToken'));
     }

     public function chargeCustomer($amount, $token)
     {
        \Stripe\Stripe::setApiKey(getenv('STRIPE_SECRET'));

         if (!$this->isStripeCustomer())
         {
             $customer = $this->createStripeCustomer($token);
         }
         else
         {
             $customer = \Stripe\Customer::retrieve(Auth::user()->stripe_id);
         }

         return $this->createStripeCharge($amount, $customer);
     }
     public function createStripeCharge($amount, $customer)
     {
         try {
             $charge = \Stripe\Charge::create(array(
                 "amount" => $amount,
                 "currency" => "brl",
                 "customer" => $customer->id,
                 "description" => "Add funds to your account"
             ));
         } catch(\Stripe\Error\Card $e) {
             return redirect()
                 ->route('index')
                 ->with('error', 'Your credit card was been declined. Please try again or contact us.');
     }

         return $this->postStoreAmount($amount);
     }

     public function createStripeCustomer($token)
     {
         \Stripe\Stripe::setApiKey(getenv('STRIPE_SECRET'));

         $customer = \Stripe\Customer::create(array(
             "description" => Auth::user()->email,
             "source" => $token
         ));

         Auth::user()->stripe_id = $customer->id;
         Auth::user()->save();

         return $customer;
     }

    /**
     * Check if the Stripe customer exists.
     *
     * @return boolean
     */
     public function isStripeCustomer()
     {
         return Auth::user() && \App\User::where('id', Auth::user()->id)->whereNotNull('stripe_id')->first();
     }

     public function postStoreAmount($amount)
     {
        $userBalance = Auth::user()->balance;
        $userBalance = $userBalance + $amount;

        Auth::user()->save();

        session()->flash('message', 'You just added funds to your account.');
        return redirect()->route('index');
     }
}

I have a field in the users table that holds the user balance.

As I mentioned, I followed a tutorial I found on the internet.. I'm not sure how this should work. Any suggestions?



via Ovidiu G

Advertisement