Paypal on cancel funtion - javascript

I've trying to send a user to another page when they cancel the paypal payment. With the script below it works fine without the onCancel function, but as soon as I add the into the JS the paypal button disappears.
Could someone please have a look at the code and tell me how to correct it.
Thanks in advance.
paypal.Button.render({
// Set your environment
env: 'sandbox', // sandbox | production
// Specify the style of the button
style: {
label: 'checkout',
size: 'medium', // small | medium | large | responsive
shape: 'pill', // pill | rect
color: 'silver' // gold | blue | silver | black
},
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: '<insert production client id>',
production: '<insert production client id>'
},
// Show the buyer a 'Pay Now' button in the checkout flow
commit: true,
// Wait for the PayPal button to be clicked
payment: function(data, actions) {
// Make a client-side call to the REST api to create the payment
return actions.payment.create({
payment: {
transactions: [
{
amount: { total: '1.09', currency: 'GBP' }
}
]
},
experience: {
input_fields: {
no_shipping: 1
}
}
});
},
// Wait for the payment to be authorized by the customer
onAuthorize: function(data, actions) {
// Execute the payment
return actions.payment.execute().then(function() {
window.location.href = "<direct to payment success page>";
});
}
onCancel: function(data, actions) {
// Show a cancel page or return to cart
}
}, '#paypal-button-container');

You need to add a , to format the JSON object for each additional item, like the onCancel. Note the comma immediately after the close curly bracket for the onAuthorize item.
},
onCancel: function(data, actions) {
// Show a cancel page or return to cart
}

Ususally you need to use both onCancel and onError
onCancel: function(data, actions) {
console.log("You are a bummer!");
},
onError: function(err) {
console.log("PayPal is a bummer!");
}

Related

Errors: Use intent=capture to use client-side capture [Paypal Javascript SDK]

I am using the PayPal javascript SDK to create a Paypal subscription button for my web page, the problem resides when testing the button using a sandbox account in which after performing all the payment for the subscription the following error appears:
Error: Use intent=capture to use client-side capture ...
Here's my HTML script used to show my pay PayPal button
<script src="https://www.paypal.com/sdk/js?client-id=MY_CLIENT_ID&vault=true&intent=subscription&components=buttons"></script>
<div id="paypal-button-container"></div>
Heres my js file which performs the respective handlers depending on the actions and status of the payment:
paypal.Buttons({
style: {
shape: 'rect',
color: 'black',
layout: 'vertical',
label: 'subscribe'
},
createSubscription: function(data, actions) {
if (discordUser.value === "") {
alert("Introduce tu usuario de discord");
return;
}
slotDecremented = true;
alterSlots();
return actions.subscription.create({
'plan_id': 'P-ID' // here is my plan id
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
sendEmailToken(details.payer.email_address, discordUser.value, data.subscriptionID);
});
},
onCancel: function(data) {
alterSlots(true);
slotDecremented = false;
},
onError: function(data) {
if (!slotDecremented) {
return;
}
alterSlots(true);
slotDecremented = false;
}
}).render('#paypal-button-container');
the alterSlot() function makes an API call with AJAX to my specific endpoint, just extra information if neccesary
EDIT:
The sendEmailToken() function makes an AJAX request to an API hosted on my server, such that the server performs the correct action and being secure (just metadata for knowing what's going on in that part)
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
sendEmailToken(details.payer.email_address, discordUser.value, data.subscriptionID);
});
},
actions.order.capture() is for a client-side one-time payment button. It does not belong in a Subscribe button, as there is no order to capture.
See e.g. the PayPal Subscriptions documentation, which only has a basic success alert in its onApprove example: https://developer.paypal.com/docs/subscriptions/integrate/#create-the-subscription
Since it appears your intent is to perform a server-side operation such as sending an email after subscription approval, you should be activating said subscription from your server to ensure subscriptions don't become active without your server being correctly being notified of this fact. Here is some information: https://stackoverflow.com/a/65139331/2069605

Paypal error ppxo_no_token_passed_to_payment aka "No value passed to payment"

