I have the following fairly basic implementation of Stripe. It successfully creates a new customer but it won´t charge and return the "SUCCESS ERROR" message in the console. The token seems to be created correctly so my guess is i am missing something in the charge.php.
NOTE: I have not used composer to install stripe but load the init.php in config.php (could that be the problem?). Also is the neccessary even though i use ajax?(removing it won´t solve the problem though)
Index.php
<?php require_once('stripe/config.php'); ?>
<form action="charge.php" method="post">
<script src="https://checkout.stripe.com/checkout.js"></script>
<button id="customButton">Purchase</button>
<script>
var handler = StripeCheckout.configure({
key: 'pk_test_*******************',
token: function(token) {
// Use the token to create the charge with a server-side script.
// You can access the token ID with `token.id`
console.log(token)
$.ajax({
url: 'stripe/charge.php',
type: 'post',
data: {tokenid: token.id, email: token.email},
success: function(data) {
if (data == 'success') {
console.log("Card successfully charged!");
}
else {
console.log("Success Error!");
}
},
error: function(data) {
console.log("Ajax Error!");
console.log(data);
}
}); // end ajax call
}
});
$('#customButton').on('click', function(e) {
// Open Checkout with further options
handler.open({
name: 'shipping free',
description: '2 widgets',
amount: 2000
});
e.preventDefault();
});
// Close Checkout on page navigation
$(window).on('popstate', function() {
handler.close();
});
</script>
</form>
CONFIG.PHP
<?php require_once('init.php');
$stripe = array(
secret_key => 'sk_test_************************',
publishable_key => 'pk_test_************************'
);
Stripe::setApiKey($stripe['secret_key']);
?>
CHARGE.PHP
<?php require_once('/config.php');
$tokenid = $_POST['tokenid'];
$email = $_POST['email'];
$customer = \Stripe\Customer::create(array(
'email' => $email,
'card' => $tokenid
));
$charge = \Stripe\Charge::create(array(
'email' => $email,
'card' => $tokenid
'amount' => 5000,
'currency' => 'usd',
));
echo '<h1>Successfully charged $50.00!</h1>';
?>
In this line, 'card' => $tokenid. you are missing comma(,).
Add comma in that line.
$charge = \Stripe\Charge::create(array(
'email' => $email,
'card' => $tokenid,
'amount' => 5000,
'currency' => 'usd',
));
Related
I have a multistep form, in the step 3 there is a button "Pay" that when is clicked it shows a Stripe modal using the jQuery below:
<form action="{{ route('registration.charge') }}" method="post" id="paymentForm">
{{csrf_field()}}
<input type="hidden" name="stripeToken" id="stripeToken"/>
<input type="submit" href="" id="payment" class="btn btn-primary float-right"
value="Pay"/>
</form>
Charge method to handle the Stripe charge:
public function charge(Request $request)
{
Stripe::setApiKey(config('services.stripe.secret'));
$source = $request->stripeToken;
Charge::create([
'currency' => 'eur',
'description' => 'Example charge',
'amount' => 2500,
'source' => $source,
]);
}
Route:
Route::post('/charge', [
'uses' => 'RegistrationController#charge',
'as' => 'registration.charge'
]);
When the user clicks in pay the stripe modal appears the user fills the form and click in Pay button the Stripe validates and send the token and the user is redirected to another page (http://proj.test/charge) because of the charge().
Do you know how to instead of redirecting the user to (http://proj.test/charge) change Stripe code to use Ajax so the user remains on the same page? So that is possible to show in that some page a success message, for example, informing that the payment was completed.
Stripe code:
let stripe = StripeCheckout.configure({
key: "{{config('services.stripe.key')}}",
image: "",
locale: "auto",
token: (token) => {
document.getElementById('stripeToken').value = token.id;
document.getElementById('paymentForm').submit();
}
});
document.getElementById('payment').addEventListener('click', function(e){
stripe.open({
name: 'test',
description: 'test',
amount: 1000
});
e.preventDefault();
});
Like this is not working, it appears the " console.log("Ajax Error!");" and then the user is redirected to "http://proj.test/charge".
let stripe = StripeCheckout.configure({
key: "{{config('services.stripe.key')}}",
image: "",
locale: "auto",
token: (token) => {
document.querySelector('#stripeToken').value = token.id;
document.querySelector('#paymentForm').submit();
$.ajax({
type: "POST",
url: '{{route('conferences.charge')}}',
data: {tokenid: token.id, email: token.email},
success: function(data) {
if (data == 'success') {
console.log("success");
}
else {
console.log("error");
console.log("Ajax Error!");
}
},
error: function(data) {
console.log(data);
}
});
}
});
document.getElementById('payment').addEventListener('click', function(e){
stripe.open({
name: 'test',
description: 'test',
amount: '{{session('total')}}'
});
e.preventDefault();
});
RegistrationController returning code 200:
public function charge(Request $request)
{
Stripe::setApiKey(config('services.stripe.secret'));
$source = $request->stripeToken;
$selectedRtypes = Session::get('selectedRtypes');
$amount = (collect($selectedRtypes)->first()['total']) * 100;
try{
Charge::create([
'currency' => 'eur',
'description' => 'Example charge',
'amount' => $amount,
'source' => $source,
]);
}
catch(\Exception $e){
return response()->json(['status' => $e->getMessage()], 422);
}
return response()->json([
'success' => true,
'message' => 'success',
], 200);
}
So this could probably be achieved in different ways.
Here is a solution from a VUE script that uses jquery to get the form
send: function () {
Stripe.setPublishableKey("stripekey")
const $form = $('#payment-form')
Stripe.card.createToken($form, (status, response) => {
if (response.error) {
return
}
this.payment_token = response.id
this.post('<your controller charge>', this.getFormData())
})
},
post: function (url, data) {
axios.post(url, data).then(response => {
// handle success here
}).catch(error => {
// handle error here
})
},
getFormData: function () {
return {
'payment_token': this.payment_token
}
},
But what I think you are looking for is
send: function () {
Stripe.setPublishableKey("stripekey")
const $form = $('#payment-form')
Stripe.card.createToken($form, (status, response) => {
if (response.error) {
return
}
let stripeToken = response.id
})
}
This uses the stripe javascript sdk
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
Here is my situation, i'm implementing Custom Stripe Checkout with Stripe PHP Api.
I have requested a post Method using jquery like this one >
var handler = StripeCheckout.configure({
key: 'pk_test_yGQM97VuEUdttuOOFQcyaPHW',
image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: function (token) {
// You can access the token ID with `token.id`.
// Get the token ID to your server-side code for use.
$.post(
'charge.php',
{
sT: token.id,
sE: token.email
}, function (data) {
console.log(data);
}
);
}
});
var thePayment = document.getElementById('pay-amount');
if (thePayment) {
thePayment.addEventListener('click', function (e) {
var desc = $('#pay-amount').attr('data-desc');
var amount = Number($('#pay-amount').attr('data-amount'));
var email = $('#pay-amount').attr('data-email');
// Open Checkout with further options:
handler.open({
name: 'Test',
description: desc,
amount: amount,
email: email,
allowRememberMe: false
});
e.preventDefault();
});
}
// Close Checkout on page navigation:
window.addEventListener('popstate', function () {
handler.close();
});
And the PHP side is just like this one >
require_once('html/includes/vendor/autoload.php');
$stripe = array(
"secret_key" => "sk_test_nJxSc9Yw716tLBWTa9HHMxhj",
"publishable_key" => "pk_test_yGQM97VuEUdttuOOFQcyaPHW"
);
$charge_reply = array();
\Stripe\Stripe::setApiKey($stripe['secret_key']);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$token = $_POST['sT'];
$email = $_POST['sE'];
$customer = \Stripe\Customer::create(array(
'email' => $email,
'source' => $token
));
$charge = \Stripe\Charge::create(array(
"amount" => 1000,
"currency" => "usd",
"source" => $customer->id,
"email" => $email,
"description" => "Example charge"
));
$charge_reply[] = [
'token' => $token,
'email' => $email
];
sendJson($charge_reply);
return;
}
I have also enabled the curl,json,mbstring in php. But the function that accepts after requesting a post method to the charge.php, prints POST http://example.com/charge.php 500 (Internal Server Error) in the console log.
So is there any way i can fix this?
500 (Internal Server Error) is something wrong in your code which means their is a fatal error.
To find the error you should use below code in your top of the page.
ini_set('display_errors',1);
error_reporting(E_ALL);
It will return the exact error so can fix it.
Note: Do not use it in production environment this for your local development.
I have a simple custom button Stripe Checkout setup at the moment which is charging payments ok but I cannot seem to get the customers email address to pass back to Stripe.
Heres my current code:
JS
var handler = StripeCheckout.configure({
key: 'myPublicKey',
image: '/images/RoadPreview.jpg',
locale: 'auto',
token: function(token, args){
$form.append(jQuery('<input type="hidden" name="stripeToken" />').val(token.id));
$form.append(jQuery('<input type="hidden" name="stripeEmail" />').val(token.email));
$form.get(0).submit();
}
});
jQuery('#roadFlow').on('click', function(e) {
var token = function(res){
var $input = jQuery('<input type=hidden name=stripeToken />').val(res.id);
jQuery('form').append($input).submit();
};
// Open Checkout with further options
handler.open({
name: 'Road Bike - Flow',
description: 'Make a £500 deposit to Order Now',
billingAddress: true,
shippingAddress: true,
currency: "gbp",
amount: 50000,
token: token
});
e.preventDefault();
});
jQuery(window).on('popstate', function() {
handler.close();
});
PHP
<?php
require_once('stripeConfig.php');
\Stripe\Stripe::setApiKey("mySecretKey");
$token = $_POST['stripeToken'];
$email = $_POST['stripeEmail'];
$customer = \Stripe\Customer::create(array(
'id' => $name,
'email' => $email,
'card' => $token
));
$charge = \Stripe\Charge::create(array(
'customer' => $customer->id,
'amount' => 50000,
'description' => "Dassi Road - Flow",
"receipt_email" => $email,
'currency' => 'gbp'
));
echo '<h1>Successfully Paid!</h1>';
?>
Button
<form action="charge.php" method="post"><button type="submit" id="roadFlow">Order Now</button>
Any ideas as to where I'm going wrong?
You're overriding the token callback that you defined in the StripeCheckout.configure() call when you call handler.open(), and the overriding function does not add the stripeEmail field.
This should work:
var handler = StripeCheckout.configure({
key: 'myPublicKey',
image: '/images/RoadPreview.jpg',
locale: 'auto',
token: function(token, args){
$form.append(jQuery('<input type="hidden" name="stripeToken" />').val(token.id));
$form.append(jQuery('<input type="hidden" name="stripeEmail" />').val(token.email));
$form.get(0).submit();
}
});
jQuery('#roadFlow').on('click', function(e) {
// Open Checkout with further options
handler.open({
name: 'Road Bike - Flow',
description: 'Make a £500 deposit to Order Now',
billingAddress: true,
shippingAddress: true,
currency: "gbp",
amount: 50000
});
e.preventDefault();
});
jQuery(window).on('popstate', function() {
handler.close();
});
Using Stripe, I want to store a customer email address from the email they supplied in Checkout. Unfortunately, posting stripeEmail in my charge.php file returns null.
How can I return the email from checkout so I can use it to send a receipt?
Here's my form code:
<script src="https://checkout.stripe.com/v2/checkout.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
<form action="charge.php" method="post">
<input type="hidden" id="amount" name="chargeAmount"/>
<button data-charge-amount="300000" data-charge-name="Name" data-charge-description="Description">Select Pledge Level</button>
<button data-charge-amount="123123" data-charge-name="Name2" data-charge-description="Description2">Donate</button>
</form>
<script>
$('button').click(function(){
var token = function(res){
var $theToken = $('<input type=hidden name=stripeToken />').val(res.id);
$('form').append($theToken).submit();
};
var amount = $(this).data("chargeAmount");
var name = $(this).data("chargeName");
var description = $(this).data("chargeDescription");
$('input#amount').val(amount);
StripeCheckout.open({
key: 'pk_test_xxxxxxxxxxxxxxxxxxxxxxxx',
address: true,
amount: amount,
currency: 'usd',
name: name,
description: description,
panelLabel: 'Pledge',
token: token,
});
return false;
});
</script>
Here is my charge.php code:
<?php
require_once('./config.php');
$token = $_POST['stripeToken'];
$amount = $_POST['chargeAmount'];
$customer = \Stripe\Customer::create(array(
'email' => $email,
'card' => $token,
));
$charge = \Stripe\Charge::create(array(
'customer' => $customer->id,
'amount' => $amount,
'currency' => 'usd',
));
?>
Here is my config.php code:
<?php
require_once('./stripe-php-2.1.2/init.php');
$stripe = array(
"secret_key" => "sk_test_xxxxxxxxxxxxxxxxxxxxxxxx",
"publishable_key" => "pk_test_xxxxxxxxxxxxxxxxxxxxxxxx"
);
\Stripe\Stripe::setApiKey($stripe['secret_key']);
?>
Any help would be much appreciated.
THANKS!
The issue here is that you're using Custom Checkout which means that Checkout won't post the data to your server automatically but instead give it in the token callback. In your case you're only retrieving the token id here which is why you are not seeing the email.
Update your code so that the token callback also retrieves the email and send it in the stripeEmail parameter:
var token = function(res){
var $theToken = $('<input type="hidden" name="stripeToken" />').val(res.id);
var $theEmail = $('<input type="hidden" name="stripeEmail" />').val(res.email);
$('form').append($theToken).append($theEmail).submit();
};
I just spent all night on this problem! #Koopajah helped a ton, so here's my entire solution in case anyone else happens to run across this.
Here's the form:
<form action="/charge.php" method="post">
<input
type="submit"
id="payMe"
class="btn btn-default btn-lg btn-success"
value=" Pay "
data-key="xxxxxxx"
data-amount="199"
data-currency="usd"
data-name="Stuff"
data-description="20 Whozits ($19.99)"
data-image="images/image.jpg"
data-bitcoin="true"
/>
<script src="https://checkout.stripe.com/v2/checkout.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>
<script>
$(document).ready(function() {
$('#payMe').on('click', function(event) {
event.preventDefault();
var $button = $(this),
$form = $button.parents('form');
var opts = $.extend({}, $button.data(), {
token: function(result) {
var $theToken = $('<input>').attr({ type: 'hidden', name: 'stripeToken', value: result.id })
var $theEmail = $('<input>').attr({ type: 'hidden', name: 'stripeEmail', value: result.email })
$form.append($theToken).append($theEmail).submit();
}
});
StripeCheckout.open(opts);
});
});
</script>
</form>
And here's charge.php:
<?php
require_once('vendor/autoload.php');
$stripe = array(
"secret_key" => "xxxx",
"publishable_key" => "xxxx"
);
\Stripe\Stripe::setApiKey($stripe['secret_key']);
$token = $_POST['stripeToken'];
$email = $_POST['stripeEmail'];
\Stripe\Customer::create(array(
"source" => $token,
"email" => $email,
"description" => "It Worked!"
));
try {
$charge = \Stripe\Charge::create(array(
"amount" => 199, // amount in cents, again
"currency" => "usd",
"source" => $_POST['stripeToken'],
"description" => "Cat Facts"));
} catch(\Stripe\Error\Card $e) {
$error = $e->getMessage();
}
?>
I have had a very similar issue but am using node.js. I modified koopajah's answer and placed it in a charge.js file
const token = req.body.stripeToken;<br>
const email = req.body.stripeEmail;
and then I used this email variable like so...
return stripe.charges.create({
// ensures we send a number, and not a string
amount: parseInt(process.env.STRIPE_COST, 10),
currency: process.env.STRIPE_CCY,
source: token,
description: 'My product', // 👈 remember to change this!
receipt_email: email, // that line sends a receipt email to the customer, you can customise that email inside stripe
metadata: {},
});
I hope this is a useful answer to someone.
I was previously charging users a fixed amount, say, "$20," but I wanted to create a donation box that would accept variables. I understand that there is "StripeCheckout.open," but does anyone know how it would look?
That being said, I am currently using the code below to charge a user a fixed amount, though I'm desperate to find out how to set a variable amount that can be charged.
<?php
require_once('config.php');
$token = $_POST['stripeToken'];
$customer = Stripe_Customer::create(array(
'email' => 'customer#example.com',
'card' => $token
));
$charge = Stripe_Charge::create(array(
'customer' => $customer->id,
'amount' => variable,
'currency' => 'cad'
));
?>
Ok, you probably should use V2 instead of V1, and what you want to do is something like this:
$('#sendPledgeBtn').click(function(){
var token = function(res){
var $input = $('<input type=hidden name=stripeToken />').val(res.id);
var tokenId = $input.val();
var email = res.email;
setTimeout(function(){
$.ajax({
url:'make-payment.php',
cache: false,
data:{ email : email, token:tokenId },
type:'POST'
})
.done(function(data){
// If Payment Success
$('#sendPledgeBtn').html('Thank You').addClass('disabled');
})
.error(function(){
$('#sendPledgeBtn').html('Error, Unable to Process Payment').addClass('disabled');
});
},500);
$('form:first-child').append($input).submit();
};
StripeCheckout.open({
key: 'pk_live_XXXXXXXXX', // Your Key
address: false,
amount: $('#amount').val(),
currency: 'usd',
name: 'Canted Pictures',
description: 'Donation',
panelLabel: 'Checkout',
token: token
});
return false;
});