I'm trying to accept payments with Stripe. I got the code from the Stripe documentation and added it to a view. When I click the button it doesn't show the form, but instead goes to the form action page (payments).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="9HgWQfTsUXQ0RmIPQPLbhNoujOobjHn5PL9en8jx">
<title>Staff</title>
<!-- Styles -->
<link href="https://localhost/staff/public/css/app.css" rel="stylesheet">
<link href="https://localhost/staff/public/css/style.css" rel="stylesheet">
</head>
<body>
<div id="app">
<form action="payments/" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="pk_test_xxx"
data-amount="999"
data-name="Demo Site"
data-description="Widget"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="auto">
</script>
</form>
</div>
<!-- Scripts -->
<script src="https://localhost/staff/public/js/app.js"></script>
</body>
</html>
I Stripped everything way down to eliminate everything a left only the button, still didn't work. One last thing to remove.....
<script src="https://localhost/staff/public/js/app.js"></script>
And that's what kept the form from showing....
So my question: Why would that be causing Stripe to not be able to show the form and what can I do to fix it? Did I just forget to set something up correctly? I'm new to Laravel, this is my first project with the framework, and my installation is pretty close to vanilla as I'm just getting started...
I ran composer require "laravel/cashier":"~7.0" and then added the service provider to config/app.php:
'providers' => [
...
Laravel\Cashier\CashierServiceProvider::class,
],
And then migrated the database.
Here are some of my files...
web.php:
...
Route::post('/payments', 'PaymentsController@subscribe')->name('payments');
Route::get('/payments', 'PaymentsController@index')->name('payments');
PaymentsController.php:
<?php
namespace Staff\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class PaymentsController extends Controller
{
//private $states;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
public function index() {
return view('payments/payment');
}
public function subscribe() {
echo "huhh";
}
}
payment.blade.php:
@extends('layouts.app')
@section('content')
<form action="" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="pk_test_fCM9Fr1e33JYW6t17ZoSyXRf"
data-amount="999"
data-name="Demo Site"
data-description="Widget"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="auto">
</script>
</form>
@endsection
services.php:
<?php
return [
...
'stripe' => [
'model' => Staff\User::class,
'key' => env('pk_test_xxx'),
'secret' => env('sk_test_zzz'),
],
];
Edit
Even if I try to create a custom form it doesn't work. However, if I create a html file outside of Laravel, it works...
<html>
<head>
<style>
form {
width: 480px;
margin: 20px auto;
}
.group {
background: white;
box-shadow: 0 7px 14px 0 rgba(49,49,93,0.10),
0 3px 6px 0 rgba(0,0,0,0.08);
border-radius: 4px;
margin-bottom: 20px;
}
label {
position: relative;
color: #8898AA;
font-weight: 300;
height: 40px;
line-height: 40px;
margin-left: 20px;
display: block;
}
.group label:not(:last-child) {
border-bottom: 1px solid #F0F5FA;
}
label > span {
width: 20%;
text-align: right;
float: left;
}
.field {
background: transparent;
font-weight: 300;
border: 0;
color: #31325F;
outline: none;
padding-right: 10px;
padding-left: 10px;
cursor: text;
width: 70%;
height: 40px;
float: right;
}
.field::-webkit-input-placeholder { color: #CFD7E0; }
.field::-moz-placeholder { color: #CFD7E0; }
.field:-ms-input-placeholder { color: #CFD7E0; }
button {
float: left;
display: block;
background: #666EE8;
color: white;
box-shadow: 0 7px 14px 0 rgba(49,49,93,0.10),
0 3px 6px 0 rgba(0,0,0,0.08);
border-radius: 4px;
border: 0;
margin-top: 20px;
font-size: 15px;
font-weight: 400;
width: 100%;
height: 40px;
line-height: 38px;
outline: none;
}
button:focus {
background: #555ABF;
}
button:active {
background: #43458B;
}
.outcome {
float: left;
width: 100%;
padding-top: 8px;
min-height: 24px;
text-align: center;
}
.success, .error {
display: none;
font-size: 13px;
}
.success.visible, .error.visible {
display: inline;
}
.error {
color: #E4584C;
}
.success {
color: #666EE8;
}
.success .token {
font-weight: 500;
font-size: 13px;
}
</style>
</head>
<body>
<script src="https://js.stripe.com/v3/"></script>
<form >
<div class="group">
<label>
<span>Name</span>
<input name="cardholder-name" class="field" placeholder="Jane Doe" />
</label>
<label>
<span>Phone</span>
<input class="field" placeholder="(123) 456-7890" type="tel" />
</label>
</div>
<div class="group">
<label>
<span>Card</span>
<div id="card-element" class="field"></div>
</label>
</div>
<button type="submit">Pay $25</button>
<div class="outcome">
<div class="error" role="alert"></div>
<div class="success">
Success! Your Stripe token is <span class="token"></span>
</div>
</div>
</form>
<script>
var stripe = Stripe('pk_test_xxx');
var elements = stripe.elements();
var card = elements.create('card', {
style: {
base: {
iconColor: '#666EE8',
color: '#31325F',
lineHeight: '40px',
fontWeight: 300,
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSize: '15px',
'::placeholder': {
color: '#CFD7E0',
},
},
}
});
card.mount('#card-element');
function setOutcome(result) {
var successElement = document.querySelector('.success');
var errorElement = document.querySelector('.error');
successElement.classList.remove('visible');
errorElement.classList.remove('visible');
if (result.token) {
// Use the token to create a charge or a customer
// https://stripe.com/docs/charges
successElement.querySelector('.token').textContent = result.token.id;
successElement.classList.add('visible');
} else if (result.error) {
errorElement.textContent = result.error.message;
errorElement.classList.add('visible');
}
}
card.on('change', function(event) {
setOutcome(event);
});
document.querySelector('form').addEventListener('submit', function(e) {
e.preventDefault();
var form = document.querySelector('form');
var extraDetails = {
name: form.querySelector('input[name=cardholder-name]').value,
};
stripe.createToken(card, extraDetails).then(setOutcome);
});
</script>
</body>
</html>