#Cavalaa

1 messages ยท Page 1 of 1 (latest)

warm gateBOT
sly folio
#

hi, the first thing to check is that youp're using the right signingSecret

#

since it's different for cli and real endpoints(the one for a real endpoint is shown to you on the Dashboard page were you create the webhook endpoint URL)

violet beacon
#

yeah I am, it works when I move the code to a local server, i triple checked the signing signature was right before and after

sly folio
#

then the next step is to add logging to log all the values being passed to the constructEvent function

violet beacon
#

yep I've got all of those

#

here's a payload from a 500 Request

sly folio
#

seems normal, so I would still say you're probably using the wrong signing secret

#

what does it look like, sharing the first 5 and last characters? whsec_.........1234

violet beacon
#

It's copied straight from the stripe dash and pasted in

#

whsec_*************Put0e

sly folio
#

ack

#

what does your code look like for the entire endpoint that accepts the POST request?

violet beacon
#

this is the routing function:

#

func StripeWebhook(paymentService *payment.Service) gin.HandlerFunc {
return func(gtx *gin.Context) {
// read payload

    payload, err := ioutil.ReadAll(gtx.Request.Body)
    if err != nil {
        gtx.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("Error reading request body: %v", err)})
        return
    }

    signature := gtx.GetHeader("Stripe-Signature")

    // Log the signature header
    log.Println("Stripe-Signature Header:", signature)
    log.Println("Payload:", string(payload))

    // handle stripe event
    if err := paymentService.StripeWebhook(gtx.Request.Context(), payload, signature); err != nil {
        gtx.JSON(500, gin.H{"error": fmt.Sprintf("%v", err)})
        return
    }

    gtx.Writer.WriteHeader(200)
}

}

#

func (s *Service) StripeWebhook(ctx context.Context, payload []byte, signature string) error {

// parse and validate webhook request
event, err := webhook.ConstructEvent(
    payload,
    signature,
    s.configs.Stripe.WebhookSecret,
)
log.Println("Stripe-Secret Sig:", s.configs.Stripe.WebhookSecret)
if err != nil {
    return fmt.Errorf("!error verifying webhook signature: %v", err)
}
#

That passes to this

#

I tested it locally though and was getting 200 HTTP Status's

sly folio
#

hmm

#

well really the only thing I see unusual is that in the logs you shared, the printed Event is missing whitespace, like the tabs

violet beacon
#

Yeah it's a bit perplexing ๐Ÿ˜…

sly folio
#

the raw string should be like

{
  "id": "evt_3N8leKAm5odgtJUY0wTRD4qv",
  "object": "event",
  "api_version": "2020-08-27",
  "created": 1684334900,
  "data": {
    "object": {
      "id": "pi_3N8leKAm5odgtJUY0QeDyCuc",
      "object": "payment_intent",
#

probably what's happening, since it always happens, is you have a middleware that is converting the request body from JSON into an object, and in your handler function you are not getting the raw body, you are getting the parsed JSON

violet beacon
#

Here's my serverserver := gin.New()

server.Use(gin.Logger())
server.Use(gin.Recovery())
server.Use(middleware.CORS(configs.Server.AllowOrigin))

// create a group for routes where middleware should be applied
authenticated := server.Group("/api")
authenticated.Use(middleware.Authenticate(auth))
authenticated.Use(middleware.Dataloaders())
authenticated.Use(middleware.RequestID())
authenticated.Use(middleware.GinContextToContext())
authenticated.GET("/graphiql", router.GraphiQL())
authenticated.POST("/graphql", router.GraphQL(
    auth,
    device,
    email,
    game,
    notification,
    party,
    payment,
    post,
    request,
    user,
    configs,
))

// graphql routes
// add routes to the main server
authenticated.POST("/pusher/auth", router.PusherAuth(notification))
authenticated.POST("/pusher/presence", router.PusherPresence(notification, user))

// paypal routes
authenticated.POST("/paypal/webhook", router.PayPalWebhook(payment))

// STRIPE ROUTE (no middleware)
server.POST("/stripe/webhook", router.StripeWebhook(payment)) code
#

I made it so the only middleware affecting the stripe webhook is CORS

sly folio
#

not sure, I've never done this sort of web development in Go and this issue rarely comes up in that language(usually it's Node which has various middleware problems)

#

there's only really a few things that can cause this

  • using the wrong secret
  • not passing the exact raw string(getting parsed by a middleware before your code sees it)
  • trying to pass the raw string but there was a special character and you didn't treat it as UTF-8 so it's mangled
#

in this case I can only imagine it's the second of those(it is suspicious to me that your logs print over over multiple lines and don't include the whitespace tab characters(which you need to preserve in the string passed to constuctEvent), maybe the CORS middleware does more than you think or there is something else running at a different layer

violet beacon
#

I guess it must be that, so I'll try and mess with CORS and see if i can fix it