I have implemented paypal express checkout in my app and everything was running smooth until I had to change my credentials today. For testing I used my own paypal account but now it has to be switched with the company's one, so I created a REST app and swapped the debug and production keys. Suddenly when I try to pay I get ppxo_no_token_passed_to_payment, if I switch back to my old public key its still working. I suspect this is an issue over at paypal where I need to authorize or enable the app or something but sadly I can not remember...
Here is the code in question, but I do believe there is nothing wrong with it, as I said, if I put my old public key then it's still working fine.
getPaypalButton(container: any, paypal: any) {
return paypal.Button.render({
env: __DEV__ ? "sandbox" : "production",
style: this.style(),
// Pass the client ids to use to create your transaction on sandbox and production environments
client: {
// from https://developer.paypal.com/developer/applications/
sandbox: env.payments.paypal.sandbox,
production: env.payments.paypal.production
},
// Pass the payment details for your transaction
// See https://developer.paypal.com/docs/api/payments/#payment_create for the expected json parameters
payment: this.payment.bind(this),
// Display a "Pay Now" button rather than a "Continue" button
commit: true,
// Pass a function to be called when the customer completes the payment
onAuthorize: this.authorize.bind(this),
// Pass a function to be called when the customer cancels the payment
onCancel: this.cancel.bind(this)
}, container)
style() {
return {
label: 'paypal',
size: 'responsive', // small | medium | large | responsive
shape: 'rect', // pill | rect
color: 'blue', // gold | blue | silver | black
tagline: false
};
}
payment(data: any, actions: any) {
return actions.payment.create({
transactions: [
{
amount: {
total: i18n.currencies.toHumanReadable(this.moneyControl.internalInput.value, "EUR").toFixed(2),
currency: "EUR"
}
}
]
}).catch((error: any) => {
if (!this.moneyControl.internalInput.value) {
this.moneyControl.displayError("validation.required");
} else {
this.moneyControl.displayError("deposit.paypalerror");
}
});
}
authorize(data: any, actions: any) {
return web.request("/paypal", {
method: "POST",
data: {
token: data.paymentToken,
payment_id: data.paymentID,
payer_id: data.payerID
}
}).then((response: any) => {
console.log('The payment was completed!', response);
this.completed();
}).catch(function (error) {
console.log(error);
});
}
cancel(data: any) {
this.moneyControl.displayError("deposit.paypalcancel");
}
One thing to notice is that the thrown error says env: "production", however __DEV__ is true.
country: "US"
env: "production"
host: "192.168.0.100:8080"
lang: "en"
pageID: ...
path: "/"
prev_corr_ids: ""
referer: "192.168.0.100:8080"
timestamp: 1528128652378
uid: ...
ver: "4.0.199"
windowID: ...
From the docs, object passed to actions.payment.create function should include a payment key.
So, instead of the object you pass now, you should have:
return actions.payment.create({
payment: {
transactions: [
{
amount: {
total: i18n.currencies.toHumanReadable(this.moneyControl.internalInput.value, "EUR").toFixed(2),
currency: "EUR"
}
}
]
}
})

Paypal Sandbox App login error

I've a problem with my sandbox app. I integrated the script given for the paypal checkout express payment in my web app. This the script :
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<div id="paypal-button-container"></div>
<script>
var total = 0;
$.getJSON("/Home/getTotal", function (result) {
total = result;
});
// Render the PayPal
paypal.Button.render({
// Set your environment
env: 'sandbox', // sandbox | production
// Specify the style of the button
style: {
label: 'buynow',
fundingicons: true, // optional
branding: true // optional
},
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: 'AT9iydEDhcqfM_dhU8MR0lvkFgZBjD1oXQVrG-CR9CyK_vd-aXpNzEnyVV7um_hAPrkqQX8JhtjGCbBt'
},
// Wait for the PayPal button to be clicked
payment: function (data, actions) {
return actions.payment.create({
transactions: [
{
amount: { total: total, currency: 'USD' }
}
]
});
},
// Wait for the payment to be authorized by the customer
onAuthorize: function (data, actions) {
return actions.payment.execute().then(function () {
window.alert('Payment Complete!');
});
}
}, '#paypal-button-container');
</script>
This code displays a paypal button. When I click on the button, it shows me a login page to proceed to the payement. The problem is : I can't login on this page with a paypal account that I have. I read somewhere that only the sandbox's test accounts can be used to login on this page, but I want to let everyone who has a paypal account login in this page. What should I do ? Thank you for your answers!
I've found the solution : if you want to let everybody login into your payment's page, you've to pass to production mode.

How to config IPN for PayPal Express Checkout?

