6.8 KiB
| date | researcher | git_commit | branch | repository | topic | tags | status | last_updated | last_updated_by | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2025-10-03T20:02:01+0200 | Codex | ac94faedb0 |
main | rentease | Stripe payment ingestion & webhook strategy |
|
complete | 2025-10-03 | Codex |
Research: Stripe payment ingestion & webhook strategy
Research Question
What changes are needed to fetch Stripe payment data for a given period and replace manual double-entry with webhook-driven updates?
Summary
Rentease currently captures payments through a manual UI that posts to /payments/:id,
persisting records with only amount and method metadata. Reporting features depend
on these records, especially for card totals.
There is no existing Stripe integration—configuration lacks API credentials,
and no driver or service encapsulates Stripe access. Extending the system will
require new infrastructure for Stripe clients, data models to track external IDs,
background or on-demand sync routines, and unauthenticated webhook endpoints secured
by Stripe signatures. Key integration hooks include the booking service
(for upserting payments), the repository layer (for queries and uniqueness), the
server router (to host webhooks), and the cron command (for scheduled backfills).
The implementation relies on github.com/stripe/stripe-go/v83 (currently pinned at v83.0.0).
Detailed Findings
Manual Payment Entry Flow
- Booking detail page exposes a modal that posts amount and method to the server (
internal/view/booking_by_id.templ:52,internal/view/booking_by_id.templ:130). /payments/:idhandler binds the form payload, callsbooking.Service.CreatePayment, and re-renders the payment list (internal/server/handle_payments.go:16, permalink: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/internal/server/handle_payments.go#L16-L51).- Booking page view model preloads payments to display them alongside line items (
internal/server/handle_bookings.go:130, permalink: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/internal/server/handle_bookings.go#L130-L179).
Payment Persistence & Reporting
booking.Service.CreatePaymentwraps repository insertions without de-duplication (internal/service/booking/payment.go:17, permalink: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/internal/service/booking/payment.go#L17-L35).PgStore.CreatePaymentwrites plainamountandpayment_method; schema lacks external references for Stripe IDs (internal/repository/booking/pg_store.go:150, permalink: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/internal/repository/booking/pg_store.go#L150-L174).- Reports compute card totals by summing
paymentsjoined to bookings, so Stripe-imported transactions must populate this table to keep analytics accurate (internal/repository/booking/pg_store.go:65,internal/service/booking/report.go:76).
Integration Hooks for Stripe API Fetch
- Configuration currently has no Stripe credentials, so
internal/config/config.gomust gainStripeSecretKey,StripeWebhookSecret, etc., andmain.goshould wire a Stripe client (internal/config/config.go:11,main.go:52). - Extraction logic can mirror existing external service patterns (e.g., the OpenAI parser driver) by adding a
internal/driver/stripeclient and abookingservice method to request Stripe payments and upsert records (internal/service/booking/sync.go:7). - The cron binary is designed to host scheduled jobs and can trigger periodic Stripe backfills once a job runner function exists (
pkg/cron/cron.go:9,cmd/cron/main.go:13).
Webhook Considerations
- Routes under
privaterequire authentication, so Stripe webhooks need a new public endpoint (e.g.,/webhooks/stripe) mounted before auth middleware ininternal/server/routes.go:8. - Handlers should verify Stripe signatures, deserialize events, and, for
payment_intent.succeededorcharge.refunded, call into a service layer that ensures idempotent upserts (likely by storing Stripe IDs in thepaymentstable). - Payment view models already display method strings from config; mapping Stripe payment methods (card, bank redirect) to existing enums may require normalisation in the webhook handler before storing (
internal/view/item_list.templ:19,internal/config/host.go:41).
External Integration Patterns
- The OpenAI booking parser demonstrates how the app encapsulates third-party clients behind drivers and service methods, including error handling and data persistence hooks (
internal/driver/parser/client.go:17,internal/service/booking/sync.go:7). This pattern can guide the Stripe integration for consistency.
Code References
internal/server/handle_payments.go:16– manual payment creation flow (perm: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/internal/server/handle_payments.go#L16-L51)internal/service/booking/payment.go:17– service layer inserts payments (perm: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/internal/service/booking/payment.go#L17-L35)internal/repository/booking/pg_store.go:65– card totals depend on stored payments (perm: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/internal/repository/booking/pg_store.go#L65-L174)internal/server/routes.go:8– current route layout and auth groups (perm: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/internal/server/routes.go#L8-L46)cmd/cron/main.go:13– cron entrypoint for scheduled jobs (perm: https://github.com/rjNemo/rentease/blob/ac94faedb0b491d710c36b04ac27b26890f4d062/cmd/cron/main.go#L13-L44)
Architecture Insights
Rentease centralises business logic in booking.Service, with storage handled through a repository abstraction and UI forms using htmx requests. External integrations live in internal/driver and are injected via main.go. Payment records are simple and lack idempotency safeguards, so any Stripe sync must extend the schema and service methods to avoid duplicates, enforce foreign keys, and reconcile amounts with existing booking items.
Historical Context (from ./thoughts/)
- No prior research documents found in
./thoughtsrelated to payments or Stripe.
Related Research
- None available.
Open Questions
- How will Stripe payments be matched to internal bookings (metadata, external IDs, or manual association)?
- Should the
paymentstable store Stripe identifiers and status fields to enable idempotent upserts and refunds? - What is the preferred flow for backfilling historical payments—ad hoc command, scheduled cron job, or admin-triggered API?
- Which Stripe event types should the webhook handle beyond successful payments (refunds, disputes, payouts)?