Skip to content

[Phase 3] Open a Checkout session inline when a hold is committed #154

Description

@Davidslv

Epic: #151
Proposal: proposals/bookings_engine.md (local, git-excluded). Argument: https://github.com/Davidslv/notes/issues/178

Purpose

After the hold commits, the guest is redirected to Checkout. Billing creates the Stripe Customer first, then the session, on that same request. Bookings never names a Billing class.

Scope

In scope

  • bin/seams bookings now requires the billing release that contains Billing::Charge.
  • Hold creation commits, releases the occurrence lock, then publishes booking.held.bookings with amount_cents, currency, payable_ref, success_url, cancel_url, the guest email, and the offering name as the line-item description.
  • Billing's subscriber, on that event, on the publisher's thread: create the Customer when the payload has no customer id, using idempotency key customer- plus the identity id. Then create the session with that customer id, idempotency key session- plus payable_ref. Write Billing::Charge. Publish charge.opened.billing with the URL and the customer id.
  • The Bookings subscriber writes the URL on the instalment and the customer id on the booking, then the controller redirects. Those writes are the same request. They are the second half of the inline exception.
  • A second publish for the same payable_ref returns the open Charge instead of creating a second session.
  • If the gateway raises, the subscriber rescues Billing's own error and publishes charge.open_failed.billing. It does not raise into the Bookings controller. The hold stays held. Log the failure through the existing observability adapter.
  • Do not call Stripe inside the occurrence lock. Do not copy the lifetime service, which holds FOR UPDATE across the Stripe call.

Out of scope

  • Expiring the session and freeing the row.
  • Confirming from payment.succeeded.billing. The hold can be marked paid by hand until that issue.
  • The balance page. booking.balance_due.bookings stays registered and unwired.

How to deliver

Branch <issue-number>-open-checkout. PR title [#<issue-number>] Open Checkout after the hold commits.

Spec the listener with a fake gateway before wiring Stripe. The occurrence lock must be released before the gateway method is called. Assert that with the test, not a comment.

Acceptance Criteria

  • The hold row is committed before the gateway is called.
  • charge.opened.billing for a first-time guest includes a customer id and a URL.
  • The redirect target is that URL, read from the instalment, not from a Billing constant.
  • A repeated booking.held.bookings for the same payable_ref does not create a second session.
  • A gateway error publishes charge.open_failed.billing, leaves the booking held, and does not raise a Billing exception into the controller.
  • Bookings files still do not reference Billing constants.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions