1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//! 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>`](Id), 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.
//!
//! [`kasapay-stripe`]: https://docs.rs/kasapay-stripe
//! [`kasapay-iyzico`]: https://docs.rs/kasapay-iyzico
pub use crate;
pub use crate;
pub use crate;
pub use crateInstrument;
pub use crate;
pub use crate;
pub use crate;
pub use crateRaw;
pub use crate;
pub use crateSecret;
pub use crate;