paypal checkout using client integration - javascript

I have the following sample code from the paypal dev documentation.
<div id="paypal-button-container"></div>
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
// Render the PayPal button
paypal.Button.render({
// Set your environment
env: 'sandbox', // sandbox | production
// Specify the style of the button
style: {
layout: 'vertical', // horizontal | vertical
size: 'medium', // medium | large | responsive
shape: 'rect', // pill | rect
color: 'gold' // gold | blue | silver | white | black
},
// Specify allowed and disallowed funding sources
//
// Options:
// - paypal.FUNDING.CARD
// - paypal.FUNDING.CREDIT
// - paypal.FUNDING.ELV
funding: {
allowed: [
paypal.FUNDING.CARD,
paypal.FUNDING.CREDIT
],
disallowed: []
},
// Enable Pay Now checkout flow (optional)
commit: true,
// 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>'
},
payment: function (data, actions) {
return actions.payment.create({
payment: {
transactions: [
{
amount: {
total: '0.01',
currency: 'USD'
}
}
]
}
});
},
onAuthorize: function (data, actions) {
return actions.payment.execute()
.then(function () {
window.alert('Payment Complete!');
});
}
}, '#paypal-button-container');
</script>
I've replaced the sandbox client ID with my own ID. When I double click on the HTMl file and open it locally on my web browser, something weird happens. When I click on the checkout box and enter my sandbox buyer's credentials, the buyer's bank account gets deducted. However, when I log onto my sandbox facilitator, it's bank account doesn't get updated.
Could someone please help me out? Thanks!!

Related

Paypal - Split payment and send it to different PayPal account

My goal is to get 5% of the amount and send it to Company PayPal account, and the other 95% will send directly to the Paypal of the other user. How can I do it in PayPal Code?
Here is my PayPal code.
paypal.Button.render({
style: {
size: 'responsive',
color: 'black'
},
env: 'sandbox', // 'sandbox' Or 'production',
client: {
sandbox: 'MyClientID',
production: ''
},
locale: 'en_US',
commit: true, // Show a 'Pay Now' button
payment: function(data, actions) {
// Set up the payment here
return actions.payment.create({
payment: {
transactions: [{
amount: { total: '1.00', currency: 'USD' }
}]
}
});
},
onAuthorize: function(data, actions) {
// Execute the payment here
return actions.payment.execute().then(function(payment) {
console.log(payment);
});
}
}, '#paypal-button');
Please help me.. Thank you.
No it's not possible with just a Paypal button. Paypal has its own way to split the money to whichever account you want to set it to and you'll need to use the Payouts API.
Note: It used to be "Adaptive Payments" but they (Paypal) stopped allowing new integrations.
According to the documentation: https://developer.paypal.com/docs/api/payments.payouts-batch/v1/
Use the Payouts API to make PayPal payments to multiple PayPal
accounts in a single API call. The Payouts API is a fast, convenient
way to send commissions, rebates, rewards, and general disbursements.
Please note that you'll need a paypal business account to be elligible for this: https://developer.paypal.com/docs/payouts/integrate/prerequisites/#

Simulate PayPal errors in a sandbox account

