Custom Stripe Checkout button not opening window on mobile - javascript

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.

Related

Google Pay - ERROR: Request Failed - Unexpected developer error, please try again later

When I try to pay(on TEST environment) with Google Pay on a real device I get a the error in the title.
I have tried changing 'gateway' into a string like the google docs show it but so far nothing.
const DETAILS = {
id: 'COMPANY',
displayItems: [
{
label: 'Phone Bill',
amount: { currency: 'USD', value: compTotal }
}
],
total: {
label: 'COMPANY',
amount: { currency: 'USD', value: compTotal }
}
};
// GOOGLE PAY
const METHOD_DATA = [{
supportedMethods: ['android-pay'],
data: {
supportedNetworks: ['visa', 'mastercard', 'amex'],
currencyCode: 'USD',
environment: 'TEST', // defaults to production
paymentMethodTokenizationParameters: {
tokenizationType: 'GATEWAY_TOKEN',
parameters: {
gateway: 'braintree',
'braintree:tokenizationKey': 'sandbox_XXXXXXXXXXX'
}
}
}
}];
const paymentRequest = new PaymentRequest(METHOD_DATA, DETAILS);
paymentRequest.show()
.then(paymentResponse => {
const { getPaymentToken } = paymentResponse.details;
return getPaymentToken()
.then(paymentToken => {
const { ephemeralPublicKey, encryptedMessage, tag } = paymentToken.details;
return fetch('...', {
method: 'POST',
body: {
ephemeralPublicKey,
encryptedMessage,
tag
}
})
.then(res => res.json())
.then(paymentResponse.complete('success'), handleConfirm())
.catch(paymentResponse.complete('fail'), alert(1));
});
});
};
Expected result would be the payment going through.
To learn more about this error, follow these steps:
1- Make sure Android Debug Bridge (adb) is installed on your computer..
Make sure USB debugging is enabled on your device. For more information, see Debug Your App.
2- Connect your phone to the computer with a USB cable.
3- Run the following command in a terminal or command prompt on your computer:
adb -d logcat -s WalletMerchantError
Turns out I was not able to do this with React-Native because 'React Native Payments' did not fully support Google Pay which in turn did not fully support Braintree & didn't support Payeezy at all.
I had to resort to native code(Java) and then link React-Native to that native module. It was pretty simple.
I used this demo on Github to guide me through it. I was using Braintree as the payment processor but looks like I will be switching to Payeezy.
I was getting the error in the title because like I said Google Pay wasn't supported fully by 'React-Native-Payments' which in turn didn't support Braintree and when the error was accuring because I was only giving this info -
parameters: {
gateway: 'braintree',
'braintree:tokenizationKey': 'sandbox_TOKEN-HERE'
}
But looks like I needed to use this(In the Java Module) -
.put("gateway", "braintree")
.put("braintree:apiVersion", "v1")
.put("braintree:sdkVersion", "BETA")
.put("braintree:clientKey", "sandbox_TOKEN-HERE")
.put("braintree:merchantId", "TOKEN-HERE"));
I have the some error because of mismatch type of price object.
I put the float value in totalPrice.
After update
data class TransactionInfo(
#SerializedName("totalPrice") val price: String,
#SerializedName("totalPriceStatus") val priceStatus: String,
#SerializedName("currencyCode") val currency: String
)
This is works fine on ENVIRONMENT_TEST case.
Use https://google.com/pay under supportedMethods to leverage Google Pay through Payment Request API.
Check these couple of examples for further reference: official docs, sample from the Chrome team.

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,

paypal checkout javascript error - this20.getParentTemplate is not a function

