The Braintree documentation says you create an environment as in their example var gateway=braintree.connect(environmental variables) and then create a clientToken by doing
gateway.clientToken.generate({}, function (err, response) {
var clientToken = response.clientToken;
});
Then their example says to insert the client token into the form used for payment
braintree.setup("CLIENT-TOKEN-FROM-SERVER", "custom", {id: "checkout"});
but they also state that clientToken is an object. I do not see anywhere how to get the token value and the return value is only a boolean. I do find that gateway.clientToken is reported as an object by using typeof().
On Stackoverflow, I see a couple of people saying the clientToken object is supposed to be a base64 encoded value but how you do this? Shouldn't Braintree's code do that?
So I'm missing a step somewhere or I can't find the right documentation but I'm definitely lost.
EDIT: Going by the response from Braintree, in the answers below, clientToken is not being filled by response.clientToken in any of the forms I've attempted this, which is many. Looking at examples from all over the web, which are few,and Braintree's light documentation, looks like I'm doing everything right.
EDIT2: My solution to the problem is in my answer below.
The problem lies in where you put the code to interact with Braintree within any node.js calls you make. In my case, I had it inside http.createServer so I could write values out while debugging this but some part of all this won't let that work. I haven't figured the exact details yet.
Also, the example code from Braintree shows clientToken inside the gateway.clientToken.generate() call which would lead me to think that's where it belongs even while not understanding how I was to extract that token value. So moving clientToken outside of that call, something I thought I once tried, solved this at least in part.
I say "in part" because you are to create a new token with every new customer and that can't be accomplished this way. I still need to determine how to generate a new token with every new customer visit. It may be only a matter of making it another function call but I haven't tried it yet.
In addition, I'm still not clear about whether a new customer needs to be created. I read the answer is no but I've also read the answer is yes so confusion reigns but this is probably a different question topic.
I work at Braintree. If you have more detailed questions, please get in touch with our support team.
It sounds like you're confusing gateway.clientToken which is the object that allows you to get a client token, and the client token itself, which is what is received by gateway.clientToken.generates callback -- response.clientToken.
Once you have the token (here, var clientToken), you need to get it to your client. From the "Hello, Server!" docs:
There are a number of ways to get your client token into JavaScript so you can setup Braintree. Many people choose to interpolate the client token into the view which contains the JavaScript to setup Braintree.
Related
My main function is I am creating a link-shortening app. When someone entered a long URL, it will give a short URL. If the user clicked on the short link it will search for the long URL on the DB and redirect it to the long URL.
Meantime I want to get the click count and clicked user's OS.
I am currently using current code :
app.get('/:shortUrl', async (req, res) => {
const shortUrl = await ShortUrl.findOne({short: req.params.shortUrl})
if (shortUrl == null) return res.sendStatus(404)
res.redirect(shortUrl.full)
})
findOne is finding the Long URL on the database using ShortID. I used mongoDB here
My questions are :
Are there multiple redirect methods in JS?
Is this method work if there is a high load?
Any other methods I can use to achieve the same result?
What other facts that matter on redirect time
What is 'No Redirection Tracking'?
This is a really long question, Thanks to those who invested their time in this.
Your code is ok, the only limitation is where you run it and mongodb.
I have created apps that are analytics tracker, handling billion rows per day.
I suggest you run your node code using AWS Beanstalk APP. It has low latency and scales on your needs.
And you need to put redis between your request and mongodb, you will call mongodb only if your data is not yet in redis. Mongodb has more read limitations than a straight redis instance.
Are there multiple redirect methods in JS?
First off, there are no redirect methods in Javascript. res.redirect() is a feature of the Express http framework that runs in nodejs. This is the only method built into Express, though all a redirect response consists of is a 3xx (often 302) http response status and setting the Location header to the redirect location. You can manually code that just as well as you can use res.redirect() in Express.
You can look at the res.redirect() code in Express here.
The main things it does are set the location header with this:
this.location(address)
And set the http status (which defaults to 302) with this:
this.statusCode = status;
Then, the rest of the code has to do with handling variable arguments, handling an older design for the API and sending a body in either plain text or html (neither of which is required).
Is this method work if there is a high load?
res.redirect() works just fine at a high load. The bottleneck in your code is probably this line of code:
const shortUrl = await ShortUrl.findOne({short: req.params.shortUrl})
And, how high a scale that goes to depends upon a whole bunch of things about your database, configuration, hardware, setup, etc... You should probably just test how many request/sec of this kind your current database can handle.
Any other methods I can use to achieve the same result?
Sure there are. But, you will have to use some data store to look up the shortUrl to find the long url and you will have to create a 302 response somehow. As said earlier, the scale you can achieve will depend entirely upon your database.
What other facts that matter on redirect time
This is pretty much covered above (hint, its all about the database).
What is 'No Redirection Tracking'?
You can read about it here on MDN.
I'm building an android application that uses Parse's push functionality to send messages between single users, and after a lot of finagling around with different solutions (without enabling Client Push because that's apparently a security risk) I settled on this:
// com.myapp.Application.java
public void onCreate(){
...
ParseInstallation i = ParseInstallation.getCurrentInstallation();
i.put("username", ParseUser.getCurrentUser().getUsername());
i.saveInBackground();
...
}
Now, when I want to send a push to a single user, I call a Cloud Code function that does this:
// cloud/main.js
Parse.Cloud.define("pushMessage", function(request,response) {
var from = request.user.getUsername();
var to = request.params["receiver"];
var query = new Parse.Query(Parse.Installation);
query.equalTo('username', to);
Parse.Push.send({
where: query,
data: {
alert: "message from " + from,
// more data
}
}
}
This feels a bit like a hack, but it works. Is it bad form? I can't really wrap my head around the solutions I've seen so far, mostly because they're almost exclusively geared toward iOS and I can't read objective-C.
Okay, so I had to re-do this. I'll answer it just in case someone has the same problems.
The issue with including the username in the installation is that you need to make sure that you handle it correctly. The installation is, as the name implies, tied to the device instead of the user. This means that if your application supports several users, it's one extra step to handle on relog, otherwise users will get pushes not meant for them.
I forgot about doing some of that, and my code turned into sphagetti.
After digging around for a bit, I changed the method to instead subscribe to a channel named after the user's ObjectId, and simply sending pushes to that channel. I then unsubscribe on logout and resubscribe every time the application opens. That way, if you close the application you can still receive pushes. It works just as well, and requires less code.
I've seen a few people having problems with the oAuth1.0 using hello.js with Twitter, LinkedIn etc. Unfortunately, I am one of them. Trying everything I can to fix it, but I need help.
To explain:
I have my Twitter credentials initialised:
hello.init({
'twitter' : '*******************'
},
{
redirect_uri:'****************',
oauth_proxy: 'https://auth-server.herokuapp.com/proxy'
});
(I presume that the 'oauth_proxy' in my case here is correct?)
Apart from that, I have tried calling the function in the button tag like so:
onclick="hello.login('twitter');">
I have seen people making errors having skipped the 'https://auth-server.herokuapp.com/#signin' step but I have all my credentials inputted there for the mean time. But, one question:
The 'Reference' section, is that just a nickname kind of thing? And what's the 'Domain' section about?
The error that I'm receiving is a 401 error message.
Another question:
Do I need all of the 'twitter.js' & 'client_id.js', or is including 'hello.js' sufficient?
I appreciate any effort to help me with this. Thank you.
As Andrew said (after all, he is the one who wrote hello.js), one of the problems could be related to the callback URL. I found out after a while that Twitter (unlike Facebook) does not accept 'localhost', so instead one has to write 127.0.0.1.
That solved all my problem when being stuck at the same point.
So yes, the reference is a nickname e.g. "dropbox", and the domain field is the domains e.g. "myapp.com". Its advised to fill both these in for your own reference and their misconfiguration wont lead to a 401.
The 401 is likely that your client id / secret is incorrect. Or the redirect_uri defined in hello.init does not match the Callback URL you assigned to that client id when you registered with a third party service.
The error handler hello(network).login().then(successHandler, errorHandler) should give more information. Can you attach that too your question?
"client_id.js" is a demo script which defines the credentials used for my hellojs demos. Do not include it!
However you may like this approach for maintaining your application credentials in a separate file - this approach is left up to you.
All you need to include to get started is dist/hello.all.js this contains hello js and all the third party configurations listed.
I am using Parse.com with my iPhone app.
I ran into a problem earlier where I was trying to add the currently logged in user to another user's PFRelation key/column called "friendsRelation" which is basically the friends list.
The only problem, is that you are not allowed to save changes to any other users besides the one that is currently logged in.
I then learned, that there is a workaround you can use, using the "master key" with Parse Cloud Code.
I ended up adding the code here to my Parse Cloud Code: https://stackoverflow.com/a/18651564/3344977
This works great and I can successfully test this and add an NSString to a string column/key in the Parse database.
However, I do not know how to modify the Parse Cloud Code to let me add a user to another user's PFRelation column/key.
I have been trying everything for the past 2 hours with the above Parse Cloud Code I linked to and could not get anything to work, and then I realized that my problem is with the actual cloud code, not with how I'm trying to use it in xcode, because like I said I can get it to successfully add an NSString object for testing purposes.
My problem is that I do not know javascript and don't understand the syntax, so I don't know how to change the Cloud Code which is written in javascript.
I need to edit the Parse Cloud Code that I linked to above, which I will also paste below at the end of this question, so that I can add the currently logged in PFUser object to another user's PFRelation key/column.
The code that I would use to do this in objective-c would be:
[friendsRelation addObject:user];
So I am pretty sure it is the same as just adding an object to an array, but like I said I don't know how to modify the Parse Cloud Code because it's in javascript.
Here is the Parse Cloud Code:
Parse.Cloud.define('editUser', function(request, response) {
var userId = request.params.userId,
newColText = request.params.newColText;
var User = Parse.Object.extend('_User'),
user = new User({ objectId: userId });
user.set('new_col', newColText);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
And then here is how I would use it in xcode using objective-c:
[PFCloud callFunction:#"editUser" withParameters:#{
#"userId": #"someuseridhere",
#"newColText": #"new text!"
}];
Now it just needs to be modified for adding the current PFUser to another user's PFRelation column/key, which I am pretty sure is technically just adding an object to an array.
This should be fairly simple for someone familiar with javascript, so I really appreciate the help.
Thank you.
I would recommend that you rethink your data model, and extract the followings out of the user table. When you plan a data model, especially for a NoSQL database, you should think about your queries first and plan your structure around that. This is especially true for mobile applications, as server connections are costly and often introduces latency issues if your app performs lots of connections.
Storing followings in the user class makes it easy to find who a person is following. But how would you solve the task of finding all users who follow YOU? You would have to check all users if you are in their followings relation. That would not be an efficient query, and it does not scale well.
When planning a social application, you should build for scalabilty. I don't know what kind of social app you are building, but imagine if the app went ballistic and became a rapidly growing success. If you didn't build for scalability, it would quickly fall apart, and you stood the chance of losing everything because the app suddenly became sluggish and therefore unusable (people have almost zero tolerance for waiting on mobile apps).
Forget all previous prioities about consistency and normalization, and design for scalability.
For storing followings and followers, use a separate "table" (Parse class) for each of those two. For each user, store an array of all usernames (or their objectId) they follow. Do the same for followers. This means that when YOU choose to follow someone, TWO tables need to be updated: you add the other user's username to the array of who you follow (in the followings table), and you also add YOUR username to the array of the other user's followers table.
Using this method, getting a list of followers and followings is extremely fast.
Have a look at this example implementation of Twitter for the Cassandra NoSQL database:
https://github.com/twissandra/twissandra
How should I design an on-login middleware that checks if the recurring subscription has failed ? I know that Stripe fires events when things happen, and that the best practice is webhooks. The problem is, I can't use webhooks in the current implementation, so I have to check when the user logs in.
The Right Answer:
As you're already aware, webhooks.
I'm not sure what you're doing that webhooks aren't an option in the current implementation: they're just a POST to a publicly-available URL, the same as any end-user request. If you can implement anything else in Node, you can implement webhook support.
Implementing webhooks is not an all-or-nothing proposition; if you only want to track delinquent payments, you only have to implement processing for one webhook event.
The This Has To Work Right Now, Customer Experience Be Damned Answer:
A retrieved Stripe Customer object contains a delinquent field. This field will be set to true if the latest invoice charge has failed.
N.B. This call may take several seconds—sometimes into the double digits—to complete, during which time your site will appear to have ceased functioning to your users. If you have a large userbase or short login sessions, you may also exceed your Stripe API rate limit.
I actually wrote the Stripe support team an email complaining about this issue (the need to loop through every invoice or customer if you're trying to pull out delinquent entries) and it appears that you can actually do this without webhooks or wasteful loops... it's just that the filtering functionality is undocumented. The current documentation shows that you can only modify queries of customers or invoices by count, created (date), and offset... but if you pass in other parameters the Stripe API will actually try to understand the query, so the cURL request:
https://api.stripe.com/v1/invoices?closed=false&count=100&offset=0
will look for only open invoices.... you can also pass a delinquent=true parameter in when looking for delinquent customers. I've only tested this in PHP, so returning delinquent customers looks like this:
Stripe_Customer::all(array(
"delinquent" => true
));
But I believe this should work in Node.js:
stripe.customers.list(
{delinquent:true},
function(err, customers) {
// asynchronously called
});
The big caveat here is that because this filtering is undocumented it could be changed without notice... but given how obvious the approach is, I'd guess that it's pretty safe.