I'm integrating PayPal payment on a web application I'm developing. I need to create an authorization for a transaction where I lock an amount of money (let's say 20€), then at the end of the transaction I complete the transaction and I take only the money that I need to take (so if the transaction's final cost is 15€, I give back 5€ to the user).
This workflow is currently working on a sandbox account, but now I wanted to test some errors that may occur while starting a new transaction, like for instance when the user doesn't have the sufficient amount of money (20€) that I need to lock in order to start a new transaction.
I found this documentation (https://developer.paypal.com/docs/api/test-values/#invoke-negative-testing) where it is stated To trigger the SENDER_EMAIL_UNCONFIRMED simulation response, set the items[0]/note value to ERRPYO002 in the POST v1/payments/payouts call. with the following code:
curl -X POST https://api.sandbox.paypal.com/v1/payments/payouts \
-H "content-type: application/json" \
-H "Authorization: Bearer Access-Token" \
-d '{
"sender_batch_header": {
"sender_batch_id": "1524086406556",
"email_subject": "This email is related to simulation"
},
"items": [
{
"recipient_type": "EMAIL",
"receiver": "payouts-simulator-receiver#paypal.com",
"note": "ERRPYO002",
"sender_item_id": "15240864065560",
"amount": {
"currency": "USD",
"value": "1.00"
}
}]
}'
So I guess that I need to pass an error code (like ERRPYO002) to a note field in my request body.
I'm using the checkout sdk, and my js code currently looks like this:
const buttonOpts = {
env: 'sandbox',
client: { production: $scope.key, sandbox: $scope.key },
style: {
label: 'paypal',
size: 'medium',
shape: 'rect',
color: 'blue',
tagline: false,
},
validate: actions => {
// stuff
},
payment: (data, actions) => {
return actions.payment.create({
intent: 'authorize',
payer: { payment_method: 'paypal' },
transactions: [
{
amount: {
total: '20.00',
currency: 'EUR',
},
description: 'My description',
},
],
});
},
onAuthorize: data => {
// Sending data.paymentID and data.payerID to my backend to confirm the new transaction
},
onCancel: () => {
// stuff
},
onError: err => {
console.log(err);
// stuff
},
};
Paypal.Button.render(buttonOpts, '#paypal-button');
I guess that I need to pass the code needed to simulate the error to my actions.payment.create object parameter, but I didn't find where exactly since my workflow is different that the one in the docs.
These are the codes that PayPal allows you to use for error testing:
https://developer.paypal.com/docs/payouts/integrate/test-payouts/#test-values
Any help is appreciated.
Thanks a lot.
Ok, I've actually found out how to solve this problem right after I posted this question.
I'll just put my solution here for anyone that may have this problem in the future.
The option object I posted is actually correct as it is now, so after the user confirms that he/she wants to start a new transaction I get the payerID and the paymentID to send to my backend.
On my backend function I changed my code so that it is as follows:
const paypal = require('paypal-rest-sdk');
const paymentId = event.paymentID;
const payerId = { payer_id: event.payerID };
paypal.configure({
mode: process.env.PAYPAL_ENVIRONMENT, //sandbox or live
client_id: '<MY_CLIENT_ID>',
client_secret: '<MY_CLIENT_SECRET>',
});
paypal.payment.execute(
paymentId,
payerId,
// START NEW CODE
{
headers: {
'Content-Type': 'application/json',
'PayPal-Mock-Response': '{"mock_application_codes": "INSUFFICIENT_FUNDS"}',
},
},
// END NEW CODE
(error, payment) => {
console.error(JSON.stringify(error));
console.error(JSON.stringify(payment));
if (error) {
/*
{
"response": {
"name": "INSUFFICIENT_FUNDS",
"message": "Buyer cannot pay - insufficient funds.",
"information_link": "https://developer.paypal.com/docs/api/payments/#errors",
"debug_id": "a1b2c3d4e5f6g",
"details": [
{
"issue": "The buyer must add a valid funding instrument, such as a credit card or bank account, to their PayPal account."
}
],
"httpStatusCode": 400
},
"httpStatusCode": 400
}
*/
return callback('unhandled_error', null);
}
if (payment.state === 'approved' && payment.transactions && payment.transactions[0].related_resources && payment.transactions[0].related_resources[0].authorization) {
return callback(null, payment.transactions[0].related_resources[0].authorization.id);
}
console.log('payment not successful');
return callback('unhandled_error', null);
}
);
In the request headers you just have to put an header called PayPal-Mock-Response that contains the error code you want to test, and that's it.
Hope this'll help somebody!

PayPal Developer Issues With Comma

I have run into an error. I am using https://developer.paypal.com/docs/checkout/integrate/ to implement the PayPal payment into my ASP.NET MVC Project. My currency is a float, and the project has prices like 150,99. Whenever this price goes through, it will say that the price is 99,00 EUR. It only reads what is behind the comma. Whenever the price is 190,00, it will correctly say that the price is 190,00 EUR. How do I fix this?
The JavaScript on the front-end is currently this:
<script>
var totalPrice = (#ViewBag.totalPrice);
</script>
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
// Render the PayPal button
paypal.Button.render({
// Set your environment
env: 'sandbox', // sandbox | production
// Specify the style of the button
style: {
layout: 'horizontal', // horizontal | vertical
size: 'large', // medium | large | responsive
shape: 'pill', // pill | rect
color: 'black' // gold | blue | silver | white | black
},
// Specify allowed and disallowed funding sources
//
// Options:
// - paypal.FUNDING.CARD
// - paypal.FUNDING.CREDIT
// - paypal.FUNDING.ELV
funding: {
allowed: [
paypal.FUNDING.CARD,
paypal.FUNDING.CREDIT
],
disallowed: []
},
// Enable Pay Now checkout flow (optional)
commit: true,
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: '<removed>',
production: '<insert production client id>'
},
payment: function (data, actions) {
return actions.payment.create({
payment: {
transactions: [
{
amount: {
total: totalPrice,
currency: 'EUR'
}
}
]
}
});
},
onAuthorize: function (data, actions) {
return actions.payment.execute()
.then(function () {
window.alert('Payment Complete!');
});
}
}, '#paypal-button-container');
</script>
And back-end for the price is like this:
[HttpGet]
public IActionResult Index()
{
...
float totalPrice = 0;
float sendcost = 2.95f;
...
foreach(ShoppingCartModel item in model)
{
item.subtotal = item.qty * item.price;
totalPrice += item.subtotal;
}
if(totalPrice < 100)
{
ViewBag.totalPrice = totalPrice + sendcost;;
}
else
{
ViewBag.totalPrice = totalPrice;
}
}
}
...
}
The official answer is that your web app's language setting causes the server to output numerical values with a comma as decimal separator. So
var totalPrice = (#ViewBag.totalPrice);
ends up
var totalPrice = (150,99);
in the browser and since JavaScript has something called a comma operator, totalPrice is now 99.
To fix this on the server side, you can change the locale used for formatting to English by adding
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.GetCultureInfo("en-US");
to the Configure() method in Startup.cs.

Paypal Express Checkout: Recurring payments on specific date

I am attempting to setup our website to accept recurring payments on a specific date (£5 on 1st June every year) regardless of when the user initially signs up (except for the month of May, then thier first rebill will be on 1st June the following year)
My searches so far have yielded that Express Checkout (checkout.js) is probably my best option.
I have managed to, in sandbox mode, take the initial payment of £5, but can't find any documentation on how to setup the recurring payment.
Code below
paypal.Button.render(
{
env: "sandbox", // 'production' Or 'sandbox',
// Pass the client ids to use to create your transaction on sandbox and production environments
client: {
sandbox:
[REDACTED], // from https://developer.paypal.com/developer/applications/
production:
[REDACTED] // 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(data, actions) {
return actions.payment.create({
transactions: [
{
amount: {
total: "5.00",
currency: "GBP"
}
}
]
});
},
// 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);
console.log(actions);
return actions.payment.execute().then(function(response) {
console.log("The payment was completed!");
});
},
// Pass a function to be called when the customer cancels the payment
onCancel: function(data) {
console.log("The payment was cancelled!");
}
},
"#paypal-button"
);

