remita-inline 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 remita-inline contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,308 @@
1
+ # remita-inline
2
+
3
+ A fully-typed TypeScript wrapper for the Remita Inline payment SDK with an RRR-only integration flow.
4
+
5
+ The library supports one payment path:
6
+ - generate or receive an RRR upstream
7
+ - pass that RRR into the SDK
8
+ - open the Remita payment widget
9
+
10
+ It works as a plain function, a React hook, or a React button component.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install remita-inline
16
+ ```
17
+
18
+ If you use the React hook or button component, install React separately:
19
+
20
+ ```bash
21
+ npm install react react-dom
22
+ ```
23
+
24
+ ## Quick start
25
+
26
+ ```ts
27
+ import { startRemitaPayment } from "remita-inline";
28
+
29
+ await startRemitaPayment(
30
+ {
31
+ key: "your-public-key",
32
+ rrr: "321489526389",
33
+ transactionId: "unique-tx-id",
34
+ onSuccess(response) {
35
+ console.log("Payment successful", response.transactionId);
36
+ },
37
+ onError(error) {
38
+ console.error("Payment failed", error.message);
39
+ },
40
+ onClose() {
41
+ console.log("Payment modal closed");
42
+ },
43
+ },
44
+ {
45
+ environment: "demo",
46
+ },
47
+ );
48
+ ```
49
+
50
+ By default the widget opens automatically after the SDK loads. Pass `autoOpen: false` if you want to control when the widget appears.
51
+
52
+ ## React hook
53
+
54
+ ```tsx
55
+ import { useRemitaInline } from "remita-inline";
56
+
57
+ function RrrPaymentButton() {
58
+ const { pay, isLoading, error, reset } = useRemitaInline({ environment: "demo" });
59
+
60
+ const handlePay = async () => {
61
+ try {
62
+ await pay({
63
+ key: "your-public-key",
64
+ rrr: "321489526389",
65
+ transactionId: "unique-tx-id",
66
+ onSuccess(res) {
67
+ console.log("Paid", res.transactionId);
68
+ },
69
+ });
70
+ } catch {
71
+ // error is already available in hook state
72
+ }
73
+ };
74
+
75
+ return (
76
+ <>
77
+ {error && (
78
+ <p>
79
+ Payment failed: {error.message}{" "}
80
+ <button onClick={reset}>Dismiss</button>
81
+ </p>
82
+ )}
83
+ <button onClick={handlePay} disabled={isLoading}>
84
+ {isLoading ? "Processing..." : "Pay with RRR"}
85
+ </button>
86
+ </>
87
+ );
88
+ }
89
+ ```
90
+
91
+ Per-call options are merged over hook-level defaults.
92
+
93
+ ## React button component
94
+
95
+ ```tsx
96
+ import { RemitaPayButton } from "remita-inline";
97
+
98
+ function Checkout() {
99
+ return (
100
+ <RemitaPayButton
101
+ paymentConfig={{
102
+ key: "your-public-key",
103
+ rrr: "321489526389",
104
+ transactionId: "unique-tx-id",
105
+ onSuccess(res) {
106
+ console.log("Paid", res.transactionId);
107
+ },
108
+ }}
109
+ paymentOptions={{ environment: "demo" }}
110
+ onPaymentStart={() => console.log("Payment started")}
111
+ onPaymentError={(err) => console.error(err.message)}
112
+ loadingText="Please wait..."
113
+ >
114
+ Pay with RRR
115
+ </RemitaPayButton>
116
+ );
117
+ }
118
+ ```
119
+
120
+ All standard button attributes are forwarded. If your custom `onClick` calls `event.preventDefault()`, the payment flow is cancelled.
121
+
122
+ ## Low-level API
123
+
124
+ ```ts
125
+ import { loadRemitaScript, initRemitaEngine } from "remita-inline";
126
+
127
+ await loadRemitaScript({ environment: "demo", timeoutMs: 10000 });
128
+
129
+ const session = initRemitaEngine({
130
+ key: "your-public-key",
131
+ rrr: "321489526389",
132
+ transactionId: "unique-tx-id",
133
+ });
134
+
135
+ session.openIframe();
136
+ ```
137
+
138
+ Or defer opening with `startRemitaPayment`:
139
+
140
+ ```ts
141
+ import { startRemitaPayment } from "remita-inline";
142
+
143
+ const { open } = await startRemitaPayment(
144
+ {
145
+ key: "your-public-key",
146
+ rrr: "321489526389",
147
+ transactionId: "unique-tx-id",
148
+ },
149
+ {
150
+ autoOpen: false,
151
+ environment: "demo",
152
+ },
153
+ );
154
+
155
+ open();
156
+ ```
157
+
158
+ ## Configuration reference
159
+
160
+ ### `RemitaPaymentConfig`
161
+
162
+ | Field | Type | Required | Description |
163
+ |---|---|---|---|
164
+ | `key` | `string` | Yes | Your Remita public key |
165
+ | `rrr` | `string \| number` | Yes | The Remita Retrieval Reference to pay |
166
+ | `transactionId` | `string \| number` | No | Optional transaction reference from your application |
167
+ | `extendedData` | `RemitaExtendedData` | No | Extra data merged into the internal Remita payload |
168
+ | `currency` | `RemitaCurrencyCode` | No | Optional currency override |
169
+ | `metadata` | `Record<string, string \| number \| boolean \| null>` | No | Arbitrary metadata |
170
+ | `onSuccess` | `(res: RemitaSuccessfulPayment) => void` | No | Called on successful payment |
171
+ | `onError` | `(err: RemitaPaymentError) => void` | No | Called on payment failure |
172
+ | `onClose` | `() => void` | No | Called when the payment modal closes |
173
+
174
+ ### `RemitaExtendedData`
175
+
176
+ | Field | Type | Description |
177
+ |---|---|---|
178
+ | `customFields` | `RemitaExtendedDataCustomField[]` | Additional custom fields merged into the Remita payload |
179
+
180
+ The library always injects the `rrr` field into `extendedData.customFields` before calling the Remita engine. Any extra custom fields you provide are preserved.
181
+
182
+ ### `RemitaStartPaymentOptions` / `RemitaLibraryOptions`
183
+
184
+ | Field | Type | Default | Description |
185
+ |---|---|---|---|
186
+ | `autoOpen` | `boolean` | `true` | Open the payment widget immediately |
187
+ | `environment` | `"demo" \| "production"` | `"production"` | Select the Remita SDK environment |
188
+ | `scriptUrl` | `string` | Environment-specific URL | Override the SDK script URL manually |
189
+ | `scriptId` | `string` | `"remita-inline-sdk"` | `id` attribute of the injected script tag |
190
+ | `timeoutMs` | `number` | `15000` | Script load timeout in milliseconds |
191
+ | `nonce` | `string` | None | CSP nonce for the injected script tag |
192
+
193
+ ## Error handling
194
+
195
+ All library errors extend `RemitaError`.
196
+
197
+ | Class | Thrown when |
198
+ |---|---|
199
+ | `ValidationError` | Required fields such as `key` or `rrr` are missing or invalid |
200
+ | `ScriptLoadError` | The Remita SDK script fails to load, times out, or runs outside a browser |
201
+ | `EngineError` | `window.RmPaymentEngine` is missing or returns an invalid session |
202
+
203
+ ```ts
204
+ import {
205
+ startRemitaPayment,
206
+ ValidationError,
207
+ ScriptLoadError,
208
+ } from "remita-inline";
209
+
210
+ try {
211
+ await startRemitaPayment({
212
+ key: "your-public-key",
213
+ rrr: "321489526389",
214
+ });
215
+ } catch (error) {
216
+ if (error instanceof ValidationError) {
217
+ showFormError(error.message);
218
+ } else if (error instanceof ScriptLoadError) {
219
+ showNetworkError();
220
+ } else {
221
+ throw error;
222
+ }
223
+ }
224
+ ```
225
+
226
+ ## Advanced options
227
+
228
+ ### Demo vs production
229
+
230
+ ```ts
231
+ await startRemitaPayment(config, { environment: "demo" });
232
+ await startRemitaPayment(config, { environment: "production" });
233
+ ```
234
+
235
+ ### Pre-loading the script
236
+
237
+ ```ts
238
+ import { loadRemitaScript } from "remita-inline";
239
+
240
+ await loadRemitaScript({ environment: "demo" });
241
+ ```
242
+
243
+ `loadRemitaScript` is idempotent: concurrent calls share one in-flight Promise, and if the engine is already on `window` it returns immediately.
244
+
245
+ ### Content Security Policy (CSP)
246
+
247
+ ```ts
248
+ await startRemitaPayment(config, { nonce: "abc123" });
249
+ ```
250
+
251
+ ### Adding extra custom fields
252
+
253
+ ```ts
254
+ await startRemitaPayment({
255
+ key: "your-public-key",
256
+ rrr: "321489526389",
257
+ extendedData: {
258
+ customFields: [
259
+ { name: "orderId", value: "ORD-123" },
260
+ { name: "customerTier", value: "gold" },
261
+ ],
262
+ },
263
+ });
264
+ ```
265
+
266
+ ## TypeScript
267
+
268
+ All public types are exported from the package root:
269
+
270
+ ```ts
271
+ import type {
272
+ RemitaEngine,
273
+ RemitaEnginePaymentConfig,
274
+ RemitaEngineSession,
275
+ RemitaExtendedData,
276
+ RemitaExtendedDataCustomField,
277
+ RemitaPaymentConfig,
278
+ RemitaPaymentError,
279
+ RemitaPaymentSession,
280
+ RemitaStartPaymentOptions,
281
+ RemitaSuccessfulPayment,
282
+ UseRemitaInlineResult,
283
+ } from "remita-inline";
284
+ ```
285
+
286
+ The package ships with declaration files and source maps in `dist/`. Both ESM and CJS consumers are supported via the `exports` field in `package.json`.
287
+
288
+ ## Browser support
289
+
290
+ Requires a browser with native `Promise`, `addEventListener`, and `document.createElement`. Equivalent to ES2020 environments. The library is browser-only because the Remita SDK depends on `window` and `document`.
291
+
292
+ For Next.js, render payment UI inside a `"use client"` component or guard execution with `typeof window !== "undefined"`.
293
+
294
+ ## Contributing
295
+
296
+ ```bash
297
+ git clone https://github.com/your-org/remita-inline
298
+ cd remita-inline
299
+ npm install
300
+
301
+ npm run typecheck
302
+ npm test
303
+ npm run build
304
+ ```
305
+
306
+ ## License
307
+
308
+ [MIT](LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,371 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/core/constant.ts
7
+ var REMITA_SCRIPT_ID = "remita-inline-sdk";
8
+ var REMITA_PRODUCTION_SCRIPT_URL = "https://login.remita.net/payment/v1/remita-pay-inline.bundle.js";
9
+ var REMITA_DEMO_SCRIPT_URL = "https://demo.remita.net/payment/v1/remita-pay-inline.bundle.js";
10
+ var REMITA_SCRIPT_URL = REMITA_PRODUCTION_SCRIPT_URL;
11
+ var REMITA_ENGINE = "RmPaymentEngine";
12
+
13
+ // src/utils/once.ts
14
+ var promise = null;
15
+ function getPromise() {
16
+ return promise;
17
+ }
18
+ function setPromise(value) {
19
+ promise = value;
20
+ }
21
+ function clearPromise() {
22
+ promise = null;
23
+ }
24
+
25
+ // src/utils/errors.ts
26
+ var RemitaError = class extends Error {
27
+ constructor(message) {
28
+ super(message);
29
+ this.name = "RemitaError";
30
+ }
31
+ };
32
+ var ValidationError = class extends RemitaError {
33
+ constructor(message) {
34
+ super(message);
35
+ this.name = "ValidationError";
36
+ }
37
+ };
38
+ var ScriptLoadError = class extends RemitaError {
39
+ constructor(message) {
40
+ super(message);
41
+ this.name = "ScriptLoadError";
42
+ }
43
+ };
44
+ var EngineError = class extends RemitaError {
45
+ constructor(message) {
46
+ super(message);
47
+ this.name = "EngineError";
48
+ }
49
+ };
50
+
51
+ // src/core/loader.ts
52
+ function isBrowserEnvironment() {
53
+ return typeof window !== "undefined" && typeof document !== "undefined";
54
+ }
55
+ function getEngine(win) {
56
+ return win[REMITA_ENGINE];
57
+ }
58
+ function resolveScriptUrl(options) {
59
+ if (options.scriptUrl) {
60
+ return options.scriptUrl;
61
+ }
62
+ if (options.environment === "demo") {
63
+ return REMITA_DEMO_SCRIPT_URL;
64
+ }
65
+ if (options.environment === "production") {
66
+ return REMITA_PRODUCTION_SCRIPT_URL;
67
+ }
68
+ return REMITA_SCRIPT_URL;
69
+ }
70
+ function waitForExistingScript(script, timeoutMs, win) {
71
+ if (script.dataset.loaded === "true" && getEngine(win)) {
72
+ return Promise.resolve();
73
+ }
74
+ return new Promise((resolve, reject) => {
75
+ let timeoutId;
76
+ const onLoad = () => {
77
+ cleanup();
78
+ script.dataset.loaded = "true";
79
+ if (!getEngine(win)) {
80
+ reject(new ScriptLoadError("Remita script loaded but payment engine is unavailable."));
81
+ return;
82
+ }
83
+ resolve();
84
+ };
85
+ const onError = () => {
86
+ cleanup();
87
+ reject(new ScriptLoadError("Failed to load Remita script."));
88
+ };
89
+ const cleanup = () => {
90
+ script.removeEventListener("load", onLoad);
91
+ script.removeEventListener("error", onError);
92
+ if (timeoutId) {
93
+ clearTimeout(timeoutId);
94
+ }
95
+ };
96
+ script.addEventListener("load", onLoad, { once: true });
97
+ script.addEventListener("error", onError, { once: true });
98
+ timeoutId = setTimeout(() => {
99
+ cleanup();
100
+ reject(new ScriptLoadError(`Timed out waiting for Remita script after ${timeoutMs}ms.`));
101
+ }, timeoutMs);
102
+ });
103
+ }
104
+ function createAndLoadScript(scriptId, scriptUrl, timeoutMs, nonce) {
105
+ const win = window;
106
+ return new Promise((resolve, reject) => {
107
+ const script = document.createElement("script");
108
+ let timeoutId;
109
+ script.id = scriptId;
110
+ script.src = scriptUrl;
111
+ script.async = true;
112
+ if (nonce) {
113
+ script.nonce = nonce;
114
+ }
115
+ const onLoad = () => {
116
+ cleanup();
117
+ script.dataset.loaded = "true";
118
+ if (!getEngine(win)) {
119
+ reject(new ScriptLoadError("Remita script loaded but payment engine is unavailable."));
120
+ return;
121
+ }
122
+ resolve();
123
+ };
124
+ const onError = () => {
125
+ cleanup();
126
+ reject(new ScriptLoadError("Failed to load Remita script."));
127
+ };
128
+ const cleanup = () => {
129
+ script.removeEventListener("load", onLoad);
130
+ script.removeEventListener("error", onError);
131
+ if (timeoutId) {
132
+ clearTimeout(timeoutId);
133
+ }
134
+ };
135
+ script.addEventListener("load", onLoad, { once: true });
136
+ script.addEventListener("error", onError, { once: true });
137
+ timeoutId = setTimeout(() => {
138
+ cleanup();
139
+ script.remove();
140
+ reject(new ScriptLoadError(`Timed out loading Remita script after ${timeoutMs}ms.`));
141
+ }, timeoutMs);
142
+ document.head.appendChild(script);
143
+ });
144
+ }
145
+ async function loadRemitaScript(options = {}) {
146
+ if (!isBrowserEnvironment()) {
147
+ throw new ScriptLoadError("Remita script loader can only run in a browser environment.");
148
+ }
149
+ const scriptId = options.scriptId ?? REMITA_SCRIPT_ID;
150
+ const scriptUrl = resolveScriptUrl(options);
151
+ const timeoutMs = options.timeoutMs ?? 15e3;
152
+ const win = window;
153
+ if (getEngine(win)) {
154
+ return;
155
+ }
156
+ const inFlight = getPromise();
157
+ if (inFlight) {
158
+ return inFlight;
159
+ }
160
+ const task = (async () => {
161
+ const existingScript = document.getElementById(scriptId);
162
+ if (existingScript) {
163
+ if (existingScript.src && existingScript.src !== scriptUrl) {
164
+ throw new ScriptLoadError(
165
+ `Script with id "${scriptId}" already exists with a different src.`
166
+ );
167
+ }
168
+ await waitForExistingScript(existingScript, timeoutMs, win);
169
+ return;
170
+ }
171
+ await createAndLoadScript(scriptId, scriptUrl, timeoutMs, options.nonce);
172
+ })();
173
+ setPromise(task);
174
+ try {
175
+ await task;
176
+ } catch (error) {
177
+ clearPromise();
178
+ throw error;
179
+ }
180
+ }
181
+
182
+ // src/core/engine.ts
183
+ function isBrowserEnvironment2() {
184
+ return typeof window !== "undefined";
185
+ }
186
+ function getRemitaEngine(win) {
187
+ if (!isBrowserEnvironment2()) {
188
+ throw new EngineError("Remita engine is only available in a browser environment.");
189
+ }
190
+ const targetWindow = win ?? window;
191
+ const engine = targetWindow[REMITA_ENGINE];
192
+ if (!engine || typeof engine.init !== "function") {
193
+ throw new EngineError("Remita payment engine is unavailable on window.");
194
+ }
195
+ return engine;
196
+ }
197
+ function initRemitaEngine(config, win) {
198
+ const engine = getRemitaEngine(win);
199
+ const rawSession = engine.init(toEnginePaymentConfig(config));
200
+ const openIframe = typeof rawSession.openIframe === "function" ? rawSession.openIframe.bind(rawSession) : typeof rawSession.showPaymentWidget === "function" ? rawSession.showPaymentWidget.bind(rawSession) : void 0;
201
+ if (!openIframe) {
202
+ throw new EngineError("Remita engine returned an invalid payment session.");
203
+ }
204
+ return {
205
+ openIframe,
206
+ ...typeof rawSession.showPaymentWidget === "function" ? { showPaymentWidget: rawSession.showPaymentWidget.bind(rawSession) } : {}
207
+ };
208
+ }
209
+ function toEnginePaymentConfig(config) {
210
+ const { rrr, extendedData, ...rest } = config;
211
+ const engineExtendedData = {
212
+ ...extendedData ?? {},
213
+ customFields: [
214
+ ...(extendedData?.customFields ?? []).filter((field) => field?.name !== "rrr"),
215
+ {
216
+ name: "rrr",
217
+ value: rrr
218
+ }
219
+ ]
220
+ };
221
+ return {
222
+ ...rest,
223
+ processRrr: true,
224
+ extendedData: engineExtendedData
225
+ };
226
+ }
227
+
228
+ // src/core/validator.ts
229
+ function assertNonEmptyString(value, fieldName) {
230
+ if (typeof value !== "string" || value.trim().length === 0) {
231
+ throw new ValidationError(`${fieldName} is required and must be a non-empty string.`);
232
+ }
233
+ }
234
+ function assertValidTransactionId(value) {
235
+ if (value === void 0) {
236
+ return;
237
+ }
238
+ const isString = typeof value === "string" && value.trim().length > 0;
239
+ const isNumber = typeof value === "number" && Number.isFinite(value);
240
+ if (!isString && !isNumber) {
241
+ throw new ValidationError(
242
+ "transactionId must be a non-empty string or a finite number when provided."
243
+ );
244
+ }
245
+ }
246
+ function assertValidRrr(value) {
247
+ const isString = typeof value === "string" && value.trim().length > 0;
248
+ const isNumber = typeof value === "number" && Number.isFinite(value);
249
+ if (!isString && !isNumber) {
250
+ throw new ValidationError("rrr is required and must be a non-empty string or a finite number.");
251
+ }
252
+ }
253
+ function validateRrrConfig(config) {
254
+ assertValidRrr(config.rrr);
255
+ }
256
+ function validatePaymentConfig(config) {
257
+ if (!config || typeof config !== "object") {
258
+ throw new ValidationError("Payment config is required.");
259
+ }
260
+ assertNonEmptyString(config.key, "key");
261
+ assertValidRrr(config.rrr);
262
+ assertValidTransactionId(config.transactionId);
263
+ validateRrrConfig(config);
264
+ return config;
265
+ }
266
+
267
+ // src/core/payment.ts
268
+ async function startRemitaPayment(config, options = {}) {
269
+ validatePaymentConfig(config);
270
+ await loadRemitaScript(options);
271
+ const session = initRemitaEngine(config);
272
+ const open = () => {
273
+ if (typeof session.showPaymentWidget === "function") {
274
+ session.showPaymentWidget();
275
+ return;
276
+ }
277
+ session.openIframe();
278
+ };
279
+ if (options.autoOpen !== false) {
280
+ open();
281
+ }
282
+ return {
283
+ open,
284
+ session
285
+ };
286
+ }
287
+ function useRemitaInline(defaultOptions = {}) {
288
+ const [isLoading, setIsLoading] = react.useState(false);
289
+ const [error, setError] = react.useState(null);
290
+ const pay = react.useCallback(
291
+ async (config, options = {}) => {
292
+ setIsLoading(true);
293
+ setError(null);
294
+ try {
295
+ await startRemitaPayment(config, {
296
+ ...defaultOptions,
297
+ ...options
298
+ });
299
+ } catch (err) {
300
+ const nextError = err instanceof Error ? err : new Error("Payment initialization failed.");
301
+ setError(nextError);
302
+ throw nextError;
303
+ } finally {
304
+ setIsLoading(false);
305
+ }
306
+ },
307
+ [defaultOptions]
308
+ );
309
+ const reset = react.useCallback(() => {
310
+ setError(null);
311
+ }, []);
312
+ return {
313
+ pay,
314
+ isLoading,
315
+ error,
316
+ reset
317
+ };
318
+ }
319
+ function RemitaPayButton({
320
+ paymentConfig,
321
+ paymentOptions,
322
+ onPaymentStart,
323
+ onPaymentError,
324
+ onClick,
325
+ loadingText = "Processing...",
326
+ disabled,
327
+ children,
328
+ ...props
329
+ }) {
330
+ const { pay, isLoading } = useRemitaInline();
331
+ const handleClick = react.useCallback(
332
+ async (event) => {
333
+ onClick?.(event);
334
+ if (event.defaultPrevented || isLoading) {
335
+ return;
336
+ }
337
+ onPaymentStart?.();
338
+ try {
339
+ await pay(paymentConfig, paymentOptions);
340
+ } catch (error) {
341
+ if (onPaymentError) {
342
+ onPaymentError(error instanceof Error ? error : new Error("Payment failed."));
343
+ }
344
+ }
345
+ },
346
+ [isLoading, onClick, onPaymentError, onPaymentStart, pay, paymentConfig, paymentOptions]
347
+ );
348
+ return /* @__PURE__ */ jsxRuntime.jsx(
349
+ "button",
350
+ {
351
+ type: "button",
352
+ ...props,
353
+ disabled: disabled || isLoading,
354
+ onClick: handleClick,
355
+ children: isLoading ? loadingText : children ?? "Pay with Remita"
356
+ }
357
+ );
358
+ }
359
+
360
+ exports.REMITA_DEMO_SCRIPT_URL = REMITA_DEMO_SCRIPT_URL;
361
+ exports.REMITA_PRODUCTION_SCRIPT_URL = REMITA_PRODUCTION_SCRIPT_URL;
362
+ exports.RemitaPayButton = RemitaPayButton;
363
+ exports.getRemitaEngine = getRemitaEngine;
364
+ exports.initRemitaEngine = initRemitaEngine;
365
+ exports.loadRemitaScript = loadRemitaScript;
366
+ exports.startRemitaPayment = startRemitaPayment;
367
+ exports.toEnginePaymentConfig = toEnginePaymentConfig;
368
+ exports.useRemitaInline = useRemitaInline;
369
+ exports.validatePaymentConfig = validatePaymentConfig;
370
+ //# sourceMappingURL=index.cjs.map
371
+ //# sourceMappingURL=index.cjs.map