Paylike modal amount parameter - javascript

I'm currently testing the paylike's web sdk and I can use the sandbox easy. But how can I avoid the user can change the amount on the client side? The amount parameter is required, but how can I ensure about after a success callback about the amount? Can I get it from the server side?
The following code is fine, but I have problem with the amount parameter
<script src="//sdk.paylike.io/3.js"></script>
<script>
var paylike = Paylike('your key');
paylike.popup({
currency: 'DKK',
amount: 1000,
}, function( err, res ){
if (err)
return console.log(err);
console.log(res.transaction.id);
alert('Thank you!');
});
</script>

Two steps are important regarding transactions. The first step is authorization.
Authorization is done with the code you added here, on the frontend. The user can tamper with the amount, but this is merely a reservation and is not taking funds from the payer credit card.
The second step is called capture. You can only capture the funds from the Paylike dashboard, or via your server. When you do that, you generally send the same amount that you initially wanted the user to pay, and if the authorization were less, you would get an error. You can also fetch the transaction to inspect the amount that was authorized if you want to reject an order, for example. You can also send a custom parameter that you might use to validate on the server, similar to a checksum if you want to.
You have a private key, which users are not able to get, so that makes it safe. The 2 step approach is a validation on its own, but as I mentioned, you can also inspect the transaction.
You can check the API docs here: https://github.com/paylike/api-docs, where you will also find links to client-side SDKs.
If you are using PHP, using the PHP library (which I maintain) you can do this to inspect a transaction:
$paylike = new \Paylike\Paylike($private_api_key);
$transactions = $paylike->transactions();
$transaction = $transactions->fetch($transaction_id);
The transaction variable will look like this:
{
"id":"5da8272132aad2256xxxxxxx",
"test":true,
"merchantId":"594d3c455be12d547xxxxxx",
"created":"2019-10-17T08:32:34.362Z",
"amount":35,
"refundedAmount":0,
"capturedAmount":0,
"voidedAmount":0,
"pendingAmount":35,
"disputedAmount":0,
"card":{
"id":"5da82743735e61604xxxxxxx",
"bin":"410000",
"last4":"0000",
"expiry":"2023-11-30T22:59:59.999Z",
"code":{
"present":true
},
"scheme":"visa"
},
"tds":"none",
"currency":"JPY",
"custom":{
"email":"customer#example.com",
"orderId":"Could not be determined at this point",
"products":[
[
{
"ID":"48",
"name":"Hoodie with Pocket",
"quantity":"1"
}
]
],
"customer":{
"name":"John Doe",
"email":"customer#example.com",
"phoneNo":"020 91X XXXX",
"address":"123 Main Street, New York, NY 10030",
"IP":"10.0.2.2"
},
"platform":{
"name":"WordPress",
"version":"5.2.4"
},
"ecommerce":{
"name":"WooCommerce",
"version":"3.7.1"
},
"paylikePluginVersion":"1.7.2"
},
"recurring":false,
"successful":true,
"error":false,
"descriptor":"PHP API WRAPPER TEST",
"trail":[
]
}

Related

Integrating GiroPay and SOFORT via Stripe

I tried to integrate the other offered payments offered by stripe. I followed the docs but it seems I overread something (read everthing like 10 times).
First I activated the payment methods.
I added the library: <script src="https://js.stripe.com/v3/"></script>
I created a Stripe client: var stripe = Stripe('pk_live_512dfvL8d63Kcs9d5Lsp548c6Sp'); (tried this with both test and publishable key)
I added an instance of Elements: var elements = stripe.elements(); (Not using it though)
Depending on the choosen payment something else gets triggered. Well here is my code:
function buyingProcess() {
console.log(choosenPaymentMethod);
if (choosenPaymentMethod == "mastervisa") {
// This works like a charm
} else if (choosenPaymentMethod == "giropay") {
stripe.createSource({
type: 'giropay',
amount: 1099,
currency: 'eur',
owner: {
name: 'Jenny Rosen',
},
redirect: {
return_url: 'https://shop.example.com/crtA6B28E1',
},
}).then(function(result) {
console.log(result);
// handle result.error or result.source
});
}
}
The last console.log function shows me the source object. While using the test key console.log(result.error) stated out, that I have to use the publishable key.
Thanks for any help. I wrote the Stripe Team. yesterday at this time but I apreciate any help. Thanks.
If you are seeing a source object in your console, then you have successfully created a source! The next step is to set up a webhook endpoint, and listen for a source.chargeable event.
Once you have received that your customer has authorized the source to be charged, and you can create a charge on your server using your secret key:
https://stripe.com/docs/sources/best-practices#charge-creation
You can delete var elements = stripe.elements(); as you don't need Elements to create sources, just the Stripe.js library.

MeteorJS publish query not working

