#gecko - stripe endpoint http vs https
1 messages · Page 1 of 1 (latest)
Hi...apologies, I"m not a web guru
so I have a stripe checkout, and used it to test webhooks....and all is good
using test webhook, I can see the checkoutsession stuff all fine
so last step in the integration process is to enable a production webhook
and this requires an https access point in my website
all good, and agree so far, yes?
Yes
ok...so what I had was a simple web page with a link to test, and the action was a URL:port/checkout....which all works fine
so once I have to switch to an https style, in support of the webhook event listener, then I get into trouble
i think the port number desgination begins to conflict with the https need....yes?
the endpoint still wants to listen to some random port....but https requires the 443?
@worthy ridge I'm sorry but that is still really vague and unclear to help you
ok let me try again
What port to use depends on your overall system and how you as the developer built it
you control this in your system however you want to configure. I use my own PHP server and my port is 8888
i have a port 80 website...unsecure....and then I use mywebsite.com:1234/checkout as the test link
and my endpoint listens for 1234
all good?
not really good no. Whether to use 1234 depends on your own server's configuration
I'm not really asking anything yet unfortunately. I'm trying to understand your question. You said "all good" so I explained that I still don't get it. What's insecure about port 80? Where does port 1234 comes from?
ok let me start over
i have www.mywebsite.com up and running. there is an index.html and a single link on there, to start a checkout
the link is http: //www.mywebsite.com:1234/checkout
i have an endpoint that listens on 1234
it handles the checkout and creates a checkout session for the customer
all boiler plate template stripe docs based implementation...do you agree so far?
Let's say yes, what's your real question, if possible all clearly in one paragraph
😅
so i am trying to implement production webhook listener. in order for me to do this, I have to have an https interface for stripe to send webhook events to
if i change my website and just run on secure (https) format instead, and try the same line: https:// www.mywebsite.com:1234/checkout, it won't work I get errors...I believe because of the port...am I wrong?
http to https change only in the URL
Unfortunately yes I think you are wrong
this should work ok?
Taking a step back
1/ How did you build your website: which exact programming language and which exact framework are you using?
2/ How did you configure HTTPS/TLS on your server
3/ In theory you never have a port in your URL, you only do this locally for testing
sorry, as I said in the intro I'm a website n00b
- JS/html
- apache and added SSL certificates today
- can I remove all the ports? I thought this was required for listening by the endpoint...?
What other language than JS. JS is client-side usually. ARe you using Node.js and Express for example? Something else?
node, express
Thanks. So you likely want to read something like https://blog.logrocket.com/configuring-apache-for-node-js/ which explains how to configure Apache to redirect to the right port for your Node.js/Express application maybe?
like....express.listen() requires a port number to monitor
and you are not supposed to have a port in your URL no
you have a website like https://www.example.org that is your domain and your server's configuration knows to redirect that incoming request to your Node.js application
i don't want it either....I assumed I'd have to proxy server that to hide it....can I get rid of the ports in general and have express listen without specifying?
yes, by an express port listener....
(NOT with Stripe) Clarification question: are you serving your website (client) and webhooks from the same domain?
yes
(NOT with Stripe) Is your website (client) server using express, and routes in express?
express yes, routes no. just post, listen, use, get, send
the implication is routes are my way of solving the port problem?
(NOT with Stripe) Sort of...
my webhook endpoints:
// build multiple CRUD interfaces:
webhook_app.post("/direct", async (request, response) => {
//send the response early - the only valid response is "received"
await commonHandler(request, response, endpointDirectSecret);
response.json({ received: true });
});
webhook_app.post("/connect", async (request, response) => {
//send the response early - the only valid response is "received"
await commonHandler(request, response, endpointSecret);
response.json({ received: true });
});
webhook_app is the Express instance
i have something just like this...posts....for a '/checkout' for example
(NOT with Stripe) Yep, so add the endpoints as above, and you'll be good to go
(NOT with Stripe) express.post("/direct") (or whichever path you choose) can become your webhook endpoint : mywebsite.com/direct
yeah....but that's not answering my question
i have mywebsite.com/checkout now (with a port number)
and express.listen(portnum)
and it works fine
the same works exactly identically for webhooks
I, as koopajah, fail to see the NEED for the port #'s
so the express.listen is useless?
if you can do example.com/checkout and it works, then example.com/my_webhook works too, with no port number
agree
and I've coded the dev environment with a specific port, per the docs
can I just remove them all?
(NOT with Stripe) I'm not sure whoo pointed at a webport UNLESS you are using a local server
so the listen is also only for localhost type stuff, and not needed in production?
(NOT with Stripe) many concepts being thrown in the pot here
sorry....I'm a web novice, as I said
yeah agreed. You might want to hire a freelancer to teach you all of this @worthy ridge
if you're going to accept live payments, that's a safer option and in a few hours they can show you the ropes
But overall the first step would be to debug what isn't working.
(not) as an example of unneeded complexity (and possibly limited understanding) express.listen is for a "socket", which is essentially a long-lived stream listener. If that doesn't make sense, you kinda gotta go back to basics
yes I understand that I think
the removal of the socket listener, means the endpoint has to handle events from the webserver another way, which is what I think I'm missing on understanding, and the core of the question
but appreciate the time in chat gents/gals
What we are trying to say is that your webhook handler is in no way different to how you handle other routes in your code. For your server/Express app it's all the same
i understand that, and agree my question isn't webhook specific
it's about getting the handshake between the client and the endpoint without using socket ports
(NOT with Stripe) Webhooks are NOT special in any way compared to a website entry point - express, pased on the .post(route, callback), simple calls the "callback" code when the "route" matches a POST event path. A website "server" is just code that ultimately send back some sort of response.
(NOT with Stripe) so your concern is NOT "catching" the webhook (which is nothing special), but sending things like the client secret back to the client?
(what does client secret have to do with their question, they are asking about a webhook handler)
no
I think he's confusing the various flows
it's more simple, I think
let's ignore webhook
i want www.mywebsite.com/checkout to cause my endpoint express handler, app.post('/checkout,....) to execute
up until today, I've been developing with an app.listen(1234) and giving my URL as www.mywebsite.com:1234/checkout
and it all worked fine
I want to get rid of all the ports in URL
so....if the app.listen is removed, how does the endpoint see the /checkout post ?
(NOT with Stripe) When express sees a POST to mywebsite/checkout, it calls the code supplied in the app.post('/checkout', callback). That's what app.post does, it "registers" the callback as the thing to do when a POST occurs to '/checkout'
agree
(NOT with Stripe) app.post does NOT execute anything by itself; EXPRESS just now knows to call the 'callback' code when a POST to 'mywebsite.com/checkout' occurs
agree
and my question is still, how does express know to look for this without a listener?
(NOT with Stripe) It's PRECISELY what Express was written to DO
you're saying, that if I simply call express(), and the post(/checkout) then it will handle it without other needs?
(NOT with Stripe) Express is actively RUNNING on your server, looking for such events
(NOT with Stripe) I can share my webhooks code, using express, if you like
sure, that would be great
// If you are testing your webhook locally with the Stripe CLI you
// can find the endpoint's secret by running `stripe listen`
// Otherwise, find your endpoint's secret in your webhook settings in the Developer Dashboard
export const endpointSecret = configs?.stripe?.stripe_endpoint_secret
? configs.stripe.stripe_endpoint_secret
: process.env.STRIPE_ENDPOINT_SECRET;
export const endpointDirectSecret = configs?.stripe
?.stripe_endpoint_secret_direct
? configs.stripe.stripe_endpoint_secret_direct
: process.env.STRIPE_ENDPOINT_SECRET_DIRECT;
// This example uses Express to receive webhooks
export const webhook_app = webhook_app_creator();
// The Firebase Admin SDK to access Cloud Firestore.
//const cors = require("cors");
// Automatically allow cross-origin requests
webhook_app.use(cors({ origin: true }));
// build multiple CRUD interfaces:
webhook_app.post("/direct", async (request, response) => {
//send the response early - the only valid response is "received"
await commonHandler(request, response, endpointDirectSecret);
response.json({ received: true });
});
webhook_app.post("/connect", async (request, response) => {
//send the response early - the only valid response is "received"
await commonHandler(request, response, endpointSecret);
response.json({ received: true });
});
const commonHandler = async (request, response, secret) => {
const sig = request.headers["stripe-signature"];
try {
request.fullEvent = stripe.webhooks.constructEvent(
request.rawBody,
sig,
secret
);
} catch (err) {
logger(`Webhook Error: ${err.message}`);
return;
}
return writeRecord("Stripe_logs", {
Id: request.fullEvent.id,
timestamp: serverTimestampFieldValue,
event: request.fullEvent
});
};
webhook_app_creator comes from:
import webhook_app_creator from "express";
export const webhook_app = webhook_app_creator();
yep looks very close to what I have too
literally creates and starts an Express server
webhook_app.post("/direct", async (request, response) => {
//send the response early - the only valid response is "received"
await commonHandler(request, response, endpointDirectSecret);
response.json({ received: true });
});
tells the running express server that any POST event to '/direct' should be sent to the anonymous/arrow function
Each endpoint is using
const commonHandler = async (request, response, secret) => {
const sig = request.headers["stripe-signature"];
try {
request.fullEvent = stripe.webhooks.constructEvent(
request.rawBody,
sig,
secret
);
} catch (err) {
logger(`Webhook Error: ${err.message}`);
return;
}
return writeRecord("Stripe_logs", {
Id: request.fullEvent.id,
timestamp: serverTimestampFieldValue,
event: request.fullEvent
});
};
to process the POST event - in this case, just queung up the event in a database
yeah I read the code and it's basically what I have too
I really don't think that's my issue
(NOT with Stripe) in essence, Express is a listener already
i have webpage not found 404, when trying to access /checkout
then more likely is Express isn't even running, OR you have a higher-priority endpoint taking precedence
(NOT with Stripe) For example: if your Express app has someone declare app.post('/', callback), that can take precendence without allowing for the other path to be reached
wihtout seeing you actual code, not much more - and to be honest, as I make painfully clear (NOT with Stripe) so there's not much more time I can do.
you're being very patient with me, I really appreciate it
const app = express();
// get the URL encoded form data
app.use(express.urlencoded({extended: false}));
app.use(express.json());
console.log('express running!');
app.post('/checkout', async (req, res) => {
app.get('/order/success', async (req, res) => {
and those are the only two I have in that file
(NOT with Stripe) basic debug question: HOW do you know Express is running? In debug, most important point to remeber is "you don't know ANYTHING if you haven't seen it recently"
simplest case...I go to terminal, node endpoint.js, put a console.log(express running) you see above...and process is still running....and I go try a website /checkout url
HOW do you know it is still running?
(NOT with Stripe) You know it STARTED (the console.log) - do you know it is RUNNING?
how would you suggest I confirm? the endpoint process didn't terminate and the app is at file scope
(NOT with Stripe) also - that express.json() middleware may well interfere with endpoint verification - it needs the RAW, entirely unprocessed post body - yes it can be PARSED as JSON, but verification is EXTREMELY (deliberately) picky about spaces, line-feeds, etc
(NOT with Stripe) well you could add some timer/interval that hits the console at regular intervals
(NOT with Stripe) To be extremely didactic, the verification process probably uses stegonography to encode extra information
(NOT with Stripe) You're gonna have to go debug on your own, here - but you're back onto a more reasonable path
so herein lies what I think is the problem....I have apache running, and it can see port 80 and 443. If I open express() on an endpoint, and don't bind it to anything, then it won't be able to listen. If i create an http/https server and attach the express app to it, and listen on 80/443, then I'll get a conflict with apache. yes?
(it's the error I see anyway)
(NOT with Stripe) I'm not using Apache, so I don't know
(not) Well, not for at least a decade, anyway
(NOT with Stripe) Is your Node instance running under Apache?
node is running on same server as apache....