Expand description
Provider-neutral payment types and the trait every kasapay adapter implements.
Nothing here talks to a network. It defines what a charge is, what an
amount is, and what a failure is, so that kasapay-stripe and
kasapay-iyzico can disagree about everything else.
§The shape of a payment
Provider::charge does not return a completed payment. It returns a
Charge with a Status, and — where the payer still has work to do —
a NextAction. Stripe answers a client_secret to confirm in the
browser; iyzico answers a deep link into its own app. Both are the same
shape here, and neither is a success yet.
§Authorising and capturing
Provider::capture takes funds an authorisation is only holding, and
Provider::cancel releases one that will never be taken. Not every
provider separates the two — iyzico’s In-Store flow takes the money at
authorisation — so Provider::capabilities says which, and it says so
before there is a payment to ask about.
§Giving money back
Provider::refund is the only way money goes back: a capture has no
inverse. A Refund is its own object with its own life — its own
identifier where the provider issues one, its own RefundStatus, and,
at one provider, its own NextAction for the payer to approve.
Status has no Refunded and will not grow one. No provider reports a
refund as a payment’s status — Stripe leaves a refunded PaymentIntent
succeeded — so the variant would be a branch that never runs for most of
them. “Has all of this gone back” is the refunds summed against
Charge::amount.
§The call whose answer never arrived
A charge that times out is the one failure where nobody knows whether the
money moved. Provider::lookup is the question to ask: keyed by
OrderRef — the caller’s own reference, which they had before they sent
anything — rather than by an identifier the lost reply never delivered.
Ok(None) says the provider has no record and the charge can be sent
again. Two of the five can answer it, Capabilities::lookup_by_order
says which, and the ones that cannot say what to do instead on
Provider::lookup itself. Guessing is not on the list: an answer of “no
record” that is merely late is how a caller authorises twice.
§What arrives without being asked for
A payment that finishes out of band is not observable through
Provider at all: the payer goes away and comes back somewhere else.
Webhook::verify is the other half — it takes the bytes a provider
posted, shows they are the provider’s, and says what they mean as an
Event.
It is a separate trait because it is a separate thing to hold: verifying
needs a webhook secret the API credentials do not carry. It is async
because verification is not one mechanism — Stripe signs the bytes, PayTR
signs three fields of them, and Mollie signs nothing at all and posts an
identifier to read back.
An EventKind this crate does not model is EventKind::Other and
never an error. A provider retries a delivery until it is acknowledged, so
refusing an unknown type is how a shop earns a week of redeliveries for an
event nobody wanted.
§Identifiers
OrderRef is the caller’s own reference for an order, and PaymentId
is how the provider names the payment that came of it. They are not the same
string even where they carry the same characters.
Two questions are asked of every identifier the provider issues, and both
are answered by Id, of which PaymentId is one kind.
What does it name? The type says, and the compiler holds it: PaymentId
is Id<kind::Payment>, and an adapter that hands back a handle to
something else — iyzico’s classic API names a hosted checkout form by a
token that is not a payment id — declares a kind of its own with IdKind
rather than lending this one out. Two identifiers the same provider issued
are alike enough to confuse, and the kind is what separates them.
Whose uniqueness does it rest on? PaymentId::source says. PayTR
issues no identifier at all and names a payment by the merchant_oid it was
sent, so its source is IdSource::Derived and names that field. A caller
relying on an identifier being unique — writing it into a unique index,
keying a retry on it — is relying on the provider’s guarantee or on their
own, and this is what tells the two apart.
Charge::id is an Option for the provider that has not named the
payment yet, and never an empty string.
§No type here holds a card number
There is no field on ChargeRequest for one and there will not be. A
server that touches a card number is in PCI DSS scope on the merchant’s
longest self-assessment rather than its shortest, and a library that makes
it easy to put one in a struct makes it easy to end up there without
noticing. Every provider kasapay ships has a way of taking a payment that
never sends a number through the caller’s process — a page the provider
hosts, a token the payer’s browser makes, a redirect — and those are the
ways kasapay implements.
What a returning customer needs instead is InstrumentId: the provider
keeps the card and hands back a handle to it, and the handle is what a
payment carries. Charging one is not the same act as taking a card number,
and only the first of the two is here.
Provider::instruments lists what a customer has on file — every
adapter answers the same shape, an Instrument carrying the identity and
something to show a person choosing between them. Charging one is not:
iyzico wants a buyer and a basket beside the token, Stripe an
off_session flag, Mollie a sequenceType, so that call stays each
adapter’s own.
§Amounts
Money counts minor units. There is no f64 anywhere in this crate,
and Money::parse refuses precision a currency does not have rather than
rounding it away.
Modules§
- kind
- What an identifier can name.
Structs§
- Address
- Somewhere to bill, ship or register a payer at.
- Basket
Item - One line of what is being paid for.
- Buyer
- The person paying.
- Capabilities
- What a provider will do, asked before there is a payment to ask it about.
- Charge
- A charge, as the provider currently sees it.
- Charge
Request - A charge to create.
- Charge
Request Builder - Collects the parts of a
ChargeRequestbefore it is checked. - Delivery
- One delivery from a provider, exactly as it arrived.
- Error
- A payment operation failed.
- Event
- What a provider told us happened, once it has been shown to be theirs.
- Id
- How a provider names one thing of kind
K. - Idempotency
Key - A key that makes replaying a charge safe.
- Instrument
- One instrument a provider holds against a customer.
- Money
- An amount in one currency, counted in that currency’s minor unit.
- Order
Ref - Our own reference for an order, chosen by the caller.
- Provider
Id - Names a provider.
- Raw
- What a provider actually sent, for everything kasapay does not model.
- Refund
- Money given back off a payment, as the provider currently sees it.
- Refund
Request - A refund to make.
- Refund
Request Builder - Collects the parts of a
RefundRequestbefore it is checked. - Repeated
Header - A header a signature depends on arrived more than once.
- Secret
- Holds a credential and keeps it out of
Debugoutput and logs. - Unknown
Currency - The string was not a currency code kasapay supports.
Enums§
- Charge
Request Error - A
ChargeRequestwas built out of parts that do not make a valid charge. - Currency
- A currency kasapay knows how to move money in.
- Error
Kind - What went wrong, in terms a caller can branch on without knowing the provider.
- Event
Kind - What a delivery says happened.
- IdSource
- Whose uniqueness an identifier rests on.
- Item
Kind - What kind of thing is being sold.
- Money
Error - A decimal string could not be read as an amount in the given currency.
- Next
Action - What the payer has to do before the payment can go on.
- Refund
Reason - What a merchant tells the provider the money went back for.
- Refund
Request Error - A
RefundRequestwas built out of parts that do not make a valid refund. - Refund
Status - Where a refund stands.
- Status
- Where a payment stands.
Traits§
- IdKind
- What an identifier names — the other question, answered in the type.
- Provider
- Takes a payment and reports on it.
- Webhook
- Checks that a delivery is the provider’s, and says what it means.
Type Aliases§
- EventId
- How one delivery to a webhook address is named.
- Instrument
Id - How the provider names one card it holds, so a payment need not carry one.
- Payment
Id - How the provider names a payment.
- Refund
Id - How the provider names one refund, where it names it at all.
Attribute Macros§
- async_
trait - Marks an implementation of
Providerso itsasync fns compile.