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);
Related
My code was working fine.
I am trying to hide the PayPal button, when I did, it goes to wrong url: https://www.paypal.com/checkoutnow?
As you can see we need here latinumcheckout not checkoutnow? What to do ? Thanks.
var FUNDING_SOURCES = [paypal.FUNDING.BANCONTACT, paypal.FUNDING.IDEAL];
FUNDING_SOURCES.forEach(function (fundingSource) {
var button = paypal
.Buttons({
createOrder: function (data, actions) {
return actions.order.create({
shipping_type: "PICKUP",
application_context: { shipping_preference: "NO_SHIPPING" },
purchase_units: [
{
amount: {
value: "88.44",
},
},
],
});
},
onApprove: function (data, actions) {
return actions.order.capture().then(function (orderData) {
console.log(
"Capture result",
orderData,
JSON.stringify(orderData, null, 2)
);
var transaction = orderData.purchase_units[0].payments.captures[0];
alert(
"Transaction " +
transaction.status +
": " +
transaction.id +
"\n\nSee console for all available details"
);
});
},
fundingSource: fundingSource,
})
.render("#bancontact-button-container");
});
I am trying to hide the PayPal button using fundingSource, but when I click on the button like baancontact or ideal I went to url start with checkoutnow? normally should be start with latinumcheckout, any advice to solve my problem?
Code looks correct, yet I can reproduce the problem and it would appear to be a bug. Contact PayPal for support on why the wrong URL is opening.
By the way, actions.order.create and actions.order.capture are deprecated, no longer supported for new integrations. Use the /v2/checkout/orders API to create and capture the order on a server backend. See the documentation/samples at https://developer.paypal.com/docs/checkout/standard/integrate/
I've been trying to integrate PayPal buttons on my Django website, but I keep having this problem where the PayPal popup window appears as about:blank#blocked. I can see this error in console:
popup_open_error_iframe_fallback
{err: 'n: Can not open popup window - blocked\n at Ie (…owser=false&allowBillingPayments=true:1342:297830', timestamp: '1644780862712', referer: 'www.sandbox.paypal.com', sdkCorrelationID: 'f12370135a997', sessionID: 'uid_d36969c1b2_mtk6mja6mzy', …}
What I don't understand is that the problem isn't there if I just open the HTML file itself in a browser... The script looks like this:
<!-- Set up a container element for the button -->
<div id="paypal-button-container" class='text-center mt-2'></div>
<!-- Include the PayPal JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?client-id=blahblahmyid¤cy=EUR"></script>
<script>
// Render the PayPal button into #paypal-button-container
paypal.Buttons({
locale: 'it_IT',
style: {
color: 'gold',
shape: 'rect',
layout: 'vertical',
label: 'pay'
},
// Set up the transaction
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '88.44'
}
}]
});
},
// Finalize the transaction
onApprove: function(data, actions) {
return actions.order.capture().then(function(orderData) {
// Successful capture! For demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
var transaction = orderData.purchase_units[0].payments.captures[0];
alert('Transaction '+ transaction.status + ': ' + transaction.id + '\n\nSee console for all available details');
// Replace the above to show a success message within this page, e.g.
// const element = document.getElementById('paypal-button-container');
// element.innerHTML = '';
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
// Or go to another URL: actions.redirect('thank_you.html');
});
}
}).render('#paypal-button-container');
</script>
What's the problem ? I don't understand.
There's a new feature in django 4.0 that follows the addition of the COOP header in newer browsers which, as I understand it, stops remote sites from opening a window in the same browsing context.
The default setting of SECURE_CROSS_ORIGIN_OPENER_POLICY in django isolates the browsing context to just the current document origin. Setting it to same-origin-allow-popups allows the paypal popup to open in the current context.
See https://docs.djangoproject.com/en/4.0/ref/middleware/#cross-origin-opener-policy
TLDR; set SECURE_CROSS_ORIGIN_OPENER_POLICY='same-origin-allow-popups'
For django 4.0 settings.py add
SECURE_CROSS_ORIGIN_OPENER_POLICY='same-origin-allow-popups'
I am using paypal Buttons SDK. The Code activating the button is:-
paypal.Buttons({
createOrder: ( data, actions ) => {
return actions.order.create({
purchase_units: [{
amount: {
value: this.amount.toFixed(2),
currency_code: "GBP",
}
}]
})
},
onApprove: ( data, actions ) => {
return actions.order.capture().then(details => {
console.log('details',details);
})
},
onError: ( error ) => {
console.log('error',error);
}
}).render('#paypal-button-container')
The User Interface operates as expected, there is then a long pause before the error is returned. The client_id used in the script tag is for a sandbox account. I can find not documentation describing possible cause for the error...
error Error: Order could not be captured
Any advice greatly appreciated.
Paypal.. https://developer.paypal.com/docs/checkout/integrate/#1-get-paypal-rest-api-credentials
As suggested in the comment try to do a curl with this URL :
https://www.sandbox.paypal.com/smart/api/order/ODER_ID/capture
And it replies with code 401 and did some research and end up finding that I was using a wrong account to make payments.
I refresh the PayPal login and login with the correct sandbox buyer account and make the payment and It works.
Probably paypal should give correct errors messages.
Can you check using CURL which returns the Paypal server?
This is a comment but I do not have 50pkt S / O. Sorry.
If you get a Xss message in the console, just try in private navigation, disconnect from your paypal buyer account.
I have had the same "Order could not be captured" error at "actions.order.capture()" in the onApprove callback.
In my case, it worked on the first run but not the subsequent calls. I found my order always had the same invoice_id. I removed invoice_id and Paypal stopped complaining.
It should be good if the invoice_id was always unique.
Same problem with Nuxt , checkout works but catch error response : Error 500 order-could-not-be-captured
<template>
<no-ssr>
<v-layout row wrap>
<div ref="paypal"></div>
</v-layout>
</no-ssr>
</template>
Script
mounted() {
const script = document.createElement("script");
script.src =
"https://www.paypal.com/sdk/js?client-id=MyKeyID";
script.addEventListener("load", this.setLoaded);
document.body.appendChild(script);
},
methods: {
setLoaded: function() {
this.loaded = true;
window.paypal
.Buttons({
createOrder: (data, actions) => {
return actions.order.create({
purchase_units: [
{
description: "Test description",
amount: {
currency_code: "USD",
value: 1
}
}
]
});
},
onApprove: async (data, actions) => {
const order = await actions.order.capture();
this.paidFor = true;
console.log(order);
},
onError: err => {
console.log(err);
}
})
.render(this.$refs.paypal);
}
I'm using PayPal Express Checkout from JavaScript.
This is the code I have and works (I see the PayPal button, I can click it, and the payment window opens fine):
<div id="paypal-button"></div>
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
paypal.Button.render({
env: 'sandbox',
client: {
sandbox: 'xxxxxx',
production: 'yyyyyy'
},
payment: function () {
var env = this.props.env;
var client = this.props.client;
return paypal.rest.payment.create(env, client, {
transactions: [
{
amount: { total: '1.00', currency: 'USD' }
}
]
});
},
commit: true,
onAuthorize: function (data, actions) {
return actions.payment.execute().then(function() {
document.querySelector('#paypal-button-container').innerText = 'Payment Complete!';
});
}
}, '#paypal-button');
</script>
But, if I supply input_fields like the code below, it stops working and throws a console error:
paypal.Button.render({
env: 'sandbox',
client: {
sandbox: 'xxxxxx',
production: 'yyyyyy'
},
payment: function () {
var env = this.props.env;
var client = this.props.client;
return paypal.rest.payment.create(env, client, {
transactions: [
{
amount: { total: '1.00', currency: 'USD' }
}
]
}, {
input_fields: {
no_shipping: 1
}
});
},
commit: true,
onAuthorize: function (data, actions) {
return actions.payment.execute().then(function() {
document.querySelector('#paypal-button-container').innerText = 'Payment Complete!';
});
}
}, '#paypal-button');
This is the error detail:
In this last case, I see the PayPal button, the window opens when I click on it, but after a few seconds the window closes itself and gives the console error provided here.
What am I missing?
UPDATE
As #bluepnume pointed out, if I switch from sandbox to production environment, the problem disappears.
But, if I also supply first_name and last_name in input_fields, I get another console error no matter if I'm in sandbox or production environment.
This is the code snippet:
, {
input_fields: {
no_shipping: 1,
first_name: 'Abc',
last_name: 'Dfg'
}
}
And this is the error message:
This is a known issue that's being tracked. For what it's worth, if you run in production mode, the issue should not be present.
EDIT: For the second issue, looks like this is not a valid request format. You should be able to see in your network tab:
Are you looking for the payer_info field for the payments api? https://developer.paypal.com/docs/api/payments/
Concerning the first issue, it seems everything is working well now. The "no_shipping" option can be used even in test conditions.
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.