@pybara/pybara-js 0.2.0 → 0.3.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 CHANGED
@@ -16,7 +16,7 @@ No bundler? The IIFE build exposes `window.Pybara` — the same calls as the mod
16
16
  <script src="https://unpkg.com/@pybara/pybara-js/dist/pybara-js.iife.js"></script>
17
17
  <script>
18
18
  const pybara = Pybara.checkout({ siteUrl, siteName, recipientPrincipal });
19
- // await pybara.open({ amount: 100 }) on click — identical to the ESM surface
19
+ // await pybara.open({ amount: '100', currency: 'EUR' }) on click — identical to the ESM surface
20
20
  </script>
21
21
  ```
22
22
 
@@ -30,12 +30,12 @@ const pybara = Pybara.checkout({
30
30
  siteUrl: 'https://example.com', // your site, as registered in Pybara Wallet
31
31
  siteName: 'Example Org',
32
32
  recipientPrincipal: 'aaaaa-bbbbb-…', // the wallet principal in your _pybara-payto DNS record
33
- currency: 'EUR',
33
+ currency: 'EUR', // optional default for open(); one currency per site
34
34
  });
35
35
 
36
36
  // On your "Pybara" payment-option click — opens the checkout over your page:
37
37
  await pybara.open({
38
- amount: 100, // in `currency`
38
+ amount: '100', // in EUR, as a decimal string: '12.34', '1000' for JPY
39
39
  donorEmail: 'laurens@example.org', // optional — enables the receipt email + tax receipts
40
40
  onSuccess: (result) => showThanks(result),
41
41
  });
@@ -43,10 +43,12 @@ await pybara.open({
43
43
 
44
44
  That's the whole integration. `open()` resolves once the checkout is up; the result arrives on `onSuccess`.
45
45
 
46
+ **Amounts** are decimal strings in the currency's major units — `'12.34'` for €12.34, `'1000'` for ¥1,000 — as PayPal's API takes them; a number is accepted too (`12.34`). The checkout reads them with the currency's ISO 4217 minor units, so your page never needs to know how many decimals a currency has, and it refuses an amount the currency can't hold (`'12.345'` EUR, `'1000.5'` JPY). It converts to USD itself, with Pybara's own rates, and shows the minimum in the payer's currency if the amount is below it.
47
+
46
48
  **Recurring** — same call, two extra params:
47
49
 
48
50
  ```ts
49
- await pybara.open({ amount: 25, frequency: 'monthly', durationMonths: 12 });
51
+ await pybara.open({ amount: '25', frequency: 'monthly', durationMonths: 12 });
50
52
  // omit durationMonths for an open-ended subscription