I would like use PayPal Express Checkout and I use the official client side example of PayPal.
https://developer.paypal.com/demo/checkout/#/pattern/client
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<div id="paypal-button-container"></div>
<script>
// Render the PayPal button
paypal.Button.render({
x
// Set your environment
env: 'sandbox', // sandbox | production
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: 'AZDxjDScFpQtjWTOUtWKbyN_bDt4OgqaF4eYXlewfBP4-8aqX3PiV8e1GWU6liB2CUXlkA59kJXE7M6R',
production: '<insert production client id>'
},
// Set to 'Pay Now'
commit: true,
// Wait for the PayPal button to be clicked
payment: function(actions) {
// Make a client-side call to the REST api to create the payment
return actions.payment.create({
transactions: [
{
amount: { total: '0.01', currency: 'USD' }
}
]
});
},
// Wait for the payment to be authorized by the customer
onAuthorize: function(data, actions) {
// Execute the payment
return actions.payment.execute().then(function() {
window.alert('Payment Complete!');
});
}
}, '#paypal-button-container');
</script>
My question is, how I can pass the notifiy_url to get the confirmation of payment and the data of the customer?
I assuming that onAuthorize function isn't enough.
If someone could clarify I will appreciate.
Thanks for help!
With the REST APIs you need to use Webhooks, not IPN. IPN is for the Classic APIs.

paypal checkout button get json response in javascript

In the paypal API reference page it says after creating a payment it will return a response. I would like to use the transaction information after payment is completed, but I'm not sure how to obtain this response json from the basic integration scenario here. After going through the documentation, I don't see where I can get this response. Am I missing a missing a option here? Thanks in advance.
The following is my code
paypal.Button.render({
// Set your environment
env: 'sandbox', // sandbox | production
// Pass the client ids to use to create your transaction on sandbox and production environments
client: {
sandbox: 'removed for security', // from https://developer.paypal.com/developer/applications/
production: 'removed for security' // from https://developer.paypal.com/developer/applications/
},
// Pass the payment details for your transaction
// See https://developer.paypal.com/docs/api/payments/#payment_create for the expected json parameters
payment: function() {
return paypal.rest.payment.create(this.props.env, this.props.client, {
transactions: [
{
amount: {
total: total,
currency: 'USD'
},
custom: purchaseOrderNumber
}
]
});
},
// Display a "Pay Now" button rather than a "Continue" button
commit: true,
// Pass a function to be called when the customer completes the payment
onAuthorize: function(data, actions) {
console.log("data", data);
console.log("actions", actions);
return actions.payment.execute().then(function() {
console.log('The payment was completed!');
//use transaction information from json response here
});
},
// Pass a function to be called when the customer cancels the payment
onCancel: function(data) {
console.log('The payment was cancelled!');
}
}, '#paypal-button');
EDIT:
console results for data
{
"paymentToken":"EC-8T213183GM917341N",
"payerID":"784ARKSZGWBPG",
"paymentID":"PAY-00M809553A479072XLEBN4RI",
"intent":"sale",
"returnUrl":"https://www.sandbox.paypal.com/?paymentId=PAY-00M809553A479072XLEBN4RI&token=EC-8T213183GM917341N&PayerID=784ARKSZGWBPG"
}
console results for actions
{
"payment":{}
}
//see below for console screenshot
EDIT2:
request to paypal framework and response
It would appear that The last picture is the response that I actually need. Is there a way to obtain this data from a basic paypal button?
Add a parameter to actions.payment.execute().then() to catch the response
paypal.Button.render({
// Set your environment
env: 'sandbox', // sandbox | production
// Pass the client ids to use to create your transaction on sandbox and production environments
client: {
sandbox: 'removed for security', // from https://developer.paypal.com/developer/applications/
production: 'removed for security' // from https://developer.paypal.com/developer/applications/
},
// Pass the payment details for your transaction
// See https://developer.paypal.com/docs/api/payments/#payment_create for the expected json parameters
payment: function() {
return paypal.rest.payment.create(this.props.env, this.props.client, {
transactions: [
{
amount: {
total: total,
currency: 'USD'
},
custom: purchaseOrderNumber
}
]
});
},
// Display a "Pay Now" button rather than a "Continue" button
commit: true,
// Pass a function to be called when the customer completes the payment
onAuthorize: function(data, actions) {
return actions.payment.execute().then(function(param) {
console.log('The payment was completed!');
//param is the json response
});
},
// Pass a function to be called when the customer cancels the payment
onCancel: function(data) {
console.log('The payment was cancelled!');
}
}, '#paypal-button');
The setup seems all good, all you need now is to decide what and how you want to handle your response.
In the onAuthorize function you can do something like (github paypal checkout button) this for all of your aproved sales (check for data.status to be approved (credit card) or created (for payment with paypal), then you should have a data.payer with all the info):
jQuery.post('/my-api/execute-payment', { paymentID: data.paymentID, payerID: data.payerID });
.done(function(data) { /* Go to a success page */ })
.fail(function(err) { /* Go to an error page */ });
or use directly the data json object in the function.

Categories

Resources