@sdkrouter/payments 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.
@@ -0,0 +1,4 @@
1
+ import '../chunk-MCTTQUAM.mjs';
2
+ export { API, enums_exports as Enums, MemoryStorageAdapter, API as PaymentsAPI, createPaymentsApi } from '../chunk-4QQBPIIT.mjs';
3
+ //# sourceMappingURL=index.mjs.map
4
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
@@ -0,0 +1,580 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var chunkP3RGFDH4_cjs = require('./chunk-P3RGFDH4.cjs');
5
+ var lucideReact = require('lucide-react');
6
+ var react = require('react');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+ var QRCode = require('react-qr-code');
9
+ var moment = require('moment');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var QRCode__default = /*#__PURE__*/_interopDefault(QRCode);
14
+ var moment__default = /*#__PURE__*/_interopDefault(moment);
15
+
16
+ // src/config.ts
17
+ var PROD_BASE_URL = "https://api.sdkrouter.com";
18
+ var STYLE_ID = "sdkr-pay-styles";
19
+ function resolveBaseUrl(baseUrl) {
20
+ return baseUrl || PROD_BASE_URL;
21
+ }
22
+
23
+ // src/hooks/usePaymentLink.ts
24
+ function usePaymentLink(options) {
25
+ const { linkId, baseUrl, customerId, onSuccess, onError } = options;
26
+ const [link, setLink] = react.useState(null);
27
+ const [isLoading, setIsLoading] = react.useState(true);
28
+ const [error, setError] = react.useState(null);
29
+ const [step, setStep] = react.useState("form");
30
+ const [paymentResult, setPaymentResult] = react.useState(null);
31
+ const [isPaying, setIsPaying] = react.useState(false);
32
+ const apiRef = react.useRef(null);
33
+ react.useEffect(() => {
34
+ const resolved = resolveBaseUrl(baseUrl);
35
+ apiRef.current = chunkP3RGFDH4_cjs.createPaymentsApi(resolved);
36
+ let cancelled = false;
37
+ setIsLoading(true);
38
+ setError(null);
39
+ apiRef.current.payments_payments.publicLinksRetrieve(linkId).then((raw) => {
40
+ if (!cancelled) {
41
+ setLink({
42
+ id: raw.id,
43
+ title: raw.title,
44
+ description: raw.description,
45
+ amountUsd: raw.amount_usd ? parseFloat(String(raw.amount_usd)) : null,
46
+ network: raw.network ?? null
47
+ });
48
+ setIsLoading(false);
49
+ }
50
+ }).catch((err) => {
51
+ if (!cancelled) {
52
+ const e = err;
53
+ const msg = e?.statusCode === 404 ? "Payment link not found" : String(e?.errorMessage ?? e?.message ?? "Failed to load payment link");
54
+ setError(msg);
55
+ setIsLoading(false);
56
+ onError?.(msg);
57
+ }
58
+ });
59
+ return () => {
60
+ cancelled = true;
61
+ };
62
+ }, [linkId, baseUrl]);
63
+ const pay = react.useCallback(async (data) => {
64
+ if (!apiRef.current) return;
65
+ setIsPaying(true);
66
+ setStep("processing");
67
+ setError(null);
68
+ try {
69
+ const raw = await apiRef.current.payments_payments.publicLinksPayCreate(linkId, {
70
+ email: data.email || void 0,
71
+ name: data.name || void 0,
72
+ amount_usd: data.amountUsd != null ? data.amountUsd.toFixed(2) : void 0,
73
+ external_id: data.externalId || customerId || void 0
74
+ });
75
+ const result = {
76
+ success: !!raw.invoice_id,
77
+ paymentId: raw.invoice_id ?? null,
78
+ paymentUrl: null,
79
+ payAddress: raw.pay_address ?? null,
80
+ payAmount: raw.pay_amount ? String(raw.pay_amount) : null,
81
+ coin: raw.coin ?? "USDT",
82
+ network: raw.network ?? null,
83
+ expiresAt: raw.expires_at ?? null,
84
+ error: null
85
+ };
86
+ setPaymentResult(result);
87
+ setStep("status");
88
+ onSuccess?.(result);
89
+ } catch (err) {
90
+ const e = err;
91
+ const msg = String(e?.errorMessage ?? e?.message ?? "Payment failed");
92
+ setError(msg);
93
+ setStep("form");
94
+ onError?.(msg);
95
+ } finally {
96
+ setIsPaying(false);
97
+ }
98
+ }, [linkId, onSuccess, onError]);
99
+ const reset = react.useCallback(() => {
100
+ setStep("form");
101
+ setPaymentResult(null);
102
+ setError(null);
103
+ }, []);
104
+ return { link, isLoading, error, step, pay, paymentResult, isPaying, reset };
105
+ }
106
+ var KEY_PREFIX = "sdkr_pay_id";
107
+ function usePaymentIdentity(opts) {
108
+ const { linkId, customerId, projectSlug } = opts;
109
+ const key = `${KEY_PREFIX}_${linkId}`;
110
+ const [identity, setIdentity] = react.useState(null);
111
+ react.useEffect(() => {
112
+ if (customerId && projectSlug) {
113
+ const value = { customerId, projectSlug };
114
+ setIdentity(value);
115
+ try {
116
+ localStorage.setItem(key, JSON.stringify(value));
117
+ } catch {
118
+ }
119
+ return;
120
+ }
121
+ try {
122
+ const raw = localStorage.getItem(key);
123
+ if (raw) setIdentity(JSON.parse(raw));
124
+ } catch {
125
+ }
126
+ }, [key, customerId, projectSlug]);
127
+ return identity;
128
+ }
129
+ var PaymentContext = react.createContext(null);
130
+ function usePayment() {
131
+ const ctx = react.useContext(PaymentContext);
132
+ if (!ctx) throw new Error("usePayment must be used within PaymentProvider");
133
+ return ctx;
134
+ }
135
+ function PaymentProvider({ children, ...config }) {
136
+ const identity = usePaymentIdentity({
137
+ linkId: config.linkId,
138
+ customerId: config.customerId,
139
+ projectSlug: config.projectSlug
140
+ });
141
+ const customerId = identity?.customerId ?? config.customerId;
142
+ const projectSlug = identity?.projectSlug ?? config.projectSlug;
143
+ const hook = usePaymentLink({
144
+ linkId: config.linkId,
145
+ baseUrl: config.baseUrl,
146
+ customerId,
147
+ onSuccess: config.onSuccess,
148
+ onError: config.onError
149
+ });
150
+ const resolvedConfig = { ...config, customerId, projectSlug };
151
+ return /* @__PURE__ */ jsxRuntime.jsx(PaymentContext.Provider, { value: { ...hook, config: resolvedConfig }, children });
152
+ }
153
+ function useCustomerPayments(options) {
154
+ const { projectSlug, customerId, baseUrl } = options;
155
+ const [payments, setPayments] = react.useState([]);
156
+ const [loading, setLoading] = react.useState(false);
157
+ const [error, setError] = react.useState(null);
158
+ const apiRef = react.useRef(null);
159
+ const enabled = Boolean(projectSlug && customerId);
160
+ react.useEffect(() => {
161
+ if (!enabled) return;
162
+ const resolved = resolveBaseUrl(baseUrl);
163
+ apiRef.current = chunkP3RGFDH4_cjs.createPaymentsApi(resolved);
164
+ let cancelled = false;
165
+ setLoading(true);
166
+ setError(null);
167
+ apiRef.current.payments_payments.customerInvoicesList().then((data) => {
168
+ if (!cancelled) {
169
+ const results = data?.results;
170
+ setPayments(Array.isArray(results) ? results : []);
171
+ setLoading(false);
172
+ }
173
+ }).catch((err) => {
174
+ if (!cancelled) {
175
+ const msg = err?.message ?? "Failed to load payment history";
176
+ console.warn("[useCustomerPayments]", msg);
177
+ setError(msg);
178
+ setLoading(false);
179
+ }
180
+ });
181
+ return () => {
182
+ cancelled = true;
183
+ };
184
+ }, [projectSlug, customerId, baseUrl, enabled]);
185
+ return { payments, loading, error };
186
+ }
187
+ function CustomerPaymentHistory() {
188
+ const { config } = usePayment();
189
+ const { payments, loading } = useCustomerPayments({
190
+ projectSlug: config.projectSlug,
191
+ customerId: config.customerId,
192
+ baseUrl: config.baseUrl
193
+ });
194
+ const enabled = Boolean(config.customerId && config.projectSlug);
195
+ const hasHistory = !loading && payments.length > 0;
196
+ if (!enabled || !hasHistory) return null;
197
+ const items = payments.map((p) => ({
198
+ id: p.id,
199
+ amount: `$${p.amount_usd}`,
200
+ status: p.status,
201
+ statusClass: `sdkr-pay-history-status sdkr-pay-history-status--${p.status}`,
202
+ date: new Date(p.created_at).toLocaleDateString()
203
+ }));
204
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-history", children: [
205
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sdkr-pay-history-title", children: "Your payments" }),
206
+ items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-history-item", children: [
207
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-history-amount", children: item.amount }),
208
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: item.statusClass, children: item.status }),
209
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-history-date", children: item.date })
210
+ ] }, item.id))
211
+ ] });
212
+ }
213
+ function PaymentInfo() {
214
+ const { link, step } = usePayment();
215
+ if (!link || step === "status") return null;
216
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-info", children: [
217
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sdkr-pay-info-icon", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ShoppingBag, { size: 20 }) }),
218
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "sdkr-pay-title", children: link.title }),
219
+ link.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "sdkr-pay-description", children: link.description }),
220
+ link.amountUsd != null && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-amount-badge", children: [
221
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sdkr-pay-amount-value", children: [
222
+ "$",
223
+ link.amountUsd.toFixed(2)
224
+ ] }),
225
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sdkr-pay-amount-currency", children: [
226
+ "USDT",
227
+ link.network ? ` \xB7 ${link.network}` : ""
228
+ ] })
229
+ ] })
230
+ ] });
231
+ }
232
+
233
+ // src/types.ts
234
+ var MIN_AMOUNT_USD = 20;
235
+ var MAX_AMOUNT_USD = 5e4;
236
+ function PaymentForm() {
237
+ const { link, pay, isPaying, error, step, config } = usePayment();
238
+ const [form, setForm] = react.useState({
239
+ email: "",
240
+ name: "",
241
+ amountUsd: void 0
242
+ });
243
+ const [fieldErrors, setFieldErrors] = react.useState({});
244
+ if (!link || step === "status") return null;
245
+ const isCustomAmount = link.amountUsd == null;
246
+ const setField = (key, value) => {
247
+ setForm((prev) => ({ ...prev, [key]: value }));
248
+ setFieldErrors((prev) => {
249
+ const next = { ...prev };
250
+ delete next[key];
251
+ return next;
252
+ });
253
+ };
254
+ const handleSubmit = (e) => {
255
+ e.preventDefault();
256
+ const errors = {};
257
+ if (isCustomAmount) {
258
+ if (!form.amountUsd || form.amountUsd < MIN_AMOUNT_USD) {
259
+ errors.amountUsd = `Minimum $${MIN_AMOUNT_USD}`;
260
+ } else if (form.amountUsd > MAX_AMOUNT_USD) {
261
+ errors.amountUsd = `Maximum $${MAX_AMOUNT_USD.toLocaleString()}`;
262
+ }
263
+ }
264
+ if (form.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email)) {
265
+ errors.email = "Invalid email address";
266
+ }
267
+ if (Object.keys(errors).length > 0) {
268
+ setFieldErrors(errors);
269
+ return;
270
+ }
271
+ const data = {};
272
+ if (form.email) data.email = form.email;
273
+ if (form.name) data.name = form.name;
274
+ if (isCustomAmount && form.amountUsd) data.amountUsd = form.amountUsd;
275
+ if (config.customerId) data.externalId = config.customerId;
276
+ pay(data);
277
+ };
278
+ const displayAmount = isCustomAmount ? form.amountUsd ? `$${form.amountUsd.toFixed(2)}` : null : `$${link.amountUsd.toFixed(2)}`;
279
+ const visibleError = step === "form" ? error : null;
280
+ return /* @__PURE__ */ jsxRuntime.jsxs("form", { className: "sdkr-pay-form", onSubmit: handleSubmit, children: [
281
+ visibleError && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-error", children: [
282
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 14 }),
283
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: visibleError })
284
+ ] }),
285
+ isCustomAmount && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-field", children: [
286
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "sdkr-pay-label", children: "Amount (USD)" }),
287
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sdkr-pay-amount-prefix", children: /* @__PURE__ */ jsxRuntime.jsx(
288
+ "input",
289
+ {
290
+ className: `sdkr-pay-input ${fieldErrors.amountUsd ? "sdkr-pay-input-error" : ""}`,
291
+ type: "number",
292
+ step: "0.01",
293
+ min: MIN_AMOUNT_USD,
294
+ inputMode: "decimal",
295
+ placeholder: "0.00",
296
+ value: form.amountUsd ?? "",
297
+ onChange: (e) => setField("amountUsd", e.target.value ? parseFloat(e.target.value) : void 0),
298
+ disabled: isPaying
299
+ }
300
+ ) }),
301
+ fieldErrors.amountUsd && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-field-error", children: [
302
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 12 }),
303
+ fieldErrors.amountUsd
304
+ ] })
305
+ ] }),
306
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-field", children: [
307
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "sdkr-pay-label", children: [
308
+ "Email ",
309
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-label-optional", children: "(optional)" })
310
+ ] }),
311
+ /* @__PURE__ */ jsxRuntime.jsx(
312
+ "input",
313
+ {
314
+ className: `sdkr-pay-input ${fieldErrors.email ? "sdkr-pay-input-error" : ""}`,
315
+ type: "email",
316
+ inputMode: "email",
317
+ autoComplete: "email",
318
+ placeholder: "buyer@example.com",
319
+ value: form.email ?? "",
320
+ onChange: (e) => setField("email", e.target.value),
321
+ disabled: isPaying
322
+ }
323
+ ),
324
+ fieldErrors.email && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-field-error", children: [
325
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 12 }),
326
+ fieldErrors.email
327
+ ] })
328
+ ] }),
329
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-field", children: [
330
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "sdkr-pay-label", children: [
331
+ "Name ",
332
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-label-optional", children: "(optional)" })
333
+ ] }),
334
+ /* @__PURE__ */ jsxRuntime.jsx(
335
+ "input",
336
+ {
337
+ className: "sdkr-pay-input",
338
+ type: "text",
339
+ autoComplete: "name",
340
+ placeholder: "John Doe",
341
+ value: form.name ?? "",
342
+ onChange: (e) => setField("name", e.target.value),
343
+ disabled: isPaying,
344
+ maxLength: 200
345
+ }
346
+ )
347
+ ] }),
348
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "sdkr-pay-btn", type: "submit", disabled: isPaying, children: isPaying ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "sdkr-pay-btn-content", children: [
349
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 16, className: "sdkr-pay-btn-spinner" }),
350
+ "Processing..."
351
+ ] }) : displayAmount ? `Pay ${displayAmount}` : "Pay" })
352
+ ] });
353
+ }
354
+ var POLL_INTERVAL = 15e3;
355
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["paid", "expired", "cancelled", "overpaid", "underpaid"]);
356
+ function useInvoicePolling(invoiceId, baseUrl, onPaid) {
357
+ const [invoiceStatus, setInvoiceStatus] = react.useState(null);
358
+ const [isPolling, setIsPolling] = react.useState(false);
359
+ const intervalRef = react.useRef(null);
360
+ const apiRef = react.useRef(null);
361
+ const stopPolling = react.useCallback(() => {
362
+ if (intervalRef.current) {
363
+ clearInterval(intervalRef.current);
364
+ intervalRef.current = null;
365
+ }
366
+ setIsPolling(false);
367
+ }, []);
368
+ const poll = react.useCallback(async () => {
369
+ if (!invoiceId || !apiRef.current) return;
370
+ try {
371
+ const resolved = resolveBaseUrl(baseUrl);
372
+ const resp = await fetch(`${resolved}/api/payments/invoices/${invoiceId}/status/`);
373
+ if (!resp.ok) return;
374
+ const data = await resp.json();
375
+ const status = {
376
+ invoiceId: data.invoice_id,
377
+ status: data.status,
378
+ confirmTimes: data.confirm_times || null,
379
+ txId: data.tx_id || null,
380
+ completedAt: data.completed_at || null
381
+ };
382
+ setInvoiceStatus(status);
383
+ if (TERMINAL_STATUSES.has(status.status)) {
384
+ stopPolling();
385
+ if (status.status === "paid") {
386
+ onPaid?.(status);
387
+ }
388
+ }
389
+ } catch {
390
+ }
391
+ }, [invoiceId, baseUrl, onPaid, stopPolling]);
392
+ react.useEffect(() => {
393
+ if (!invoiceId) return;
394
+ apiRef.current = chunkP3RGFDH4_cjs.createPaymentsApi(resolveBaseUrl(baseUrl));
395
+ setIsPolling(true);
396
+ poll();
397
+ intervalRef.current = setInterval(poll, POLL_INTERVAL);
398
+ return () => {
399
+ stopPolling();
400
+ };
401
+ }, [invoiceId]);
402
+ return { invoiceStatus, isPolling, stopPolling };
403
+ }
404
+ function useCountdown(expiresAt) {
405
+ const expiresAtMoment = react.useMemo(
406
+ () => expiresAt ? moment__default.default.utc(expiresAt) : null,
407
+ [expiresAt]
408
+ );
409
+ const [now, setNow] = react.useState(() => moment__default.default.utc());
410
+ react.useEffect(() => {
411
+ if (!expiresAtMoment) return;
412
+ const interval = setInterval(() => {
413
+ setNow(moment__default.default.utc());
414
+ }, 1e3);
415
+ return () => clearInterval(interval);
416
+ }, [expiresAtMoment]);
417
+ if (!expiresAtMoment) {
418
+ return { display: "--:--", totalSeconds: 0, isExpired: false, isUrgent: false, minutes: 0, seconds: 0 };
419
+ }
420
+ const diff = expiresAtMoment.diff(now, "seconds");
421
+ const totalSeconds = Math.max(0, diff);
422
+ const isExpired = totalSeconds <= 0;
423
+ const isUrgent = totalSeconds > 0 && totalSeconds < 300;
424
+ const hours = Math.floor(totalSeconds / 3600);
425
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
426
+ const seconds = totalSeconds % 60;
427
+ const pad = (n) => n.toString().padStart(2, "0");
428
+ const display = isExpired ? "Expired" : hours > 0 ? `${hours}:${pad(minutes)}:${pad(seconds)}` : `${pad(minutes)}:${pad(seconds)}`;
429
+ return { display, totalSeconds, isExpired, isUrgent, minutes, seconds };
430
+ }
431
+ function CopyButton({ text }) {
432
+ const [copied, setCopied] = react.useState(false);
433
+ const copy = react.useCallback(() => {
434
+ navigator.clipboard.writeText(text);
435
+ setCopied(true);
436
+ setTimeout(() => setCopied(false), 2e3);
437
+ }, [text]);
438
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: copy, className: "sdkr-pay-copy-btn", title: "Copy to clipboard", children: copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { size: 14 }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { size: 14 }) });
439
+ }
440
+ var STATUS_CONFIG = {
441
+ waiting: {
442
+ icon: lucideReact.Clock,
443
+ iconClass: "sdkr-pay-status-icon--waiting",
444
+ title: "Awaiting Payment"
445
+ },
446
+ paid: {
447
+ icon: lucideReact.CircleCheck,
448
+ iconClass: "sdkr-pay-status-icon--paid",
449
+ title: "Payment Received"
450
+ },
451
+ expired: {
452
+ icon: lucideReact.CircleX,
453
+ iconClass: "sdkr-pay-status-icon--error",
454
+ title: "Payment Expired"
455
+ },
456
+ error: {
457
+ icon: lucideReact.CircleAlert,
458
+ iconClass: "sdkr-pay-status-icon--error",
459
+ title: "Payment Error"
460
+ }
461
+ };
462
+ function PaymentStatus() {
463
+ const { paymentResult, step, reset, config } = usePayment();
464
+ const invoiceId = paymentResult?.paymentId ?? null;
465
+ const { invoiceStatus, isPolling } = useInvoicePolling(
466
+ step === "status" && !paymentResult?.error ? invoiceId : null,
467
+ config.baseUrl
468
+ );
469
+ const countdown = useCountdown(paymentResult?.expiresAt ?? null);
470
+ if (step !== "status" || !paymentResult) return null;
471
+ const hasError = !!paymentResult.error;
472
+ const coin = paymentResult.coin || "USDT";
473
+ const network = paymentResult.network || "";
474
+ const isPaid = invoiceStatus?.status === "paid";
475
+ const isExpired = invoiceStatus?.status === "expired" || countdown.isExpired;
476
+ const isActive = !hasError && !isPaid && !isExpired;
477
+ const visualStatus = hasError ? "error" : isPaid ? "paid" : isExpired ? "expired" : "waiting";
478
+ const { icon: StatusLucide, iconClass, title } = STATUS_CONFIG[visualStatus];
479
+ const subtitle = hasError ? paymentResult.error || "Something went wrong" : isPaid ? invoiceStatus?.txId ? `Confirmed \xB7 ${invoiceStatus.txId.slice(0, 16)}...` : "Transaction confirmed" : isExpired ? "This invoice has expired" : "Send the exact amount to the address below";
480
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-status", children: [
481
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-status-header", children: [
482
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: `sdkr-pay-status-icon ${iconClass}`, children: /* @__PURE__ */ jsxRuntime.jsx(StatusLucide, { size: 24 }) }),
483
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "sdkr-pay-status-title", children: title }),
484
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "sdkr-pay-status-subtitle", children: subtitle })
485
+ ] }),
486
+ isActive && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
487
+ paymentResult.payAmount && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-hero-amount", children: [
488
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Wallet, { size: 16, className: "sdkr-pay-hero-amount-icon" }),
489
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-hero-amount-value", children: paymentResult.payAmount }),
490
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-hero-amount-coin", children: coin }),
491
+ /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { text: paymentResult.payAmount })
492
+ ] }),
493
+ paymentResult.payAddress && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sdkr-pay-qr", children: /* @__PURE__ */ jsxRuntime.jsx(
494
+ QRCode__default.default,
495
+ {
496
+ value: paymentResult.payAddress,
497
+ size: 160,
498
+ level: "M",
499
+ bgColor: "var(--sdkr-pay-qr-bg)",
500
+ fgColor: "var(--sdkr-pay-qr-fg)"
501
+ }
502
+ ) }),
503
+ paymentResult.payAddress && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-detail", children: [
504
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-detail-label", children: [
505
+ "Deposit Address",
506
+ network && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-network-badge", children: network })
507
+ ] }),
508
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-detail-value sdkr-pay-detail-mono sdkr-pay-detail-copyable", children: [
509
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: paymentResult.payAddress }),
510
+ /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { text: paymentResult.payAddress })
511
+ ] })
512
+ ] }),
513
+ paymentResult.expiresAt && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `sdkr-pay-countdown ${countdown.isUrgent ? "sdkr-pay-countdown--urgent" : ""}`, children: [
514
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Clock, { size: 14, className: "sdkr-pay-countdown-icon" }),
515
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-countdown-value", children: countdown.display })
516
+ ] }),
517
+ invoiceStatus?.confirmTimes && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-confirmations", children: [
518
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { size: 14, className: "sdkr-pay-confirmations-icon" }),
519
+ "Confirmations: ",
520
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: invoiceStatus.confirmTimes })
521
+ ] }),
522
+ isPolling && !invoiceStatus?.confirmTimes && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-polling", children: [
523
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-polling-dot" }),
524
+ " Checking for payment..."
525
+ ] }),
526
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-warning", children: [
527
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleAlert, { size: 12 }),
528
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
529
+ "Send exactly ",
530
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
531
+ paymentResult.payAmount,
532
+ " ",
533
+ coin
534
+ ] }),
535
+ " \u2014 different amount won't be matched"
536
+ ] })
537
+ ] })
538
+ ] }),
539
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sdkr-pay-status-actions", children: /* @__PURE__ */ jsxRuntime.jsxs("button", { className: "sdkr-pay-btn sdkr-pay-btn--ghost", onClick: reset, children: [
540
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeft, { size: 14 }),
541
+ hasError || isExpired ? "Try again" : isPaid ? "New payment" : "Cancel"
542
+ ] }) })
543
+ ] });
544
+ }
545
+ function PaymentContent() {
546
+ const { isLoading, error, step, link } = usePayment();
547
+ const showErrorOnly = Boolean(error) && step === "form" && !link;
548
+ if (isLoading) {
549
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sdkr-pay-loading", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sdkr-pay-spinner" }) });
550
+ }
551
+ if (showErrorOnly) {
552
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sdkr-pay-error-page", children: [
553
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sdkr-pay-status-icon sdkr-pay-status-icon--error", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircle, { size: 24 }) }),
554
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "sdkr-pay-error-text", children: error })
555
+ ] });
556
+ }
557
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `sdkr-pay-content sdkr-pay-step--${step}`, children: [
558
+ /* @__PURE__ */ jsxRuntime.jsx(PaymentInfo, {}),
559
+ Boolean(link) && step !== "status" && /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "sdkr-pay-separator" }),
560
+ /* @__PURE__ */ jsxRuntime.jsx(PaymentForm, {}),
561
+ /* @__PURE__ */ jsxRuntime.jsx(PaymentStatus, {}),
562
+ /* @__PURE__ */ jsxRuntime.jsx(CustomerPaymentHistory, {})
563
+ ] });
564
+ }
565
+
566
+ exports.CustomerPaymentHistory = CustomerPaymentHistory;
567
+ exports.MAX_AMOUNT_USD = MAX_AMOUNT_USD;
568
+ exports.MIN_AMOUNT_USD = MIN_AMOUNT_USD;
569
+ exports.PaymentContent = PaymentContent;
570
+ exports.PaymentForm = PaymentForm;
571
+ exports.PaymentInfo = PaymentInfo;
572
+ exports.PaymentProvider = PaymentProvider;
573
+ exports.PaymentStatus = PaymentStatus;
574
+ exports.STYLE_ID = STYLE_ID;
575
+ exports.useCustomerPayments = useCustomerPayments;
576
+ exports.usePayment = usePayment;
577
+ exports.usePaymentIdentity = usePaymentIdentity;
578
+ exports.usePaymentLink = usePaymentLink;
579
+ //# sourceMappingURL=chunk-3W2GRACB.cjs.map
580
+ //# sourceMappingURL=chunk-3W2GRACB.cjs.map