I have the little Paypal window working in the sandbox and production mode. The onAuthorize function gets called and my message window pops up thanking you for the purchase and giving the purchased credits to the customer.
paypal.Button.render({
<% if (useBankAccount) { %>
env: 'production', // Or 'sandbox', 'production'
<% } else { %>
env: 'sandbox', // Or 'sandbox', 'production'
<% }%>
client: {
sandbox: 'Axxx',
production: 'Axxx'
},
commit: true,
style: {
size: 'responsive',
color: 'gold',
shape: 'pill',
label: 'pay'
},
payment: function (data, actions) {
return actions.payment.create({
payment: {
transactions: [
{
amount: { total: currentPayment, currency: 'USD' }
}
]
}
});
},
onAuthorize: function (data, actions) {
if (window.ga) { // Google Analytics
window.ga('send', 'event', 'Credits', 'Purchase', 'Payment', currentPayment);
window.ga('send', 'event', 'Credits', 'Purchase', 'Credits', currentCredits);
}
document.getElementById("<%= PurchaseDone.ClientID %>").value = "Yes";
document.getElementById("<%= PurchaseAmount.ClientID %>").value = currentPayment;
TheForm.submit();
},
onCancel: function (data, actions) {
OpenMessageWindow("The payment was cancelled.");
},
onError: function (err) {
var result = err.message.toString().indexOf("Amount cannot be zero")
if (result > 0) {
OpenMessageWindow('Payment Error: The purchase amount must be more than zero');
return;
}
OpenMessageWindow('Payment Error:<br/>' + err.message)
}
}, '#paypal-button');
Looking the data passed into OnAuthorize()
{paymentToken: "EC-xxx",
orderID: "EC-xxx",
payerID: "FTxxx",
paymentID: "PAY-xxx",
intent: "sale", …}
intent:"sale" orderID:"EC-xxx"
payerID:"FTxxx"
paymentID:"PAY-xxx"
paymentToken:"EC-xxx"
returnUrl:
"https://www.paypal.com/?paymentId=PAY-0Kxxx&token=EC-xx&PayerID=FTxxx"
__proto__ :Object
actions is
{close: ƒ, redirect: ƒ, payment: {…}, order: {…}, restart: ƒ, …}
To see those values, I commented out the TheForm.Submit(), which could have been the problem but the payment still did not happen.
The problem is, in production, the customer purchase does not happen. The customer (me) logs into their Paypal account, presses Pay Now, the window disappears calling onAuthorize.
No payment registers on the customer account. No payment transaction happens and my software gives the credits for free.
Ideas? What can I look at? Paypal telephone support does not know anything about development.
Thank you for any help.
The solution is to call actions.payment.execute() in the onAuthorize callback. It causes a second busy indicator that does the payment. It's like the onAuthorize says the user accepts, now do you accept?
Now, this is my working code.
paypal.Button.render({
<% if (useBankAccount) { %>
env: 'production', // Or 'sandbox', 'production'
<% } else { %>
env: 'sandbox', // Or 'sandbox', 'production'
<% }%>
client: {
sandbox: 'xxx',
production: 'xxx'
},
commit: true,
payment: function (data, actions) {
return actions.payment.create({
payment: {
transactions: [
{
amount: { total: currentPayment, currency: 'USD' }
}
]
}
});
},
onAuthorize: function (data, actions) {
return actions.payment.execute().then(function (payment) {
// setup the data to post
TheForm.submit();
});
},
onCancel: function (data, actions) {
OpenMessageWindow("The payment was cancelled.");
},
onError: function (err) {
var result = err.message.toString().indexOf("Amount cannot be zero")
if (result > 0) {
OpenMessageWindow('Payment Error: The purchase amount must be more than zero');
return;
}
OpenMessageWindow('Payment Error:<br/>' + err.message)
}
}, '#paypal-button');
I added two things from the PayPal example to get it working.
The "commit: true," is needed to change the Continue button to Pay Now. Unbelievably, the default is to have a button called Continue that pays.
The second is calling actions.payment.execute() in onAuthorize. Not something you could figure out except by being told.
I am quite incredulous that the PayPal example does not include these two items providing an example that simply does not work. AND you don't know about it until you test a live purchase, sandbox seems fine.
Additionally, Stack Overflow is PayPal's development support, why was this question never answered? I actually found the solution to the problem on a web page explaining how bad PayPal is compared to Stripe. The page gave a nice example of the complicated PayPal code that had the missing function call.
Related
Can somebody tell me why? This is a simple integration of paypal sdk for javascript. And It is working fine except that the event bellow onShippingChange is never fired. I've searching this for 2 days now. I need to update my price according to the user address.
src="https://www.paypal.com/sdk/js?client-id=XXXXXXXXX"> // Required. Replace SB_CLIENT_ID with your sandbox client ID.
</script>
<div id="paypal-button-container"></div>
<script>
paypal.Buttons({
createOrder: function(data, actions) {
// This function sets up the details of the transaction, including the amount and line item details.
console.log('createOrder ' + data);
return actions.order.create({
application_context : {
shipping_preference: 'SET_PROVIDED_ADDRESS'
},purchase_units: [{
shipping: {
address: {
address_line_1: '555 example bs',
admin_area_2: 'San bastard',
admin_area_1: 'CA',
postal_code: '95111',
country_code: 'CA'
}
},
amount: {
value: '0.01'
}
}]
});
},
onApprove: function(data, actions) {
console.log('onApprove ' + data);
// This function captures the funds from the transaction.
return actions.order.capture().then(function(details) {
// This function shows a transaction success message to your buyer.
alert('Transaction completed by ' + details.payer.name.given_name);
});
},
onClientAuthorization: (data) => {
console.log('onClientAuthorization - you should probably inform your server about completed transaction at this point', data);
this.showSuccess = true;
},
onShippingChange: (data, actions) => {
// this event is never fired no matter what I do
console.log('onShippingChange - Shipping information have changed', data, actions);
},
onCancel: (data, actions) => {
console.log('OnCancel', data, actions);
},
onError: err => {
console.log('OnError', err);
},
onClick: (data, actions) => {
console.log('onClick', data, actions);
}
}).render('#paypal-button-container');
//This function displays Smart Payment Buttons on your web page.
</script>
here is the solution of this question first of the shippings fees can only be managed after you enable it on your account (Login to PayPal >> Hover over to the profile name >> Account Settings >> Shipping >> Here you can create shipping profiles as per your requirements.) it will be available only for customer who pay from a paypal account. For any other payment you won't be able to manage it.
Regards
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);
}
My problem today is that I have a web application with an express checkout to execute.
I used the Client - Server architecture to avoid security issues.
So my client code is the following:
paypal.Button.render({
env : 'sandbox',
commit: true,
style: {
size: 'medium',
color: 'gold',
shape: 'pill',
label: 'checkout'
},
locale: 'en_US',
payment: function() {
nickname = $("#nickname").val();
amount = $("#amount").val();
description = $("#description").val();
data = {
"nickname" : nickname,
"amount" : amount,
"description" : description
};
return new paypal.Promise(function(resolve, reject) {
// Call your server side to get the Payment ID from step 3, then pass it to the resolve callback
jQuery.post("/newPayment", data).done(function(data){
console.log("HEI I GOT THE PAYMENT JSON = " + data);
parsed_data = JSON.parse(data);
resolve(parsed_data['id']);
});
});
},
onAuthorize: function(data, actions) {
console.log("JSON = " + JSON.stringify(actions.payment.getTransactions()[0]));
console.log("TRANSACTION = " + actions.payment.getTransactions()[0])
console.log("PAYMENT SUCCESSFUL");
return actions.payment.execute();
},
onError: function(data, actions){
console.log("ERRORRRRRR");
$("#warning").show();
}
}, '#paypal-button');
My server side code:
app.post("/newPayment",function(req,res){
console.log("RECEIVING POST WITH AMOUNT = " + req.body.amount);
//CONFIGURE PAYMENY - PAYPAL PHASE 1
var first_config = {
'mode': 'sandbox',
'client_id': '<MY CLIENT ID>',
'client_secret': '<MY SECRET>'
};
paypal.configure(first_config);
console.log("AMOUNT AUTHORIZED = " + req.body.amount);
//CREATING PAYMENT
PAYMENT = {
"intent": "sale",
"payer": {
"payment_method": "paypal"
},
"redirect_urls": {
"return_url": "http://return.url",
"cancel_url": "http://cancel.url"
},
"transactions": [{
"amount": {
"currency": "EUR",
"total": req.body.amount
},
"description": "This is the payment description."
}]
};
//CREATING PAYMENT AND SENDING IT TO THE CLIENT
paypal.payment.create(PAYMENT, function (error, payment) {
if (error) {
throw error;
} else {
console.log("Create Payment Response");
res.send(JSON.stringify(payment));
}
});
Now, the paypal window opens and I can insert all my data to execute a test payment.
But when I confirm payment and Paypal service should call my "onAuthorize" method, instead methon "onError" fires...
What could be the problem?
Redirect URLS?
The fact that I should execute the paypal.configure() with a .then() after it to ensure the flow of actions?
I'm really exploding trying to use Paypal services
EDIT:
Pushing my code on cloudno.de the payment is executed correctly, but running it locally it doesn't work... I don't know what to say ahah
actions.payment.getTransactions is not a function. You need to call actions.payment.get().then(function(result) { ... })
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 trying to implement the payment process with Paypal Checkout
This is my code
<div class='wrapper-packages'>
<div id="paypal-button"></div>
</div>
<script>
paypal.Button.render({
env: 'sandbox',
client: {
sandbox: 'xxxxxxxx',
production: 'xxxxxxxx'
},
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, // Optional: show a 'Pay Now' button in the checkout flow
onAuthorize: function(data, actions) {
// Optional: display a confirmation page here
return actions.payment.execute().then(function() {
alert('ok');
});
}
}, '#paypal-button')
</script>
When I click on Paypal Checkout button, it opens the modal for log in paypal account, but I can't do login
The login credentials are ok, I've checked it.
So, what can be the problem?
When using PayPal's Sandbox, you need to use Sandbox Test Accounts. You can read more about them in the Docs