Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m10s
payment.sx — payment-request materialises {:order :amount :currency :return-url}
at the IO edge (amount from the ledger, currency/return-url host-supplied), so
lib/commerce stays vendor-agnostic; SumUp/Stripe adapters live in the orders
service and order-settle!(ref, amount) is the resume seam. pending-payments
enumerates suspended orders + envelopes (host poller seam). Gotcha handled: a
Scheme string flow-payload round-trips back wrapped as {:scm-string ...} —
unwrapped via scm->string. Total 209/209 across 13 suites.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
42 lines
1.9 KiB
Plaintext
42 lines
1.9 KiB
Plaintext
;; lib/commerce/payment.sx — provider-neutral payment-request envelope.
|
|
;;
|
|
;; The order flow (order.sx) suspends on `(request 'payment oid)` — it carries
|
|
;; ONLY the order-id and calls no provider. This layer materialises, at the IO
|
|
;; edge, the envelope a provider adapter needs to initiate payment:
|
|
;;
|
|
;; {:order oid :amount <ledger total> :currency C :return-url U}
|
|
;;
|
|
;; amount comes from the ledger (the :created quote total); currency + return-url
|
|
;; are host/provider config (legitimately host-supplied). The engine stays
|
|
;; vendor-agnostic: SumUp/Stripe/etc. adapters consume this envelope, and
|
|
;; order-settle!(ref, amount) is the vendor-neutral resume seam. No provider
|
|
;; SDK, HTTP, or webhook parsing lives here — that is the orders service's job.
|
|
|
|
(define payment-request (fn (b oid currency return-url) {:order oid :amount (order-total b oid) :return-url return-url :currency currency}))
|
|
|
|
(define payment-request-order (fn (pr) (get pr :order)))
|
|
(define payment-request-amount (fn (pr) (get pr :amount)))
|
|
(define payment-request-currency (fn (pr) (get pr :currency)))
|
|
(define payment-request-return-url (fn (pr) (get pr :return-url)))
|
|
|
|
;; A Scheme string carried as a flow payload round-trips back to SX wrapped as
|
|
;; {:scm-string "..."}; unwrap it to the bare order-id.
|
|
(define
|
|
scm->string
|
|
(fn
|
|
(v)
|
|
(if (and (dict? v) (has-key? v :scm-string)) (get v :scm-string) v)))
|
|
|
|
;; Host poller seam: every order currently suspended awaiting payment, each with
|
|
;; its envelope. A provider adapter iterates these, initiates payment, and later
|
|
;; calls order-settle! when the webhook arrives. Needs the flow env.
|
|
(define
|
|
pending-payments
|
|
(fn
|
|
(env b currency return-url)
|
|
(let
|
|
((reqs (flow-run-in env "(flow-host-requests)")))
|
|
(map
|
|
(fn (r) {:id (first r) :request (payment-request b (scm->string (nth r 2)) currency return-url)})
|
|
(filter (fn (r) (= (nth r 1) "payment")) reqs)))))
|