pass amount total to PayPal express checkout

I have the express checkout button on my ASP.NET webforms webpage but can't seem to figure out how to pass the total variable (stored in a label on the page) to the PayPal popup when the button is clicked.
I know this question has been asked already (How Can pass order Total to (amount: { total: '0.01', currency: 'USD' } ) in paypal) but the answer makes little sense to me and doesn't go into as much detail as I need as a beginner programmer.
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
paypal.Button.render({
env: 'sandbox', // sandbox | production
style: {
label: 'pay',
size: 'small', // small | medium | large | responsive
shape: 'rect', // pill | rect
color: 'gold' // gold | blue | silver | black
},
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: 'AWDwdGr-KZK4jJi0WBUZmFowgG6oCtLpNDxtXuiOfAT1UdNUYeSlvoXYkrKW7SRdcYqqjHCo7IcYPmJf',
production: 'Production ClientID'
},
// payment() is called when the button is clicked
payment: function(data, actions) {
// Make a call to the REST api to create the payment
return actions.payment.create({
payment: {
transactions: [
{
amount: { total: '0.01' , currency: 'EUR' }
}
]
}
});
},
// onAuthorize() is called when the buyer approves the payment
onAuthorize: function(data, actions) {
// Make a call to the REST api to execute the payment
return actions.payment.execute().then(function() {
window.alert('Payment Complete!');
});
}
}, '#paypal-button-container');
</script>
Could someone please give me some guidance on how I can go about doing this?
The answer you linked does explain this pretty well but as you wanted more explanation, in WebForms you can use asp.net inline server tags to access elements from your page as long as they are on an aspx file. The syntax is as follows:
<%=ElementName.Property%>
This allows you to either access the value directly or assign it to a javascript variable. In your case either should work fine, for elements such as labels and things that contain text the property you are looking for will generally be innerHTML or innerText, so the following should give you the result you need:
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://www.paypalobjects.com/api/checkout.js"></script>
<script>
paypal.Button.render({
env: 'sandbox', // sandbox | production
style: {
label: 'pay',
size: 'small', // small | medium | large | responsive
shape: 'rect', // pill | rect
color: 'gold' // gold | blue | silver | black
},
// PayPal Client IDs - replace with your own
// Create a PayPal app: https://developer.paypal.com/developer/applications/create
client: {
sandbox: 'AWDwdGr-KZK4jJi0WBUZmFowgG6oCtLpNDxtXuiOfAT1UdNUYeSlvoXYkrKW7SRdcYqqjHCo7IcYPmJf',
production: 'Production ClientID'
},
// payment() is called when the button is clicked
payment: function(data, actions) {
// Make a call to the REST api to create the payment
return actions.payment.create({
payment: {
transactions: [
{
amount: { total: '<%=TheNameOfYourLabel.innerText%>' , currency: 'EUR' }
}
]
}
});
},
// onAuthorize() is called when the buyer approves the payment
onAuthorize: function(data, actions) {
// Make a call to the REST api to execute the payment
return actions.payment.execute().then(function() {
window.alert('Payment Complete!');
});
}
}, '#paypal-button-container');
</script>

Categories

Resources