@pybara/pybara-js 0.2.0 → 0.4.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/README.md +19 -11
- package/checkout.schema.json +17 -9
- package/dist/admin/core/PybaraAdminClient.d.ts +5 -0
- package/dist/admin/core/PybaraAdminClient.d.ts.map +1 -1
- package/dist/admin/index.d.ts +7 -2
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/{admin-D2vUTEg1.js → admin-B1pVP25-.js} +29 -7
- package/dist/checkout.d.ts +16 -10
- package/dist/checkout.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/modal/config.d.ts +19 -0
- package/dist/modal/config.d.ts.map +1 -0
- package/dist/modal/index.d.ts +15 -0
- package/dist/modal/index.d.ts.map +1 -0
- package/dist/modal/index.js +1 -0
- package/dist/modal/lock-page-scroll.d.ts +9 -0
- package/dist/modal/lock-page-scroll.d.ts.map +1 -0
- package/dist/modal/modal.d.ts +200 -0
- package/dist/modal/modal.d.ts.map +1 -0
- package/dist/modal-DCwwkKZ7.js +190 -0
- package/dist/pybara-js.iife.js +5 -5
- package/dist/pybara-js.js +144 -307
- package/dist/types.d.ts +16 -7
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -3
- package/dist/constants.d.ts +0 -13
- package/dist/constants.d.ts.map +0 -1
package/dist/pybara-js.js
CHANGED
|
@@ -1,236 +1,42 @@
|
|
|
1
1
|
/* Pybara.js - pybara.com */
|
|
2
|
-
import { n as e, r as t, t as n } from "./admin-
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
Z_INDEX: 999999,
|
|
6
|
-
BACKGROUND: "rgba(0, 0, 0, 0.7)"
|
|
7
|
-
}, i = {
|
|
8
|
-
OVERLAY_FADE_IN_MS: 200,
|
|
9
|
-
PANEL_OPEN_MS: 300,
|
|
10
|
-
PANEL_CLOSE_MS: 200,
|
|
11
|
-
OVERLAY_FADE_OUT_DELAY_MS: 50,
|
|
12
|
-
OVERLAY_FADE_OUT_MS: 150
|
|
13
|
-
}, a = 0, o = 0, s = 0;
|
|
14
|
-
function c(e) {
|
|
15
|
-
e.preventDefault();
|
|
16
|
-
}
|
|
17
|
-
function l(e) {
|
|
18
|
-
e.preventDefault();
|
|
19
|
-
}
|
|
20
|
-
function u(e) {
|
|
21
|
-
e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || [
|
|
22
|
-
"ArrowUp",
|
|
23
|
-
"ArrowDown",
|
|
24
|
-
"PageUp",
|
|
25
|
-
"PageDown",
|
|
26
|
-
"Home",
|
|
27
|
-
"End",
|
|
28
|
-
" "
|
|
29
|
-
].includes(e.key) && e.preventDefault();
|
|
30
|
-
}
|
|
31
|
-
function d() {
|
|
32
|
-
window.scrollTo(o, s);
|
|
33
|
-
}
|
|
34
|
-
function f() {
|
|
35
|
-
a === 0 && (o = window.scrollX, s = window.scrollY, window.addEventListener("wheel", c, { passive: !1 }), window.addEventListener("touchmove", l, { passive: !1 }), window.addEventListener("keydown", u), window.addEventListener("scroll", d)), a += 1;
|
|
36
|
-
}
|
|
37
|
-
function p() {
|
|
38
|
-
a !== 0 && (--a, a === 0 && (window.removeEventListener("wheel", c), window.removeEventListener("touchmove", l), window.removeEventListener("keydown", u), window.removeEventListener("scroll", d)));
|
|
39
|
-
}
|
|
40
|
-
//#endregion
|
|
41
|
-
//#region node_modules/@pybara/pybara-ux/dist/modal.js
|
|
42
|
-
function m() {
|
|
43
|
-
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
44
|
-
}
|
|
45
|
-
var h = [
|
|
46
|
-
"DESTINATION_REFUSED",
|
|
47
|
-
"INVALID_BENEFICIARY",
|
|
48
|
-
"NO_WALLET_AVAILABLE",
|
|
49
|
-
"SITE_MISMATCH"
|
|
50
|
-
];
|
|
51
|
-
function g(e) {
|
|
52
|
-
return h.includes(e) ? e : "UNKNOWN";
|
|
53
|
-
}
|
|
54
|
-
var _ = class extends Error {
|
|
55
|
-
constructor(e, t) {
|
|
56
|
-
super(t), this.name = "EmbeddedError", this.code = e, Object.setPrototypeOf(this, new.target.prototype);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
function v(e) {
|
|
60
|
-
return typeof e == "object" && !!e && typeof e.type == "string" && e.type.startsWith("pybara_embedded_");
|
|
61
|
-
}
|
|
62
|
-
var y = class {
|
|
63
|
-
constructor(e) {
|
|
64
|
-
this.overlay = null, this.iframe = null, this.spinner = null, this.handleMessage = null, this.handleEscapeKey = null, this.closable = !0, this.iframeLoaded = !1, this.pendingPaymentData = null, this.config = e, this.walletOrigin = new URL(e.walletUrl).origin, this.createIframe();
|
|
65
|
-
}
|
|
66
|
-
createIframe() {
|
|
67
|
-
let e = document.createElement("div");
|
|
68
|
-
e.className = "pybara-checkout-overlay", e.style.cssText = `
|
|
69
|
-
position: fixed;
|
|
70
|
-
top: 0;
|
|
71
|
-
left: 0;
|
|
72
|
-
right: 0;
|
|
73
|
-
bottom: 0;
|
|
74
|
-
background: ${r.BACKGROUND};
|
|
75
|
-
z-index: ${r.Z_INDEX};
|
|
76
|
-
display: none;
|
|
77
|
-
align-items: center;
|
|
78
|
-
justify-content: center;
|
|
79
|
-
overscroll-behavior: none;
|
|
80
|
-
user-select: none;
|
|
81
|
-
`;
|
|
82
|
-
let t = document.createElement("iframe");
|
|
83
|
-
t.src = `${this.config.walletUrl}/pay?mode=embedded`, t.title = "Pybara Wallet", t.style.cssText = "\n width: 100%;\n max-width: 500px;\n height: 0;\n max-height: 90vh;\n border: none;\n border-radius: 20px;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);\n overscroll-behavior: none;\n ";
|
|
84
|
-
let n = document.createElement("div");
|
|
85
|
-
n.setAttribute("aria-hidden", "true"), n.style.cssText = "\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n ", n.innerHTML = "\n <svg viewBox=\"0 0 50 50\" width=\"50\" height=\"50\">\n <circle cx=\"25\" cy=\"25\" r=\"20\" fill=\"none\" stroke=\"white\" stroke-width=\"3\" stroke-linecap=\"round\" stroke-dasharray=\"80\" stroke-dashoffset=\"20\"/>\n </svg>\n ", n.querySelector("svg")?.animate([{ transform: "rotate(0deg)" }, { transform: "rotate(360deg)" }], {
|
|
86
|
-
duration: 1e3,
|
|
87
|
-
iterations: Infinity
|
|
88
|
-
}), t.addEventListener("load", () => {
|
|
89
|
-
this.iframeLoaded = !0, this.pendingPaymentData &&= (this.sendInitMessage(this.pendingPaymentData), null);
|
|
90
|
-
}, { once: !0 }), this.handleMessage = (e) => {
|
|
91
|
-
if (e.origin === this.walletOrigin && e.source === t.contentWindow && v(e.data)) switch (e.data.type) {
|
|
92
|
-
case "pybara_embedded_result":
|
|
93
|
-
this.config.onSuccess?.({
|
|
94
|
-
blockIndex: e.data.blockIndex,
|
|
95
|
-
reference: e.data.reference,
|
|
96
|
-
payerPrincipal: e.data.payerPrincipal,
|
|
97
|
-
token: e.data.token
|
|
98
|
-
});
|
|
99
|
-
break;
|
|
100
|
-
case "pybara_embedded_error":
|
|
101
|
-
this.close(), this.config.onError?.(new _(g(e.data.code), e.data.message));
|
|
102
|
-
break;
|
|
103
|
-
case "pybara_embedded_closed":
|
|
104
|
-
this.close(), this.config.onClose?.();
|
|
105
|
-
break;
|
|
106
|
-
case "pybara_embedded_resize":
|
|
107
|
-
t.style.height !== `${e.data.height}px` && (t.style.height = `${e.data.height}px`), this.spinner && (this.spinner.remove(), this.spinner = null, m() || t.animate([{
|
|
108
|
-
transform: "translateY(20px)",
|
|
109
|
-
opacity: 0
|
|
110
|
-
}, {
|
|
111
|
-
transform: "none",
|
|
112
|
-
opacity: 1
|
|
113
|
-
}], {
|
|
114
|
-
duration: i.PANEL_OPEN_MS,
|
|
115
|
-
easing: "ease"
|
|
116
|
-
}));
|
|
117
|
-
break;
|
|
118
|
-
case "pybara_embedded_closable": this.closable = e.data.closable;
|
|
119
|
-
}
|
|
120
|
-
}, window.addEventListener("message", this.handleMessage), this.handleEscapeKey = (e) => {
|
|
121
|
-
e.key === "Escape" && this.closable && (this.close(), this.config.onClose?.());
|
|
122
|
-
}, document.addEventListener("keydown", this.handleEscapeKey), e.appendChild(n), e.appendChild(t), document.body.appendChild(e), this.overlay = e, this.iframe = t, this.spinner = n;
|
|
123
|
-
}
|
|
124
|
-
sendInitMessage(e) {
|
|
125
|
-
let t = {
|
|
126
|
-
type: "pybara_embedded_init",
|
|
127
|
-
beneficiary: e.modalData.beneficiary,
|
|
128
|
-
salt: e.modalData.salt,
|
|
129
|
-
amountUSD: e.modalData.amountUSD,
|
|
130
|
-
reference: e.modalData.reference,
|
|
131
|
-
context: this.config.context,
|
|
132
|
-
...e.recurring ? { recurring: e.recurring } : {},
|
|
133
|
-
...e.sdkFields ? { sdkFields: e.sdkFields } : {},
|
|
134
|
-
...this.config.thankYouMessage ? { thankYouMessage: this.config.thankYouMessage } : {}
|
|
135
|
-
};
|
|
136
|
-
this.iframe?.contentWindow?.postMessage(t, this.walletOrigin);
|
|
137
|
-
}
|
|
138
|
-
open() {
|
|
139
|
-
this.overlay && this.overlay.style.display !== "flex" && (f(), this.overlay.style.display = "flex", m() || this.overlay.animate([{ opacity: 0 }, { opacity: 1 }], {
|
|
140
|
-
duration: i.OVERLAY_FADE_IN_MS,
|
|
141
|
-
easing: "ease"
|
|
142
|
-
}));
|
|
143
|
-
}
|
|
144
|
-
show(e) {
|
|
145
|
-
this.open(), this.iframeLoaded ? this.sendInitMessage(e) : this.pendingPaymentData = e;
|
|
146
|
-
}
|
|
147
|
-
renderTerminalState(e) {
|
|
148
|
-
this.close(), f();
|
|
149
|
-
let t = document.createElement("div");
|
|
150
|
-
t.className = "pybara-checkout-overlay", t.style.cssText = `
|
|
151
|
-
position: fixed;
|
|
152
|
-
top: 0;
|
|
153
|
-
left: 0;
|
|
154
|
-
right: 0;
|
|
155
|
-
bottom: 0;
|
|
156
|
-
background: ${r.BACKGROUND};
|
|
157
|
-
z-index: ${r.Z_INDEX};
|
|
158
|
-
display: flex;
|
|
159
|
-
align-items: center;
|
|
160
|
-
justify-content: center;
|
|
161
|
-
user-select: none;
|
|
162
|
-
`;
|
|
163
|
-
let n = document.createElement("div");
|
|
164
|
-
n.style.cssText = "\n background: #fff;\n border-radius: 12px;\n color: #666;\n padding: 2rem;\n line-height: 1.4;\n max-width: 360px;\n text-align: center;\n font-family: system-ui, sans-serif;\n user-select: text;\n ", n.textContent = e, t.appendChild(n), t.addEventListener("click", (e) => {
|
|
165
|
-
e.target === t && (t.remove(), p(), this.config.onClose?.());
|
|
166
|
-
}), document.body.appendChild(t), this.overlay = t;
|
|
167
|
-
}
|
|
168
|
-
close() {
|
|
169
|
-
this.handleMessage &&= (window.removeEventListener("message", this.handleMessage), null), this.handleEscapeKey &&= (document.removeEventListener("keydown", this.handleEscapeKey), null), p();
|
|
170
|
-
let e = this.overlay, t = this.iframe;
|
|
171
|
-
this.overlay = null, this.iframe = null, this.spinner = null, this.iframeLoaded = !1, this.pendingPaymentData = null, this.closable = !0, e && (e.style.display === "none" || m() ? e.remove() : (e.style.pointerEvents = "none", t?.animate([{
|
|
172
|
-
transform: "scale(1)",
|
|
173
|
-
opacity: 1
|
|
174
|
-
}, {
|
|
175
|
-
transform: "scale(0.95)",
|
|
176
|
-
opacity: 0
|
|
177
|
-
}], {
|
|
178
|
-
duration: i.PANEL_CLOSE_MS,
|
|
179
|
-
easing: "ease-out",
|
|
180
|
-
fill: "forwards"
|
|
181
|
-
}), e.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
182
|
-
duration: i.OVERLAY_FADE_OUT_MS,
|
|
183
|
-
delay: i.OVERLAY_FADE_OUT_DELAY_MS,
|
|
184
|
-
easing: "ease-out",
|
|
185
|
-
fill: "forwards"
|
|
186
|
-
}).finished.then(() => e.remove(), () => e.remove())));
|
|
187
|
-
}
|
|
188
|
-
}, b = {
|
|
189
|
-
every2min: 120,
|
|
190
|
-
weekly: 604800,
|
|
191
|
-
monthly: 2592e3,
|
|
192
|
-
yearly: 31536e3
|
|
193
|
-
}, x = 2592e3, S = [
|
|
194
|
-
3,
|
|
195
|
-
6,
|
|
196
|
-
12,
|
|
197
|
-
24
|
|
198
|
-
], C = .5, w = {
|
|
2
|
+
import { n as e, r as t, t as n } from "./admin-B1pVP25-.js";
|
|
3
|
+
import { t as r } from "./modal-DCwwkKZ7.js";
|
|
4
|
+
var i = {
|
|
199
5
|
widget: "donate-widget",
|
|
200
6
|
recurring: "donate-widget-recurring"
|
|
201
7
|
};
|
|
202
|
-
function
|
|
8
|
+
function a(e, t) {
|
|
203
9
|
let n = (e) => {
|
|
204
10
|
let t = /^(\d+)-(\d+)$/.exec(e);
|
|
205
11
|
return t ? [Number(t[1]), Number(t[2])] : null;
|
|
206
12
|
}, r = n(e), i = n(t);
|
|
207
13
|
return !r || !i ? !1 : r[0] > i[0] || r[0] === i[0] && r[1] >= i[1];
|
|
208
14
|
}
|
|
209
|
-
async function
|
|
15
|
+
async function o(e) {
|
|
210
16
|
let t = await fetch(e);
|
|
211
17
|
if (!t.ok) throw Error(`HTTP ${t.status} from ${e}`);
|
|
212
18
|
return await t.json();
|
|
213
19
|
}
|
|
214
|
-
async function
|
|
215
|
-
let
|
|
20
|
+
async function s(t, n, r) {
|
|
21
|
+
let s = e[t], c = `https://${s.admin_core}.raw.icp0.io/widget-config`, l = `https://${s.admin_regs}.raw.icp0.io/widget-terms?site_url=${encodeURIComponent(n)}&principal=${encodeURIComponent(r)}`, u, d;
|
|
216
22
|
try {
|
|
217
|
-
[
|
|
23
|
+
[u, d] = await Promise.all([o(c), o(l)]);
|
|
218
24
|
} catch (e) {
|
|
219
25
|
return {
|
|
220
26
|
show: !1,
|
|
221
27
|
reason: `could not read the widget's configuration (${e instanceof Error ? e.message : String(e)})`
|
|
222
28
|
};
|
|
223
29
|
}
|
|
224
|
-
let
|
|
225
|
-
return
|
|
30
|
+
let f = u.kill_switch?.plugins ?? {};
|
|
31
|
+
return f[i.widget]?.enabled === !0 ? !d.signed || !d.version ? {
|
|
226
32
|
show: !1,
|
|
227
33
|
reason: `${n} has not accepted the widget's terms in Pybara Wallet (Manage › Sites › Add a site without a plugin)`
|
|
228
|
-
} :
|
|
34
|
+
} : a(d.version, "1-0") ? {
|
|
229
35
|
show: !0,
|
|
230
|
-
recurring:
|
|
36
|
+
recurring: f[i.recurring]?.enabled === !0
|
|
231
37
|
} : {
|
|
232
38
|
show: !1,
|
|
233
|
-
reason: `this widget version requires terms 1-0, and ${n} accepted ${
|
|
39
|
+
reason: `this widget version requires terms 1-0, and ${n} accepted ${d.version}: accept the new terms in Pybara Wallet (Manage › Sites)`
|
|
234
40
|
} : {
|
|
235
41
|
show: !1,
|
|
236
42
|
reason: "the widget is switched off by Pybara for now"
|
|
@@ -238,143 +44,173 @@ async function D(t, n, r) {
|
|
|
238
44
|
}
|
|
239
45
|
//#endregion
|
|
240
46
|
//#region src/types.ts
|
|
241
|
-
var
|
|
47
|
+
var c = class extends Error {
|
|
242
48
|
constructor(e, t) {
|
|
243
49
|
super(t), this.name = "PybaraError", this.code = e;
|
|
244
50
|
}
|
|
245
|
-
},
|
|
51
|
+
}, l = /^(0|[1-9]\d*)(\.\d+)?$/, u = /^[a-z0-9-]{1,64}$/, d = class {
|
|
246
52
|
constructor(e) {
|
|
247
|
-
this.adminClient = null, this.
|
|
53
|
+
this.adminClient = null, this.modal = null, this.gateOutcome = null, this.isOpen = !1, this.completedPayment = !1, this.activePayment = null, this.config = m(e), this.ready = this.init();
|
|
54
|
+
}
|
|
55
|
+
get gate() {
|
|
56
|
+
return this.gateOutcome;
|
|
248
57
|
}
|
|
249
58
|
async open(e) {
|
|
250
|
-
if (await this.ready, this.
|
|
251
|
-
let t = e.amount;
|
|
252
|
-
if (
|
|
253
|
-
let n = e.currency ?? this.config.currency
|
|
254
|
-
if (
|
|
255
|
-
|
|
256
|
-
if (
|
|
59
|
+
if (await this.ready, this.gateOutcome && !this.gateOutcome.show) throw new c("GATE_REFUSED", this.gateOutcome.reason ?? "This site cannot accept Pybara payments yet.");
|
|
60
|
+
let t = f(e.amount);
|
|
61
|
+
if (t === null) throw new c("INVALID_CONFIG", `open(): "amount" must be a decimal string in the currency's major units, e.g. "12.34", or a positive number — got ${JSON.stringify(e.amount)}`);
|
|
62
|
+
let n = e.currency ?? this.config.currency;
|
|
63
|
+
if (!n) throw new c("INVALID_CONFIG", "open(): \"currency\" is required — pass it to open(), or set it once in Pybara.checkout()");
|
|
64
|
+
if (!/^[A-Z]{3}$/.test(n)) throw new c("INVALID_CONFIG", `open(): "currency" must be an uppercase ISO 4217 code, e.g. "EUR" — got ${JSON.stringify(n)}`);
|
|
65
|
+
if (e.durationMonths != null && !e.frequency) throw new c("INVALID_CONFIG", "open(): \"durationMonths\" needs a \"frequency\"");
|
|
66
|
+
let r = e.frequency ? {
|
|
67
|
+
frequency: e.frequency,
|
|
68
|
+
...e.durationMonths == null ? {} : { durationMonths: e.durationMonths }
|
|
69
|
+
} : void 0;
|
|
70
|
+
if (r && this.gateOutcome && this.gateOutcome.show && !this.gateOutcome.recurring) throw new c("GATE_REFUSED", "Recurring payments are temporarily unavailable.");
|
|
257
71
|
if (this.isOpen) return;
|
|
258
72
|
this.isOpen = !0;
|
|
259
|
-
let
|
|
73
|
+
let i = !1;
|
|
260
74
|
try {
|
|
261
75
|
await this.adminClient?.getRecipientDataWithCache(this.config.siteUrl);
|
|
262
76
|
} catch (e) {
|
|
263
|
-
this.config.debug && console.warn("🧩 pybara-js: recipient access validation failed:", e),
|
|
77
|
+
this.config.debug && console.warn("🧩 pybara-js: recipient access validation failed:", e), i = !0;
|
|
264
78
|
}
|
|
265
79
|
this.modal || this.initCheckoutModal();
|
|
266
|
-
let
|
|
267
|
-
if (!
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
80
|
+
let a = this.modal;
|
|
81
|
+
if (!a) throw this.isOpen = !1, new c("CHECKOUT_FAILED", "The checkout modal could not be initialised.");
|
|
82
|
+
if (i) this.isOpen = !1, a.renderTerminalState("This recipient is currently unable to accept donations."), this.initCheckoutModal();
|
|
83
|
+
else {
|
|
84
|
+
this.activePayment = e;
|
|
85
|
+
try {
|
|
86
|
+
a.show({
|
|
87
|
+
modalData: {
|
|
88
|
+
beneficiary: this.config.recipientPrincipal,
|
|
89
|
+
salt: h(),
|
|
90
|
+
reference: this.config.siteName
|
|
91
|
+
},
|
|
92
|
+
recurring: r,
|
|
93
|
+
checkout: this.checkoutFor(e, t, n)
|
|
94
|
+
});
|
|
95
|
+
} catch (e) {
|
|
96
|
+
throw this.isOpen = !1, this.activePayment = null, g(e);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
278
99
|
}
|
|
279
100
|
close() {
|
|
280
101
|
this.modal?.close();
|
|
281
102
|
}
|
|
282
103
|
async init() {
|
|
283
104
|
let t = this.config.staging ? "staging" : "prod", r = this.config.debug;
|
|
284
|
-
r && console.log("🧩 pybara-js: initializing checkout…"), this.
|
|
105
|
+
r && console.log("🧩 pybara-js: initializing checkout…"), this.preconnectWallet(t), this.initCheckoutModal();
|
|
106
|
+
let i = new n({
|
|
285
107
|
adminCoreCanisterId: e[t].admin_core,
|
|
286
108
|
debug: r
|
|
287
109
|
});
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
110
|
+
this.adminClient = i;
|
|
111
|
+
let a = (async () => {
|
|
112
|
+
try {
|
|
113
|
+
await i.init(), await i.getPybaraAdminConfig(), r && console.log("🧩 pybara-js: admin client ready"), i.getRecipientDataWithCache(this.config.siteUrl).catch((e) => {
|
|
114
|
+
r && console.warn("🧩 pybara-js: recipient prewarm failed:", e);
|
|
115
|
+
});
|
|
116
|
+
} catch (e) {
|
|
117
|
+
r && console.error("🧩 pybara-js: admin client init failed:", e);
|
|
118
|
+
}
|
|
119
|
+
})(), o = (async () => {
|
|
120
|
+
this.config.pluginVersion || (this.gateOutcome = await s(t, this.config.siteUrl, this.config.recipientPrincipal), !this.gateOutcome.show && r && console.warn("🧩 pybara-js: gate refused —", this.gateOutcome.reason));
|
|
121
|
+
})();
|
|
122
|
+
await Promise.all([a, o]);
|
|
296
123
|
}
|
|
297
124
|
initCheckoutModal() {
|
|
298
|
-
let e = this.config.staging ? "staging" : "prod", n = this.config,
|
|
299
|
-
this.modal = new
|
|
125
|
+
let e = this.config.staging ? "staging" : "prod", n = this.config, i = this;
|
|
126
|
+
this.modal = new r({
|
|
300
127
|
walletUrl: t[e],
|
|
301
128
|
context: "donation",
|
|
302
129
|
thankYouMessage: n.thankYouMessage,
|
|
303
130
|
onSuccess: (e) => {
|
|
304
|
-
|
|
131
|
+
i.completedPayment = !0;
|
|
132
|
+
let t = i.activePayment, r = t?.frequency != null, a = {
|
|
305
133
|
blockIndex: e.blockIndex,
|
|
306
134
|
reference: e.reference,
|
|
307
135
|
token: e.token,
|
|
308
|
-
recurring:
|
|
136
|
+
recurring: r,
|
|
309
137
|
frequency: t?.frequency,
|
|
310
|
-
durationMonths:
|
|
311
|
-
isUnlimited:
|
|
138
|
+
durationMonths: r ? t?.durationMonths ?? void 0 : void 0,
|
|
139
|
+
isUnlimited: r && t?.durationMonths == null,
|
|
312
140
|
payerPrincipal: e.payerPrincipal,
|
|
313
141
|
recipientPrincipal: n.recipientPrincipal
|
|
314
142
|
};
|
|
315
143
|
t?.onSuccess?.(a);
|
|
316
144
|
},
|
|
317
145
|
onError: (e) => {
|
|
318
|
-
|
|
319
|
-
let t =
|
|
320
|
-
|
|
146
|
+
i.isOpen = !1;
|
|
147
|
+
let t = i.activePayment;
|
|
148
|
+
i.activePayment = null, t?.onError?.(g(e)), i.modal = null, i.initCheckoutModal();
|
|
321
149
|
},
|
|
322
150
|
onClose: () => {
|
|
323
|
-
|
|
324
|
-
let e =
|
|
325
|
-
|
|
151
|
+
i.isOpen = !1;
|
|
152
|
+
let e = i.activePayment;
|
|
153
|
+
i.activePayment = null, e?.onClose?.(), i.completedPayment && n.thankYouRedirectUrl ? window.location.href = n.thankYouRedirectUrl : (i.completedPayment = !1, i.modal = null, i.initCheckoutModal());
|
|
326
154
|
}
|
|
327
155
|
});
|
|
328
156
|
}
|
|
329
|
-
|
|
330
|
-
let
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
157
|
+
checkoutFor(e, t, n) {
|
|
158
|
+
let r = this.config;
|
|
159
|
+
return {
|
|
160
|
+
v: 1,
|
|
161
|
+
amount: t,
|
|
162
|
+
currency: n,
|
|
163
|
+
site: {
|
|
164
|
+
url: r.siteUrl,
|
|
165
|
+
name: r.siteName,
|
|
166
|
+
country: r.siteCountry
|
|
167
|
+
},
|
|
168
|
+
platform: r.platform ?? "pybara-js",
|
|
169
|
+
pluginVersion: r.pluginVersion,
|
|
170
|
+
siteTerms: {
|
|
171
|
+
version: r.recipientTosVersion,
|
|
172
|
+
acceptedAt: r.recipientTosAcceptedAt
|
|
173
|
+
},
|
|
174
|
+
notify: {
|
|
175
|
+
email: r.notifyEmail,
|
|
176
|
+
enabled: r.notifyDonations
|
|
177
|
+
},
|
|
178
|
+
donation: {
|
|
179
|
+
donor: {
|
|
180
|
+
email: e.donorEmail,
|
|
181
|
+
firstName: e.donorFirstName,
|
|
182
|
+
lastName: e.donorLastName,
|
|
183
|
+
company: e.donorCompany,
|
|
184
|
+
country: e.donorCountry,
|
|
185
|
+
address: {
|
|
186
|
+
line1: e.donorAddressLine1,
|
|
187
|
+
line2: e.donorAddressLine2,
|
|
188
|
+
city: e.donorAddressCity,
|
|
189
|
+
state: e.donorAddressState,
|
|
190
|
+
postalCode: e.donorAddressPostalCode,
|
|
191
|
+
country: e.donorAddressCountry
|
|
192
|
+
},
|
|
193
|
+
tos: {
|
|
194
|
+
version: e.donorTosVersion,
|
|
195
|
+
acceptedAt: e.donorTosAcceptedAt
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
message: e.donorMessage,
|
|
199
|
+
isAnonymous: e.donorIsAnonymous,
|
|
200
|
+
wantsTaxReceipt: e.wantsTaxReceipt
|
|
201
|
+
}
|
|
202
|
+
};
|
|
357
203
|
}
|
|
358
204
|
preconnectWallet(e) {
|
|
359
205
|
let n = document.createElement("link");
|
|
360
206
|
n.rel = "preconnect", n.href = new URL(t[e]).origin, n.crossOrigin = "anonymous", document.head.appendChild(n);
|
|
361
207
|
}
|
|
362
208
|
};
|
|
363
|
-
function
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (n == null) return {
|
|
367
|
-
frequency: e.frequency,
|
|
368
|
-
totalPulls: 0
|
|
369
|
-
};
|
|
370
|
-
if (!S.includes(n)) throw new O("INVALID_CONFIG", `durationMonths must be one of ${S.join(", ")} — got ${n}.`);
|
|
371
|
-
return {
|
|
372
|
-
frequency: e.frequency,
|
|
373
|
-
totalPulls: Math.ceil(n * x / t),
|
|
374
|
-
durationMonths: n
|
|
375
|
-
};
|
|
209
|
+
function f(e) {
|
|
210
|
+
let t = typeof e == "number" && Number.isFinite(e) ? String(e) : e;
|
|
211
|
+
return typeof t != "string" || !l.test(t) || !/[1-9]/.test(t) ? null : t;
|
|
376
212
|
}
|
|
377
|
-
function
|
|
213
|
+
function p(e) {
|
|
378
214
|
let t = e.trim();
|
|
379
215
|
if (!t) return null;
|
|
380
216
|
let n;
|
|
@@ -385,32 +221,33 @@ function j(e) {
|
|
|
385
221
|
}
|
|
386
222
|
return n.protocol !== "https:" && n.protocol !== "http:" ? null : n.origin + n.pathname.replace(/\/+$/, "");
|
|
387
223
|
}
|
|
388
|
-
function
|
|
389
|
-
if (!e.recipientPrincipal) throw new
|
|
390
|
-
if (!e.siteUrl) throw new
|
|
391
|
-
let t =
|
|
392
|
-
if (!t) throw new
|
|
393
|
-
if (!e.siteName) throw new
|
|
224
|
+
function m(e) {
|
|
225
|
+
if (!e.recipientPrincipal) throw new c("INVALID_CONFIG", "Pybara.checkout: \"recipientPrincipal\" is required");
|
|
226
|
+
if (!e.siteUrl) throw new c("INVALID_CONFIG", "Pybara.checkout: \"siteUrl\" is required");
|
|
227
|
+
let t = p(e.siteUrl);
|
|
228
|
+
if (!t) throw new c("INVALID_CONFIG", `Pybara.checkout: "siteUrl" is not a valid http(s) URL: ${e.siteUrl}`);
|
|
229
|
+
if (!e.siteName) throw new c("INVALID_CONFIG", "Pybara.checkout: \"siteName\" is required");
|
|
230
|
+
if (e.currency != null && !/^[A-Z]{3}$/.test(e.currency)) throw new c("INVALID_CONFIG", `Pybara.checkout: "currency" must be an uppercase ISO 4217 code, e.g. "EUR" — got ${JSON.stringify(e.currency)}`);
|
|
231
|
+
if (e.platform != null && !u.test(e.platform)) throw new c("INVALID_CONFIG", "Pybara.checkout: \"platform\" must be a lowercase slug (a-z, 0-9, -), at most 64 characters");
|
|
394
232
|
return {
|
|
395
233
|
...e,
|
|
396
234
|
siteUrl: t,
|
|
397
|
-
currency: e.currency ?? "USD",
|
|
398
235
|
staging: e.staging ?? !1,
|
|
399
236
|
debug: e.debug ?? !1
|
|
400
237
|
};
|
|
401
238
|
}
|
|
402
|
-
function
|
|
239
|
+
function h() {
|
|
403
240
|
let e = crypto.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
|
|
404
241
|
return btoa(String.fromCharCode(...e));
|
|
405
242
|
}
|
|
406
|
-
function
|
|
243
|
+
function g(e) {
|
|
407
244
|
return e instanceof Error ? e : Error(String(e));
|
|
408
245
|
}
|
|
409
246
|
//#endregion
|
|
410
247
|
//#region src/index.ts
|
|
411
|
-
function
|
|
412
|
-
return new
|
|
248
|
+
function _(e) {
|
|
249
|
+
return new d(e);
|
|
413
250
|
}
|
|
414
|
-
var
|
|
251
|
+
var v = { checkout: _ };
|
|
415
252
|
//#endregion
|
|
416
|
-
export {
|
|
253
|
+
export { v as Pybara, d as PybaraCheckout, c as PybaraError, _ as checkout };
|
package/dist/types.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export interface CheckoutConfig {
|
|
|
14
14
|
siteUrl: string;
|
|
15
15
|
/** Site display name — shown in the checkout frame and stored as the subscription name on recurring payments. */
|
|
16
16
|
siteName: string;
|
|
17
|
-
/**
|
|
17
|
+
/** The currency open() charges in when its own `currency` is absent (ISO 4217, e.g. 'EUR'): set it once on a single-currency site. No default — open() refuses when neither is set. */
|
|
18
18
|
currency?: string;
|
|
19
19
|
/** Replaces the success screen's default title. */
|
|
20
20
|
thankYouMessage?: string;
|
|
@@ -22,6 +22,8 @@ export interface CheckoutConfig {
|
|
|
22
22
|
thankYouRedirectUrl?: string;
|
|
23
23
|
/** Site base country (ISO 3166-1 alpha-2). */
|
|
24
24
|
siteCountry?: string;
|
|
25
|
+
/** The integration surface reported in the payment log's `platform` field: a lowercase slug (a-z, 0-9, -), at most 64 characters — default 'pybara-js'. First-party consumers set their own (e.g. 'pybara-donate'). A label, never used for a decision. */
|
|
26
|
+
platform?: string;
|
|
25
27
|
/** Site operator's contact email — terms warnings, per-payment notification emails. */
|
|
26
28
|
notifyEmail?: string;
|
|
27
29
|
/** false silences the per-payment notification email at notifyEmail. Default true. */
|
|
@@ -39,13 +41,17 @@ export interface CheckoutConfig {
|
|
|
39
41
|
}
|
|
40
42
|
/** One payment attempt — the params of a single open() call. */
|
|
41
43
|
export interface PaymentParams {
|
|
42
|
-
/**
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* The amount in the currency's major units, as a decimal string — "12.34" for €12.34, "1000" for ¥1,000 — as PayPal's API takes it.
|
|
46
|
+
* A number is accepted and turned into its decimal text (12.34 → "12.34").
|
|
47
|
+
* The checkout reads it with the currency's ISO 4217 minor units, and refuses more decimals than the currency holds ("12.345" EUR, "1000.5" JPY), so the page never needs to know them.
|
|
48
|
+
*/
|
|
49
|
+
amount: string | number;
|
|
50
|
+
/** The currency charged (ISO 4217, e.g. 'EUR') — the checkout config's when absent; one of the two is required. A multi-currency site passes it on every call. */
|
|
45
51
|
currency?: string;
|
|
46
52
|
/** Recurring frequency — omit for a one-time payment. */
|
|
47
53
|
frequency?: Frequency;
|
|
48
|
-
/** Recurring length in months: 3 | 6 | 12 | 24. Omit with frequency for an unlimited subscription. */
|
|
54
|
+
/** Recurring length in months: 3 | 6 | 12 | 24, checked by the checkout. Omit with frequency for an unlimited subscription. */
|
|
49
55
|
durationMonths?: number;
|
|
50
56
|
/** Hide the payer's identity on the public record. */
|
|
51
57
|
donorIsAnonymous?: boolean;
|
|
@@ -95,8 +101,11 @@ export interface CheckoutResult {
|
|
|
95
101
|
/** The recipient's wallet principal — the checkout config's, echoed for convenience. */
|
|
96
102
|
recipientPrincipal: string;
|
|
97
103
|
}
|
|
98
|
-
/**
|
|
99
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Typed codes for what Pybara.checkout() and open() throw before the checkout opens, as EmbeddedError's codes are for what the checkout reports once open.
|
|
106
|
+
* An amount below the minimum is not one: the checkout shows the minimum itself, in the payer's currency.
|
|
107
|
+
*/
|
|
108
|
+
export type PybaraErrorCode = 'INVALID_CONFIG' | 'GATE_REFUSED' | 'RECIPIENT_SUSPENDED' | 'CHECKOUT_FAILED';
|
|
100
109
|
export declare class PybaraError extends Error {
|
|
101
110
|
readonly code: PybaraErrorCode;
|
|
102
111
|
constructor(code: PybaraErrorCode, message: string);
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8IAA8I;AAC9I,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAEtE,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,uKAAuK;IACvK,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gIAAgI;IAChI,OAAO,EAAE,MAAM,CAAC;IAChB,iHAAiH;IACjH,QAAQ,EAAE,MAAM,CAAC;IACjB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|