@coincircuit/checkout 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.
@@ -0,0 +1,91 @@
1
+ import { C as CheckoutConfig, a as CheckoutOptions, P as PaymentCompleteData, b as PaymentFailedData, c as CheckoutTheme } from './types-B0nOHvDT.cjs';
2
+ export { d as CheckoutButtonProps } from './types-B0nOHvDT.cjs';
3
+
4
+ /**
5
+ * CoinCircuitCheckout opens a full-screen modal overlay with the checkout
6
+ * page embedded in an iframe. The merchant's page stays in the background.
7
+ *
8
+ * Usage:
9
+ * ```ts
10
+ * const checkout = new CoinCircuitCheckout({ publicKey: 'pk_live_...' });
11
+ *
12
+ * checkout.open({
13
+ * reference: 'cs_ref_abc123',
14
+ * theme: 'dark',
15
+ * onPaymentComplete: (data) => console.log('Paid!', data),
16
+ * onClose: () => console.log('Checkout closed'),
17
+ * });
18
+ * ```
19
+ */
20
+ declare class CoinCircuitCheckout {
21
+ private readonly baseUrl;
22
+ private readonly origin;
23
+ private readonly publicKey;
24
+ private overlay;
25
+ private removeMessageListener;
26
+ private loadTimeout;
27
+ constructor(config?: CheckoutConfig);
28
+ /**
29
+ * Opens the checkout modal overlay.
30
+ *
31
+ * @param options - Configuration for this checkout session.
32
+ * @throws If reference is missing.
33
+ */
34
+ open(options: CheckoutOptions): void;
35
+ /**
36
+ * Closes the checkout modal and cleans up listeners.
37
+ */
38
+ close(): void;
39
+ /**
40
+ * Returns true if the checkout modal is currently open.
41
+ */
42
+ isOpen(): boolean;
43
+ }
44
+
45
+ /**
46
+ * All message type identifiers sent from the checkout popup to the opener.
47
+ */
48
+ declare const CHECKOUT_MESSAGE_TYPES: {
49
+ readonly READY: "coincircuit:ready";
50
+ readonly PAYMENT_COMPLETE: "coincircuit:payment_complete";
51
+ readonly PAYMENT_FAILED: "coincircuit:payment_failed";
52
+ readonly EXPIRED: "coincircuit:expired";
53
+ readonly CLOSE: "coincircuit:close";
54
+ };
55
+ type CheckoutMessageType = (typeof CHECKOUT_MESSAGE_TYPES)[keyof typeof CHECKOUT_MESSAGE_TYPES];
56
+ /**
57
+ * Shape of a postMessage sent from the checkout popup.
58
+ */
59
+ interface CheckoutMessage {
60
+ type: CheckoutMessageType;
61
+ data?: PaymentCompleteData | PaymentFailedData | undefined;
62
+ }
63
+ /**
64
+ * Callbacks dispatched when validated messages arrive from the popup.
65
+ */
66
+ interface CheckoutEventHandlers {
67
+ onReady?: () => void;
68
+ onPaymentComplete?: (data: PaymentCompleteData) => void;
69
+ onPaymentFailed?: (data: PaymentFailedData) => void;
70
+ onExpired?: () => void;
71
+ onClose?: () => void;
72
+ }
73
+ /**
74
+ * Creates a message event listener that validates origin, parses the message,
75
+ * and dispatches to the appropriate handler.
76
+ *
77
+ * @returns A cleanup function that removes the event listener.
78
+ */
79
+ declare function createMessageListener(allowedOrigin: string, handlers: CheckoutEventHandlers): () => void;
80
+
81
+ declare const DEFAULT_BASE_URL = "https://checkout.coincircuit.io";
82
+ /**
83
+ * Builds the checkout URL with embed flag.
84
+ */
85
+ declare function buildCheckoutUrl(baseUrl: string, reference: string, theme?: CheckoutTheme): string;
86
+ /**
87
+ * Extracts the origin from a URL for postMessage validation.
88
+ */
89
+ declare function extractOrigin(baseUrl: string): string;
90
+
91
+ export { CHECKOUT_MESSAGE_TYPES, CheckoutConfig, type CheckoutEventHandlers, type CheckoutMessage, type CheckoutMessageType, CheckoutOptions, CheckoutTheme, CoinCircuitCheckout, DEFAULT_BASE_URL, PaymentCompleteData, PaymentFailedData, buildCheckoutUrl, createMessageListener, extractOrigin };
@@ -0,0 +1,91 @@
1
+ import { C as CheckoutConfig, a as CheckoutOptions, P as PaymentCompleteData, b as PaymentFailedData, c as CheckoutTheme } from './types-B0nOHvDT.js';
2
+ export { d as CheckoutButtonProps } from './types-B0nOHvDT.js';
3
+
4
+ /**
5
+ * CoinCircuitCheckout opens a full-screen modal overlay with the checkout
6
+ * page embedded in an iframe. The merchant's page stays in the background.
7
+ *
8
+ * Usage:
9
+ * ```ts
10
+ * const checkout = new CoinCircuitCheckout({ publicKey: 'pk_live_...' });
11
+ *
12
+ * checkout.open({
13
+ * reference: 'cs_ref_abc123',
14
+ * theme: 'dark',
15
+ * onPaymentComplete: (data) => console.log('Paid!', data),
16
+ * onClose: () => console.log('Checkout closed'),
17
+ * });
18
+ * ```
19
+ */
20
+ declare class CoinCircuitCheckout {
21
+ private readonly baseUrl;
22
+ private readonly origin;
23
+ private readonly publicKey;
24
+ private overlay;
25
+ private removeMessageListener;
26
+ private loadTimeout;
27
+ constructor(config?: CheckoutConfig);
28
+ /**
29
+ * Opens the checkout modal overlay.
30
+ *
31
+ * @param options - Configuration for this checkout session.
32
+ * @throws If reference is missing.
33
+ */
34
+ open(options: CheckoutOptions): void;
35
+ /**
36
+ * Closes the checkout modal and cleans up listeners.
37
+ */
38
+ close(): void;
39
+ /**
40
+ * Returns true if the checkout modal is currently open.
41
+ */
42
+ isOpen(): boolean;
43
+ }
44
+
45
+ /**
46
+ * All message type identifiers sent from the checkout popup to the opener.
47
+ */
48
+ declare const CHECKOUT_MESSAGE_TYPES: {
49
+ readonly READY: "coincircuit:ready";
50
+ readonly PAYMENT_COMPLETE: "coincircuit:payment_complete";
51
+ readonly PAYMENT_FAILED: "coincircuit:payment_failed";
52
+ readonly EXPIRED: "coincircuit:expired";
53
+ readonly CLOSE: "coincircuit:close";
54
+ };
55
+ type CheckoutMessageType = (typeof CHECKOUT_MESSAGE_TYPES)[keyof typeof CHECKOUT_MESSAGE_TYPES];
56
+ /**
57
+ * Shape of a postMessage sent from the checkout popup.
58
+ */
59
+ interface CheckoutMessage {
60
+ type: CheckoutMessageType;
61
+ data?: PaymentCompleteData | PaymentFailedData | undefined;
62
+ }
63
+ /**
64
+ * Callbacks dispatched when validated messages arrive from the popup.
65
+ */
66
+ interface CheckoutEventHandlers {
67
+ onReady?: () => void;
68
+ onPaymentComplete?: (data: PaymentCompleteData) => void;
69
+ onPaymentFailed?: (data: PaymentFailedData) => void;
70
+ onExpired?: () => void;
71
+ onClose?: () => void;
72
+ }
73
+ /**
74
+ * Creates a message event listener that validates origin, parses the message,
75
+ * and dispatches to the appropriate handler.
76
+ *
77
+ * @returns A cleanup function that removes the event listener.
78
+ */
79
+ declare function createMessageListener(allowedOrigin: string, handlers: CheckoutEventHandlers): () => void;
80
+
81
+ declare const DEFAULT_BASE_URL = "https://checkout.coincircuit.io";
82
+ /**
83
+ * Builds the checkout URL with embed flag.
84
+ */
85
+ declare function buildCheckoutUrl(baseUrl: string, reference: string, theme?: CheckoutTheme): string;
86
+ /**
87
+ * Extracts the origin from a URL for postMessage validation.
88
+ */
89
+ declare function extractOrigin(baseUrl: string): string;
90
+
91
+ export { CHECKOUT_MESSAGE_TYPES, CheckoutConfig, type CheckoutEventHandlers, type CheckoutMessage, type CheckoutMessageType, CheckoutOptions, CheckoutTheme, CoinCircuitCheckout, DEFAULT_BASE_URL, PaymentCompleteData, PaymentFailedData, buildCheckoutUrl, createMessageListener, extractOrigin };
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ import {
2
+ CHECKOUT_MESSAGE_TYPES,
3
+ CoinCircuitCheckout,
4
+ DEFAULT_BASE_URL,
5
+ buildCheckoutUrl,
6
+ createMessageListener,
7
+ extractOrigin
8
+ } from "./chunk-VYS76EOY.js";
9
+ export {
10
+ CHECKOUT_MESSAGE_TYPES,
11
+ CoinCircuitCheckout,
12
+ DEFAULT_BASE_URL,
13
+ buildCheckoutUrl,
14
+ createMessageListener,
15
+ extractOrigin
16
+ };
package/dist/react.cjs ADDED
@@ -0,0 +1,418 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react.ts
21
+ var react_exports = {};
22
+ __export(react_exports, {
23
+ CoinCircuitCheckoutButton: () => CoinCircuitCheckoutButton
24
+ });
25
+ module.exports = __toCommonJS(react_exports);
26
+ var import_react = require("react");
27
+
28
+ // src/events.ts
29
+ var CHECKOUT_MESSAGE_TYPES = {
30
+ READY: "coincircuit:ready",
31
+ PAYMENT_COMPLETE: "coincircuit:payment_complete",
32
+ PAYMENT_FAILED: "coincircuit:payment_failed",
33
+ EXPIRED: "coincircuit:expired",
34
+ CLOSE: "coincircuit:close"
35
+ };
36
+ function isCheckoutMessage(value) {
37
+ if (typeof value !== "object" || value === null) return false;
38
+ const msg = value;
39
+ return typeof msg.type === "string" && msg.type.startsWith("coincircuit:");
40
+ }
41
+ function createMessageListener(allowedOrigin, handlers) {
42
+ function onMessage(event) {
43
+ if (event.origin !== allowedOrigin) return;
44
+ const message = event.data;
45
+ if (!isCheckoutMessage(message)) return;
46
+ switch (message.type) {
47
+ case CHECKOUT_MESSAGE_TYPES.READY:
48
+ handlers.onReady?.();
49
+ break;
50
+ case CHECKOUT_MESSAGE_TYPES.PAYMENT_COMPLETE:
51
+ if (message.data) {
52
+ handlers.onPaymentComplete?.(message.data);
53
+ }
54
+ break;
55
+ case CHECKOUT_MESSAGE_TYPES.PAYMENT_FAILED:
56
+ if (message.data) {
57
+ handlers.onPaymentFailed?.(message.data);
58
+ }
59
+ break;
60
+ case CHECKOUT_MESSAGE_TYPES.EXPIRED:
61
+ handlers.onExpired?.();
62
+ break;
63
+ case CHECKOUT_MESSAGE_TYPES.CLOSE:
64
+ handlers.onClose?.();
65
+ break;
66
+ }
67
+ }
68
+ window.addEventListener("message", onMessage);
69
+ return () => window.removeEventListener("message", onMessage);
70
+ }
71
+
72
+ // src/utils.ts
73
+ var DEFAULT_BASE_URL = "https://checkout.coincircuit.io";
74
+ function buildCheckoutUrl(baseUrl, reference, theme) {
75
+ const url = new URL(`/pay/${encodeURIComponent(reference)}`, baseUrl);
76
+ url.searchParams.set("embed", "true");
77
+ if (theme) {
78
+ url.searchParams.set("theme", theme);
79
+ }
80
+ return url.toString();
81
+ }
82
+ function extractOrigin(baseUrl) {
83
+ try {
84
+ return new URL(baseUrl).origin;
85
+ } catch {
86
+ return baseUrl;
87
+ }
88
+ }
89
+ var OVERLAY_ID = "coincircuit-checkout-overlay";
90
+ var STYLES_ID = "coincircuit-checkout-styles";
91
+ function injectStyles() {
92
+ if (document.getElementById(STYLES_ID)) return;
93
+ const style = document.createElement("style");
94
+ style.id = STYLES_ID;
95
+ style.textContent = `
96
+ #${OVERLAY_ID} {
97
+ position: fixed;
98
+ inset: 0;
99
+ z-index: 999999;
100
+ display: flex;
101
+ align-items: center;
102
+ justify-content: center;
103
+ background: rgba(0, 0, 0, 0.6);
104
+ backdrop-filter: blur(4px);
105
+ opacity: 0;
106
+ transition: opacity 0.2s ease;
107
+ }
108
+ #${OVERLAY_ID}.cc-visible {
109
+ opacity: 1;
110
+ }
111
+ #${OVERLAY_ID} .cc-modal {
112
+ position: relative;
113
+ width: 100%;
114
+ max-width: 450px;
115
+ height: 90vh;
116
+ max-height: 700px;
117
+ border-radius: 16px;
118
+ overflow: hidden;
119
+ background: #fff;
120
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.4);
121
+ }
122
+ #${OVERLAY_ID} .cc-close {
123
+ position: absolute;
124
+ top: 12px;
125
+ right: 12px;
126
+ z-index: 10;
127
+ width: 32px;
128
+ height: 32px;
129
+ border: none;
130
+ border-radius: 50%;
131
+ background: rgba(0, 0, 0, 0.5);
132
+ color: #fff;
133
+ font-size: 18px;
134
+ line-height: 1;
135
+ cursor: pointer;
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: center;
139
+ transition: background 0.15s;
140
+ }
141
+ #${OVERLAY_ID} .cc-close:hover {
142
+ background: rgba(0, 0, 0, 0.7);
143
+ }
144
+ #${OVERLAY_ID} iframe {
145
+ width: 100%;
146
+ height: 100%;
147
+ border: none;
148
+ display: block;
149
+ }
150
+ #${OVERLAY_ID} .cc-spinner {
151
+ position: absolute;
152
+ inset: 0;
153
+ display: flex;
154
+ align-items: center;
155
+ justify-content: center;
156
+ background: #fff;
157
+ transition: opacity 0.2s;
158
+ }
159
+ #${OVERLAY_ID} .cc-spinner div {
160
+ width: 36px;
161
+ height: 36px;
162
+ border: 3px solid #e5e7eb;
163
+ border-top-color: #6366f1;
164
+ border-radius: 50%;
165
+ animation: cc-spin 0.8s linear infinite;
166
+ }
167
+ @keyframes cc-spin { to { transform: rotate(360deg); } }
168
+ @media (max-width: 480px) {
169
+ #${OVERLAY_ID} .cc-modal {
170
+ max-width: 100%;
171
+ height: 100vh;
172
+ max-height: 100vh;
173
+ border-radius: 0;
174
+ }
175
+ }
176
+ `;
177
+ document.head.appendChild(style);
178
+ }
179
+ function createOverlay(checkoutUrl, onCloseClick) {
180
+ injectStyles();
181
+ const overlay = document.createElement("div");
182
+ overlay.id = OVERLAY_ID;
183
+ overlay.addEventListener("click", (e) => {
184
+ if (e.target === overlay) onCloseClick();
185
+ });
186
+ const onKeydown = (e) => {
187
+ if (e.key === "Escape") onCloseClick();
188
+ };
189
+ document.addEventListener("keydown", onKeydown);
190
+ overlay.dataset.keydownAttached = "true";
191
+ overlay._removeKeydown = () => document.removeEventListener("keydown", onKeydown);
192
+ const modal = document.createElement("div");
193
+ modal.className = "cc-modal";
194
+ const spinner = document.createElement("div");
195
+ spinner.className = "cc-spinner";
196
+ spinner.innerHTML = "<div></div>";
197
+ const iframe = document.createElement("iframe");
198
+ iframe.src = checkoutUrl;
199
+ iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox");
200
+ iframe.setAttribute("referrerpolicy", "strict-origin-when-cross-origin");
201
+ iframe.setAttribute("title", "CoinCircuit Checkout");
202
+ iframe.setAttribute("allow", "payment");
203
+ modal.appendChild(spinner);
204
+ modal.appendChild(iframe);
205
+ overlay.appendChild(modal);
206
+ return { overlay, iframe };
207
+ }
208
+ function showOverlay(overlay) {
209
+ document.body.appendChild(overlay);
210
+ document.body.style.overflow = "hidden";
211
+ overlay.offsetHeight;
212
+ overlay.classList.add("cc-visible");
213
+ }
214
+ function removeOverlay(overlay) {
215
+ overlay._removeKeydown?.();
216
+ overlay.classList.remove("cc-visible");
217
+ document.body.style.overflow = "";
218
+ setTimeout(() => {
219
+ overlay.parentNode?.removeChild(overlay);
220
+ }, 200);
221
+ }
222
+ function hideSpinner(overlay) {
223
+ const spinner = overlay.querySelector(".cc-spinner");
224
+ if (spinner) {
225
+ spinner.style.opacity = "0";
226
+ setTimeout(() => spinner.parentNode?.removeChild(spinner), 200);
227
+ }
228
+ }
229
+ function showErrorToast(message) {
230
+ const toast = document.createElement("div");
231
+ toast.textContent = message;
232
+ Object.assign(toast.style, {
233
+ position: "fixed",
234
+ top: "20px",
235
+ left: "50%",
236
+ transform: "translateX(-50%) translateY(-10px)",
237
+ zIndex: "9999999",
238
+ background: "#ef4444",
239
+ color: "#fff",
240
+ padding: "12px 24px",
241
+ borderRadius: "8px",
242
+ fontSize: "14px",
243
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
244
+ boxShadow: "0 4px 12px rgba(0,0,0,0.3)",
245
+ opacity: "0",
246
+ transition: "opacity 0.2s, transform 0.2s",
247
+ maxWidth: "90vw",
248
+ textAlign: "center"
249
+ });
250
+ document.body.appendChild(toast);
251
+ toast.offsetHeight;
252
+ toast.style.opacity = "1";
253
+ toast.style.transform = "translateX(-50%) translateY(0)";
254
+ setTimeout(() => {
255
+ toast.style.opacity = "0";
256
+ toast.style.transform = "translateX(-50%) translateY(-10px)";
257
+ setTimeout(() => toast.parentNode?.removeChild(toast), 200);
258
+ }, 6e3);
259
+ }
260
+
261
+ // src/checkout.ts
262
+ var CoinCircuitCheckout = class {
263
+ baseUrl;
264
+ origin;
265
+ publicKey;
266
+ overlay = null;
267
+ removeMessageListener = null;
268
+ loadTimeout = null;
269
+ constructor(config = {}) {
270
+ this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
271
+ this.origin = extractOrigin(this.baseUrl);
272
+ this.publicKey = config.publicKey;
273
+ }
274
+ /**
275
+ * Opens the checkout modal overlay.
276
+ *
277
+ * @param options - Configuration for this checkout session.
278
+ * @throws If reference is missing.
279
+ */
280
+ open(options) {
281
+ this.close();
282
+ if (!options.reference) {
283
+ throw new Error('CoinCircuitCheckout: "reference" is required.');
284
+ }
285
+ const checkoutUrl = buildCheckoutUrl(
286
+ this.baseUrl,
287
+ options.reference,
288
+ options.theme
289
+ );
290
+ const { overlay, iframe } = createOverlay(checkoutUrl, () => {
291
+ options.onClose?.();
292
+ this.close();
293
+ });
294
+ this.overlay = overlay;
295
+ this.loadTimeout = setTimeout(() => {
296
+ showErrorToast(
297
+ "Checkout failed to load. The checkout service may be unavailable or blocked by security policy."
298
+ );
299
+ this.close();
300
+ }, 15e3);
301
+ iframe.addEventListener("error", () => {
302
+ if (this.loadTimeout) clearTimeout(this.loadTimeout);
303
+ showErrorToast("Checkout failed to load. Please try again.");
304
+ this.close();
305
+ });
306
+ this.removeMessageListener = createMessageListener(this.origin, {
307
+ onReady: () => {
308
+ if (this.loadTimeout) {
309
+ clearTimeout(this.loadTimeout);
310
+ this.loadTimeout = null;
311
+ }
312
+ if (this.overlay) hideSpinner(this.overlay);
313
+ options.onReady?.();
314
+ },
315
+ onPaymentComplete: (data) => {
316
+ options.onPaymentComplete?.(data);
317
+ },
318
+ onPaymentFailed: (data) => {
319
+ options.onPaymentFailed?.(data);
320
+ },
321
+ onExpired: () => {
322
+ options.onExpired?.();
323
+ },
324
+ onClose: () => {
325
+ options.onClose?.();
326
+ this.close();
327
+ }
328
+ });
329
+ showOverlay(overlay);
330
+ }
331
+ /**
332
+ * Closes the checkout modal and cleans up listeners.
333
+ */
334
+ close() {
335
+ if (this.loadTimeout) {
336
+ clearTimeout(this.loadTimeout);
337
+ this.loadTimeout = null;
338
+ }
339
+ if (this.removeMessageListener) {
340
+ this.removeMessageListener();
341
+ this.removeMessageListener = null;
342
+ }
343
+ if (this.overlay) {
344
+ removeOverlay(this.overlay);
345
+ this.overlay = null;
346
+ }
347
+ }
348
+ /**
349
+ * Returns true if the checkout modal is currently open.
350
+ */
351
+ isOpen() {
352
+ return this.overlay !== null;
353
+ }
354
+ };
355
+
356
+ // src/react.ts
357
+ function CoinCircuitCheckoutButton(props) {
358
+ const {
359
+ reference,
360
+ theme,
361
+ baseUrl,
362
+ publicKey,
363
+ label = "Pay with CoinCircuit",
364
+ className,
365
+ style,
366
+ disabled,
367
+ onReady,
368
+ onPaymentComplete,
369
+ onPaymentFailed,
370
+ onExpired,
371
+ onClose
372
+ } = props;
373
+ const checkoutRef = (0, import_react.useRef)(null);
374
+ const onReadyRef = (0, import_react.useRef)(onReady);
375
+ const onPaymentCompleteRef = (0, import_react.useRef)(onPaymentComplete);
376
+ const onPaymentFailedRef = (0, import_react.useRef)(onPaymentFailed);
377
+ const onExpiredRef = (0, import_react.useRef)(onExpired);
378
+ const onCloseRef = (0, import_react.useRef)(onClose);
379
+ onReadyRef.current = onReady;
380
+ onPaymentCompleteRef.current = onPaymentComplete;
381
+ onPaymentFailedRef.current = onPaymentFailed;
382
+ onExpiredRef.current = onExpired;
383
+ onCloseRef.current = onClose;
384
+ (0, import_react.useEffect)(() => {
385
+ checkoutRef.current = new CoinCircuitCheckout({ baseUrl, publicKey });
386
+ return () => {
387
+ checkoutRef.current?.close();
388
+ };
389
+ }, [baseUrl, publicKey]);
390
+ const handleClick = (0, import_react.useCallback)(() => {
391
+ if (!checkoutRef.current || !reference) return;
392
+ checkoutRef.current.open({
393
+ reference,
394
+ theme,
395
+ onReady: () => onReadyRef.current?.(),
396
+ onPaymentComplete: (data) => onPaymentCompleteRef.current?.(data),
397
+ onPaymentFailed: (data) => onPaymentFailedRef.current?.(data),
398
+ onExpired: () => onExpiredRef.current?.(),
399
+ onClose: () => onCloseRef.current?.()
400
+ });
401
+ }, [reference, theme]);
402
+ return (0, import_react.createElement)(
403
+ "button",
404
+ {
405
+ type: "button",
406
+ onClick: handleClick,
407
+ disabled: disabled || !reference,
408
+ className,
409
+ style,
410
+ "data-coincircuit-checkout": "true"
411
+ },
412
+ label
413
+ );
414
+ }
415
+ // Annotate the CommonJS export names for ESM import in node:
416
+ 0 && (module.exports = {
417
+ CoinCircuitCheckoutButton
418
+ });
@@ -0,0 +1,28 @@
1
+ import * as react from 'react';
2
+ import { d as CheckoutButtonProps } from './types-B0nOHvDT.cjs';
3
+
4
+ /**
5
+ * React component that renders a button to open the CoinCircuit checkout modal.
6
+ *
7
+ * Usage:
8
+ * ```tsx
9
+ * import { CoinCircuitCheckoutButton } from '@coincircuit/checkout/react';
10
+ *
11
+ * <CoinCircuitCheckoutButton
12
+ * reference="cs_ref_abc123"
13
+ * theme="dark"
14
+ * onPaymentComplete={(data) => console.log('Paid!', data)}
15
+ * onClose={() => console.log('Closed')}
16
+ * />
17
+ * ```
18
+ */
19
+ declare function CoinCircuitCheckoutButton(props: CheckoutButtonProps): react.DetailedReactHTMLElement<{
20
+ type: string;
21
+ onClick: () => void;
22
+ disabled: boolean;
23
+ className: string | undefined;
24
+ style: Record<string, string | number> | undefined;
25
+ 'data-coincircuit-checkout': string;
26
+ }, HTMLElement>;
27
+
28
+ export { CheckoutButtonProps, CoinCircuitCheckoutButton };
@@ -0,0 +1,28 @@
1
+ import * as react from 'react';
2
+ import { d as CheckoutButtonProps } from './types-B0nOHvDT.js';
3
+
4
+ /**
5
+ * React component that renders a button to open the CoinCircuit checkout modal.
6
+ *
7
+ * Usage:
8
+ * ```tsx
9
+ * import { CoinCircuitCheckoutButton } from '@coincircuit/checkout/react';
10
+ *
11
+ * <CoinCircuitCheckoutButton
12
+ * reference="cs_ref_abc123"
13
+ * theme="dark"
14
+ * onPaymentComplete={(data) => console.log('Paid!', data)}
15
+ * onClose={() => console.log('Closed')}
16
+ * />
17
+ * ```
18
+ */
19
+ declare function CoinCircuitCheckoutButton(props: CheckoutButtonProps): react.DetailedReactHTMLElement<{
20
+ type: string;
21
+ onClick: () => void;
22
+ disabled: boolean;
23
+ className: string | undefined;
24
+ style: Record<string, string | number> | undefined;
25
+ 'data-coincircuit-checkout': string;
26
+ }, HTMLElement>;
27
+
28
+ export { CheckoutButtonProps, CoinCircuitCheckoutButton };