I get the above error when trying to checkout. In my services.php,I have my keys and values:
'stripe' => [
'model' => App\Product::class,
'public_key' => env('STRIPE_KEY'),
'secret_key' => env('STRIPE_SECRET'),
]
The values are given in the .env:
STRIPE_KEY=blabla
STRIPE_SECRET=blabla
Here's my code when I checkout:
class CheckoutController extends Controller
{
public function store(Request $request)
{
request()->validate([
'name' => 'required|min:5',
'email' => 'required|min:10',
'address' => 'required|min:10',
'address2',
'country' => 'required',
'postcode' => 'required',
'card-name' => 'required'
]);
// storing Stripe data
$stripe = new Stripe();
$stripe = Stripe::make('blabla');
try {
$charge = Stripe::charges()->create([
'amount' => Cart::total(),
'currency' => 'GBP',
'source' => $request->stripeToken,
'description' => 'Thank you for your purchase.',
'receipt_email' => $request->email,
'metadata' => [
'quantity' => 1,
],
]);
$customer = $stripe->customers()->create(['email' => $request->email]);
Cart::destroy();
Mail::send(new OrderConfirmed);
return redirect()->route('confirmation')
->with('paymentSuccessMessage', 'Thank you! Your payment has been accepted.
Please check your inbox for a confirmation email.');
}
catch (CardErrorException $e) {
return back()->withErrors('Error! ' . $e->getMessage());
}
}
}
What am I missing here? I believe I have everything defined where it should be.
EDIT: Here's my checkout.blade.php:
<link rel="stylesheet" type="text/css" href="/css/app.css">
<!-- Stripe integration -->
<script src="https://js.stripe.com/v3/"></script>
<title>Checkout</title>
<body class="bg-light">
<hr style="width: 90%;" class="mt-4 mb-5">
<div class="container">
{{-- BILLING INFO --}}
<div class="col-md-8 order-md-1">
<h4 class="mb-3">Billing Information</h4>
<form action="{{ route('checkout.store') }}" method="POST" class="needs-validation" id="payment-form" novalidate>
@csrf
<div class="row">
<div class="col-md-6 mb-3">
<label for="name">Name</label>
<input name="name" type="text" class="form-control" id="name" placeholder="John Appleseed" value="{{ old('name') }}" required>
<div class="invalid-feedback">Valid name is required.</div>
</div>
<div class="col-md-6 mb-3">
<label for="email">Email</label>
<input name="email" type="text" class="form-control" id="email" placeholder="[email protected]" value="{{ old('email') }}" required>
<div class="invalid-feedback">Valid email is required.</div>
</div>
</div>
<div class="mb-3">
<label for="address">Address</label>
<input name="address" type="text" class="form-control" id="address" placeholder="1234 Main St" value="{{ old('address') }}" required>
<div class="invalid-feedback">Please enter your shipping address.</div>
</div>
<div class="mb-3">
<label for="address2">Address 2 <span class="text-muted">(Optional)</span></label>
<input name="address2" type="text" class="form-control" id="address2" placeholder="Apartment or suite" value="{{ old('address2') }}">
</div>
<div class="row">
<div class="col-md-5 mb-3">
<div class="invalid-feedback">
Please select a valid country.
</div>
</div>
<div class="col-md-3 mb-3">
<label for="postcode">Postcode</label>
<input name="postcode" type="text" class="form-control" id="postcode" value="{{ old('postcode') }}" required>
<div class="invalid-feedback">
Postcode required.
</div>
</div>
</div>
<hr class="mb-4">
<h4 class="mb-3">Payment</h4>
<div class="row">
<div class="col-md-6 mb-3">
<label for="cc-name">Name on card</label>
<input name="card-name" type="text" class="form-control" id="cc-name" placeholder="John F Appleseed" value="{{ old('card-name') }}" required>
<small class="text-muted">Full name as displayed on card</small>
<div class="invalid-feedback">Name on card is required</div>
</div>
</div>
<!-- STRIPE ELEMENTS -->
<form action="/charge" method="post" id="payment-form">
<div class="form-row">
<label class="ml-1" for="card-element">
Credit or debit card
</label>
<div id="card-element">
<!-- a Stripe Element will be inserted here. -->
</div>
<!-- Used to display form errors. -->
<div id="card-errors" role="alert"></div>
</div>
<br>
<hr class="mb-4">
<p id="no-products"></p>
<button id="submit-payment" class="btn btn-lg btn-block" type="submit"><b>Submit Payment</b></button>
</form>
<!-- END STRIPE ELEMENTS -->
{{-- END BILLING INFO --}}
</form>
</div>
</div>
</div>
{{-- ALERT: CART IS EMPTY --}}
@if(Cart::count() == 0)
<script>
document.getElementById('submit-payment').disabled = true;
document.getElementById('no-products').textContent = 'Your cart is empty!';
document.getElementById('no-products').className = 'w-25 alert alert-danger';
</script>
@endif
{{-- END ALERT: CART IS EMPTY --}}
<script>
(function() {
// creates a Stripe client
var stripe = Stripe('pk_test_9dn1vt3i0j0Q5GZdwAXn9iUs00iMziQDyD');
// creates an instance of Elements
var elements = stripe.elements();
var style = {
base: {
color: '#32325d',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: 'red',
iconColor: 'red'
}
};
// creates an instance of the card Element
var card = elements.create('card', { style: style, hidePostalCode: true });
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
// handles real-time validation errors from the card Element
card.addEventListener('change', function(event) {
var displayError = document.getElementById('card-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
});
// handles form submission.
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
// disables the submit button to prevent repeated clicks
document.getElementById('submit-payment').disabled = true;
stripe.createToken(card).then(function(result) {
if (result.error) {
// informs the user if there was an error
// enables the submit button if validation fails
document.getElementById('submit-payment').disabled = false;
var errorElement = document.getElementById('card-errors');
errorElement.textContent = result.error.message;
} else {
// sends the token to the server
stripeTokenHandler(result.token);
}
});
});
// submits the form with the token ID
function stripeTokenHandler(token) {
// inserts the token ID into the form so it gets submitted to the server
var form = document.getElementById('payment-form');
var hiddenInput = document.createElement('input');
hiddenInput.setAttribute('type', 'hidden');
hiddenInput.setAttribute('name', 'stripeToken');
hiddenInput.setAttribute('value', token.id);
form.appendChild(hiddenInput);
// submits the form
form.submit();
}
})();
</script>
</body>
</html>
I can see the Stripe token being added in dev tools so it's there.
You will to submit the form with the token ID. First you have to create the token handler function
Submit the form
Then in Your controller you will access the token this way
Please let know it that helps.