#Cavalaa
1 messages ยท Page 1 of 1 (latest)
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)
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
then the next step is to add logging to log all the values being passed to the constructEvent function
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
ack
what does your code look like for the entire endpoint that accepts the POST request?
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
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
Yeah it's a bit perplexing ๐
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
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
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
I guess it must be that, so I'll try and mess with CORS and see if i can fix it