package middleware import ( "context" "io" "net/http" "apps/backend/internal/response" ) const stripeWebhookMaxBytes = 1 << 20 type stripeRawBodyKey struct{} type stripeSignatureKey struct{} type StripeRawBodyMiddleware struct { } func NewStripeRawBodyMiddleware() *StripeRawBodyMiddleware { return &StripeRawBodyMiddleware{} } func (m *StripeRawBodyMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { body, err := io.ReadAll(http.MaxBytesReader(w, r.Body, stripeWebhookMaxBytes)) if err != nil { response.Fail(w, http.StatusRequestEntityTooLarge, 413001, "webhook payload too large", nil) return } ctx := context.WithValue(r.Context(), stripeRawBodyKey{}, body) ctx = context.WithValue(ctx, stripeSignatureKey{}, r.Header.Get("Stripe-Signature")) next(w, r.WithContext(ctx)) } } func StripeWebhookPayload(ctx context.Context) ([]byte, string, bool) { payload, payloadOK := ctx.Value(stripeRawBodyKey{}).([]byte) signature, signatureOK := ctx.Value(stripeSignatureKey{}).(string) return payload, signature, payloadOK && signatureOK }