Stripe custom checkout not Posting - javascript

Can anyone assist as to why this is not posting to booking/charge upon completion of input to the checkout pop up window?
The simple checkout example posts fine, I am new to js so I don't quite understand the flow of the commands.
<form action="/booking/charge" method="post">
<script src="https://checkout.stripe.com/checkout.js"></script>
<button id="customButton">Purchase</button>
<script>
var handler = StripeCheckout.configure({
key: 'pk_test_xxxxxxxxxxx',
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.
}
});
document.getElementById('customButton').addEventListener('click', function(e) {
// Open Checkout with further options:
handler.open({
name: 'xxxx',
email: "test#test.com",
description: '2 widgets',
currency: 'gbp',
amount: 350
});
e.preventDefault();
});
// Close Checkout on page navigation:
window.addEventListener('popstate', function() {
handler.close();
});
</script>
</form>

If you use the custom Checkout integration, you need to do a little more work. You write your own code to handle the token returned by Stripe. This is all done within token callback.
Here's a traditional form submission example, it uses JQuery, appends the token and user's email as values to hidden form elements, then submits the form.
function (token) {
// Use the token to create the charge with a server-side script.
$("#stripeToken").val(token.id);
$("#stripeEmail").val(token.email);
$("#myForm").submit();
}
Full Example: https://jsfiddle.net/osrLsc8m/
Alternatively, you could submit the data to your backend with an AJAX request.
function (token) {
var myData = {
token: token.id,
email: token.email
};
/*
Make an AJAX post request using JQuery,
change the first parameter to your charge script
*/
$.post("/echo/html/",myData,function(data){ ... });
}
Full Example: http://jsfiddle.net/742tety5/

Code that has worked for me (must include script for jQuery in header not footer)
<script src="https://checkout.stripe.com/checkout.js"></script>
<form id="myForm">
<input type="hidden" id="message" value="Hello, world"/></p>
<input type="hidden" id="amount" value="10.00" /></p>
<p><button type="submit" id="customButton">Pay</button></p>
</form>
<script>
// checkout handler
var handler = StripeCheckout.configure({
key: '<YOUR PUBLIC KEY>',
image: 'https://stripe.com/img/documentation/checkout/marketplace.png',
token: function(token) {
/* Use the token to create the charge with a server-side script.
You can access the token ID with `token.id`
Pass along various parameters you get from the token response
and your form.*/
var myData = {
token: token.id,
email: token.email,
amount: Math.round($("#amount").val() * 100),
message: $("#message").val()
};
/* Make an AJAX post request using JQuery,
change the first parameter to your charge script*/
$.post("<YOUR ROUTE TO charge.php", myData,function (data) {
// if you get some results back update results
$("#myForm").hide();
$(".results").html("Your charge was successful");
}).fail(function () {
// if things fail, tell us
$(".results").html("I'm sorry something went wrong");
})
}
});
$('#myForm').on('submit', function (e) {
// Open Checkout with further options
handler.open({
name: 'Stripe.com',
email: 'test#test.com',
description: '2 widgets',
amount: Math.round($("#amount").val() * 100)
});
e.preventDefault();
});
// Close Checkout on page navigation
$(window).on('popstate', function () {
handler.close();
});
</script>
Hope this is of help to someone, experiencing same issue.

Related

Clarification on functionality of the stripe token