51
53
  ```
52
54
 
@@ -63,12 +65,13 @@ The code above is all an AI builder needs. The one thing code can't do: the site
63
65
  | `recipientPrincipal` | `string` | ✓ | The recipient's wallet principal — the one in the `_pybara-payto` DNS record |
64
66
  | `siteUrl` | `string` | ✓ | Site registry key, e.g. `'https://example.com'` |
65
67
  | `siteName` | `string` | ✓ | Display name — shown in the checkout and stored on subscriptions |
66
- | `currency` | `string` | | Fiat for `open().amount`, ISO 4217 (default `'USD'`) |
68
+ | `currency` | `string` | | Default currency for `open()`, ISO 4217 uppercase (`'EUR'`) — no default of its own |
67
69
  | `thankYouMessage` | `string` | | Success-screen title override |
68
70
  | `thankYouRedirectUrl` | `string` | | Redirect after the payer closes the success screen |
69
71
  | `siteCountry` | `string` | | ISO 3166-1 alpha-2 |
70
72
  | `notifyEmail` | `string` | | Operator email — terms warnings, payment notifications |
71
73
  | `notifyDonations` | `boolean` | | `false` silences per-payment emails (default `true`) |
74
+ | `platform` | `string` | | Your integration's slug in the payment log, `a-z 0-9 -` (default `'pybara-js'`) |
72
75
  | `pluginVersion` | `string` | | Set by plugins — skips the autonomous-embed terms gate |
73
76
  | `staging` / `debug` | `boolean` | | Staging canisters + wallet / console logging |
74
77
 
@@ -76,8 +79,8 @@ The code above is all an AI builder needs. The one thing code can't do: the site
76
79
 
77
80
  | Field | Type | Description |
78
81
  |---|---|---|
79
- | `amount` | `number` | In the checkout's currency |
80
- | `currency` | `string` | Per-call override |
82
+ | `amount` | `string` \| `number` | Decimal string in the currency's major units: `'12.34'`, `'1000'` (JPY) |
83
+ | `currency` | `string` | ISO 4217 — required here unless set in `Pybara.checkout()`; a multi-currency site passes it on every call |
81
84
  | `frequency` | `'weekly' \| 'monthly' \| 'yearly'` | Omit for one-time |
82
85
  | `durationMonths` | `3 \| 6 \| 12 \| 24` | Omit for unlimited |
83
86
  | `donorEmail` `donorFirstName` `donorLastName` `donorCompany` `donorCountry` `donorAddress*` | `string` | Donor identity — pass what your form already collects |
@@ -85,7 +88,7 @@ The code above is all an AI builder needs. The one thing code can't do: the site
85
88
  | `donorMessage` | `string` | Stored with the payment log |
86
89
  | `wantsTaxReceipt` | `boolean` | Prefills the receipt checkbox (eligible sites only) |
87
90
  | `onSuccess(result)` | `function` | Payment confirmed — `result` carries block height, token, principals |
88
- | `onError(err)` `onClose()` | `function` | Frame-level errors / modal closed |
91
+ | `onError(err)` `onClose()` | `function` | Checkout refusals (`EmbeddedError`, `err.code`) / modal closed |
89
92
 
90
93
  ### Errors
91
94
 
@@ -95,9 +98,10 @@ The code above is all an AI builder needs. The one thing code can't do: the site
95
98
  |---|---|
96
99
  | `GATE_REFUSED` | Site hasn't accepted the widget terms, or a kill switch is on — `err.message` says which |
97
100
  | `RECIPIENT_SUSPENDED` | Recipient can't accept payments right now |
98
- | `BELOW_MINIMUM` | Amount under $0.50 USD after conversion |
99
- | `INVALID_CONFIG` | Missing/invalid config or params |
100
- | `CHECKOUT_FAILED` | Modal couldn't initialise |
101
+ | `INVALID_CONFIG` | Missing or malformed config or params — `err.message` names the field, e.g. `open(): "currency" is required` |
102
+ | `CHECKOUT_FAILED` | The checkout modal couldn't initialise |
103
+
104
+ Once open, the checkout reports a refusal to `onError` as an `EmbeddedError`, also with `err.code`. The ones an integration can cause: `INVALID_CHECKOUT` (the message names the field and what it must be, e.g. `checkout.amount "12.345" has more decimals than EUR has (2)`) and `RATE_UNAVAILABLE` (Pybara's rate for the currency couldn't be loaded — let the payer try again). An amount below the minimum isn't an error: the checkout shows the minimum itself.
101
105
 
102
106
  ## Scope
103
107
 
@@ -105,6 +109,10 @@ Today `checkout()` runs the **donation** flow (the `siteUrl` resolves a register
105
109
 
106
110
  If you want the whole donation *form* — presets, amount selector, frequency picker, styled button — that's [`@pybara/donate-widget`](https://github.com/pybara/pybara-widget), a product built on the same machinery.
107
111
 
112
+ ## Internal entry points
113
+
114
+ `@pybara/pybara-js/modal` and `@pybara/pybara-js/admin` are Pybara's own machinery for its plugins: not part of the public API, with no compatibility promise between versions. Integrate with `Pybara.checkout()`.
115
+
108
116
  ## Links
109
117
 
110
118
  - Docs — <https://docs.pybara.com>
@@ -24,9 +24,14 @@
24
24
  },
25
25
  "currency": {
26
26
  "type": "string",
27
- "pattern": "^[A-Za-z]{3}$",
28
- "default": "USD",
29
- "description": "Fiat currency the amounts passed to open() are in (ISO 4217, e.g. 'EUR'). Converted to USD for payment."
27
+ "pattern": "^[A-Z]{3}$",
28
+ "description": "The currency open() charges in when its own currency is absent (ISO 4217, uppercase, e.g. 'EUR'): set it once on a single-currency site. No default — open() refuses when neither is set."
29
+ },
30
+ "platform": {
31
+ "type": "string",
32
+ "pattern": "^[a-z0-9-]{1,64}$",
33
+ "default": "pybara-js",
34
+ "description": "The integration surface reported in the payment log's platform field: a lowercase slug — first-party consumers set their own (e.g. 'pybara-donate'). A label, never used for a decision."
30
35
  },
31
36
  "siteCountry": {
32
37
  "type": "string",
@@ -84,14 +89,17 @@
84
89
  "required": ["amount"],
85
90
  "properties": {
86
91
  "amount": {
87
- "type": "number",
88
- "exclusiveMinimum": 0,
89
- "description": "Amount in the checkout's currency; the USD equivalent must be ≥ $0.50."
92
+ "oneOf": [
93
+ { "type": "string", "pattern": "^(0|[1-9][0-9]*)(\\.[0-9]+)?$" },
94
+ { "type": "number", "exclusiveMinimum": 0 }
95
+ ],
96
+ "examples": ["12.34", "1000", "5"],
97
+ "description": "The amount in the currency's major units, as a decimal string ('12.34' for €12.34, '1000' for ¥1,000); a number is accepted and turned into its decimal text. 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. No minimum is checked here: the checkout shows its own, in the payer's currency."
90
98
  },
91
99
  "currency": {
92
100
  "type": "string",
93
- "pattern": "^[A-Za-z]{3}$",
94
- "description": "Per-call fiat override (ISO 4217) — defaults to the checkout's currency."
101
+ "pattern": "^[A-Z]{3}$",
102
+ "description": "The currency charged (ISO 4217, uppercase) — the checkout config's when absent; one of the two is required. A multi-currency site passes it on every call."
95
103
  },
96
104
  "frequency": {
97
105
  "enum": ["weekly", "monthly", "yearly", "every2min"],
@@ -99,7 +107,7 @@
99
107
  },
100
108
  "durationMonths": {
101
109
  "enum": [3, 6, 12, 24],
102
- "description": "Recurring length in months — omit with frequency for an unlimited subscription."
110
+ "description": "Recurring length in months, checked by the checkout — omit with frequency for an unlimited subscription."
103
111
  },
104
112
  "donorIsAnonymous": {
105
113
  "type": "boolean",
@@ -10,6 +10,9 @@ export declare class PybaraAdminClient {
10
10
  /** null is cached too: a site not registered yet (before its first payment) is the common case on a new store, and would otherwise cost a regs query on every click. */
11
11
  private merchantDataCache;
12
12
  private recipientDataCache;
13
+ /** In-flight fetches — a click during the page-load prewarm shares the one query instead of issuing a second. */
14
+ private merchantDataInFlight;
15
+ private recipientDataInFlight;
13
16
  private readonly adminCoreCanisterId;
14
17
  /** The admin regs of adminCoreCanisterId's environment: staging's for staging's core, prod's otherwise. */
15
18
  private readonly adminRegsCanisterId;
@@ -48,6 +51,7 @@ export declare class PybaraAdminClient {
48
51
  * @throws Error if the merchant is suspended.
49
52
  */
50
53
  getMerchantDataWithCache(siteUrl: string): Promise<MerchantRecord | null>;
54
+ private fetchMerchantData;
51
55
  /**
52
56
  * Recipient record for a site, with a 5-minute in-memory cache. Same cache-before-validate reasoning as getMerchantDataWithCache().
53
57
  *
@@ -56,6 +60,7 @@ export declare class PybaraAdminClient {
56
60
  * @throws Error if a registered recipient is suspended.
57
61
  */
58
62
  getRecipientDataWithCache(siteUrl: string): Promise<RecipientRecord | null>;
63
+ private fetchRecipientData;
59
64
  /**
60
65
  * The kill switch. Call early in the checkout flow, before showing any payment UI.
61
66
  *
@@ -1 +1 @@
1
- {"version":3,"file":"PybaraAdminClient.d.ts","sourceRoot":"","sources":["../../../src/admin/core/PybaraAdminClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAKN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAKrE,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,KAAK,CAAU;IACvB,oGAAoG;IACpG,OAAO,CAAC,WAAW,CAA4B;IAC/C,wKAAwK;IACxK,OAAO,CAAC,iBAAiB,CAGX;IACd,OAAO,CAAC,kBAAkB,CAGZ;IAEd,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,2GAA2G;IAC3G,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;gBAEjC,OAAO,EAAE,wBAAwB;IAS7C;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B;;;;;OAKG;YACW,YAAY;IAuB1B,+DAA+D;IACzD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqB3D;;;;OAIG;IACG,oBAAoB,IAAI,OAAO,CAAC,WAAW,CAAC;IA+ClD;;;;;;;;;;;OAWG;IACG,wBAAwB,CAC7B,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAsBjC;;;;;;OAMG;IACG,yBAAyB,CAC9B,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAoBlC;;;;;;OAMG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBvE,sEAAsE;YACxD,QAAQ;YAMR,aAAa;YAab,YAAY;IAa1B;;;OAGG;YACW,sBAAsB;IAsBpC,OAAO,CAAC,sBAAsB;IAQ9B,qEAAqE;IACrE,OAAO,CAAC,uBAAuB;CAO/B"}
1
+ {"version":3,"file":"PybaraAdminClient.d.ts","sourceRoot":"","sources":["../../../src/admin/core/PybaraAdminClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAKN,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAKrE,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,KAAK,CAAU;IACvB,oGAAoG;IACpG,OAAO,CAAC,WAAW,CAA4B;IAC/C,wKAAwK;IACxK,OAAO,CAAC,iBAAiB,CAGX;IACd,OAAO,CAAC,kBAAkB,CAGZ;IACd,iHAAiH;IACjH,OAAO,CAAC,oBAAoB,CAA0D;IACtF,OAAO,CAAC,qBAAqB,CAA2D;IAExF,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,2GAA2G;IAC3G,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;gBAEjC,OAAO,EAAE,wBAAwB;IAS7C;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B;;;;;OAKG;YACW,YAAY;IAuB1B,+DAA+D;IACzD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAqB3D;;;;OAIG;IACG,oBAAoB,IAAI,OAAO,CAAC,WAAW,CAAC;IA+ClD;;;;;;;;;;;OAWG;IACG,wBAAwB,CAC7B,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;YAqBnB,iBAAiB;IAiB/B;;;;;;OAMG;IACG,yBAAyB,CAC9B,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;YAqBpB,kBAAkB;IAehC;;;;;;OAMG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBvE,sEAAsE;YACxD,QAAQ;YAMR,aAAa;YAab,YAAY;IAa1B;;;OAGG;YACW,sBAAsB;IAsBpC,OAAO,CAAC,sBAAsB;IAQ9B,qEAAqE;IACrE,OAAO,CAAC,uBAAuB;CAO/B"}
@@ -1,9 +1,14 @@
1
1
  /**
2
2
  * @pybara/pybara-js/admin
3
3
  *
4
- * Read client for pybara-admin's `core` and `regs` canisters, plus the constants a first-party consumer needs to reach the Pybara protocol. Consumed by pybara-for-woocommerce and the donate widget.
4
+ * Read client for pybara-admin's `core` and `regs` canisters — internal machinery for
5
+ * first-party consumers (the plugins). Integrations taking payments or donations use
6
+ * `Pybara.checkout()` on the package root, not this subpath.
5
7
  *
6
- * It signs nothing and moves no funds. Payments and donations are executed by the buyer's own wallet inside pybara-wallet's checkout frame, which consumers reach through pybara-ux's CheckoutModal.
8
+ * @internal Not part of the public API: no compatibility promise between versions, even minor ones.
9
+ *
10
+ * It signs nothing and moves no funds. Payments and donations are executed by the buyer's
11
+ * own wallet inside pybara-wallet's checkout frame, which `Pybara.checkout()` opens.
7
12
  *
8
13
  * This was `@pybara/pybara-sdk` — absorbed into pybara-js so the browser SDK and its machinery version together.
9
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/admin/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -1 +1 @@
1
- export { n as CANISTER_IDS, r as PYBARA_WALLET_URLS, t as PybaraAdminClient } from "../admin-D2vUTEg1.js";
1
+ export { n as CANISTER_IDS, r as PYBARA_WALLET_URLS, t as PybaraAdminClient } from "../admin-B1pVP25-.js";
@@ -7958,7 +7958,7 @@ var Fu = ({ IDL: e }) => e.Service({
7958
7958
  });
7959
7959
  }, Lu = "https://icp-api.io", Ru = class {
7960
7960
  constructor(e) {
7961
- this.agent = null, this.adminCoreActor = null, this.adminRegsActor = null, this.adminConfig = null, this.merchantDataCache = /* @__PURE__ */ new Map(), this.recipientDataCache = /* @__PURE__ */ new Map(), this.adminCoreCanisterId = e.adminCoreCanisterId, this.adminRegsCanisterId = e.adminCoreCanisterId === r.staging.admin_core ? r.staging.admin_regs : r.prod.admin_regs, this.debug = e.debug ?? !1;
7961
+ this.agent = null, this.adminCoreActor = null, this.adminRegsActor = null, this.adminConfig = null, this.merchantDataCache = /* @__PURE__ */ new Map(), this.recipientDataCache = /* @__PURE__ */ new Map(), this.merchantDataInFlight = /* @__PURE__ */ new Map(), this.recipientDataInFlight = /* @__PURE__ */ new Map(), this.adminCoreCanisterId = e.adminCoreCanisterId, this.adminRegsCanisterId = e.adminCoreCanisterId === r.staging.admin_core ? r.staging.admin_regs : r.prod.admin_regs, this.debug = e.debug ?? !1;
7962
7962
  }
7963
7963
  async init() {
7964
7964
  this.agent = await Tu.create({ host: Lu }), this.adminCoreActor = ku.createActor(Fu, {
@@ -8019,20 +8019,42 @@ var Fu = ({ IDL: e }) => e.Service({
8019
8019
  async getMerchantDataWithCache(e) {
8020
8020
  let t = Date.now(), n = this.merchantDataCache.get(e);
8021
8021
  if (n && t - n.timestamp < 3e5) return this.validateMerchantAccess(n.data), n.data;
8022
- let r = (await (await this.getRegsActor()).get_merchant(e))?.[0] ?? null;
8022
+ let r = this.merchantDataInFlight.get(e);
8023
+ if (r) return r;
8024
+ let i = this.fetchMerchantData(e, t);
8025
+ this.merchantDataInFlight.set(e, i);
8026
+ try {
8027
+ return await i;
8028
+ } finally {
8029
+ this.merchantDataInFlight.delete(e);
8030
+ }
8031
+ }
8032
+ async fetchMerchantData(e, t) {
8033
+ let n = (await (await this.getRegsActor()).get_merchant(e))?.[0] ?? null;
8023
8034
  return this.merchantDataCache.set(e, {
8024
- data: r,
8035
+ data: n,
8025
8036
  timestamp: t
8026
- }), this.validateMerchantAccess(r), r;
8037
+ }), this.validateMerchantAccess(n), n;
8027
8038
  }
8028
8039
  async getRecipientDataWithCache(e) {
8029
8040
  let t = Date.now(), n = this.recipientDataCache.get(e);
8030
8041
  if (n && t - n.timestamp < 3e5) return this.validateRecipientAccess(n.data), n.data;
8031
- let r = (await (await this.getRegsActor()).get_recipient(e))?.[0] ?? null;
8042
+ let r = this.recipientDataInFlight.get(e);
8043
+ if (r) return r;
8044
+ let i = this.fetchRecipientData(e, t);
8045
+ this.recipientDataInFlight.set(e, i);
8046
+ try {
8047
+ return await i;
8048
+ } finally {
8049
+ this.recipientDataInFlight.delete(e);
8050
+ }
8051
+ }
8052
+ async fetchRecipientData(e, t) {
8053
+ let n = (await (await this.getRegsActor()).get_recipient(e))?.[0] ?? null;
8032
8054
  return this.recipientDataCache.set(e, {
8033
- data: r,
8055
+ data: n,
8034
8056
  timestamp: t
8035
- }), this.validateRecipientAccess(r), r;
8057
+ }), this.validateRecipientAccess(n), n;
8036
8058
  }
8037
8059
  async validatePlugin(e, t) {
8038
8060
  this.adminConfig || await this.getPybaraAdminConfig();
@@ -1,26 +1,31 @@
1
+ import { WidgetGate } from './gate';
1
2
  import { CheckoutConfig, PaymentParams } from './types';
2
3
  /**
3
4
  * A bound checkout — what Pybara.checkout() returns.
4
5
  *
5
- * checkout() is the "mount": it resolves the admin client, fetches the fiat rate, runs the terms/kill-switch gate
6
- * for autonomous embeds, and loads the hidden checkout iframe, so open() is instant on the payer's click.
6
+ * checkout() is the "mount": it resolves the admin client, runs the terms/kill-switch gate for autonomous embeds, and loads the hidden checkout iframe, so open() is instant on the payer's click.
7
7
  * The host keeps its own DOM entirely — there is nothing to render here.
8
+ * open() sends what the page knows, in its own terms (a `checkout`); the checkout frame converts the amount with core's rate and records the payment, so this package holds neither a rate nor the log's field format.
8
9
  */
9
10
  export declare class PybaraCheckout {
10
11
  private readonly config;
11
12
  private adminClient;
12
- private fiatRate;
13
13
  private modal;
14
- private gate;
14
+ private gateOutcome;
15
15
  private isOpen;
16
+ /** Set by onSuccess while the success screen is up — the close that follows redirects instead of counting as a cancellation. */
17
+ private completedPayment;
16
18
  private activePayment;
17
- /** All async binding work — open() awaits it so the gate, the rate and the iframe prewarm are resolved first. */
18
- private readonly ready;
19
+ /** All async binding work — open() awaits it so the gate and the iframe prewarm are resolved first. */
20
+ readonly ready: Promise<void>;
19
21
  constructor(userConfig: CheckoutConfig);
22
+ /** The autonomous-embed gate outcome once `ready` resolves — null while pending or under plugin terms (a plugin's host checks its own). */
23
+ get gate(): WidgetGate | null;
20
24
  /**
21
25
  * Open the Pybara checkout for one payment attempt.
22
26
  * Resolves once the checkout surface is up; the payment result arrives on the params' onSuccess/onError/onClose callbacks.
23
- * Rejects with a PybaraError when the checkout cannot open at all (gate, invalid params, below minimum).
27
+ * Rejects with a PybaraError when the checkout cannot open at all (gate, invalid params).
28
+ * The params' shape is checked here, so a typo fails at the call; the checkout checks everything again, plus what only it knows (the currency's decimals, the minimum), and reports a refusal to onError.
24
29
  */
25
30
  open(payment: PaymentParams): Promise<void>;
26
31
  /** Close an open modal — teardown is final, the next open() rebuilds it. */
@@ -28,10 +33,11 @@ export declare class PybaraCheckout {
28
33
  private init;
29
34
  private initCheckoutModal;
30
35
  /**
31
- * The fields settle stores with the payment log — the same bag the donate widget fills,
32
- * so a custom-form payment is indistinguishable downstream (notifications, tax receipts, stats).
36
+ * The checkout as the frame reads it (pybara-wallet's EmbeddedCheckout, version 1): what the page knows, in its own terms.
37
+ * The frame turns it into the payment log's fields; their names and encodings live there, not here, so no installed version of this package can drift from them.
38
+ * Values are passed as given, nulls included — a config read from JSON (pybara-donate's, from PHP) carries null for a setting that is not set, which the frame reads as absent.
33
39
  */
34
- private buildSdkFields;
40
+ private checkoutFor;
35
41
  /** Warm the TLS handshake to the wallet origin so the iframe's first real load is faster. */
36
42
  private preconnectWallet;
37
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,aAAa,EAEnB,MAAM,SAAS,CAAC;AAUjB;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,QAAQ,CAAO;IACvB,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,aAAa,CAA8B;IACnD,iHAAiH;IACjH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAE1B,UAAU,EAAE,cAAc;IAKtC;;;;OAIG;IACG,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAkEjD,4EAA4E;IAC5E,KAAK,IAAI,IAAI;YAIC,IAAI;IAqClB,OAAO,CAAC,iBAAiB;IAkDzB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAgDtB,6FAA6F;IAC7F,OAAO,CAAC,gBAAgB;CAOzB"}
1
+ {"version":3,"file":"checkout.d.ts","sourceRoot":"","sources":["../src/checkout.ts"],"names":[],"mappings":"AAMA,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EACL,KAAK,cAAc,EAEnB,KAAK,aAAa,EAEnB,MAAM,SAAS,CAAC;AAcjB;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,WAAW,CAA2B;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,gIAAgI;IAChI,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,aAAa,CAA8B;IACnD,uGAAuG;IACvG,SAAgB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;gBAEzB,UAAU,EAAE,cAAc;IAKtC,2IAA2I;IAC3I,IAAI,IAAI,IAAI,UAAU,GAAG,IAAI,CAE5B;IAED;;;;;OAKG;IACG,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA8EjD,4EAA4E;IAC5E,KAAK,IAAI,IAAI;YAIC,IAAI;IA8ClB,OAAO,CAAC,iBAAiB;IAqDzB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAmCnB,6FAA6F;IAC7F,OAAO,CAAC,gBAAgB;CAOzB"}
package/dist/index.d.ts CHANGED
@@ -9,5 +9,6 @@ export declare const Pybara: {
9
9
  checkout: typeof checkout;
10
10
  };
11
11
  export { PybaraCheckout } from './checkout';
12
+ export { type WidgetGate } from './gate';
12
13
  export { type CheckoutConfig, type CheckoutResult, type Frequency, type PaymentParams, PybaraError, type PybaraErrorCode, } from './types';
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAE/D;AAID,eAAO,MAAM,MAAM;;CAAe,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,WAAW,EACX,KAAK,eAAe,GACrB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,cAAc,CAE/D;AAID,eAAO,MAAM,MAAM;;CAAe,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,WAAW,EACX,KAAK,eAAe,GACrB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Modal Configuration
3
+ */
4
+ export declare const OVERLAY_STYLES: {
5
+ Z_INDEX: number;
6
+ BACKGROUND: string;
7
+ };
8
+ /** Show/hide motion, the same timings as pybara-ux-v0's modal (its styles/animations.css and MODAL_TIMINGS). */
9
+ export declare const MODAL_MOTION: {
10
+ OVERLAY_FADE_IN_MS: number;
11
+ /** The panel slides up 20px while fading in, once the frame has content to show. */
12
+ PANEL_OPEN_MS: number;
13
+ /** The panel scales down to 95% while fading out. */
14
+ PANEL_CLOSE_MS: number;
15
+ /** The backdrop starts fading this long after the panel, for a layered close. */
16
+ OVERLAY_FADE_OUT_DELAY_MS: number;
17
+ OVERLAY_FADE_OUT_MS: number;
18
+ };
19
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/modal/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,cAAc;;;CAG1B,CAAC;AAEF,gHAAgH;AAChH,eAAO,MAAM,YAAY;;IAExB,oFAAoF;;IAEpF,qDAAqD;;IAErD,iFAAiF;;;CAGjF,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @pybara/pybara-js/modal
3
+ *
4
+ * The checkout surface itself: a backdrop and an iframe onto Pybara Wallet's
5
+ * mode-2 frame, plus the error type its callbacks report. Internal machinery —
6
+ * integrations use `Pybara.checkout()` on the package root; first-party
7
+ * consumers that drive the modal directly (the plugins) import it from here.
8
+ *
9
+ * @internal Not part of the public API: no compatibility promise between versions, even minor ones.
10
+ * Its raw `sdkFields` are the payment log's own field format, which `Pybara.checkout()` never asks an integrator to hold.
11
+ *
12
+ * This was `@pybara/pybara-ux` — absorbed into pybara-js so the SDK and its
13
+ * modal kit version together.
14
+ */
15
+ export { CheckoutModal, EmbeddedError, type Checkout, type CheckoutModalConfig, type ModalData, type PaymentData, } from './modal.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modal/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,aAAa,EACb,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC"}
@@ -0,0 +1 @@
1
+ export { t as CheckoutModal, n as EmbeddedError } from "../modal-BCDMoDW9.js";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Freezes the host page under a checkout overlay without hiding the page scrollbar.
3
+ * overflow:hidden + padding compensation never matches OS scrollbar width exactly, so the page still jumps.
4
+ * Wheel/touch/keys on the parent document are cancelled. Wheel inside the wallet iframe never reaches those listeners (separate document) and overscroll-chains to the parent instead — a scroll listener pins window.scrollX/Y so that chain cannot move the page.
5
+ * Locks are counted, so two checkouts on one page (a WooCommerce checkout and a donation widget, say) never unlock each other.
6
+ */
7
+ export declare function lockPageScroll(): void;
8
+ export declare function unlockPageScroll(): void;
9
+ //# sourceMappingURL=lock-page-scroll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lock-page-scroll.d.ts","sourceRoot":"","sources":["../../src/modal/lock-page-scroll.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyBH,wBAAgB,cAAc,IAAI,IAAI,CAUrC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CASvC"}
@@ -0,0 +1,160 @@
1
+ /**
2
+ * CheckoutModal — the merchant page's side of the Pybara checkout.
3
+ *
4
+ * A backdrop and an iframe onto pybara-wallet's checkout frame (mode 2, `/pay?mode=embedded`), where wallet choice, sign-in, token selection, confirmation and the payment itself all happen.
5
+ * This package never touches a wallet, a balance or a price: it opens the frame, posts it the payment data, and reports the outcome.
6
+ *
7
+ * The constructor builds the iframe straight away, hidden, so the frame loads in the background while the buyer is still filling in the form.
8
+ * open() and show() then only reveal an already-loaded frame, at the moment latency matters most.
9
+ */
10
+ export interface ModalData {
11
+ /** Order or donation total in USD; the frame converts it into whichever token the buyer picks. Left out with a `checkout`, whose amount the frame converts itself. */
12
+ amountUSD?: number;
13
+ /** The recipient's principal (merchant or donation recipient); the frame checks it against the connecting origin's DNS record before any transfer. */
14
+ beneficiary: string;
15
+ /** Base64 salt for the deposit subaccount: random per order or donation, never reused. */
16
+ salt: string;
17
+ /** The platform's name for this checkout, e.g. the site name. Echoed back in onSuccess; a subscription also stores it as the name the buyer's wallet shows. */
18
+ reference: string;
19
+ }
20
+ export interface CheckoutModalConfig {
21
+ /** Where the wallet lives, e.g. 'https://pybara.io' (prod) or the staging wallet URL. */
22
+ walletUrl: string;
23
+ /** Decides settle.pay_and_log() vs. donate_and_log() inside the frame. Known before the order exists, unlike PaymentData. */
24
+ context: 'payment' | 'donation';
25
+ /** Replaces the success screen's default title ("You're all set!"), e.g. pybara-donate's "Thank you message" setting. Plain text; the frame escapes it. */
26
+ thankYouMessage?: string;
27
+ /** The payment is complete: the frame's success screen has appeared, and the modal stays open until the buyer closes it (onClose). The moment to confirm the payment server-side. */
28
+ onSuccess?: (data: {
29
+ blockIndex: string;
30
+ reference: string;
31
+ payerPrincipal: string;
32
+ token: string;
33
+ }) => void;
34
+ /** The frame refused, with an EmbeddedError; the modal has closed. */
35
+ onError?: (error: Error) => void;
36
+ /** The modal has closed: a cancellation before any onSuccess, or the buyer leaving the success screen after one. */
37
+ onClose?: () => void;
38
+ }
39
+ /** What show() needs that only exists once the order or donation does — unlike CheckoutModalConfig, known at construction. */
40
+ export interface PaymentData {
41
+ modalData: ModalData;
42
+ /**
43
+ * Present only for a recurring payment. totalPulls: 0 means unlimited, as in subs.mo's CreateSubscriptionArgs.
44
+ * With a `checkout`, totalPulls is left out: the frame computes it from durationMonths (absent: unlimited).
45
+ */
46
+ recurring?: {
47
+ frequency: string;
48
+ totalPulls?: number;
49
+ /** Months the donor chose, when bounded. totalPulls is derived from it; the checkout shows both. */
50
+ durationMonths?: number;
51
+ };
52
+ /** Opaque key-value metadata forwarded unchanged to settle's pay_and_log()/donate_and_log(): order or donor details the platform already has (email, WooCommerce order ID, …). The frame never interprets them. */
53
+ sdkFields?: [string, string][];
54
+ /** The semantic checkout, which the frame turns into the log fields and the USD amount itself; sent instead of `sdkFields` and `modalData.amountUSD`, never with them. */
55
+ checkout?: Checkout;
56
+ }
57
+ /**
58
+ * Mirrors pybara-wallet's EmbeddedCheckout (modes/mode-2-embedded/contract.ts), version 1: a core every kind of checkout shares, and the part for its kind, matching `context`.
59
+ * The frame validates it field by field and refuses it with INVALID_CHECKOUT, naming the faulty field.
60
+ */
61
+ export interface Checkout {
62
+ v: 1;
63
+ /** A decimal string in the currency's major units: "12.34" is €12.34, "1000" is ¥1,000. The frame reads it with the currency's ISO 4217 minor units. */
64
+ amount: string;
65
+ /** ISO 4217, uppercase. */
66
+ currency: string;
67
+ site: {
68
+ url: string;
69
+ name: string;
70
+ country?: string;
71
+ };
72
+ /** The integration's slug (a-z, 0-9, -), logged as a label. */
73
+ platform?: string;
74
+ pluginVersion?: string;
75
+ siteTerms?: {
76
+ version?: string;
77
+ acceptedAt?: string;
78
+ };
79
+ notify?: {
80
+ email?: string;
81
+ enabled?: boolean;
82
+ };
83
+ donation?: {
84
+ donor?: {
85
+ email?: string;
86
+ firstName?: string;
87
+ lastName?: string;
88
+ company?: string;
89
+ country?: string;
90
+ address?: {
91
+ line1?: string;
92
+ line2?: string;
93
+ city?: string;
94
+ state?: string;
95
+ postalCode?: string;
96
+ country?: string;
97
+ };
98
+ tos?: {
99
+ version?: string;
100
+ acceptedAt?: string;
101
+ };
102
+ };
103
+ message?: string;
104
+ isAnonymous?: boolean;
105
+ wantsTaxReceipt?: boolean;
106
+ };
107
+ }
108
+ /**
109
+ * Mirrors pybara-wallet's EmbeddedErrorCode. Every value but RATE_UNAVAILABLE is a terminal refusal; the frame handles other transient failures with its own retry screen and never posts them.
110
+ * RATE_UNAVAILABLE: core's exchange rate for a checkout's currency could not be loaded, so the frame had no amount to show; worth trying again.
111
+ */
112
+ declare const EMBEDDED_ERROR_CODES: readonly ["DESTINATION_REFUSED", "INVALID_BENEFICIARY", "INVALID_CHECKOUT", "NO_WALLET_AVAILABLE", "RATE_UNAVAILABLE", "SITE_MISMATCH"];
113
+ type EmbeddedErrorCode = typeof EMBEDDED_ERROR_CODES[number];
114
+ /**
115
+ * The error handed to onError() when the frame refuses.
116
+ * Carries `.code` so a platform branches on it rather than string-matching `.message`, which may be reworded or localised at any time.
117
+ */
118
+ export declare class EmbeddedError extends Error {
119
+ readonly code: EmbeddedErrorCode | 'UNKNOWN';
120
+ constructor(code: EmbeddedErrorCode | 'UNKNOWN', message: string);
121
+ }
122
+ export declare class CheckoutModal {
123
+ private config;
124
+ private overlay;
125
+ private iframe;
126
+ /** Shown until the frame posts its first content height: the iframe starts at height 0, so the backdrop would otherwise look empty. */
127
+ private spinner;
128
+ private walletOrigin;
129
+ private handleMessage;
130
+ private handleEscapeKey;
131
+ /** False while the frame reports a payment or subscription in flight, so Escape cannot abandon it halfway. True by default, for a frame that never reports it. */
132
+ private closable;
133
+ /** Set once the iframe's `load` fires; until then show() cannot post to it. */
134
+ private iframeLoaded;
135
+ /** Held by show() when it runs before `load`; the `load` handler sends it. */
136
+ private pendingPaymentData;
137
+ constructor(config: CheckoutModalConfig);
138
+ /** Backdrop and iframe, built at construction and hidden until open() — see the file header for why. */
139
+ private createIframe;
140
+ private sendInitMessage;
141
+ /**
142
+ * Show the backdrop and its spinner now, before the payment data exists: a platform calls it on the buyer's click, while it still creates the order, so one overlay covers the whole sequence.
143
+ * Does nothing if already shown; show() calls it too. close() takes it down again if the platform fails before show().
144
+ */
145
+ open(): void;
146
+ /** Reveal the (usually already loaded) iframe, opening the backdrop if open() has not already, and post the frame its payment data. */
147
+ show(data: PaymentData): void;
148
+ /**
149
+ * A message box instead of the frame, for a platform-side check that fails before checkout opens (a suspended merchant or recipient, a missing principal).
150
+ * The caller supplies the text, translated: everything after opening is the frame's to report, so this package holds no error copy.
151
+ */
152
+ renderTerminalState(message: string): void;
153
+ /**
154
+ * Releases all state at once, so nothing can reach the frame any more; only the overlay element lingers for the close animation.
155
+ * renderTerminalState() relies on this: it builds its own overlay straight after, while the old one is still fading.
156
+ */
157
+ close(): void;
158
+ }
159
+ export {};
160
+ //# sourceMappingURL=modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../src/modal/modal.ts"],"names":[],"mappings":"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"}