Via Composer
$ composer require shekel/shekel
If you don't use auto-discovery, add the ServiceProvider to the providers array in config/app.php
Shekel\ShekelServiceProvider::class,
In order to use shekel you need to run migrations. It will add a meta field to your users table. Additionally subscriptions and plans tables will be created.
If you want to disable migrations just add Shekel::$disableMigrations = true;
to your AppServiceProvider boot method.
To use shekel just add Billable trait to your model that you will be billing.
use Shekel\Traits\Billable;
class User extends Authenticatable
{
use Billable;
}
If you are using a different model just define it in your .env file
BILLABLE_MODEL=\App\MyModel
In order to use stripe you need to add your stripe public and secret keys to the .env file. You can find your api keys in your stripe dashboard > Developers > API keys
STRIPE_PUBLIC=pk_test_xxxxxx
STRIPE_SECRET=sk_test_xxxxxx
Default currency is set to USD, but you can change that in your .env file
BILLABLE_CURRENCY=eur
List of supported currencies (by stripe for now):
USD, AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD, BDT, BGN, BIF, BMD, BND, BOB, BRL, BSD, BWP, BZD, CAD, CDF, CHF, CLP, CNY, COP, CRC, CVE, CZK, DJF, DKK, DOP, DZD, EGP, ETB, EUR, FJD, FKP, GBP, GEL, GIP, GMD, GNF, GTQ, GYD, HKD, HNL, HRK, HTG, HUF, IDR, ILS, INR, ISK, JMD, JPY, KES, KGS, KHR, KMF, KRW, KYD, KZT, LAK, LBP, LKR, LRD, LSL, MAD, MDL, MGA, MKD, MMK, MNT, MOP, MRO, MUR, MVR, MWK, MXN, MYR, MZN, NAD, NGN, NIO, NOK, NPR, NZD, PAB, PEN, PGK, PHP, PKR, PLN, PYG, QAR, RON, RSD, RUB, RWF, SAR, SBD, SCR, SEK, SGD, SHP, SLL, SOS, SRD, STD, SZL, THB, TJS, TOP, TRY, TTD, TWD, TZS, UAH, UGX, UYU, UZS, VND, VUV, WST, XAF, XCD, XOF, XPF, YER, ZAR, ZMW
In order to make subscriptions first you need to create a new plan.
use Shekel\Models\Plan;
$plan = Plan::create([
'title' => 'Basic monthly', //Your plan name
'price' => 999, //Plan price in cents
'billing_period' => 'monthly', //Supported periods - daily, weekly, monthly, yearly
'trial_period_days' => 30, //trial days (max 730)
]);
All data is validated under the hood, and a plan in stripe database is created assuming stripe is enabled.
To update a plan you can use laravels default update method and the plan will update in stripe also. NOTICE: stripe does not allow updating any fields except trial_period_days so all updates are validated and will throw ValidationException if you try to update any restricted fields.
//WILL THROW AN EXCEPTION
$plan->update(['title' => 'my-title']);
//WILL UPDATE NORMALY
$plan->update(['trial_period_days' => 10]);
To delete a plan just call the delete method. Stripe plan will also be deleted (but the product that the plan is attached to will remain intact).
$plan->delete();
If all is successful you should go to your stripe dashboard > Billing > Products and see a new product created.
After creating a plan you need to setup a payment form.
First you will need to list your plans so use can pick whitch plan he is subscribing to.
//TODO create a @include('Shekel::plans') view helper.
<div class="mb-3 mt-3">
<label>Plan</label>
<select name="billing_plan_id" class="form-control">
@foreach($plans as $plan)
<option value="{{ $plan->id }}">{{ $plan->title }} - {{ number_format($plan->price / 100, 2) }}</option>
@endforeach
</select>
</div>
After that you need to add a credit card field in your form. Package provides a helper so you don't need to deal with stripes html/css/js.
@include('Shekel::stripe.payment_form')
Last thing to do is adding shekel-form
class to your html form.
<form method="POST" action="{{ route('register') }}" class="shekel-form">
//TODO Think through use case scenarios and make more convenient helpers. Adding a class to a form is not practical and register form is not the only use case.
After submitting a form to your controller you need to subscribe the user to a plan. To do that all you need to do is call stripeSubscription method on the user model. First argument is plan id that you are subscribing to and the second parameter is a payment method string privided by stripe from the credit card form.
class RegisterController extends Controller {
public function create(Request $request) {
$user = User::create($request->all());
$plan = $request->input('billing_plan_id');
$paymentMethod = $request->input('payment_method');
$user->newSubscription('stripe', $plan, $paymentMethod)->create();
}
}
And thats it. Your user is now subscribed to your defined plan.
To cancel a subscription just run:
$user->subscription()->cancel();
To cancel multiple subscriptions use the provided subscritions relationship:
use Shekel\Models\Subscription;
$user->subscriptions()->each(fn(Subscription $subscription) => $subscription->cancel());
By default canceling a subscription will hold it's grace period until the subscription expires. If you want to cancel the subscription now use cancelNow method.
$user->subscription()->cancelNow();
If you want to change users subscription plan just call changePlan method on any subscription. Single argument needed is the plan id that you want to swap to.
$user->subscription()->changePlan(2);
If you have a quantity based subscription (eg. subscription price is based on how many users a team has) then you can use changeQuantity method to increase or decrease it. Single argument required is the quantity amount number.
$user->subscription()->changeQuantity(2);
By default quantity is always set to 1 so if you want to adjust the quantity while creating the subscription use quantity method.
$user->newSubscription('stripe', $plan_id, $paymentMethod)->quantity(2)->create();