remita-checkout-client 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +211 -170
- package/dist/{chunk-RLUJCMLB.mjs → chunk-O2KJGHVA.mjs} +90 -15
- package/dist/chunk-O2KJGHVA.mjs.map +1 -0
- package/dist/cli.js +95 -33
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +18 -26
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +97 -5
- package/dist/index.d.ts +97 -5
- package/dist/index.js +87 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-RLUJCMLB.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,57 +1,60 @@
|
|
|
1
1
|
# remita-checkout-client
|
|
2
2
|
|
|
3
|
-
A typed client for the Remita Checkout
|
|
4
|
-
|
|
3
|
+
A typed TypeScript client for the Remita Checkout API. It lets you accept
|
|
4
|
+
payments, run the full payment lifecycle, check payment status in real time, and
|
|
5
|
+
look up supported channels — from the browser or Node.js 18+.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
Two clients are available:
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
- **`MerchantCheckoutClient`** — start a checkout and verify the result. Best for
|
|
10
|
+
storefronts and businesses that only need to accept payment for a sale.
|
|
11
|
+
- **`RemitaPlatformClient`** — the full payment lifecycle (pre-payment, fees,
|
|
12
|
+
initiation, authorization, validation, verification) plus channel lookups.
|
|
13
|
+
Best for payment facilitators, gateways, and platforms.
|
|
9
14
|
|
|
10
|
-
|
|
15
|
+
## Requirements
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
for
|
|
17
|
+
- Node.js 18 or newer, or a browser with `fetch` support.
|
|
18
|
+
- A Remita public key for your environment.
|
|
14
19
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- create a checkout session
|
|
18
|
-
- redirect or embed the payment flow
|
|
19
|
-
- verify payment completion
|
|
20
|
-
- update order status
|
|
21
|
-
|
|
22
|
-
Recommended client:
|
|
23
|
-
|
|
24
|
-
- `MerchantCheckoutClient`
|
|
20
|
+
## Install
|
|
25
21
|
|
|
26
|
-
|
|
22
|
+
```bash
|
|
23
|
+
npm install remita-checkout-client
|
|
24
|
+
```
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
needs the full Remita lifecycle.
|
|
26
|
+
The package includes TypeScript types and works with both ESM and CommonJS.
|
|
30
27
|
|
|
31
|
-
|
|
28
|
+
## Environments
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
- fee calculation
|
|
35
|
-
- payment initiation
|
|
36
|
-
- authorization and validation
|
|
37
|
-
- status verification
|
|
38
|
-
- channel lookup and platform configuration
|
|
30
|
+
Choose the environment that matches your key:
|
|
39
31
|
|
|
40
|
-
|
|
32
|
+
| Environment | Base URL |
|
|
33
|
+
| ------------ | ----------------------------------------------------- |
|
|
34
|
+
| `qa` | `https://api-checkout-qa.systemspecsng.com/api/v1` |
|
|
35
|
+
| `demo` | `https://api-checkout-demo.systemspecsng.com/api/v1` |
|
|
36
|
+
| `production` | `https://api-checkout.systemspecsng.com/api/v1` |
|
|
41
37
|
|
|
42
|
-
|
|
38
|
+
Set the environment explicitly, especially for production.
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
```ts
|
|
41
|
+
import { RemitaPlatformClient } from "remita-checkout-client";
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
const client = new RemitaPlatformClient({
|
|
44
|
+
publicKey: process.env.REMITA_PUBLIC_KEY!,
|
|
45
|
+
environment: "qa",
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
Your public key is sent in a request header. Keep secret keys out of browser
|
|
50
|
+
code, and always verify a payment on your server before fulfilling an order.
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
## Merchant checkout
|
|
53
53
|
|
|
54
|
-
|
|
54
|
+
Merchant payments use Remita's hosted inline checkout. The client loads Remita's
|
|
55
|
+
`payment-checkout.js`, then drives the global `RmPaymentEngine` — the same
|
|
56
|
+
integration as Remita's own inline sample — and can verify the payment
|
|
57
|
+
afterwards over REST.
|
|
55
58
|
|
|
56
59
|
```ts
|
|
57
60
|
import { MerchantCheckoutClient } from "remita-checkout-client";
|
|
@@ -61,22 +64,62 @@ const checkout = new MerchantCheckoutClient({
|
|
|
61
64
|
environment: "production",
|
|
62
65
|
});
|
|
63
66
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
paymentIdentifier:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
// Loads Remita's checkout script once and calls RmPaymentEngine.init.
|
|
68
|
+
const engine = await checkout.init({
|
|
69
|
+
paymentIdentifier: 788885554,
|
|
70
|
+
customerId: "abc@ya.com",
|
|
71
|
+
firstName: "Mike",
|
|
72
|
+
lastName: "Mike",
|
|
73
|
+
email: "abc@ya.com",
|
|
74
|
+
phoneNumber: "08067493797",
|
|
75
|
+
amount: "3000",
|
|
76
|
+
narration: "Test Payment",
|
|
77
|
+
currency: "NGN",
|
|
78
|
+
// channels: "TRANSFER",
|
|
79
|
+
onSuccess: (response) => console.log("success", response),
|
|
80
|
+
onError: (response) => console.log("error", response),
|
|
81
|
+
onClose: () => console.log("closed"),
|
|
71
82
|
});
|
|
72
83
|
|
|
73
|
-
|
|
74
|
-
console.log(verified.status);
|
|
84
|
+
engine.openIframe();
|
|
75
85
|
```
|
|
76
86
|
|
|
77
|
-
|
|
87
|
+
After the customer completes payment, verify it on your server before
|
|
88
|
+
fulfilling the order:
|
|
78
89
|
|
|
79
|
-
|
|
90
|
+
```ts
|
|
91
|
+
const verified = await checkout.verifyPayment("PAYMENT_REF_FROM_REMITA");
|
|
92
|
+
if (verified.status === "APPROVED") {
|
|
93
|
+
// Confirm the order on your backend before fulfilling it.
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
To collect an existing Remita Retrieval Reference (RRR) instead, use
|
|
98
|
+
`processRRR`, which mirrors `RmPaymentEngine.processRRR`:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const engine = await checkout.processRRR({
|
|
102
|
+
rrr: "927227066514",
|
|
103
|
+
paymentIdentifier: "7888855540094893435734834935035408",
|
|
104
|
+
channels: "",
|
|
105
|
+
onSuccess: (response) => console.log("success", response),
|
|
106
|
+
onError: (response) => console.log("error", response),
|
|
107
|
+
onClose: () => console.log("closed"),
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
engine.openIframe();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The hosted checkout is browser-only. `init`, `createCheckoutSession`,
|
|
114
|
+
`createSession`, and `processRRR` return the `RmPaymentEngine` instance, so you
|
|
115
|
+
call `openIframe()` to display it exactly like the script tag example. The
|
|
116
|
+
script URL is chosen from the environment and can be overridden with
|
|
117
|
+
`scriptUrl`.
|
|
118
|
+
|
|
119
|
+
## Platform lifecycle
|
|
120
|
+
|
|
121
|
+
`RemitaPlatformClient` walks the full flow: pre-payment, fee, initiation,
|
|
122
|
+
authorization, validation, and verification.
|
|
80
123
|
|
|
81
124
|
```ts
|
|
82
125
|
import { RemitaPlatformClient } from "remita-checkout-client";
|
|
@@ -87,19 +130,16 @@ const remita = new RemitaPlatformClient({
|
|
|
87
130
|
});
|
|
88
131
|
|
|
89
132
|
const pre = await remita.prePayment({
|
|
90
|
-
firstName: "
|
|
91
|
-
lastName: "
|
|
92
|
-
email: "
|
|
133
|
+
firstName: "Ada",
|
|
134
|
+
lastName: "Okafor",
|
|
135
|
+
email: "ada@example.com",
|
|
93
136
|
phoneNumber: "08000000000",
|
|
94
137
|
paymentIdentifier: "ORDER-123",
|
|
95
138
|
currency: "NGN",
|
|
96
139
|
amount: 25000,
|
|
97
140
|
});
|
|
98
141
|
|
|
99
|
-
const fee = await remita.calculateFee({
|
|
100
|
-
amount: 25000,
|
|
101
|
-
channel: "card",
|
|
102
|
-
});
|
|
142
|
+
const fee = await remita.calculateFee({ amount: 25000, channel: "card" });
|
|
103
143
|
|
|
104
144
|
const paymentIdentifier = pre.transactionId ?? pre.paymentReference;
|
|
105
145
|
if (!paymentIdentifier) throw new Error("Pre-payment did not return a transaction reference");
|
|
@@ -110,114 +150,51 @@ const initiated = await remita.initiatePayment({
|
|
|
110
150
|
paymentChannel: "CARD",
|
|
111
151
|
});
|
|
112
152
|
|
|
113
|
-
|
|
114
|
-
console.log(verified.status);
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## ⚠️ Before you use this in anything real
|
|
118
|
-
|
|
119
|
-
The request/response **field names** in `src/types.ts` were written from
|
|
120
|
-
endpoint paths + one-line descriptions only — not the actual DTOs. Every
|
|
121
|
-
interface has an index signature so unexpected fields won't break at the
|
|
122
|
-
type level, but treat the field names themselves as **unverified**. To
|
|
123
|
-
tighten them, pull the actual interfaces out of:
|
|
124
|
-
|
|
125
|
-
- `remita-api-client.service.ts`
|
|
126
|
-
- `payment-status.service.ts`
|
|
127
|
-
|
|
128
|
-
and update `src/types.ts` to match. The transport layer, URLs, HTTP
|
|
129
|
-
methods, and the pre → fee → initiate → authorize → validate → verify
|
|
130
|
-
sequencing are all solid; it's specifically the shape of each request/
|
|
131
|
-
response body that needs confirming.
|
|
132
|
-
|
|
133
|
-
The **environment auto-detection from key prefix** (`src/environment.ts`)
|
|
134
|
-
is also a guess (Stripe-style `pk_test_`/`pk_live_` conventions) — it has
|
|
135
|
-
not been verified against Remita's real key format. It intentionally never
|
|
136
|
-
silently resolves to `"production"` — an unrecognized prefix falls back to
|
|
137
|
-
`"qa"` and reports `detected: false` so you can log/warn on it. Until you
|
|
138
|
-
verify the real prefixes, pass `environment` explicitly and skip detection.
|
|
139
|
-
|
|
140
|
-
## Install
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
npm install remita-checkout-client
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## Usage
|
|
147
|
-
|
|
148
|
-
### Low-level client
|
|
149
|
-
|
|
150
|
-
```ts
|
|
151
|
-
import { RemitaCheckoutClient } from "remita-checkout-client";
|
|
152
|
-
|
|
153
|
-
const client = new RemitaCheckoutClient({
|
|
154
|
-
publicKey: "YOUR_PUBLIC_KEY",
|
|
155
|
-
// environment: "qa", // recommended explicitly until prefix detection is verified
|
|
156
|
-
onEnvironmentDetectionFallback: (guessed) =>
|
|
157
|
-
console.warn(`Couldn't detect environment from key prefix, defaulting to ${guessed}`),
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
const pre = await client.prePayment({
|
|
161
|
-
firstName: "Test",
|
|
162
|
-
lastName: "User",
|
|
163
|
-
email: "test@example.com",
|
|
164
|
-
phoneNumber: "08000000000",
|
|
165
|
-
paymentIdentifier: "ORDER-123",
|
|
166
|
-
currency: "NGN",
|
|
167
|
-
amount: 5000,
|
|
168
|
-
});
|
|
169
|
-
const fee = await client.calculateFee({ publicKey: client.publicKey, amount: 5000, channel: "card" });
|
|
170
|
-
const paymentIdentifier = pre.transactionId ?? pre.paymentReference;
|
|
171
|
-
if (!paymentIdentifier) throw new Error("Pre-payment did not return a transaction reference");
|
|
172
|
-
const initiated = await client.initiatePayment({
|
|
173
|
-
amount: 5000,
|
|
174
|
-
paymentIdentifier: "TRANSACTION_REF_123",
|
|
175
|
-
paymentChannel: "CARD",
|
|
176
|
-
});
|
|
177
|
-
|
|
153
|
+
// Only when the payment processor asks for it:
|
|
178
154
|
if (initiated.actionUrl) {
|
|
179
|
-
await
|
|
155
|
+
await remita.authorize(initiated.actionUrl, { otp: "123456" });
|
|
156
|
+
await remita.validatePayment({ paymentReference: initiated.paymentReference, otp: "123456" });
|
|
180
157
|
}
|
|
181
158
|
|
|
182
|
-
const verified = await
|
|
159
|
+
const verified = await remita.verifyPayment(initiated.paymentReference!);
|
|
183
160
|
console.log(verified.status); // "APPROVED" | "PENDING" | "FAILED" | ...
|
|
184
161
|
```
|
|
185
162
|
|
|
186
|
-
###
|
|
163
|
+
### Tracking a payment with PaymentSession
|
|
164
|
+
|
|
165
|
+
`PaymentSession` carries the references between steps so you don't have to, and
|
|
166
|
+
tracks the current stage of the flow. Its `stage` becomes `verified` only when
|
|
167
|
+
the payment is `APPROVED` and `failed` when it is `FAILED`; a `PENDING` payment
|
|
168
|
+
leaves the stage unchanged.
|
|
187
169
|
|
|
188
170
|
```ts
|
|
189
|
-
import {
|
|
171
|
+
import { RemitaPlatformClient, PaymentSession } from "remita-checkout-client";
|
|
190
172
|
|
|
191
|
-
const client = new
|
|
173
|
+
const client = new RemitaPlatformClient({ publicKey: "YOUR_PUBLIC_KEY", environment: "qa" });
|
|
192
174
|
const session = new PaymentSession(client);
|
|
193
175
|
|
|
194
176
|
await session.pre({
|
|
195
|
-
firstName: "
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
phoneNumber: "08000000000",
|
|
199
|
-
paymentIdentifier: "ORDER-123",
|
|
200
|
-
currency: "NGN",
|
|
201
|
-
amount: 5000,
|
|
177
|
+
firstName: "Ada", lastName: "Okafor", email: "ada@example.com",
|
|
178
|
+
phoneNumber: "08000000000", paymentIdentifier: "ORDER-123",
|
|
179
|
+
currency: "NGN", amount: 25000,
|
|
202
180
|
});
|
|
203
|
-
await session.fee({
|
|
181
|
+
await session.fee({ amount: 25000, channel: "card" });
|
|
182
|
+
|
|
204
183
|
const paymentIdentifier = session.transactionId ?? session.paymentReference;
|
|
205
184
|
if (!paymentIdentifier) throw new Error("Pre-payment did not return a transaction reference");
|
|
206
|
-
await session.initiate({
|
|
207
|
-
amount: 5000,
|
|
208
|
-
paymentIdentifier,
|
|
209
|
-
paymentChannel: "CARD",
|
|
210
|
-
});
|
|
185
|
+
await session.initiate({ amount: 25000, paymentIdentifier, paymentChannel: "CARD" });
|
|
211
186
|
|
|
212
|
-
// actionUrl from initiate() is remembered automatically
|
|
187
|
+
// The actionUrl from initiate() is remembered automatically.
|
|
213
188
|
await session.authorize({ otp: "123456" });
|
|
214
189
|
await session.validate({ otp: "123456" });
|
|
215
190
|
|
|
216
|
-
const result = await session.verify();
|
|
191
|
+
const result = await session.verify();
|
|
217
192
|
console.log(session.stage, result.status);
|
|
218
193
|
```
|
|
219
194
|
|
|
220
|
-
|
|
195
|
+
## Real-time payment status
|
|
196
|
+
|
|
197
|
+
Follow a payment's status live with server-sent events:
|
|
221
198
|
|
|
222
199
|
```ts
|
|
223
200
|
const handle = client.streamPaymentStatus(trxRef, {
|
|
@@ -226,15 +203,10 @@ const handle = client.streamPaymentStatus(trxRef, {
|
|
|
226
203
|
onError: (err) => console.error("stream error:", err),
|
|
227
204
|
});
|
|
228
205
|
|
|
229
|
-
//
|
|
230
|
-
handle.close();
|
|
206
|
+
handle.close(); // when you're done
|
|
231
207
|
```
|
|
232
208
|
|
|
233
|
-
|
|
234
|
-
browser-only `EventSource` global), so it behaves the same in the browser
|
|
235
|
-
and in Node.
|
|
236
|
-
|
|
237
|
-
### Channel config endpoints
|
|
209
|
+
## Channel and configuration lookups
|
|
238
210
|
|
|
239
211
|
```ts
|
|
240
212
|
const banks = await client.getBankList();
|
|
@@ -242,36 +214,105 @@ const ussdCodes = await client.getUssdCodes();
|
|
|
242
214
|
const wallets = await client.getWalletTypes();
|
|
243
215
|
```
|
|
244
216
|
|
|
245
|
-
##
|
|
217
|
+
## Command line
|
|
246
218
|
|
|
247
|
-
|
|
219
|
+
The package also installs a `remita-checkout` command with two groups:
|
|
220
|
+
`merchant` and `platform`.
|
|
248
221
|
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const client = new RemitaCheckoutClient({
|
|
253
|
-
publicKey: "...",
|
|
254
|
-
environment: "qa",
|
|
255
|
-
fetchImpl: fetch as unknown as typeof globalThis.fetch,
|
|
256
|
-
});
|
|
222
|
+
```bash
|
|
223
|
+
remita-checkout <group> <command> [options]
|
|
257
224
|
```
|
|
258
225
|
|
|
259
|
-
|
|
226
|
+
### Merchant commands
|
|
227
|
+
|
|
228
|
+
| Command | Description |
|
|
229
|
+
| ------------------ | -------------------------------- |
|
|
230
|
+
| `merchant verify` | Verify a payment by reference |
|
|
231
|
+
| `merchant status` | Alias for `verify` |
|
|
232
|
+
|
|
233
|
+
Merchant checkout itself runs in the browser through the hosted
|
|
234
|
+
`RmPaymentEngine`, so there is no CLI command to start it — the CLI only checks
|
|
235
|
+
payment status.
|
|
236
|
+
|
|
237
|
+
### Platform commands
|
|
238
|
+
|
|
239
|
+
| Command | Description |
|
|
240
|
+
| -------------------- | --------------------------------------------- |
|
|
241
|
+
| `platform pre` | Pre-payment initialization |
|
|
242
|
+
| `platform fee` | Calculate the fee for a channel |
|
|
243
|
+
| `platform initiate` | Initiate a payment |
|
|
244
|
+
| `platform authorize` | Submit authorization details |
|
|
245
|
+
| `platform validate` | Complete second-factor authorization (OTP) |
|
|
246
|
+
| `platform verify` | Verify payment status by reference |
|
|
247
|
+
| `platform stream` | Stream real-time status updates |
|
|
248
|
+
| `platform banks` | List supported banks |
|
|
249
|
+
| `platform ussd` | List USSD codes |
|
|
250
|
+
| `platform wallets` | List wallet types |
|
|
251
|
+
|
|
252
|
+
### Options
|
|
253
|
+
|
|
254
|
+
| Option | Description |
|
|
255
|
+
| ----------------------------- | --------------------------------------------------- |
|
|
256
|
+
| `--key <publicKey>` | Remita public key (required for most commands) |
|
|
257
|
+
| `--env <qa\|demo\|production>`| Environment to use |
|
|
258
|
+
| `--payment-identifier <ref>` | Reference from the payment flow |
|
|
259
|
+
| `--payment-channel <channel>` | Payment channel, e.g. `CARD` |
|
|
260
|
+
| `--payload <json>` | Additional details as JSON |
|
|
261
|
+
| `--show-payload` | Preview the request with sensitive fields redacted |
|
|
262
|
+
| `--json` | Print raw JSON, useful for piping |
|
|
263
|
+
|
|
264
|
+
### Examples
|
|
260
265
|
|
|
261
|
-
|
|
266
|
+
```bash
|
|
267
|
+
remita-checkout merchant verify --key QA-abc123 --ref PAY-REF-1 --json
|
|
268
|
+
remita-checkout platform pre --key QA-abc123 --rrr 123456789
|
|
269
|
+
remita-checkout platform verify --key QA-abc123 --ref PAY-REF-1 --json
|
|
270
|
+
```
|
|
262
271
|
|
|
263
|
-
-
|
|
264
|
-
|
|
265
|
-
return listener endpoint)
|
|
272
|
+
Only use Remita-approved test data in QA. Never pass real card details on the
|
|
273
|
+
command line — `--show-payload` redacts them, but shell history does not.
|
|
266
274
|
|
|
267
|
-
|
|
268
|
-
CyberSource's Accept.js script loading) — worth their own follow-up rather
|
|
269
|
-
than bolting on here.
|
|
275
|
+
## Errors
|
|
270
276
|
|
|
271
|
-
|
|
277
|
+
Failed requests throw a `RemitaApiError` that includes the HTTP status and the
|
|
278
|
+
error details returned by the API:
|
|
272
279
|
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
280
|
+
```ts
|
|
281
|
+
import { RemitaApiError } from "remita-checkout-client";
|
|
282
|
+
|
|
283
|
+
try {
|
|
284
|
+
await client.verifyPayment("PAYMENT_REF");
|
|
285
|
+
} catch (error) {
|
|
286
|
+
if (error instanceof RemitaApiError) {
|
|
287
|
+
console.error(error.status, error.message, error.payload);
|
|
288
|
+
} else {
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
277
292
|
```
|
|
293
|
+
|
|
294
|
+
## API coverage
|
|
295
|
+
|
|
296
|
+
| Operation | Method and path |
|
|
297
|
+
| ---------------------------- | --------------------------------------------------- |
|
|
298
|
+
| Pre-payment | `POST /payment/pre` |
|
|
299
|
+
| Fee calculation | `POST /payment/pre/feeCharge` |
|
|
300
|
+
| Initiate / merchant checkout | `POST /payment/initiate` |
|
|
301
|
+
| Authorize | `POST` to the action URL returned by initiation |
|
|
302
|
+
| Validate payment | `POST /payment/validate` |
|
|
303
|
+
| Verify payment | `GET /payment/verify/{reference}` |
|
|
304
|
+
| Payment status stream | `GET /payment/status/stream/{transactionReference}` |
|
|
305
|
+
| Bank list | `GET /payment/bank-list` |
|
|
306
|
+
| USSD codes | `GET /misc/ussd-codes` |
|
|
307
|
+
| Wallet types | `GET /misc/wallet-type` |
|
|
308
|
+
|
|
309
|
+
## Notes
|
|
310
|
+
|
|
311
|
+
- Google Pay / Apple Pay configuration and the CyberSource / Cardinal 3DS iframe
|
|
312
|
+
flow are not included in this version.
|
|
313
|
+
- Confirm request and response details against Remita's current API
|
|
314
|
+
documentation for your environment before going live.
|
|
315
|
+
|
|
316
|
+
## License
|
|
317
|
+
|
|
318
|
+
MIT
|
|
@@ -5,6 +5,16 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
5
5
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
+
// src/types.ts
|
|
9
|
+
var RemitaApiError = class extends Error {
|
|
10
|
+
constructor(message, status, payload) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "RemitaApiError";
|
|
13
|
+
this.status = status;
|
|
14
|
+
this.payload = payload;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
8
18
|
// src/environment.ts
|
|
9
19
|
var ENVIRONMENT_BASE_URLS = {
|
|
10
20
|
qa: "https://api-checkout-qa.systemspecsng.com/api/v1",
|
|
@@ -91,15 +101,39 @@ function openStatusStream(baseUrl, trxRef, publicKey, options) {
|
|
|
91
101
|
};
|
|
92
102
|
}
|
|
93
103
|
|
|
94
|
-
// src/
|
|
95
|
-
var
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
this.payload = payload;
|
|
100
|
-
this.name = "RemitaApiError";
|
|
101
|
-
}
|
|
104
|
+
// src/inline.ts
|
|
105
|
+
var INLINE_CHECKOUT_SCRIPT_URLS = {
|
|
106
|
+
qa: "https://checkout-web-qa.systemspecsng.com/js/payment-checkout.js",
|
|
107
|
+
demo: "https://checkout-web-demo.systemspecsng.com/js/payment-checkout.js",
|
|
108
|
+
production: "https://checkout-web.systemspecsng.com/js/payment-checkout.js"
|
|
102
109
|
};
|
|
110
|
+
function getInlineCheckoutScriptUrl(environment, override) {
|
|
111
|
+
return override ?? INLINE_CHECKOUT_SCRIPT_URLS[environment];
|
|
112
|
+
}
|
|
113
|
+
function loadInlineCheckoutScript(scriptUrl, env = {}) {
|
|
114
|
+
const win = env.window ?? globalThis;
|
|
115
|
+
const doc = env.document ?? win.document;
|
|
116
|
+
if (!doc) {
|
|
117
|
+
return Promise.reject(
|
|
118
|
+
new Error("Inline checkout requires a browser DOM (no document available).")
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
if (win.RmPaymentEngine) return Promise.resolve();
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
const script = doc.createElement("script");
|
|
124
|
+
script.src = scriptUrl;
|
|
125
|
+
script.async = true;
|
|
126
|
+
script.onload = () => resolve();
|
|
127
|
+
script.onerror = () => reject(new Error(`Failed to load Remita checkout script: ${scriptUrl}`));
|
|
128
|
+
doc.head?.appendChild(script);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function getRmPaymentEngine(env = {}) {
|
|
132
|
+
const win = env.window ?? globalThis;
|
|
133
|
+
return win.RmPaymentEngine;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// src/http-client.ts
|
|
103
137
|
var HttpClient = class {
|
|
104
138
|
constructor(options) {
|
|
105
139
|
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
@@ -191,15 +225,51 @@ var CheckoutCoreClient = class {
|
|
|
191
225
|
}
|
|
192
226
|
};
|
|
193
227
|
var MerchantCheckoutClient = class extends CheckoutCoreClient {
|
|
228
|
+
constructor(options) {
|
|
229
|
+
super(options);
|
|
230
|
+
this.scriptLoaded = false;
|
|
231
|
+
this.scriptUrl = getInlineCheckoutScriptUrl(
|
|
232
|
+
this.environment,
|
|
233
|
+
options.scriptUrl
|
|
234
|
+
);
|
|
235
|
+
this.inlineEnvironment = options.inlineEnvironment ?? {};
|
|
236
|
+
}
|
|
194
237
|
/**
|
|
195
|
-
* Merchant checkout
|
|
196
|
-
* payment
|
|
238
|
+
* Merchant checkout mirrors Remita's hosted inline flow: load
|
|
239
|
+
* `payment-checkout.js`, then drive the global `RmPaymentEngine`.
|
|
197
240
|
*/
|
|
198
|
-
|
|
199
|
-
|
|
241
|
+
async load() {
|
|
242
|
+
if (this.scriptLoaded) return;
|
|
243
|
+
await loadInlineCheckoutScript(this.scriptUrl, this.inlineEnvironment);
|
|
244
|
+
this.scriptLoaded = true;
|
|
245
|
+
}
|
|
246
|
+
engine() {
|
|
247
|
+
const engine = getRmPaymentEngine(this.inlineEnvironment);
|
|
248
|
+
if (!engine) {
|
|
249
|
+
throw new Error(
|
|
250
|
+
"RmPaymentEngine is not available. Call load() before creating a checkout session."
|
|
251
|
+
);
|
|
252
|
+
}
|
|
253
|
+
return engine;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Mirrors `RmPaymentEngine.init(...)`. The returned engine's `openIframe()`
|
|
257
|
+
* opens the hosted checkout. The public key is injected automatically.
|
|
258
|
+
*/
|
|
259
|
+
async init(options = {}) {
|
|
260
|
+
await this.load();
|
|
261
|
+
return this.engine().init({ key: this.publicKey, ...options });
|
|
262
|
+
}
|
|
263
|
+
async createCheckoutSession(options = {}) {
|
|
264
|
+
return this.init(options);
|
|
265
|
+
}
|
|
266
|
+
async createSession(options = {}) {
|
|
267
|
+
return this.init(options);
|
|
200
268
|
}
|
|
201
|
-
|
|
202
|
-
|
|
269
|
+
/** Mirrors `RmPaymentEngine.processRRR(...)` for RRR-based payments. */
|
|
270
|
+
async processRRR(options) {
|
|
271
|
+
await this.load();
|
|
272
|
+
return this.engine().processRRR({ key: this.publicKey, ...options });
|
|
203
273
|
}
|
|
204
274
|
};
|
|
205
275
|
var RemitaPlatformClient = class extends CheckoutCoreClient {
|
|
@@ -257,12 +327,17 @@ var RemitaCheckoutClient = class extends RemitaPlatformClient {
|
|
|
257
327
|
|
|
258
328
|
export {
|
|
259
329
|
__require,
|
|
330
|
+
RemitaApiError,
|
|
260
331
|
ENVIRONMENT_BASE_URLS,
|
|
261
332
|
resolveEnvironment,
|
|
262
333
|
openStatusStream,
|
|
334
|
+
INLINE_CHECKOUT_SCRIPT_URLS,
|
|
335
|
+
getInlineCheckoutScriptUrl,
|
|
336
|
+
loadInlineCheckoutScript,
|
|
337
|
+
getRmPaymentEngine,
|
|
263
338
|
CheckoutCoreClient,
|
|
264
339
|
MerchantCheckoutClient,
|
|
265
340
|
RemitaPlatformClient,
|
|
266
341
|
RemitaCheckoutClient
|
|
267
342
|
};
|
|
268
|
-
//# sourceMappingURL=chunk-
|
|
343
|
+
//# sourceMappingURL=chunk-O2KJGHVA.mjs.map
|