Stripe as a READER over the hosted-checkout rail.
Everything Stripe-specific is here and it is all data plus one signature
check: which event names mean settled, where the invoice id is replayed, and
how a notice authenticates itself. The rail behaviour lives in
payments.hosted; adding a second processor means writing another reader
this size, not another rail.
The signature is verified with javax.crypto rather than the Stripe SDK, so
a notice can be authenticated by a build that carries no vendor jar at all —
the SDK is confined to the gateway adapter that opens sessions.
Stripe as a READER over the hosted-checkout rail. Everything Stripe-specific is here and it is all data plus one signature check: which event names mean settled, where the invoice id is replayed, and how a notice authenticates itself. The rail behaviour lives in `payments.hosted`; adding a second processor means writing another reader this size, not another rail. The signature is verified with `javax.crypto` rather than the Stripe SDK, so a notice can be authenticated by a build that carries no vendor jar at all — the SDK is confined to the gateway adapter that opens sessions.
How old a signed notice may be. Stripe's own recommendation.
How old a signed notice may be. Stripe's own recommendation.
(entry config)A registry entry {:profile :rail} for Stripe over :gateway.
Every profile key is overridable by config: a deployment selling in euros
passes :provider/currency :eur and nothing else moves.
A registry entry {:profile :rail} for Stripe over `:gateway`.
Every profile key is overridable by `config`: a deployment selling in euros
passes `:provider/currency :eur` and nothing else moves.(parse-signature-header header)The t timestamp and every v1 signature in a Stripe-Signature header, as
{:signature/timestamp long :signature/values #{hex}}.
Nil when the header is absent, blank, carries no parsable t, or carries no
v1.
The `t` timestamp and every `v1` signature in a Stripe-Signature header, as
{:signature/timestamp long :signature/values #{hex}}.
Nil when the header is absent, blank, carries no parsable `t`, or carries no
`v1`.Stripe settles in one movement, needs no confirmations, and signs its notices.
Stripe settles in one movement, needs no confirmations, and signs its notices.
(reader {:keys [webhook-secret webhook-tolerance-seconds]})The Stripe notice reader. :webhook-secret is the endpoint signing secret;
without it every notice is refused and the rail settles by polling alone.
The Stripe notice reader. `:webhook-secret` is the endpoint signing secret; without it every notice is refused and the rail settles by polling alone.
(signature-valid? {:keys [secret tolerance-seconds]}
header
raw-body
received-at)True when header carries a v1 HMAC-SHA256 of the signed payload under
secret, stamped within tolerance-seconds either side of received-at.
raw-body must be the untouched request body — reserializing a parsed body
changes bytes and every signature over it. A blank secret accepts nothing:
an unconfigured endpoint that fails open is worse than one that is off. The
future bound is this store's own, because Stripe's tolerance is one-sided and
a notice stamped a year ahead is not a notice.
True when `header` carries a v1 HMAC-SHA256 of the signed payload under `secret`, stamped within `tolerance-seconds` either side of `received-at`. `raw-body` must be the untouched request body — reserializing a parsed body changes bytes and every signature over it. A blank secret accepts nothing: an unconfigured endpoint that fails open is worse than one that is off. The future bound is this store's own, because Stripe's tolerance is one-sided and a notice stamped a year ahead is not a notice.
(signed-payload timestamp raw-body)The exact string Stripe signs: the header timestamp, a dot, the raw body.
The exact string Stripe signs: the header timestamp, a dot, the raw body.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |