Skip to main content

Crate kasapay_core

Crate kasapay_core 

Source
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.
BasketItem
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.
ChargeRequest
A charge to create.
ChargeRequestBuilder
Collects the parts of a ChargeRequest before 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.
IdempotencyKey
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.
OrderRef
Our own reference for an order, chosen by the caller.
ProviderId
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.
RefundRequest
A refund to make.
RefundRequestBuilder
Collects the parts of a RefundRequest before it is checked.
RepeatedHeader
A header a signature depends on arrived more than once.
Secret
Holds a credential and keeps it out of Debug output and logs.
UnknownCurrency
The string was not a currency code kasapay supports.

Enums§

ChargeRequestError
A ChargeRequest was built out of parts that do not make a valid charge.
Currency
A currency kasapay knows how to move money in.
ErrorKind
What went wrong, in terms a caller can branch on without knowing the provider.
EventKind
What a delivery says happened.
IdSource
Whose uniqueness an identifier rests on.
ItemKind
What kind of thing is being sold.
MoneyError
A decimal string could not be read as an amount in the given currency.
NextAction
What the payer has to do before the payment can go on.
RefundReason
What a merchant tells the provider the money went back for.
RefundRequestError
A RefundRequest was built out of parts that do not make a valid refund.
RefundStatus
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.
InstrumentId
How the provider names one card it holds, so a payment need not carry one.
PaymentId
How the provider names a payment.
RefundId
How the provider names one refund, where it names it at all.

Attribute Macros§

async_trait
Marks an implementation of Provider so its async fns compile.