PayPal Developer Issues With Comma - javascript

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.

Related

How to pass a JS variable to a second script without it being accessible or mutable from the console?

I have two scripts, one to calculate a total for the items in a shopping cart and one to pass the variable to a PayPal API. Is it possible to pass this variable from the shopping cart script to the PayPal script without someone being able to change its value from the console? Otherwise people would be able to determine how much they would like to pay for the items and send the info through to PayPal. Here is my code:
Shopping Cart:
```
var total = 0; //Total for all the items in the shopping cart, value is passed off to paypal-buttons.js to complete the checkout.
// Calculates values items in cart depending on quantity
function addData(clicked_id, quantity) {
var price = values[clicked_id].price;
var qty = document.getElementById(quantity).value;
var lineTotal = price * qty;
total += lineTotal;
document.getElementById("total").innerHTML = total;
addRow(clicked_id, qty, lineTotal);
}
PayPal:
paypal.Buttons({
style: {
shape: 'rect',
color: 'gold',
layout: 'vertical',
label: 'checkout',
},
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: total
}
}]
});
},
onApprove: function(data, actions) {
return actions.order.capture().then(function(details) {
alert('Thank you for your order ' + details.payer.name.given_name + ', your equipment is on its way!');
});
}
}).render('#paypal-button-container');
I would like to send the value of 'total' from the shopping cart to PayPal. I might try using obfuscation as a partial solution but I would like it to be more secure then that.
The only way to secure against malicious client-side changes is to switch to a server-side integration for the API calls to set up and capture the payment. Here is a demo pattern of the UI:
https://developer.paypal.com/demo/checkout/#/pattern/server
Here is a guide to implementing the necessary v2/orders API calls from your server:
https://developer.paypal.com/docs/checkout/reference/server-integration/

paypal checkout using client integration

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!!

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>

Clear cookies or logout so the next scenario is not logged in

How to Clear cookies after the test so the next test I run is not already logged in. I am trying to test logins and the solution below i am trying does not work. It feels this is the cucumber issue?
var myHooks = function () {
// Synchronous
this.Before(function (scenario) {
this.count = 0;
return this.driver.open();
});
// Asynchronous Callback
this.Before(function (scenario, callback) {
var world = this;
tmp.dir({unsafeCleanup: true}, function(error, dir) {
if (error) {
callback(error);
} else {
world.tmpDir = dir;
callback();
}
});
});
// Asynchronous Promise
this.After(function (scenario) {
// Assuming this.driver is a selenium webdriver
return this.driver.close();
});
};
module.exports = myHooks;
I also tried to change the config file and added shardTestFiles: true but no luck. What can i add in the config file so it restarts the browser after each cucumber scenario? Note that i am adding multiple examples in the feature file for login
const crew = require('serenity-js/lib/stage_crew');
exports.config = {
getPageTimeout: 30000,
seleniumAddress: 'http://localhost:4444/wd/hub',
baseUrl: 'https://abcccc.com/',
specs: [ 'features/**/*.feature' ],
shardTestFiles: true,
multicapabilities: [{
'browserName': 'chrome'
/* }, {
'browserName': 'firefox'
}, {
'browserName': 'internet explorer' */
}],
// maxSession: 2,
framework: 'custom',
frameworkPath: require.resolve('serenity-js'),
serenity: {
crew: [
crew.serenityBDDReporter(),
crew.photographer(),
crew.consoleReporter()
]
},
cucumberOpts: {
require: [ './features/step_definition/*.ts' ],
format: [ "pretty" ],
compiler: 'ts:ts-node/register'
}
};
And here is my feature file, it seems like this might be a cucumber issue?
Feature: Add item and place the order for that item
In order to wear something new
As an online shopping customer
I want to be able to add an item to my shopping bag and then place the order
Scenario Outline: Add an item to shopping bag to place the order using PaypalPro
Given "<User>" is logged in to his "<EnvName>" account
When he searches item with SKU "<SKUID>" from "<Gender>" section and adds it to his shopping bag
Then "<User>" can place the order
Examples:
| User | EnvName | SKUID | Gender |
| user1 | Test | 51230M000010 | men |
| user2 | Test | 51230M000010 | women |

Categories

Resources