(c *echo.Context)
| 46 | } |
| 47 | |
| 48 | func (h *WebhookHandler) handleCallback(c *echo.Context) error { |
| 49 | ctx := c.Request().Context() |
| 50 | body, err := io.ReadAll(c.Request().Body) |
| 51 | if err != nil { |
| 52 | slog.Error("failed to read stripe webhook request body", log.BBError(err)) |
| 53 | return c.String(http.StatusBadRequest, "failed to read request body") |
| 54 | } |
| 55 | |
| 56 | sig := c.Request().Header.Get("Stripe-Signature") |
| 57 | // Our Stripe account is pinned to the basil API version, but stripe-go v85 |
| 58 | // targets dahlia. Existing webhook endpoints can't have their API version |
| 59 | // changed in the Stripe Dashboard, so we accept the version mismatch — every |
| 60 | // Subscription/Invoice field this handler reads is schema-identical between |
| 61 | // basil and dahlia. |
| 62 | event, err := webhook.ConstructEventWithOptions(body, sig, h.webhookSecret, webhook.ConstructEventOptions{ |
| 63 | IgnoreAPIVersionMismatch: true, |
| 64 | }) |
| 65 | if err != nil { |
| 66 | slog.Error("stripe webhook signature verification failed", log.BBError(err)) |
| 67 | return c.String(http.StatusBadRequest, "invalid signature") |
| 68 | } |
| 69 | |
| 70 | if err := h.processEvent(ctx, &event); err != nil { |
| 71 | slog.Error("failed to process stripe webhook event", |
| 72 | log.BBError(err), |
| 73 | slog.String("type", string(event.Type)), |
| 74 | slog.String("id", event.ID), |
| 75 | ) |
| 76 | return c.JSON(http.StatusInternalServerError, map[string]string{"status": "error"}) |
| 77 | } |
| 78 | |
| 79 | return c.JSON(http.StatusOK, map[string]string{"status": "success"}) |
| 80 | } |
| 81 | |
| 82 | func (h *WebhookHandler) processEvent(ctx context.Context, event *stripego.Event) error { |
| 83 | switch event.Type { |
nothing calls this directly
no test coverage detected