Problem getting Stripe webhook to work in Stripe CLI
Asked Answered
P

5

9

I am using Stripe Checkout in an ASP.NET Web Forms app to let people pay for subscriptions, and that part of the code works fine. I created a webhook with the following code:

using Stripe;
using Stripe.Checkout;
using System.IO;
using System.Web;
using System;

namespace BNet {
    public class spdata : IHttpHandler {

        public void ProcessRequest ( HttpContext ctx ) {
            try {
                var epSecret = "whsec_u...";
                var json = new StreamReader(ctx.Request.InputStream).ReadToEnd();
                FileOps.WriteFile ("~/files/output.txt", "testing", out _, out _ );
                var sig = ctx.Request.Headers["Stripe-Signature"];
                try {
                    var se = EventUtility.ConstructEvent(
                    json,
                    sig,
                    epSecret
                );
                    if ( se.Type == "checkout.session.completed" ) {
                        var session = se.Data.Object as Session;
                        ProcessSubscription ( session );
                    }
                }
                catch ( StripeException e ) {
                    FileOps.WriteFile ( "~/files/StripeLog.txt", e.Message, out _, out _ );
                }
                catch ( Exception ex ) {
                    FileOps.WriteFile ( "~/files/ErrorLog.txt", ex.Message, out _, out _ );
                }
                ctx.Response.Write ( "ok" );
                ctx.Response.Flush ( );
            }
            catch (Exception exp) {
                ctx.Response.Write ( exp.Message );
            }
        }


        void ProcessSubscription (Session session) {
            FileOps.WriteFile ( "StripeLog.txt", session.ToString ( ), out _, out _ );
        }

        public bool IsReusable {
            get {
                return false;
            }
        }
    }
}

So, I created an endpoint in Stripe to use this webhook, and when I run the app, the Dashboard returns a server status of 200 OK, but none of the code in the webhook ever fires.

Then, I set up Stripe CLI to test the webhook locally. I use the following command to start CLI:

stripe listen --forward-to http://localhost:44357/spdata

CLI gives me a secret key, which I copied into the webhook. When I run the web app, it goes just fine. But in the CLI window, here's what I get for every event Stripe fires back to me:

2021-06-08 15:38:23   --> checkout.session.completed [evt_1J0CctBQEZK85JIBn76jElzT]
2021-06-08 15:38:23            [ERROR] Failed to POST: Post "http://localhost:44357/spdata": read tcp [::1]:54739->[::1]:44357: wsarecv: An existing connection was forcibly closed by the remote host.

I don't know what the source of the error is. I shut down Windows Firewall, and I don't have anything else running that could interfere. Any help out there?

Proctor answered 8/6, 2021 at 21:51 Comment(4)
I don't know a lot about .NET routing, but don't you need to add something like [Route("[controller]")] to indicate the URL/path to your code just above your public class declaration? If you add simple logging to the beginning of your function and try a simple POST request via curl, like curl -v -X POST http://localhost:44357/spdata does it log, or do you get an error/unexpected behavior/no log?Inlay
That's what you use when you're doing MVC, which this isn't. (smile) The code has a "WriteFile" call in several places that uses a custom function to write to a text file, and it doesn't even hit that code. It's almost like it fails silently, and until or unless I can get the Stripe CLI to work, I can't debug it. The big question is, why does Stripe CLI keep throwing all of the "Failed to POST" messages? That's where I'm hoping someone who knows Stripe comes in!Proctor
Usually the error you're getting from Stripe CLI indicates your server code is refusing the connection. That's why I suggested the curl test, to see if that's also rejected, or if it's something specific to Stripe CLI.Inlay
I know ITS bit late. AS of 2023, stripe webhook ACCEPT only https. and also I am unable to make it works on the console they provide <code>stripe listen --forward-to https_urlKatykatya
A
10

I might be late, but change this from this

stripe listen --forward-to http://localhost:44357/spdata

to this

stripe listen --forward-to https://localhost:44357/spdata

Stripe will only post on https.

Note: if you don't specify the protocol, like this stripe listen --forward-to localhost:44357/spdata (which is how it is done in the docs) it will default to http and will not work with just a generic error of FAILED TO POST

Ankus answered 25/8, 2021 at 17:11 Comment(3)
Subtracting 1, This post assumes the local https certificate will be trusted by the stripe cli, which it will not be by default, and will lead to another error: x509: certificate signed by unknown authorityZane
@Zane - to get around your certificate issue, add --skip-verify to the listen CLI command. e.g. stripe listen --forward-to https://localhost:44357/spdata --skip-verifyGobetween
http works in test modeUrethrectomy
S
3

I couldn't figure out why I was not getting webhooks through the CLI either, until I removed the http:// from the '--forward-to' parameter. Then I suddenly started getting them.

Try this: stripe listen --forward-to localhost:44357/spdata

(Note: I never even got the errors like you did - maybe I'm on an earlier CLI version?)

Statue answered 9/6, 2021 at 21:13 Comment(0)
Z
1

Use --skip-verify in addition to pointing stripe to the https port to get it to work. stripe listen won't POST to an http port, as one answer correctly stated.

However, if stripe doesn't trust your local TLS certificate (it does not by default), then calling the webhook will fail when it tries to establish the TLS handshake.

Zane answered 17/1, 2023 at 2:22 Comment(0)
S
1

Just for anyone still struggling the command

stripe listen --forward-to localhost:4242/webhook

must be running while executing

stripe trigger [event]

Otherwise it won't work.

Sam answered 5/5, 2024 at 20:55 Comment(0)
N
0

Most likely obvious for most of us, but I was tricked by it:

Make sure, your controller action is not restrcited by some authorization.

[AllowAnonymous]

Symptom: you see Status Code 302, which is the redirect to the login page

That having said, Plain HTTP (without HTTPS) seems to work now, in a testing environment.

Nedi answered 13/6, 2023 at 16:45 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.