Stripe webhook POST route does not have req.user - node.js

I am testing Stripe webhooks locally using ngrok, so that the webhooks can be sent to an endpoint on localhost.
I want to test saving customer and payment information to my database, however, it seems like the middleware isn't attaching req.user (set by Passport) like it is on any other route. This makes it a lot less convenient in terms of accessing the authenticated user.
I could do the database work on the routes where I receive a Stripe token, but the bulk of useful information is sent as a webhook. Another option is to save the charge id or customer id at that stage, and then to look up the user at a later stage, but again this seems like unnecessary work.
I'm a little confused as to why this is, unless I'm missing something super obvious.
router.post('/stripe/webhook', (req, res) => {
console.log(req.user); //undefined
res.sendStatus(200);
});

You can find the detail of Stripe webhook mechanism here
You need to parse the body of the request which is holding the payload JSON
Example receiving endpoint :
app.post("/my/webhook/url", function(request, response) {
// Retrieve the request's body and parse it as JSON
var event_json = JSON.parse(request.body);
// Do something with event_json
response.send(200);
});
You can test the your receiving endpoint by test JSON which you can found in Event API of Stripe! And you send test JSON using many app like POSTMAN
(having also a chrome app)

Related

Setting up crypto payments via Bitpay

I want to set up nodejs bitpay crypto payments. I am trying to test the setup for now.
I have used the bitpay button for it but it doesn't send back the request to the backend at IPN it asks, as my route is: http://localhost:4000/cryptopay
Bitpay Sevice IPN and Browser Redirect
The browser redirect is working but the service IPN is not getting any response from the bitpay. I tried doing console.log at the request.
Backend request handler.
app.post("/cryptopay", async(req, res) => {
console.log("Crypto Pay: ")
console.log(req);
});
Even after many successful payments, I don't have any response here.

How can i secure my api endpoint when there is no users registration

I have front end page - contact us - where every user can fill up the form and contact us.After that the filled form is send to our email. Because on our web site, there will not be user registration, so possible client can contact us but he will not need to sign up to visit our web site because it is not "friendly".
I always secured my web api with json web token, so i see if the user is registered in our db so he can have access to some api routes or not. But because this time there will be no DB with users, how can i secure my api endpoints ?
For example: malicious user comes to my website, he can see in the network tab the post request that is made for sending the email.
He can go in postman, and he can make thousands of request if he wants to my api endpoint and it will make me a problems because he is not filling the form on the frontend page, but maybe he will ping my endpoint very often with pre-made body post maked object in postman.
How can i prevent this things without user authentication ?
So the only way that i found until now is to check the origin - from where the request is coming. We can write a middleware at the beggining of our .js file before all other routes and check that
const express = require('express');
const router = express.Router();
const helpers = require('../utils/helpers');
router.use(helpers.checkOrigin);
router.post("/sendemail", async (req, res) => {
...
})
helpers.js file
const checkOrigin = (req, res, next) => {
console.log("checkOrigin", req.headers.origin);
if(req.headers.origin == "www.yourdomain.com") {
next();
} else {
res.status(403).json({error: "Unauthorized"});
}
}
in the
console.log("checkOrigin", req.headers.origin);
when we send request from postman then it prints undefined so it goes to the else block
but if the request comes from www.yourdomain.com then it will go in the if block, execute next middleware and accept request from all routes below including - sendemail.
If anyone has other solutions and better please let me know !

401 Error when sending data to Stripe `Customers` API

