Ir al contenido principal
Petanque Life

Pricing & Payments (PL-T187)

F22.05 12 funcionalidades

En resumen

A rule-based pricing stack with a deterministic Quote preview plus a full payments lifecycle. Peak/off-peak multipliers, member-tier discounts via ChainPassport, group and duration brackets, promo codes, gift cards with CSPRNG codes and atomic redemption, deposit-and-pay-at-venue paired rows, online Stripe payments with webhook idempotency, refunds with status recompute to PARTIAL_REFUND/REFUNDED, and per-row audit trails on every transition.

Cómo funciona

Pricing is composed from a rule stack on ChainVenueProfile. Each rule has a type (peak_multiplier, tier_discount, group_discount, duration_bracket, promo_code) and parameters; the engine applies them in order and returns a Quote with a line-item breakdown. Dynamic pricing is gated by dynamic_pricing_enabled so a tenant can pin flat rates without removing rules.

POST /chain/pricing-rules/preview is the single deterministic source — both the customer wizard and the operator console call it to render an explainable price before submit. Gift cards use 16-character CSPRNG codes with a unique (tenant_id, code) constraint and atomic redemption — the redemption decrements the balance inside a single update with the audit trail attached. Anonymous balance lookup is available (rate-limited at the gateway) so a customer holding a card can check remaining value without an account.

The deposit flow writes paired BookingPayment rows — a deposit row charged at booking time and a pay_at_venue row settled at check-in. Online payments use Stripe PaymentIntents with metadata round-trip; the /webhooks/stripe/booking-payments endpoint verifies the Stripe-Signature header and uses StripeWebhookEvent.event_id for idempotency, so duplicate webhook deliveries don't double-count payments. Refunds run against succeeded rows with parent_payment_id linkage; the engine recomputes booking status to PARTIAL_REFUND or REFUNDED and writes a new audit_trail entry.

Every transition (created, captured, refunded, voided) records actor, action, and metadata on BookingPayment.audit_trail.

Capacidades clave

  • Composable pricing-rule stack (peak, tier, group, duration, promo) with Quote preview
  • ChainPassport BRONZE/SILVER/GOLD tier discounts
  • Gift cards with CSPRNG codes, atomic redemption + anonymous balance lookup
  • Deposit + pay-at-venue paired payment rows
  • Stripe PaymentIntent with webhook idempotency on event_id
  • Refund flow with status recompute (PARTIAL_REFUND / REFUNDED)
  • Per-row audit trail on every payment transition

En la práctica

A customer with a SILVER ChainPassport books two lanes for six people on a Friday at 20:00 with promo code SUMMER20. The wizard calls the preview endpoint, which returns a Quote: base rate 800 SEK + peak multiplier 1.3 → 1040, group discount −10% → 936, SILVER tier −5% → 889, promo SUMMER20 −20% → 711. The customer redeems a 200 SEK gift card (atomic decrement, balance now 0) and pays the remaining 511 SEK via Stripe — the PaymentIntent succeeds, the webhook arrives twice (Stripe retried), but StripeWebhookEvent.event_id deduplicates.

The next morning the customer cancels — within the cancellation window, so the operator triggers a refund. The engine refunds the Stripe charge, the gift-card balance is restored, the booking flips to REFUNDED, and the audit trail records every step.

Funcionalidades de este subsistema

12
ID Status Funcionalidades
F22.05.01 Entregado Peak / off-peak pricing rules (rule-based stack with peak_multiplier, gated by dynamic_pricing_enabled)
F22.05.02 Entregado Member-tier discount (ChainPassport BRONZE/SILVER/GOLD via tier_discount rule)
F22.05.03 Entregado Group discount (group_discount rule with min_party_size threshold)
F22.05.04 Entregado Duration-bracket discount (duration_bracket rule) and promo-code (promo_code rule)
F22.05.05 Entregado Deterministic preview via POST /chain/pricing-rules/preview returning a Quote with line breakdown
F22.05.06 Entregado Gift cards: 16-char CSPRNG codes, (tenant_id, code) unique, atomic redemption with audit trail
F22.05.07 Entregado Anonymous balance lookup endpoint (rate-limited at gateway) — exposes balance + status only
F22.05.08 Entregado Deposit flow — paired deposit + pay_at_venue rows, balance settled at check-in
F22.05.09 Entregado Online payment via Stripe PaymentIntent with metadata round-trip
F22.05.10 Entregado Stripe webhook /webhooks/stripe/booking-payments — signature verification + StripeWebhookEvent idempotency on event_id
F22.05.11 Entregado Refund flow against succeeded rows with parent_payment_id linkage and recompute → PARTIAL_REFUND/REFUNDED
F22.05.12 Entregado BookingPayment.audit_trail records every transition (actor, action, metadata)