Your post to /purchases doesn't seem to include the product in the request. Try adding this.product to the post after the stripe data.
stripeToken: token.id,
stripeEmail: token.email,
this.product
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
I am on lesson 4 of the Stripe tutorial (https://laracasts.com/series/how-to-accept-payments-with-stripe/episodes/4) and while almost everything has gone well I've run into a problem when trying to complete the charge. The issue appears to be this line:
$product = Product::findOrFail(request('product'));
As when I comment it out and hard code a price value in rather than try and pull it dynamically the operation completes as normal and I can see the charge in my Stripe account. Looking in the inspector in Google the error I am receiving is: No query results for model [App\Product]
I tried to print the request using the log but when I check it, it is empty as there is no value attached.
Here are the various pages:
bilable.blade.php (not an error, accidentally mispelled it)
@extends('layouts.app')
@section('content')
<h1>Buy My Book for $25.00</h1>
<checkout-form :products="{{ $products }}"></checkout-form>
@endsection
CheckForm.vue
<template>
<form action="/purchases" method="POST">
<input type="hidden" name="stripeToken" v-model="stripeToken">
<input type="hidden" name="stripeEmail" v-model="stripeEmail">
<select name="product" v-model="product">
<option v-for="product in products" :value="product.id">
{{ product.name }} — ${{ product.price /100 }}
</option>
</select>
<button type="submit" @click.prevent="buy">Buy Book</button>
</form>
</template>
<script>
export default {
props: ['products'],
data() {
return {
stripeEmail: '',
stripeToken: '',
product: 1
};
},
created(){
this.stripe = StripeCheckout.configure({
key: Laravel.stripeKey,
image: "https://stripe.com/img/documentation/checkout/marketplace.png",
locale: "auto",
token: function(token){
axios.post('/purchases', {
stripeToken: token.id,
stripeEmail: token.email
})
.then(function (response) {
alert('Complete! Thanks for your payment!');
})
.catch(function (error) {
console.log(error);
});
}
});
},
methods: {
buy(){
let product = this.findProductById(this.product);
this.stripe.open({
name: product.name,
description: product.description,
zipCode: true,
amount: product.price
});
},
findProductById(id){
return this.products.find(product => product.id == id);
}
}
}
</script>
Purchases Controller:
<?php
namespace App\Http\Controllers;
use Log;
use App\Product;
use Illuminate\Http\Request;
use Stripe\{Charge, Customer};
class PurchasesController extends Controller
{
public function store()
{
Log::info("Product Info: " . request('product'));
$product = Product::findOrFail(request('product'));
$customer = Customer::create([
'email' => request('stripeEmail'),
'source' => request('stripeToken')
]);
Charge::create([
'customer' => $customer->id,
'amount' => 8000,
'currency' => 'aud'
]);
return 'All done';
}
}
Web Routes:
Route::get('/billing', function () {
$products = App\Product::all();
return view('organisation.bilable', compact('products')); // no error here, I accidentally misspelled "billable" but couldn't be bothered to fix it for what I am doing.
});
Route::post('/purchases', 'PurchasesController@store');
Thank you in advance.
Edit: The solution was to recast this in the FormCheckout.vue file to be a separate variable as seen in the answer below.
created(){
let module = this; // cast to separate variable
this.stripe = StripeCheckout.configure({
key: Laravel.stripeKey,
image: "https://stripe.com/img/documentation/checkout/marketplace.png",
locale: "auto",
token: function(token){
axios.post('/purchases', {
stripeToken: token.id,
stripeEmail: token.email,
product: module.product
})
.then(function (response) {
alert('Complete! Thanks for your payment!');
})
.catch(function (error) {
console.log(error);
});
}
});
},
Please or to participate in this conversation.