I want to create a new customer in Stripe upon form submit and add that customer's credit card to their account. As of now, I'm using the following code upon submit in my React App. The create customer call is then made separately from my server:
async submit(ev) {
let {token} = await this.props.stripe.createToken({name: "Name"});
let response = await fetch("https://api.stripe.com/v1/customers", {
method: "POST",
headers: {"Content-Type": "text/plain"},
body: token.id
});
When sending that data, I get a 401 error on the let response = ... line. I know that a 401 is an auth error, but my test API keys are definitely correct and don't have limits on how they can access my stripe account. Can anyone advise?
The issue here is that you are trying to create a Customer object client-side in raw Javascript. This API request requires your Secret API key. This means you can never do this client-side, otherwise anyone could find your API key and use it to make refunds or transfer for example.
Instead, you need to send the token to your own server. There, you will be able to create a Customer or a Charge using one of Stripe's official libraries instead of making the raw HTTP request yourself.
In my case, it's throwing the error due to a missing of stripe public key
var stripe = Stripe('{{ env("STRIPE_KEY") }}');
then I pass the public key as above, and it worked like a charm.

How to I pass a Stripe Firebase Cloud Function Error To The Client

When I create a cloud function to process a charge on a user’s card (by writing a stripe token to firebase and using a cloud function to charge), how do I pass errors (like a declined card due to insufficient funds) to the client. If it’s important, I’m using the firebase web sdk to send the tokens.
write the errors to a firebase database so that you can read the errors from the database and show them where you need to.
I decided to use a Firebase HTTP cloud function and just send the token to the link firebase sets for the function. Like so,
exports.addSourceToCustomer = functions.https.onRequest((req, res) => {
const token = req.body.token // use the stripe token however you like here
// when an error occurs use res.status(errorCode).send(errorMessage);
// which sends the error back to the client that made the request
});

Node.js - How to use access / auth tokens?

I have built my first Node.js app that is supposed to be installed on a Shopify store. If you want to see what my actual code looks like (app.js) you can view it here. It's really basic so reading through won't be hard.
I know how to authenticate the installation of the app (following the Shopify instructions) but I don't how to authenticate all subsequent requests using the permanent access token that a successful installation provides me with.
By subsequent requests I'm referring to requests to either render the app or requests to install the app, even though the app is already installed.
Right now, I'm storing the shop's name (which is unique) along with the permanent token that Shopify sends me in my database. But I don't know if that's necessary. If I'm not mistaken, simply using the browser's session will do ? But how do I do that ? And how do I use this token every time a request comes through to check if it is a valid one?
Thank you for any help/suggestions!
The code below is sort of a representation of what my actual code looks like in order to give you an idea of what my issues are :
db.once('open', function(callback)
{
app.get('/', function (req, res)
{
var name = getNameFrom(req);
if (existsInDB(name) && tokenExistsInDBfor(name))
{
res.redirect('/render');
/*
Is checking that the shop (along with a permanent token)
exists in my DB enough ?
Shouldn't I check whether the current request comes with
a token that is equal to the one in my DB ?
What if the token received with this request is different
from the one stored in my DB ?
*/
}
else res.redirect('/auth');
});
app.get('/auth', function (req, res)
{
if (authenticated(req))
{
var token = getPermanentToken();
storeItInDB(nameFrom(req), token);
res.redirect('/render');
/*
aren't I supposed to do anything more
with the token I've received ? send it
back/store it in the browser session as well maybe?
is storing it in the db necessary ?
*/
}
});
app.get('/render', function (req, res)
{
/*
How do I check that this request is coming
from an authorised shop that has the necessary token ?
Simply checking my DB will not do
because there might be some inconsistency correct ?
*/
res.sendFile(*file that will build app on the client*);
});
});
Getting access token from Shopify is once time process.
Save access token and shop's name in your DB, and also generate and save 'auth token' based on some algorithm. Return generated auth token to Client. Make sure client sends this auth token in every request.
Now when client hit your server verify auth token; once verified make call to Shopify API using appropriate 'access token' and shop name.
Authentication flow could be as follows:
Get Access token from Shopify
Generate token(i am refering this as auth token) for the Shopify Shop, refer this
Now save shopify's access token, shopify store name and your generated token into DB
Now send your generated token to client(save it in cookie or local storage)
Validation flow:
Clients hits your server to get data with your auth token
Verify this auth token in your DB, and get access token and shop name for that auth token
Now make calls to Shopify API using this access token and shop name
Hope this method helps

Resources