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
//! Client configuration: gateway host, credentials, and transport tuning.
//!
//! # The ALAT gateway topology (important)
//!
//! ALAT by Wema publishes its APIs through **Azure API Management (APIM)**. A
//! single APIM gateway fronts many *products*, each mounted under a path prefix
//! (e.g. `/funds-transfer-open`, `/bills-payment`, `/wallet-creation`). Every
//! request is therefore `https://<gateway-host>/<product-prefix>/...`.
//!
//! Wema exposes **two public developer sandboxes**, and — crucially — they are
//! *separate* APIM instances with *separate* subscription keys and *different*
//! sets of products:
//!
//! | Sandbox | Gateway host | Hosts (among others) |
//! |---------------|-------------------------------------------|---------------------------------|
//! | **Playground**| `https://playground.alat.ng` | wallet creation, account, statement, bills, airtime |
//! | **APIM Dev** | `https://wema-alatdev-apimgt.azure-api.net` | funds transfer, name enquiry |
//!
//! Because a [`Client`](crate::Client) is bound to exactly one gateway + key,
//! exercising endpoints that live on *both* sandboxes requires two clients (see
//! the crate-level docs). In **production**, Wema typically fronts all of your
//! subscribed products behind a single gateway host that they issue to you —
//! pass that host to [`Config::new`].
//!
//! > The previous revision of this SDK defaulted to `https://sandbox.alat.ng`,
//! > which does not resolve. There is intentionally **no hidden default host**
//! > here: you must name the gateway explicitly (or use a named sandbox
//! > constructor), so a typo can never silently point at the wrong bank.
use Duration;
/// The default per-request timeout applied if the caller does not override it.
///
/// Banking calls should never hang indefinitely; 30s is generous for the
/// synchronous "accepted/pending" responses these endpoints return.
pub const DEFAULT_TIMEOUT: Duration = from_secs;
/// Connection details and credentials for a single ALAT gateway.
///
/// A `Config` is consumed by [`Client::new`](crate::Client::new). It is cheap to
/// clone and holds no live connections.
///
/// # Authentication
///
/// APIM gates every product with a **subscription key**
/// (`Ocp-Apim-Subscription-Key`). On top of that, ALAT identifies the calling
/// software *channel* with an **API key** (`x-api-key`). A subset of products
/// (bills & airtime) additionally require an **access key** sent in an `access`
/// header — supply it via [`Config::with_access_key`] when you use those
/// endpoints.