I am implementing paypal express checkout button into my developing wordpress plugin.
I have an edit order page, where there is a "confirm order" button, which a popup modal message confirming the total payable amount, where the checkout button is rendered.
$("#mdp-order-button").click(function(e){
e.preventDefault();
mdp_render_confirm_modal();
});
function mdp_render_confirm_modal(){
if (!$("#mdp_upload_image")[0].files[0]){
alert("please upload an image first");
}else{
if(mdp_check_overlap()){
alert("the block is either out of the grid or overlapped with other block, please place it again");
}else{
var current_block = $('.current_block');
var cost = current_block.width() * current_block.height();
$('#mdp-show-size').html("Your block is "+current_block.width()+"px X "+current_block.height()+"px");
$('#mdp-show-cost').html("Total: "+cost);
$('#mdp-modal').show();
$('#mdp-close').click(function(){
$('mdp-modal').hide();
})
mdp_render_paypal_button(cost)
}
}
}
function mdp_render_paypal_button(charge) {
paypal.Button.render({
env: 'sandbox', // Or 'sandbox'
commit: true, // Show a 'Pay Now' button
client: {
sandbox: 'censored xxxxx'
},
payment: function() {
return paypal.rest.payment.create(this.props.env, this.props.client, {
transactions: [
{
amount: {
total: charge,
currency: 'USD'
}
}
]
});
},
onAuthorize: function(data, actions) {
return actions.payment.execute().then(function(response) {
console.log(response);
});
}
}, '#paypal-button');
}
When I click on the checkout button, the paypal window popup and close straight away, and error is displayed on console
checkout.js:4225 ppxo_xc_ppcheckout_destroy Object {timestamp: 1494405598944, windowID: "53bb903148", pageID: "84e2908f4a", host: "www.sandbox.paypal.com", path: "/webapps/hermes/button"…}
checkout.js:2021 Uncaught Error: _this20.getParentTemplate is not a function
TypeError: _this20.getParentTemplate is not a function
at Object.onSuccess (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:9346:40)
at _loop2 (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1077:62)
at SyncPromise.dispatch (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1107:29)
at SyncPromise.then (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1125:18)
at Function.syncPromiseTry [as try] (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1170:42)
at DelegateComponent.openContainer (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:9342:55)
at Object.onSuccess (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:8556:35)
at _loop2 (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1077:62)
at SyncPromise.dispatch (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1107:29)
at SyncPromise.then (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1125:18)
at Object.onSuccess (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:9346:40)
at _loop2 (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1077:62)
at SyncPromise.dispatch (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1107:29)
at SyncPromise.then (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1125:18)
at Function.syncPromiseTry [as try] (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1170:42)
at DelegateComponent.openContainer (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:9342:55)
at Object.onSuccess (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:8556:35)
at _loop2 (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1077:62)
at SyncPromise.dispatch (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1107:29)
at SyncPromise.then (https://www.paypalobjects.com/api/checkout.js?ver=4.7.4:1125:18)
at Object._RECEIVE_MESSAGE_TYPE.(anonymous function) [as postrobot_message_response] (https://www.paypalobjects.com/api/checkout.js:2021:118)
at receiveMessage (https://www.paypalobjects.com/api/checkout.js:1929:73)
at messageListener (https://www.paypalobjects.com/api/checkout.js:1949:13)
I tried to search on the web but I found no similar questions nor documentation and I really have no ideas on why this happen.
Thanks in advance for the help, full sta
Thank you so much for #bluepnume help.
It is the problem with how wordpress load the script, which by default appending a query string ?ver='current_wordpress_version' to scripts that get loaded, have disabled that and now it is getting the latest version of the checkout.js
instead of just
wp_enqueue_script('paypal_checkout', 'https://www.paypalobjects.com/api/checkout.js');
it is now
wp_enqueue_script('paypal_checkout', 'https://www.paypalobjects.com/api/checkout.js',array(),null);

Stripe custom checkout not Posting

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.

Asterisk: create user with template via AMI

I need to modify sip.conf with AMI, adding a new user to it. Everything works fine, and I can create a user like this without problems:
[1000]
secret=pass12
But I have to create user with template like
[1000](mytemp)
secret=pass12
and I don't know how to do this. Neither Google, nor Digium forum can't help me.
P.S. I use JavaScript asterisk-manager to interact with Asterisk, and here is my code, which adds extension:
var amiAction = {
action: 'UpdateConfig',
reload: 'yes',
srcfilename: 'sip.conf',
dstfilename: 'sip.conf',
'action-000000': 'newcat',
'cat-000000': '1000',
'action-000001': 'append',
'cat-000001': '1000',
'var-000001': 'secret',
'value-000001': 'pass12'
};
ami.action(amiAction, function(err, resp) {
console.log(err, resp);
});
var amiAction = {
action: 'UpdateConfig',
reload: 'chan_sip',
srcfilename: 'sip.conf',
dstfilename: 'sip.conf',
'action-000000': 'newcat',
'cat-000000': '1000',
'options-000000': 'inherit=template-name'
};
I'm sure you've tried this, but:
'cat-000000': '1000 [(mytemp)]',
... should work just fine. If it does not, what error message does it throw?

Categories