I try to use Meteor.publish (server side) with this query:
return Meteor.users.find({_id:{$ne:this.userId}});
When I do a query on the client side with Meteor.subscribe, it works:
return Meteor.users.find({_id:{$ne:Meteor.userId()}});
so why is it not working on the server side...It seems I can only query it once its on the client side...The problem is, I do not want to download the entire collection because I will have over 20,000 users. Do publish methods not allow '$' queries?
Also how can I attach this to my following query statement:
return Meteor.users.find({"profile.loc":{ $near: [ to[0].profile.loc.lat, to[0].profile.loc.lon ], $maxDistance: (1/111.2)*250}});
As the answer above states, you would anyway publish 19,999 users if you do what you wrote.
Your question is in 2 parts though, and you should really address both with one query: to do this you should have a publication with parameter:
Meteor.publish('users', function(location) {
return Meteor.users.find(
{_id: {$ne: this.userId},
"profile.loc":{
$near: [ location.lat, location.lon ],
$maxDistance: (1/111.2)*250}
}
});
That will screen users on the server who match the location criteria.
On the client side you subscribe to it with:
location = {lon: 12.123, lat: 110.2};
Meteor.subscribe('users', location);
or the object of your choice.
The publish method does allow $ queries. What your publication is doing is publishing all users whose id is not equal to this.userId. If you have 20,000 users, this method will publish data for 19,999 users.
If you only want to publish the current user's data then try:
Meteor.publish('userData', function() { return Meteor.users.find(this.userId) };

Mongo check if a document already exists

In the MEAN app I'm currently building, the client-side makes a $http POST request to my API with a JSON array of soundcloud track data specific to that user. What I now want to achieve is for those tracks to be saved to my app database under a 'tracks' table. That way I'm then able to load tracks for that user from the database and also have the ability to create unique client URLs (/tracks/:track)
Some example data:
{
artist: "Nicole Moudaber"
artwork: "https://i1.sndcdn.com/artworks-000087731284-gevxfm-large.jpg?e76cf77"
source: "soundcloud"
stream: "https://api.soundcloud.com/tracks/162626499/stream.mp3?client_id=7d7e31b7e9ae5dc73586fcd143574550"
title: "In The MOOD - Episode 14"
}
This data is then passed to the API like so:
app.post('/tracks/add/new', function (req, res) {
var newTrack;
for (var i = 0; i < req.body.length; i++) {
newTrack = new tracksTable({
for_user: req.user._id,
title: req.body[i].title,
artist: req.body[i].artist,
artwork: req.body[i].artwork,
source: req.body[i].source,
stream: req.body[i].stream
});
tracksTable.find({'for_user': req.user._id, stream: req.body[i].stream}, function (err, trackTableData) {
if (err)
console.log('MongoDB Error: ' + err);
// stuck here - read below
});
}
});
The point at which I'm stuck, as marked above is this: I need to check if that track already exists in the database for that user, if it doesn't then save it. Then, once the loop has finished and all tracks have either been saved or ignored, a 200 response needs to be sent back to my client.
I've tried several methods so far and nothing seems to work, I've really hit a wall and so help/advice on this would be greatly appreciated.
Create a compound index and make it unique.
Using the index mentioned above will ensure that there are no documents which have the same for_user and stream.
trackSchema.ensureIndex( {for_user:1, stream:1}, {unique, true} )
Now use the mongoDB batch operation to insert multiple documents.
//docs is the array of tracks you are going to insert.
trackTable.collection.insert(docs, options, function(err,savedDocs){
//savedDocs is the array of docs saved.
//By checking savedDocs you can see how many tracks were actually inserted
})
Make sure to validate your objects as by using .collection we are bypassing mongoose.
Make a unique _id based on user and track. In mongo you can pass in the _id that you want to use.
Example {_id : "NicoleMoudaber InTheMOODEpisode14",
artist: "Nicole Moudaber"
artwork: "https://i1.sndcdn.com/artworks-000087731284-gevxfm-large.jpg?e76cf77"
source: "soundcloud"
stream: "https://api.soundcloud.com/tracks/162626499/stream.mp3? client_id=7d7e31b7e9ae5dc73586fcd143574550"
title: "In The MOOD - Episode 14"}
_id must be unique and won't let you insert another document with the same _id. You could also use this to find the record later db.collection.find({_id : NicoleMoudaber InTheMOODEpisode14})
or you could find all tracks for db.collection.find({_id : /^NicoleMoudaber/}) and it will still use the index.
There is another method to this that I can explain if you dont' like this one.
Both options will work in a sharded environment as well as a single replica set. "Unique" indexes do not work in a sharded environment.
Soundcloud API provides a track id, just use it.
then before inserting datas you make a
tracks.find({id_soundcloud : 25645456}).exec(function(err,track){
if(track.length){ console.log("do nothing")}else {//insert}
});

Angular.js accessing and displaying nested models efficiently

I'm building a site at the moment where there are many relational links between data. As an example, users can make bookings, which will have booker and bookee, along with an array of messages which can be attached to a booking.
An example json would be...
booking = {
id: 1,
location: 'POST CDE',
desc: "Awesome stackoverflow description."
booker: {
id: 1, fname: 'Lawrence', lname: 'Jones',
},
bookee: {
id: 2, fname: 'Stack', lname: 'Overflow',
},
messages: [
{ id: 1, mssg: 'For illustration only' }
]
}
Now my question is, how would you model this data in your angular app? And, while very much related, how would you pull it from the server?
As I can see it I have a few options.
Pull everything from the server at once
Here I would rely on the server to serialize the nested data and just use the given json object. Downsides are that I don't know what users will be involved when requesting a booking or similar object, so I can't cache them and I'll therefore be pulling a large chunk of data every time I request.
Pull the booking with booker/bookee as user ids
For this I would use promises for my data models, and have the server return an object such as...
booking = {
id: 1,
location: 'POST CDE',
desc: "Awesome stackoverflow description."
booker: 1, bookee: 2,
messages: [1]
}
Which I would then pass to a Booking constructor, which would resolve the relevant (booker,bookee and message) ids into data objects via their respective factories.
The disadvantages here are that many ajax requests are used for a single booking request, though it gives me the ability to cache user/message information.
In summary, is it better practise to rely on a single ajax request to collect all the nested information at once, or rely on various requests to 'flesh out' the initial response after the fact.
I'm using Rails 4 if that helps (maybe Rails would be more suited to a single request?)
I'm going to use a system where I can hopefully have the best of both worlds, by creating a base class for all my resources that will be given a custom resolve function, that will know what fields in that particular class may require resolving. A sample resource function would look like this...
class Booking
# other methods...
resolve: ->
booking = this
User
.query(booking.booker, booking.bookee)
.then (users) ->
[booking.booker, booking.bookee] = users
Where it will pass the value of the booker and bookee fields to the User factory, which will have a constructor like so...
class User
# other methods
constructor: (data) ->
user = this
if not isNaN(id = parseInt data, 10)
User.get(data).then (data) ->
angular.extend user, data
else angular.extend this, data
If I have passed the User constructor a value that cannot be parsed into a number (so this will happily take string ids as well as numerical) then it will use the User factorys get function to retrieve the data from the server (or through a caching system, implementation is obviously inside the get function itself). If however the value is detected to be non-NaN, then I'll assume that the User has already been serialized and just extend this with the value.
So it's invisible in how it caches and is independent of how the server returns the nested objects. Allows for modular ajax requests and avoids having to redownload unnecessary data via its caching system.
Once everything is up and running I'll write some tests to see whether the application would be better served with larger, chunked ajax requests or smaller modular ones like above. Either way this lets you pass all model data through your angular factories, so you can rely on every record having inherited any prototype methods you may want to use.

BreezeJS Database Connection Security

Is interacting with the database in BreezeJS secure?
For example, if I use the following code, it clearly shows the Database name, tables and the query itself directly in the javascript. Does it make a secure connection to the database?
var manager = new breeze.EntityManager('api/northwind');
var query = new breeze.EntityQuery()
.from("Employees");
manager.executeQuery(query).then(function(data){
ko.applyBindings(data);
}).fail(function(e) {
alert(e);
});
The line "var manager = new breeze.EntityManager('api/northwind');" doesn't says anything about the database. It is the route to the MVC controller ( webapi in this case ).
And the line "var query = new breeze.EntityQuery().from("Employees");" does not have any relation to the database, it's the name of a methd in you controller.
Having in consideration that you can use the mechanics that mvc provides to securize the controller ( like the Authorize attribute ), I don't see any risk using breeze.
The security of breeze.js in the end falls to the programming language used to actually run the queries. As I saw in the docs, it's mainly for ASP.
Checking the TODO sample, doing an action calls /api/todos/SaveChanges with a payload of:
{
"entities": [{
"Id": 2908,
"Description": "Wine",
"CreatedAt": "2012-08-22T09:06:00.000Z",
"IsDone": true,
"IsArchived": false,
"entityAspect": {
"entityTypeName": "TodoItem:#Todo.Models",
"entityState": "Modified",
"originalValuesMap": {
"IsDone": false
},
"autoGeneratedKey": {
"propertyName": "Id",
"autoGeneratedKeyType": "Identity"
}
}
}],
"saveOptions": {
"allowConcurrentSaves": false
}
}
The only sensitive thing there is the Id. Even if you don't use JavaScript you still have to expose some data in one way or another. I'm not saying this is best way of doing it, but this does not have any immediate drawbacks that I can think of. At least not in the JS component.
It falls on behalf of the application (just like in any situation) to sanitize any input from users. This includes any AJAX calls, be it done with breeze or not.
If you can comment with some of the ASP code used to sanitize/run the queries, we can offer more insight on the matter.
So in summary. No issues. JavaScript by itself does NOT connect to the database so it does not have any inherent security issues.

Categories

Resources