feat: wire FX + deposit invoice into the booking hold (#3) #7
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/payment-settle"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Makes the payment path real so the happy path completes end-to-end (testable on FakeWallet, no relays needed). Closes the code portion of #3 — see the manual-close note below.
What changed
_to_sats()— real FX viafiat_amount_as_satoshis(sat/sats pass through). Single conversion point; result becomes the canonicalamount_sat, never recomputed downstream (source-of-truth rule).api_request_booking— after theheldwrite, creates a sats-denominated deposit invoice (amount locked at quote time, immune to FX drift before payment), tagged{tag: chatelet, booking_id}sotasks.on_invoice_paidmatches the settle. OnInvoiceErrorthe hold is released (status=declined) so a dead hold can't block dates.BookingQuote— new response: held booking + bolt11 + payment_hash.Settlement (
awaiting_payment → confirmed, dates hard-blocked, reservation republished) was already present intasks.pyand now fires on real payments.Manual test (FakeWallet)
satto skip FX, orEURto exercise it).POST /chatelet/api/v1/bookings→ expectBookingQuotewith a bolt11, bookingawaiting_payment.confirmed; re-request same dates →409.Out of scope (tracked)
Why PR (not direct-to-main)
Money-handling extension (creates invoices, credits wallets) → PR category per workspace rules. Handing off merge to you via the Forgejo UI.
🤖 Generated with Claude Code
Booking requests now complete end-to-end over HTTP: - _to_sats() converts fiat->sats via fiat_amount_as_satoshis (sat/sats pass through). This is the single conversion point; the result is the canonical amount_sat and is not recomputed downstream. - api_request_booking creates a sats-denominated deposit invoice (locked amount, immune to FX drift before payment), tagged {tag:chatelet, booking_id} so tasks.on_invoice_paid matches the settle. On InvoiceError the hold is released (status=declined) so dead holds don't block dates. - New BookingQuote response returns the held booking + bolt11 + hash. Settlement (tasks.on_invoice_paid: awaiting_payment -> confirmed, dates hard-blocked, reservation republished) was already in place and now fires on real payments. Testable on FakeWallet. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD