Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

monove's avatar

Laravel Cashier creating customer without subscription

Our app initially stores the user's credit card with Stripe, and only bills them when they purchase a given product at a later date.

We're considering switching to Laravel 5 but I can't seem to find anywhere in Laravel Cashier instructions on simply storing a token of a card (really a token obtained by Stripe.js) for future billing.

I've installed LC locally and see a stripe_id field in the users table. Is it just a matter of assigning it $user->stripe_id = \Request::input('stripe_customer_token')?

0 likes
10 replies
Kryptonit3's avatar

Have you tried not passing anything to subscription() it allows for null.

$user->subscription()->create($request->input('stripeToken'));

not tested. test in dev environment first.

but yeah, you could just set the id.

$user->setStripeId($request->input('stripeToken'));
jekinney's avatar

As it utilizes subscriptions to charge at intervals. Changing the logic to your business logic should be do able. Set the token when a user adds a card, how ever is done in your app. I probably would set a boolean value that a user has a card available. Then when needed charge the user.

Most of it would be how you have stripe set up on that end.

Kryptonit3's avatar

refer to

\vendor\laravel\cashier\src\Laravel\Cashier\Billable.php

and

\vendor\laravel\cashier\src\Laravel\Cashier\StripeGateway.php

for available methods.

monove's avatar

In the end, I created a plan in stripe with a value of $0.00 and called it 'customer'.

I then did

$user->subscription('customer')->create(\Request::input('response_id_from_strips_js'));
Kryptonit3's avatar

But won't that generate an invoice and when you show invoices they will wonder what it is? I suppose you could write logic to hide it.

info@joelvardy.com's avatar

My solution to this was to add a method to my Billable class (aka: App\User)

public function setBillingCard($stripeToken) {

    if ($this->stripeIsActive()) {
        return $this->updateCard($stripeToken);
    }

    $stripeGateway = $this->subscription();

    $customer = $stripeGateway->createStripeCustomer($stripeToken, [
        'email' => $this->email
    ]);
    return $stripeGateway->updateLocalStripeData($customer);

}

One thing to note, because the database field stripe_active will be set to true, the $user->subscribed() method will always return true. I decided to write another method to check against the $user->stripe_subscription along with $user->onGracePeriod().

2 likes
derrekbertrand's avatar

I had some success adding a card without a subscription by running this on Laravel 5:

//pass the user object to the gateway; it must implement BillableContract
$gateway = new \Laravel\Cashier\StripeGateway($user);
//manually create a new Customer instance with Stripe
$customer = $gateway->createStripeCustomer($request->get('stripe_token'));
//update the model's info
$gateway->updateLocalStripeData($customer);
2 likes
jeffzeller's avatar

I had to manually add the card if there was no stripe ID found in the database.

Here is the stripe form with no payment charged.

<script
    src="https://checkout.stripe.com/checkout.js" class="stripe-button"
    data-key="{{ env('STRIPE_KEY')}}"
    data-bitcoin="true"
    data-name="Company Name."
    data-description="Service Name"
    data-image="{{ asset('images/brand/logo.svg')}}"
    data-locale="auto"
    data-currency="cad">
</script>

If the user has a paid subscription the stripe ID should already be there.

Else the stripe ID is added to the user database with the last 4 digits and the card brand.

public function payment_complete(Request $request) {
    $this->validate( $request, [ 'stripeToken' => 'required'] );

    $user = Auth::user();
    $payment_ammount = '1000';

    if ($user->hasStripeId()) {
         $user->charge($payment_ammount);
    } else {

         $user->createAsStripeCustomer($request->stripeToken);
         $user->charge($payment_ammount);
   }
}

Please or to participate in this conversation.