So I'm currently in the final stages of designing a small online shop and I'm having a bit of difficulty understanding what the stripe token contains, how to pick it up on the node.js server and that kind of thing.
currently, my client-side code looks like this:
<div style="text-align: center;">
<form id="paymentForm" action="//httpbin.org/post" method="POST">
<input type="hidden" id="stripeToken" name="stripeToken" />
<input type="hidden" id="stripeEmail" name="stripeEmail" />
<input type="hidden" id="cartTotal" name="cartTotal" />
<input type="hidden" id="cartContents" name="cartContents" />
</form>
<p><input type="button" class="button" id="purchaseButton" value="チェックアウト"></p>
<script>
var totalCost = 0;
var totalCartLoad = "";
totalCost = localStorage.getItem('totalCartPrice');
totalCartLoad = localStorage.getItem('whatsInCart');
totalCartLoad = totalCartLoad.replace('undefined','');
totalCartLoad = '_____________________________________' + totalCartLoad;
var finalCartLoad = String(totalCartLoad); //convert it to a string for display
var handler = StripeCheckout.configure({
key: 'pk_test_6pRNASCoBOKtIshFeQd4XMUh',
token: function(token) {
$("#stripeToken").val(token.id);
$("#stripeEmail").val(token.email);
$("#cartTotal").val(totalCost);
$("#cartContents").val(finalCartLoad);
$("#paymentForm").submit();
}
});
$('#purchaseButton').on('click', function(e) {
// Open Checkout with further options
handler.open({
name: "チェックアウト",
description: finalCartLoad,
shippingAddress: true,
billingAddress: true,
zipCode: true,
allowRememberMe: true,
currency: 'JPY',
amount: totalCost
});
e.preventDefault();
});
// Close Checkout on page navigation
$(window).on('popstate', function() {
handler.close();
});
</script>
</div>
and my server code looks like this:
const stripe = require("stripe")("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
module.exports = (req) => {
// the token is generated by Stripe and POST'ed
// to the `action` URL in our form
const token = req.body.stripeToken;
// now we create a charge which returns a `promise`
// so we need to make sure we correctly handle
// success and failure, but that's outside of this
// function (and we'll see it later)
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: process.env.STRIPE_DESCRIPTION, // 👈 remember to change this!
// this metadata object property can hold any
// extra private meta data (like IP address)
metadata: {},
});
}
However I am uncertain how to make sure that the details I need such as shipping address, customer email, product manifest and that kind of thing, which I have collected on my client, end up where I need it, on the invoice or somewhere in my account on stripe. I am also uncertain exactly how the charge is made (I know I need an app.js file to go with this as well, so I'd appreciate some pointers at this point cause its really been doing my head in.
The Token.id is what you want to use as the source when creating the Charge, and it looks like that's what you're doing, so you should be good to go from that side.
You should currently find the email at req.body.stripeEmail; in fact, you should find all of the following in req.body:
$("#stripeToken").val(token.id); // req.body.stripeToken
$("#stripeEmail").val(token.email); // req.body.stripeEmail
$("#cartTotal").val(totalCost); // req.body.cartTotal
$("#cartContents").val(finalCartLoad); // req.body.cartContents
In order to get the Shipping address, you'll need to pass those along too; you can find them in the args argument of the token() function, so you just need to pull what you need from there and send it along in your form as well.
var handler = StripeCheckout.configure({
key: 'pk_test_6pRNASCoBOKtIshFeQd4XMUh',
token: function(token) {
$("#stripeToken").val(token.id);
$("#stripeEmail").val(token.email);
$("#cartTotal").val(totalCost);
$("#cartContents").val(finalCartLoad);
$("#userShippingA").val(token.shippingAddress);
$("#userBillingA").val(token.billingAddress);
$("#paymentForm").submit();
}
});
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: req.body.cartContents,
shippingAddress: req.body.shippingAddress,
billingAddress: req.body.billingAddress,
email: req.body.stripeEmail,

Page not redirecting after stripe checkout

I'm trying to add a stripe checkout button to my Leadpages landing page and after somebody completes a successful payment they're supposed to be redirected...but that redirect is not happening and I have no idea why.
Here's my page: http://snapstories.leadpages.co/test/... it's using test keys right now so you can test the checkout with Stripe's demo Visa number: 4242424242424242 and any expiry / security code...you'll see that you don't get redirected anywhere.
The demo-stripe.php script is supposed to send a 'success' response to my front-end code which triggers the redirect but that 'success' response is not being sent.
Here's the demo-stripe.php code:
<?php
require_once('./stripe/init.php');
$stripe = array(
"secret_key" => "sk_test_******",
"publishable_key" => "pk_test_******"
);
\Stripe\Stripe::setApiKey($stripe['secret_key']);
// Get the credit card details submitted by the form
$token = $_GET['stripeToken'];
$email = $_GET['stripeEmail'];
$callback = $_GET['callback'];
try {
$customer = \Stripe\Customer::create(array(
"source" => $token,
"email" => $email
));
$charge = \Stripe\Charge::create(array(
'customer' => $customer->id,
'amount' => 100,
'currency' => 'usd'
));
header('Content-type: application/json');
$response_array['status'] = 'success';
echo $callback.'('.json_encode($response_array).')';
return 1;
}
catch ( \Stripe\Error\Card $e) {
// Since it's a decline, \Stripe\Error\Card will be caught
}
?>
Here's the front-end code:
<script src="https://checkout.stripe.com/checkout.js"></script>
<script>
var handler = StripeCheckout.configure({
key: 'pk_test_*****',
image: 'imagefile.png',
locale: 'auto',
token: function(token) {
$.ajax({
type: "POST",
dataType: 'jsonp',
url: "https://snapstories.co/demo-stripe.php",
data: { stripeToken: token.id, stripeEmail: token.email},
success: function(data) {
window.location.href = "http//www.google.com";
},
});
}
});
document.getElementsByClassName('w-f73e4cf1-859d-e3e4-97af-8efccae7644a')[0].addEventListener('click', function(e) {
// Open Checkout with further options:
handler.open({
name: 'Testing',
description: 'testing',
amount: 100
});
e.preventDefault();
});
// Close Checkout on page navigation:
window.addEventListener('popstate', function() {
handler.close();
});
</script>
I'm guessing your front-end code doesn't get to the success function.
Web console returns:
ReferenceError: $ is not defined
It looks like you're using the jQuery command $.ajax(), but I can't see where you've loaded the jQuery library. Try and load it above the script that uses it and see what happens
Be sure to double check the Stripe Checkout requirements. It seems, based on the link you posted, that you're using the HTTP protocol. Stripe Checkout requires you use the HTTPS protocol. That means if you're not using an ssl certificate on your page using Checkout, your page isn't going to return a token nor will it execute any further.

Custom Stripe Checkout button not opening window on mobile

I'm aware of the issue concerning handler.open in anything but a click event, due to browser popup blockers, but please see the following code I am using:
HTML
<button type="button" data-stripe data-image="/path/to/image.jpg">The button</button>
JS
export function paymentScreen(form, response) {
const restaurant = form.querySelector('[name="restaurant"]').value,
guests = form.querySelector('[name="guests"]').value,
time = form.querySelector('[name="time"]').value.split(':').slice(0, 2).join(':'),
email = form.querySelector('[name="email"]').value,
stripe = form.querySelector('[data-stripe]');
const handler = window.StripeCheckout.configure({
key: response.StripePublishableKey,
name: `Dim t - ${restaurant}`,
description: `Booking for ${guests} guests at ${time}`,
amount: parseInt(response.PaymentAmount, 10),
email: email,
currency: 'GBP',
locale: 'auto',
token(stripeResponse) {
stripePaymentProcess(form, response, stripeResponse);
}
});
// This part fails, even though we're in a click event listener.
stripe.addEventListener('click', function (e) {
handler.open({
image: this.dataset.image,
zipCode: false
});
});
}
The error I get in the console is as follows:
Stripe Checkout was unable to open a new window, possibly due to a
popup blocker. To provide the best experience for your users, follow
the guide at
https://stripe.com/docs/checkout#integration-more-runloop.
If I read the guide, I cannot see what I am doing wrong.
Any ideas on how to solve this? Thanks.

Laravel 5.1 Cashier - Adds customer but without info

I am using Laravel 5.1 trying to set it up with Stripe using Cashier.
I am using a custom button to execute the javascript (using Angular):
$scope.subscribe = function(plan){
var handler = StripeCheckout.configure({
key: 'pk_test_*************',
image: '/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: function(token) {
// Use the token to create the charge with a server-side script.
// You can access the token ID with `token.id`
var data = 'stripeToken=' + token.id;
$http.post("/createSubscription", data).success(function(data, status) {
console.log(data);
});
}
});
handler.open({
name: 'basic',
description: 'basic monthly $100',
currency: "usd",
amount: 10000
});
$(window).on('popstate', function() {
handler.close();
});
};
And in my Laravel code I have:
public function createSubscription(Request $request)
{
$user = JWTAuth::parseToken()->authenticate();
$token = Input::get('stripeToken');
$user->subscription("basic_plan")->create($token);
return 'test';
}
But I keep getting an error saying "this customer has no attached payment source".
The returned token at this line:
token: function(token) {
...
Does contain the users email, card info (+ card token), and stripe token. But when I check my Stripe dashboard, a customer is added without any data (no card, no email and not set up with the subscription).
I am trying to create customers with a subscription plan via this form.
(I do have the Billable trait set up and included in the controller)

Can't do POST requests with Polymer's core-ajax

This is what I have:
Polymer('my-element', {
created: function() {
this.data = {
name: 'John Doe',
email: 'john#doe.com'
};
},
handleResponse: function(e, d) {
console.log(d.response);
}
});
<core-ajax
id="ajax"
auto
url="/test"
method="POST"
handleAs="json"
body="{{data}}"
on-core-response="{{handleResponse"}}>
</core-ajax>
And I have a server set up to return the body of the POST message when the user posts to /test.
app.post('/test', function(req, res) {
res.json(req.body);
}
However, this is what I get as response on the console:
Object {object Object: ""}
core ajax all data you want to get with post must be sent with params attribute not body attribute.
that would make your core ajax tag look like
<core-ajax
id="ajax"
auto
url="/test"
method="POST"
handleAs="json"
params="{{data}}"
on-core-response="{{handleResponse"}}>
</core-ajax>
that would allow you to catch the data like normal in node
app.post('/test', function(req, res) {
res.json(req.body);
}
it is confusing cause in node you think of params as get data and body as post data but this doesn't matter with core ajax. all data get or post is sent with the params attribute.
This looks like core-ajax performs the AJAX call before this.data in ready.
Try 'manuel' AJAX request initiation, i.e. ajax.go()
Do this inside:
created: function() {
this.data = {
name: 'John Doe',
email: 'john#doe.com'
};
var respuesta = this.$.ajax;
console.log(respuesta);
respuesta.go();
},
Example Plunk

Categories