@fayz-ai/plugin-payments 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Faya Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,80 @@
1
+ import { createSafeDataProvider } from '@fayz-ai/core';
2
+
3
+ // src/index.ts
4
+
5
+ // src/data/mock.ts
6
+ var seq = 0;
7
+ function buildBrCode(amount, chargeId) {
8
+ const amt = amount.toFixed(2);
9
+ return `00020126850014br.gov.bcb.pix2563qrcode.fayz.dev/pix/v2/${chargeId}520400005303986540${amt.length}${amt}5802BR5913HEMPDENT6009SAO PAULO62070503***6304FZ${seq % 90 + 10}`;
10
+ }
11
+ function createMockPaymentProvider(options) {
12
+ const autoPayAfterMs = options?.autoPayAfterMs ?? 6e3;
13
+ const expiresAfterMs = options?.expiresAfterMs ?? 5 * 6e4;
14
+ const charges = /* @__PURE__ */ new Map();
15
+ function statusOf(rec) {
16
+ if (rec.paid) return "paid";
17
+ const now = Date.now();
18
+ if (now >= rec.autoPayAt) return "paid";
19
+ if (now >= rec.expiresAt) return "expired";
20
+ return "pending";
21
+ }
22
+ return {
23
+ async createCharge(input) {
24
+ const now = Date.now();
25
+ const chargeId = `mockpix-${++seq}-${input.orderId ?? "na"}`;
26
+ const brCode = buildBrCode(input.amount, chargeId);
27
+ const charge = {
28
+ chargeId,
29
+ status: "pending",
30
+ amount: input.amount,
31
+ currency: input.currency,
32
+ pixQrCode: brCode,
33
+ pixCopyPaste: brCode,
34
+ expiresAt: new Date(now + expiresAfterMs).toISOString()
35
+ };
36
+ charges.set(chargeId, {
37
+ charge,
38
+ createdAt: now,
39
+ autoPayAt: now + autoPayAfterMs,
40
+ expiresAt: now + expiresAfterMs,
41
+ paid: false
42
+ });
43
+ return charge;
44
+ },
45
+ async getChargeStatus(chargeId) {
46
+ const rec = charges.get(chargeId);
47
+ if (!rec) return "failed";
48
+ return statusOf(rec);
49
+ },
50
+ markPaid(chargeId) {
51
+ const rec = charges.get(chargeId);
52
+ if (rec) rec.paid = true;
53
+ }
54
+ };
55
+ }
56
+
57
+ // src/data/supabase.ts
58
+ function createSupabasePaymentProvider() {
59
+ const notImplemented = () => {
60
+ throw new Error(
61
+ "[plugin-payments] Supabase/MercadoPago provider not implemented yet \u2014 deferred. Run on the mock provider (no gateway configured) for now."
62
+ );
63
+ };
64
+ return {
65
+ createCharge: (_input) => notImplemented(),
66
+ getChargeStatus: (_chargeId) => notImplemented()
67
+ };
68
+ }
69
+
70
+ // src/index.ts
71
+ function createSafePaymentProvider(mockOptions) {
72
+ return createSafeDataProvider(
73
+ () => createSupabasePaymentProvider(),
74
+ () => createMockPaymentProvider(mockOptions)
75
+ );
76
+ }
77
+
78
+ export { createMockPaymentProvider, createSafePaymentProvider, createSupabasePaymentProvider };
79
+ //# sourceMappingURL=chunk-CSJFAXHO.js.map
80
+ //# sourceMappingURL=chunk-CSJFAXHO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/data/mock.ts","../src/data/supabase.ts","../src/index.ts"],"names":[],"mappings":";;;;;AAuBA,IAAI,GAAA,GAAM,CAAA;AAGV,SAAS,WAAA,CAAY,QAAgB,QAAA,EAA0B;AAC7D,EAAA,MAAM,GAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA;AAE5B,EAAA,OACE,CAAA,uDAAA,EAA0D,QAAQ,CAAA,kBAAA,EAC7C,GAAA,CAAI,MAAM,GAAG,GAAG,CAAA,gDAAA,EAAoD,GAAA,GAAM,EAAA,GAAK,EAAG,CAAA,CAAA;AAE3G;AAEO,SAAS,0BAA0B,OAAA,EAAmD;AAC3F,EAAA,MAAM,cAAA,GAAiB,SAAS,cAAA,IAAkB,GAAA;AAClD,EAAA,MAAM,cAAA,GAAiB,OAAA,EAAS,cAAA,IAAkB,CAAA,GAAI,GAAA;AACtD,EAAA,MAAM,OAAA,uBAAc,GAAA,EAA0B;AAE9C,EAAA,SAAS,SAAS,GAAA,EAAiC;AACjD,IAAA,IAAI,GAAA,CAAI,MAAM,OAAO,MAAA;AACrB,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,GAAA,IAAO,GAAA,CAAI,SAAA,EAAW,OAAO,MAAA;AACjC,IAAA,IAAI,GAAA,IAAO,GAAA,CAAI,SAAA,EAAW,OAAO,SAAA;AACjC,IAAA,OAAO,SAAA;AAAA,EACT;AAEA,EAAA,OAAO;AAAA,IACL,MAAM,aAAa,KAAA,EAA8C;AAC/D,MAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,MAAA,MAAM,WAAW,CAAA,QAAA,EAAW,EAAE,GAAG,CAAA,CAAA,EAAI,KAAA,CAAM,WAAW,IAAI,CAAA,CAAA;AAC1D,MAAA,MAAM,MAAA,GAAS,WAAA,CAAY,KAAA,CAAM,MAAA,EAAQ,QAAQ,CAAA;AACjD,MAAA,MAAM,MAAA,GAAoB;AAAA,QACxB,QAAA;AAAA,QACA,MAAA,EAAQ,SAAA;AAAA,QACR,QAAQ,KAAA,CAAM,MAAA;AAAA,QACd,UAAU,KAAA,CAAM,QAAA;AAAA,QAChB,SAAA,EAAW,MAAA;AAAA,QACX,YAAA,EAAc,MAAA;AAAA,QACd,WAAW,IAAI,IAAA,CAAK,GAAA,GAAM,cAAc,EAAE,WAAA;AAAY,OACxD;AACA,MAAA,OAAA,CAAQ,IAAI,QAAA,EAAU;AAAA,QACpB,MAAA;AAAA,QACA,SAAA,EAAW,GAAA;AAAA,QACX,WAAW,GAAA,GAAM,cAAA;AAAA,QACjB,WAAW,GAAA,GAAM,cAAA;AAAA,QACjB,IAAA,EAAM;AAAA,OACP,CAAA;AACD,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IAEA,MAAM,gBAAgB,QAAA,EAAyC;AAC7D,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AAChC,MAAA,IAAI,CAAC,KAAK,OAAO,QAAA;AACjB,MAAA,OAAO,SAAS,GAAG,CAAA;AAAA,IACrB,CAAA;AAAA,IAEA,SAAS,QAAA,EAAwB;AAC/B,MAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA;AAChC,MAAA,IAAI,GAAA,MAAS,IAAA,GAAO,IAAA;AAAA,IACtB;AAAA,GACF;AACF;;;ACvEO,SAAS,6BAAA,GAAiD;AAC/D,EAAA,MAAM,iBAAiB,MAAa;AAClC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF,CAAA;AACA,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,CAAC,MAAA,KAAkD,cAAA,EAAe;AAAA,IAChF,eAAA,EAAiB,CAAC,SAAA,KAA6C,cAAA;AAAe,GAChF;AACF;;;ACVO,SAAS,0BAA0B,WAAA,EAAmD;AAC3F,EAAA,OAAO,sBAAA;AAAA,IACL,MAAM,6BAAA,EAA8B;AAAA,IACpC,MAAM,0BAA0B,WAAW;AAAA,GAC7C;AACF","file":"chunk-CSJFAXHO.js","sourcesContent":["import type { PaymentProvider, CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'\n\n/** Mock provider adds a demo-only `markPaid` shortcut on top of the contract. */\nexport interface MockPaymentProvider extends PaymentProvider {\n /** Force a charge to 'paid' immediately (demo \"Já paguei\" button). */\n markPaid(chargeId: string): void\n}\n\nexport interface MockPaymentOptions {\n /** Auto-confirm a pending charge after this many ms (simulates the gateway webhook). Default 6000. */\n autoPayAfterMs?: number\n /** Charge validity window in ms. Default 5 min. */\n expiresAfterMs?: number\n}\n\ninterface ChargeRecord {\n charge: PixCharge\n createdAt: number\n autoPayAt: number\n expiresAt: number\n paid: boolean\n}\n\nlet seq = 0\n\n/** Build a realistic-looking (non-functional) Pix BR Code \"copia e cola\". */\nfunction buildBrCode(amount: number, chargeId: string): string {\n const amt = amount.toFixed(2)\n // Simplified EMV-ish layout — enough to look/scan like a Pix payload in the POC.\n return (\n `00020126850014br.gov.bcb.pix2563qrcode.fayz.dev/pix/v2/${chargeId}` +\n `520400005303986540${amt.length}${amt}5802BR5913HEMPDENT6009SAO PAULO62070503***6304FZ${(seq % 90 + 10)}`\n )\n}\n\nexport function createMockPaymentProvider(options?: MockPaymentOptions): MockPaymentProvider {\n const autoPayAfterMs = options?.autoPayAfterMs ?? 6000\n const expiresAfterMs = options?.expiresAfterMs ?? 5 * 60_000\n const charges = new Map<string, ChargeRecord>()\n\n function statusOf(rec: ChargeRecord): ChargeStatus {\n if (rec.paid) return 'paid'\n const now = Date.now()\n if (now >= rec.autoPayAt) return 'paid'\n if (now >= rec.expiresAt) return 'expired'\n return 'pending'\n }\n\n return {\n async createCharge(input: CreateChargeInput): Promise<PixCharge> {\n const now = Date.now()\n const chargeId = `mockpix-${++seq}-${input.orderId ?? 'na'}`\n const brCode = buildBrCode(input.amount, chargeId)\n const charge: PixCharge = {\n chargeId,\n status: 'pending',\n amount: input.amount,\n currency: input.currency,\n pixQrCode: brCode,\n pixCopyPaste: brCode,\n expiresAt: new Date(now + expiresAfterMs).toISOString(),\n }\n charges.set(chargeId, {\n charge,\n createdAt: now,\n autoPayAt: now + autoPayAfterMs,\n expiresAt: now + expiresAfterMs,\n paid: false,\n })\n return charge\n },\n\n async getChargeStatus(chargeId: string): Promise<ChargeStatus> {\n const rec = charges.get(chargeId)\n if (!rec) return 'failed'\n return statusOf(rec)\n },\n\n markPaid(chargeId: string): void {\n const rec = charges.get(chargeId)\n if (rec) rec.paid = true\n },\n }\n}\n","import type { PaymentProvider, CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Supabase/gateway-backed payment provider — STUB (deferred).\n//\n// Later: a real MercadoPago (or other PSP) Pix integration via a Supabase edge\n// function (credentials server-side; actions create_charge | get_status |\n// webhook), mirroring the plugbank-sync edge function. Swapping this in is a\n// pure provider change — the booking widget and hooks are untouched because they\n// depend only on the core PaymentProvider interface.\n// ---------------------------------------------------------------------------\n\nexport function createSupabasePaymentProvider(): PaymentProvider {\n const notImplemented = (): never => {\n throw new Error(\n '[plugin-payments] Supabase/MercadoPago provider not implemented yet — deferred. ' +\n 'Run on the mock provider (no gateway configured) for now.',\n )\n }\n return {\n createCharge: (_input: CreateChargeInput): Promise<PixCharge> => notImplemented(),\n getChargeStatus: (_chargeId: string): Promise<ChargeStatus> => notImplemented(),\n }\n}\n","import { createSafeDataProvider } from '@fayz-ai/core'\nimport type { PaymentProvider } from '@fayz-ai/core'\nimport { createMockPaymentProvider, type MockPaymentOptions } from './data/mock'\nimport { createSupabasePaymentProvider } from './data/supabase'\n\n// ---------------------------------------------------------------------------\n// @fayz-ai/plugin-payments — gateway-agnostic charge provider (Pix today).\n// Bookkeeping (invoices/movements/reconciliation) stays in plugin-financial;\n// this plugin OWNS money-in initiation (create a charge → payable artifacts →\n// status). Mirrors createSafeFinancialProvider.\n// ---------------------------------------------------------------------------\n\n/** Supabase/gateway when configured, else the mock provider. */\nexport function createSafePaymentProvider(mockOptions?: MockPaymentOptions): PaymentProvider {\n return createSafeDataProvider(\n () => createSupabasePaymentProvider(),\n () => createMockPaymentProvider(mockOptions),\n )\n}\n\nexport { createMockPaymentProvider, createSupabasePaymentProvider } from './data'\nexport type { MockPaymentProvider, MockPaymentOptions } from './data'\nexport type {\n PaymentProvider, PaymentMethod, ChargeStatus, CreateChargeInput, PixCharge,\n} from '@fayz-ai/core'\n"]}
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+
3
+ var core = require('@fayz-ai/core');
4
+
5
+ // src/index.ts
6
+
7
+ // src/data/mock.ts
8
+ var seq = 0;
9
+ function buildBrCode(amount, chargeId) {
10
+ const amt = amount.toFixed(2);
11
+ return `00020126850014br.gov.bcb.pix2563qrcode.fayz.dev/pix/v2/${chargeId}520400005303986540${amt.length}${amt}5802BR5913HEMPDENT6009SAO PAULO62070503***6304FZ${seq % 90 + 10}`;
12
+ }
13
+ function createMockPaymentProvider(options) {
14
+ const autoPayAfterMs = options?.autoPayAfterMs ?? 6e3;
15
+ const expiresAfterMs = options?.expiresAfterMs ?? 5 * 6e4;
16
+ const charges = /* @__PURE__ */ new Map();
17
+ function statusOf(rec) {
18
+ if (rec.paid) return "paid";
19
+ const now = Date.now();
20
+ if (now >= rec.autoPayAt) return "paid";
21
+ if (now >= rec.expiresAt) return "expired";
22
+ return "pending";
23
+ }
24
+ return {
25
+ async createCharge(input) {
26
+ const now = Date.now();
27
+ const chargeId = `mockpix-${++seq}-${input.orderId ?? "na"}`;
28
+ const brCode = buildBrCode(input.amount, chargeId);
29
+ const charge = {
30
+ chargeId,
31
+ status: "pending",
32
+ amount: input.amount,
33
+ currency: input.currency,
34
+ pixQrCode: brCode,
35
+ pixCopyPaste: brCode,
36
+ expiresAt: new Date(now + expiresAfterMs).toISOString()
37
+ };
38
+ charges.set(chargeId, {
39
+ charge,
40
+ createdAt: now,
41
+ autoPayAt: now + autoPayAfterMs,
42
+ expiresAt: now + expiresAfterMs,
43
+ paid: false
44
+ });
45
+ return charge;
46
+ },
47
+ async getChargeStatus(chargeId) {
48
+ const rec = charges.get(chargeId);
49
+ if (!rec) return "failed";
50
+ return statusOf(rec);
51
+ },
52
+ markPaid(chargeId) {
53
+ const rec = charges.get(chargeId);
54
+ if (rec) rec.paid = true;
55
+ }
56
+ };
57
+ }
58
+
59
+ // src/data/supabase.ts
60
+ function createSupabasePaymentProvider() {
61
+ const notImplemented = () => {
62
+ throw new Error(
63
+ "[plugin-payments] Supabase/MercadoPago provider not implemented yet \u2014 deferred. Run on the mock provider (no gateway configured) for now."
64
+ );
65
+ };
66
+ return {
67
+ createCharge: (_input) => notImplemented(),
68
+ getChargeStatus: (_chargeId) => notImplemented()
69
+ };
70
+ }
71
+
72
+ // src/index.ts
73
+ function createSafePaymentProvider(mockOptions) {
74
+ return core.createSafeDataProvider(
75
+ () => createSupabasePaymentProvider(),
76
+ () => createMockPaymentProvider(mockOptions)
77
+ );
78
+ }
79
+
80
+ exports.createMockPaymentProvider = createMockPaymentProvider;
81
+ exports.createSafePaymentProvider = createSafePaymentProvider;
82
+ exports.createSupabasePaymentProvider = createSupabasePaymentProvider;
83
+ //# sourceMappingURL=chunk-RMA57VFG.cjs.map
84
+ //# sourceMappingURL=chunk-RMA57VFG.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/data/mock.ts","../src/data/supabase.ts","../src/index.ts"],"names":["createSafeDataProvider"],"mappings":"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","file":"chunk-RMA57VFG.cjs","sourcesContent":["import type { PaymentProvider, CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'\n\n/** Mock provider adds a demo-only `markPaid` shortcut on top of the contract. */\nexport interface MockPaymentProvider extends PaymentProvider {\n /** Force a charge to 'paid' immediately (demo \"Já paguei\" button). */\n markPaid(chargeId: string): void\n}\n\nexport interface MockPaymentOptions {\n /** Auto-confirm a pending charge after this many ms (simulates the gateway webhook). Default 6000. */\n autoPayAfterMs?: number\n /** Charge validity window in ms. Default 5 min. */\n expiresAfterMs?: number\n}\n\ninterface ChargeRecord {\n charge: PixCharge\n createdAt: number\n autoPayAt: number\n expiresAt: number\n paid: boolean\n}\n\nlet seq = 0\n\n/** Build a realistic-looking (non-functional) Pix BR Code \"copia e cola\". */\nfunction buildBrCode(amount: number, chargeId: string): string {\n const amt = amount.toFixed(2)\n // Simplified EMV-ish layout — enough to look/scan like a Pix payload in the POC.\n return (\n `00020126850014br.gov.bcb.pix2563qrcode.fayz.dev/pix/v2/${chargeId}` +\n `520400005303986540${amt.length}${amt}5802BR5913HEMPDENT6009SAO PAULO62070503***6304FZ${(seq % 90 + 10)}`\n )\n}\n\nexport function createMockPaymentProvider(options?: MockPaymentOptions): MockPaymentProvider {\n const autoPayAfterMs = options?.autoPayAfterMs ?? 6000\n const expiresAfterMs = options?.expiresAfterMs ?? 5 * 60_000\n const charges = new Map<string, ChargeRecord>()\n\n function statusOf(rec: ChargeRecord): ChargeStatus {\n if (rec.paid) return 'paid'\n const now = Date.now()\n if (now >= rec.autoPayAt) return 'paid'\n if (now >= rec.expiresAt) return 'expired'\n return 'pending'\n }\n\n return {\n async createCharge(input: CreateChargeInput): Promise<PixCharge> {\n const now = Date.now()\n const chargeId = `mockpix-${++seq}-${input.orderId ?? 'na'}`\n const brCode = buildBrCode(input.amount, chargeId)\n const charge: PixCharge = {\n chargeId,\n status: 'pending',\n amount: input.amount,\n currency: input.currency,\n pixQrCode: brCode,\n pixCopyPaste: brCode,\n expiresAt: new Date(now + expiresAfterMs).toISOString(),\n }\n charges.set(chargeId, {\n charge,\n createdAt: now,\n autoPayAt: now + autoPayAfterMs,\n expiresAt: now + expiresAfterMs,\n paid: false,\n })\n return charge\n },\n\n async getChargeStatus(chargeId: string): Promise<ChargeStatus> {\n const rec = charges.get(chargeId)\n if (!rec) return 'failed'\n return statusOf(rec)\n },\n\n markPaid(chargeId: string): void {\n const rec = charges.get(chargeId)\n if (rec) rec.paid = true\n },\n }\n}\n","import type { PaymentProvider, CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Supabase/gateway-backed payment provider — STUB (deferred).\n//\n// Later: a real MercadoPago (or other PSP) Pix integration via a Supabase edge\n// function (credentials server-side; actions create_charge | get_status |\n// webhook), mirroring the plugbank-sync edge function. Swapping this in is a\n// pure provider change — the booking widget and hooks are untouched because they\n// depend only on the core PaymentProvider interface.\n// ---------------------------------------------------------------------------\n\nexport function createSupabasePaymentProvider(): PaymentProvider {\n const notImplemented = (): never => {\n throw new Error(\n '[plugin-payments] Supabase/MercadoPago provider not implemented yet — deferred. ' +\n 'Run on the mock provider (no gateway configured) for now.',\n )\n }\n return {\n createCharge: (_input: CreateChargeInput): Promise<PixCharge> => notImplemented(),\n getChargeStatus: (_chargeId: string): Promise<ChargeStatus> => notImplemented(),\n }\n}\n","import { createSafeDataProvider } from '@fayz-ai/core'\nimport type { PaymentProvider } from '@fayz-ai/core'\nimport { createMockPaymentProvider, type MockPaymentOptions } from './data/mock'\nimport { createSupabasePaymentProvider } from './data/supabase'\n\n// ---------------------------------------------------------------------------\n// @fayz-ai/plugin-payments — gateway-agnostic charge provider (Pix today).\n// Bookkeeping (invoices/movements/reconciliation) stays in plugin-financial;\n// this plugin OWNS money-in initiation (create a charge → payable artifacts →\n// status). Mirrors createSafeFinancialProvider.\n// ---------------------------------------------------------------------------\n\n/** Supabase/gateway when configured, else the mock provider. */\nexport function createSafePaymentProvider(mockOptions?: MockPaymentOptions): PaymentProvider {\n return createSafeDataProvider(\n () => createSupabasePaymentProvider(),\n () => createMockPaymentProvider(mockOptions),\n )\n}\n\nexport { createMockPaymentProvider, createSupabasePaymentProvider } from './data'\nexport type { MockPaymentProvider, MockPaymentOptions } from './data'\nexport type {\n PaymentProvider, PaymentMethod, ChargeStatus, CreateChargeInput, PixCharge,\n} from '@fayz-ai/core'\n"]}
@@ -0,0 +1,4 @@
1
+ export { createMockPaymentProvider } from './mock';
2
+ export type { MockPaymentProvider, MockPaymentOptions } from './mock';
3
+ export { createSupabasePaymentProvider } from './supabase';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/data/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,QAAQ,CAAA;AAClD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AACrE,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA"}
@@ -0,0 +1,14 @@
1
+ import type { PaymentProvider } from '@fayz-ai/core';
2
+ /** Mock provider adds a demo-only `markPaid` shortcut on top of the contract. */
3
+ export interface MockPaymentProvider extends PaymentProvider {
4
+ /** Force a charge to 'paid' immediately (demo "Já paguei" button). */
5
+ markPaid(chargeId: string): void;
6
+ }
7
+ export interface MockPaymentOptions {
8
+ /** Auto-confirm a pending charge after this many ms (simulates the gateway webhook). Default 6000. */
9
+ autoPayAfterMs?: number;
10
+ /** Charge validity window in ms. Default 5 min. */
11
+ expiresAfterMs?: number;
12
+ }
13
+ export declare function createMockPaymentProvider(options?: MockPaymentOptions): MockPaymentProvider;
14
+ //# sourceMappingURL=mock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/data/mock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAA8C,MAAM,eAAe,CAAA;AAEhG,iFAAiF;AACjF,MAAM,WAAW,mBAAoB,SAAQ,eAAe;IAC1D,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,sGAAsG;IACtG,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,mDAAmD;IACnD,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAsBD,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,mBAAmB,CAgD3F"}
@@ -0,0 +1,3 @@
1
+ import type { PaymentProvider } from '@fayz-ai/core';
2
+ export declare function createSupabasePaymentProvider(): PaymentProvider;
3
+ //# sourceMappingURL=supabase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/data/supabase.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAA8C,MAAM,eAAe,CAAA;AAYhG,wBAAgB,6BAA6B,IAAI,eAAe,CAW/D"}
package/dist/index.cjs ADDED
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ var chunkRMA57VFG_cjs = require('./chunk-RMA57VFG.cjs');
4
+
5
+
6
+
7
+ Object.defineProperty(exports, "createMockPaymentProvider", {
8
+ enumerable: true,
9
+ get: function () { return chunkRMA57VFG_cjs.createMockPaymentProvider; }
10
+ });
11
+ Object.defineProperty(exports, "createSafePaymentProvider", {
12
+ enumerable: true,
13
+ get: function () { return chunkRMA57VFG_cjs.createSafePaymentProvider; }
14
+ });
15
+ Object.defineProperty(exports, "createSupabasePaymentProvider", {
16
+ enumerable: true,
17
+ get: function () { return chunkRMA57VFG_cjs.createSupabasePaymentProvider; }
18
+ });
19
+ //# sourceMappingURL=index.cjs.map
20
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.cjs"}
@@ -0,0 +1,8 @@
1
+ import type { PaymentProvider } from '@fayz-ai/core';
2
+ import { type MockPaymentOptions } from './data/mock';
3
+ /** Supabase/gateway when configured, else the mock provider. */
4
+ export declare function createSafePaymentProvider(mockOptions?: MockPaymentOptions): PaymentProvider;
5
+ export { createMockPaymentProvider, createSupabasePaymentProvider } from './data';
6
+ export type { MockPaymentProvider, MockPaymentOptions } from './data';
7
+ export type { PaymentProvider, PaymentMethod, ChargeStatus, CreateChargeInput, PixCharge, } from '@fayz-ai/core';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AACpD,OAAO,EAA6B,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAUhF,gEAAgE;AAChE,wBAAgB,yBAAyB,CAAC,WAAW,CAAC,EAAE,kBAAkB,GAAG,eAAe,CAK3F;AAED,OAAO,EAAE,yBAAyB,EAAE,6BAA6B,EAAE,MAAM,QAAQ,CAAA;AACjF,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAA;AACrE,YAAY,EACV,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,SAAS,GAC3E,MAAM,eAAe,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { createMockPaymentProvider, createSafePaymentProvider, createSupabasePaymentProvider } from './chunk-CSJFAXHO.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,11 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { PaymentProvider } from '@fayz-ai/core';
3
+ export interface PaymentContextValue {
4
+ provider: PaymentProvider;
5
+ }
6
+ export declare function PaymentProviderContext({ value, children }: {
7
+ value: PaymentContextValue;
8
+ children: ReactNode;
9
+ }): import("react").JSX.Element;
10
+ export declare function usePaymentContext(): PaymentContextValue;
11
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/public/context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,eAAe,CAAA;CAC1B;AAID,wBAAgB,sBAAsB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,mBAAmB,CAAC;IAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAE9G;AAED,wBAAgB,iBAAiB,IAAI,mBAAmB,CAMvD"}
@@ -0,0 +1,21 @@
1
+ import { type FC, type ReactNode } from 'react';
2
+ import type { PluginManifest, PluginScope, PaymentProvider } from '@fayz-ai/core';
3
+ import type { MockPaymentOptions } from '../data/mock';
4
+ export interface PublicPaymentOptions {
5
+ /** Currency for charges (informational; charges carry their own). */
6
+ currency?: string;
7
+ /** Inject a custom provider (real gateway). Overrides the safe resolver. */
8
+ paymentProvider?: PaymentProvider;
9
+ /** Tuning for the mock provider (auto-pay/expiry) when no real provider is set. */
10
+ mock?: MockPaymentOptions;
11
+ scope?: PluginScope;
12
+ }
13
+ export interface PublicPaymentPlugin {
14
+ manifest: PluginManifest;
15
+ Provider: FC<{
16
+ children: ReactNode;
17
+ }>;
18
+ paymentProvider: PaymentProvider;
19
+ }
20
+ export declare function createPublicPaymentPlugin(options?: PublicPaymentOptions): PublicPaymentPlugin;
21
+ //# sourceMappingURL=createPublicPaymentPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createPublicPaymentPlugin.d.ts","sourceRoot":"","sources":["../../src/public/createPublicPaymentPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAYtD,MAAM,WAAW,oBAAoB;IACnC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,mFAAmF;IACnF,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,cAAc,CAAA;IACxB,QAAQ,EAAE,EAAE,CAAC;QAAE,QAAQ,EAAE,SAAS,CAAA;KAAE,CAAC,CAAA;IACrC,eAAe,EAAE,eAAe,CAAA;CACjC;AAED,wBAAgB,yBAAyB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,mBAAmB,CAuB7F"}
@@ -0,0 +1,19 @@
1
+ import type { CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core';
2
+ export interface UsePixChargeResult {
3
+ charge: PixCharge | null;
4
+ creating: boolean;
5
+ error: Error | null;
6
+ create: (input: CreateChargeInput) => Promise<PixCharge | null>;
7
+ reset: () => void;
8
+ }
9
+ /**
10
+ * Create a Pix charge on demand. For a standalone checkout page; the booking
11
+ * widget uses its own injected provider directly (agenda depends only on core).
12
+ */
13
+ export declare function usePixCharge(): UsePixChargeResult;
14
+ /**
15
+ * Poll a charge's status until it settles. Cleans the interval on unmount,
16
+ * chargeId change, and terminal states.
17
+ */
18
+ export declare function useChargeStatus(chargeId: string | null, intervalMs?: number): ChargeStatus | null;
19
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/public/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG/E,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACnB,MAAM,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAA;IAC/D,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,kBAAkB,CA8BjD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,SAAO,GAAG,YAAY,GAAG,IAAI,CA6B/F"}
@@ -0,0 +1,114 @@
1
+ 'use strict';
2
+
3
+ var chunkRMA57VFG_cjs = require('../chunk-RMA57VFG.cjs');
4
+ var react = require('react');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ var PaymentContext = react.createContext(null);
8
+ function PaymentProviderContext({ value, children }) {
9
+ return /* @__PURE__ */ jsxRuntime.jsx(PaymentContext.Provider, { value, children });
10
+ }
11
+ function usePaymentContext() {
12
+ const ctx = react.useContext(PaymentContext);
13
+ if (!ctx) {
14
+ throw new Error("[plugin-payments] usePaymentContext must be used within the payments Provider.");
15
+ }
16
+ return ctx;
17
+ }
18
+
19
+ // src/public/createPublicPaymentPlugin.ts
20
+ function createPublicPaymentPlugin(options) {
21
+ const paymentProvider = options?.paymentProvider ?? chunkRMA57VFG_cjs.createSafePaymentProvider(options?.mock);
22
+ const value = { provider: paymentProvider };
23
+ const Provider = ({ children }) => react.createElement(PaymentProviderContext, { value, children });
24
+ Provider.displayName = "PaymentPluginProvider";
25
+ const manifest = {
26
+ id: "payments",
27
+ name: "Pagamentos",
28
+ icon: "CreditCard",
29
+ version: "0.1.0",
30
+ scope: options?.scope ?? "universal",
31
+ scaffolds: ["website", "landing_page"],
32
+ defaultEnabled: true,
33
+ dependencies: [],
34
+ navigation: [],
35
+ routes: [],
36
+ widgets: []
37
+ };
38
+ return { manifest, Provider, paymentProvider };
39
+ }
40
+ function usePixCharge() {
41
+ const { provider } = usePaymentContext();
42
+ const [charge, setCharge] = react.useState(null);
43
+ const [creating, setCreating] = react.useState(false);
44
+ const [error, setError] = react.useState(null);
45
+ const create = react.useCallback(
46
+ async (input) => {
47
+ setCreating(true);
48
+ setError(null);
49
+ try {
50
+ const c = await provider.createCharge(input);
51
+ setCharge(c);
52
+ return c;
53
+ } catch (err) {
54
+ setError(err instanceof Error ? err : new Error(String(err)));
55
+ return null;
56
+ } finally {
57
+ setCreating(false);
58
+ }
59
+ },
60
+ [provider]
61
+ );
62
+ const reset = react.useCallback(() => {
63
+ setCharge(null);
64
+ setError(null);
65
+ }, []);
66
+ return { charge, creating, error, create, reset };
67
+ }
68
+ function useChargeStatus(chargeId, intervalMs = 2500) {
69
+ const { provider } = usePaymentContext();
70
+ const [status, setStatus] = react.useState(null);
71
+ const timer = react.useRef(null);
72
+ react.useEffect(() => {
73
+ let active = true;
74
+ setStatus(null);
75
+ if (!chargeId) return;
76
+ const clear = () => {
77
+ if (timer.current) {
78
+ clearInterval(timer.current);
79
+ timer.current = null;
80
+ }
81
+ };
82
+ const tick = () => {
83
+ provider.getChargeStatus(chargeId).then((s) => {
84
+ if (!active) return;
85
+ setStatus(s);
86
+ if (s === "paid" || s === "expired" || s === "failed") clear();
87
+ }).catch(() => {
88
+ });
89
+ };
90
+ tick();
91
+ timer.current = setInterval(tick, intervalMs);
92
+ return () => {
93
+ active = false;
94
+ clear();
95
+ };
96
+ }, [provider, chargeId, intervalMs]);
97
+ return status;
98
+ }
99
+
100
+ Object.defineProperty(exports, "createMockPaymentProvider", {
101
+ enumerable: true,
102
+ get: function () { return chunkRMA57VFG_cjs.createMockPaymentProvider; }
103
+ });
104
+ Object.defineProperty(exports, "createSafePaymentProvider", {
105
+ enumerable: true,
106
+ get: function () { return chunkRMA57VFG_cjs.createSafePaymentProvider; }
107
+ });
108
+ exports.PaymentProviderContext = PaymentProviderContext;
109
+ exports.createPublicPaymentPlugin = createPublicPaymentPlugin;
110
+ exports.useChargeStatus = useChargeStatus;
111
+ exports.usePaymentContext = usePaymentContext;
112
+ exports.usePixCharge = usePixCharge;
113
+ //# sourceMappingURL=index.cjs.map
114
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/public/context.tsx","../../src/public/createPublicPaymentPlugin.ts","../../src/public/hooks.ts"],"names":["createContext","jsx","useContext","createSafePaymentProvider","createElement","useState","useCallback","useRef","useEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createContext, useContext, type ReactNode } from 'react'\nimport type { PaymentProvider } from '@fayz-ai/core'\n\nexport interface PaymentContextValue {\n provider: PaymentProvider\n}\n\nconst PaymentContext = createContext<PaymentContextValue | null>(null)\n\nexport function PaymentProviderContext({ value, children }: { value: PaymentContextValue; children: ReactNode }) {\n return <PaymentContext.Provider value={value}>{children}</PaymentContext.Provider>\n}\n\nexport function usePaymentContext(): PaymentContextValue {\n const ctx = useContext(PaymentContext)\n if (!ctx) {\n throw new Error('[plugin-payments] usePaymentContext must be used within the payments Provider.')\n }\n return ctx\n}\n","import { createElement, type FC, type ReactNode } from 'react'\nimport type { PluginManifest, PluginScope, PaymentProvider } from '@fayz-ai/core'\nimport { createSafePaymentProvider } from '../index'\nimport type { MockPaymentOptions } from '../data/mock'\nimport { PaymentProviderContext, type PaymentContextValue } from './context'\n\n// ---------------------------------------------------------------------------\n// @fayz-ai/plugin-payments/public — website payment surface.\n//\n// Returns a { manifest, Provider, paymentProvider } bundle mirroring the other\n// website plugins. The host injects `paymentProvider` into the booking plugin;\n// the Provider/hooks are for a future standalone checkout page. No routes — a\n// payment is a service, not a screen.\n// ---------------------------------------------------------------------------\n\nexport interface PublicPaymentOptions {\n /** Currency for charges (informational; charges carry their own). */\n currency?: string\n /** Inject a custom provider (real gateway). Overrides the safe resolver. */\n paymentProvider?: PaymentProvider\n /** Tuning for the mock provider (auto-pay/expiry) when no real provider is set. */\n mock?: MockPaymentOptions\n scope?: PluginScope\n}\n\nexport interface PublicPaymentPlugin {\n manifest: PluginManifest\n Provider: FC<{ children: ReactNode }>\n paymentProvider: PaymentProvider\n}\n\nexport function createPublicPaymentPlugin(options?: PublicPaymentOptions): PublicPaymentPlugin {\n const paymentProvider = options?.paymentProvider ?? createSafePaymentProvider(options?.mock)\n\n const value: PaymentContextValue = { provider: paymentProvider }\n const Provider: FC<{ children: ReactNode }> = ({ children }) =>\n createElement(PaymentProviderContext, { value, children })\n Provider.displayName = 'PaymentPluginProvider'\n\n const manifest: PluginManifest = {\n id: 'payments',\n name: 'Pagamentos',\n icon: 'CreditCard',\n version: '0.1.0',\n scope: options?.scope ?? 'universal',\n scaffolds: ['website', 'landing_page'],\n defaultEnabled: true,\n dependencies: [],\n navigation: [],\n routes: [],\n widgets: [],\n }\n\n return { manifest, Provider, paymentProvider }\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'\nimport { usePaymentContext } from './context'\n\nexport interface UsePixChargeResult {\n charge: PixCharge | null\n creating: boolean\n error: Error | null\n create: (input: CreateChargeInput) => Promise<PixCharge | null>\n reset: () => void\n}\n\n/**\n * Create a Pix charge on demand. For a standalone checkout page; the booking\n * widget uses its own injected provider directly (agenda depends only on core).\n */\nexport function usePixCharge(): UsePixChargeResult {\n const { provider } = usePaymentContext()\n const [charge, setCharge] = useState<PixCharge | null>(null)\n const [creating, setCreating] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n\n const create = useCallback(\n async (input: CreateChargeInput) => {\n setCreating(true)\n setError(null)\n try {\n const c = await provider.createCharge(input)\n setCharge(c)\n return c\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)))\n return null\n } finally {\n setCreating(false)\n }\n },\n [provider],\n )\n\n const reset = useCallback(() => {\n setCharge(null)\n setError(null)\n }, [])\n\n return { charge, creating, error, create, reset }\n}\n\n/**\n * Poll a charge's status until it settles. Cleans the interval on unmount,\n * chargeId change, and terminal states.\n */\nexport function useChargeStatus(chargeId: string | null, intervalMs = 2500): ChargeStatus | null {\n const { provider } = usePaymentContext()\n const [status, setStatus] = useState<ChargeStatus | null>(null)\n const timer = useRef<ReturnType<typeof setInterval> | null>(null)\n\n useEffect(() => {\n let active = true\n setStatus(null)\n if (!chargeId) return\n\n const clear = () => {\n if (timer.current) { clearInterval(timer.current); timer.current = null }\n }\n const tick = () => {\n provider\n .getChargeStatus(chargeId)\n .then((s) => {\n if (!active) return\n setStatus(s)\n if (s === 'paid' || s === 'expired' || s === 'failed') clear()\n })\n .catch(() => { /* keep polling on transient errors */ })\n }\n tick()\n timer.current = setInterval(tick, intervalMs)\n return () => { active = false; clear() }\n }, [provider, chargeId, intervalMs])\n\n return status\n}\n"]}
@@ -0,0 +1,9 @@
1
+ export { createPublicPaymentPlugin } from './createPublicPaymentPlugin';
2
+ export type { PublicPaymentOptions, PublicPaymentPlugin } from './createPublicPaymentPlugin';
3
+ export { PaymentProviderContext, usePaymentContext } from './context';
4
+ export type { PaymentContextValue } from './context';
5
+ export { usePixCharge, useChargeStatus } from './hooks';
6
+ export type { UsePixChargeResult } from './hooks';
7
+ export { createSafePaymentProvider, createMockPaymentProvider } from '../index';
8
+ export type { PaymentProvider, ChargeStatus, CreateChargeInput, PixCharge, MockPaymentProvider, MockPaymentOptions, } from '../index';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/public/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAA;AACvE,YAAY,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAC5F,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AACrE,YAAY,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AACjD,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAA;AAC/E,YAAY,EACV,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,mBAAmB,EAAE,kBAAkB,GACrG,MAAM,UAAU,CAAA"}
@@ -0,0 +1,101 @@
1
+ import { createSafePaymentProvider } from '../chunk-CSJFAXHO.js';
2
+ export { createMockPaymentProvider, createSafePaymentProvider } from '../chunk-CSJFAXHO.js';
3
+ import { createContext, useContext, useState, useCallback, useRef, useEffect, createElement } from 'react';
4
+ import { jsx } from 'react/jsx-runtime';
5
+
6
+ var PaymentContext = createContext(null);
7
+ function PaymentProviderContext({ value, children }) {
8
+ return /* @__PURE__ */ jsx(PaymentContext.Provider, { value, children });
9
+ }
10
+ function usePaymentContext() {
11
+ const ctx = useContext(PaymentContext);
12
+ if (!ctx) {
13
+ throw new Error("[plugin-payments] usePaymentContext must be used within the payments Provider.");
14
+ }
15
+ return ctx;
16
+ }
17
+
18
+ // src/public/createPublicPaymentPlugin.ts
19
+ function createPublicPaymentPlugin(options) {
20
+ const paymentProvider = options?.paymentProvider ?? createSafePaymentProvider(options?.mock);
21
+ const value = { provider: paymentProvider };
22
+ const Provider = ({ children }) => createElement(PaymentProviderContext, { value, children });
23
+ Provider.displayName = "PaymentPluginProvider";
24
+ const manifest = {
25
+ id: "payments",
26
+ name: "Pagamentos",
27
+ icon: "CreditCard",
28
+ version: "0.1.0",
29
+ scope: options?.scope ?? "universal",
30
+ scaffolds: ["website", "landing_page"],
31
+ defaultEnabled: true,
32
+ dependencies: [],
33
+ navigation: [],
34
+ routes: [],
35
+ widgets: []
36
+ };
37
+ return { manifest, Provider, paymentProvider };
38
+ }
39
+ function usePixCharge() {
40
+ const { provider } = usePaymentContext();
41
+ const [charge, setCharge] = useState(null);
42
+ const [creating, setCreating] = useState(false);
43
+ const [error, setError] = useState(null);
44
+ const create = useCallback(
45
+ async (input) => {
46
+ setCreating(true);
47
+ setError(null);
48
+ try {
49
+ const c = await provider.createCharge(input);
50
+ setCharge(c);
51
+ return c;
52
+ } catch (err) {
53
+ setError(err instanceof Error ? err : new Error(String(err)));
54
+ return null;
55
+ } finally {
56
+ setCreating(false);
57
+ }
58
+ },
59
+ [provider]
60
+ );
61
+ const reset = useCallback(() => {
62
+ setCharge(null);
63
+ setError(null);
64
+ }, []);
65
+ return { charge, creating, error, create, reset };
66
+ }
67
+ function useChargeStatus(chargeId, intervalMs = 2500) {
68
+ const { provider } = usePaymentContext();
69
+ const [status, setStatus] = useState(null);
70
+ const timer = useRef(null);
71
+ useEffect(() => {
72
+ let active = true;
73
+ setStatus(null);
74
+ if (!chargeId) return;
75
+ const clear = () => {
76
+ if (timer.current) {
77
+ clearInterval(timer.current);
78
+ timer.current = null;
79
+ }
80
+ };
81
+ const tick = () => {
82
+ provider.getChargeStatus(chargeId).then((s) => {
83
+ if (!active) return;
84
+ setStatus(s);
85
+ if (s === "paid" || s === "expired" || s === "failed") clear();
86
+ }).catch(() => {
87
+ });
88
+ };
89
+ tick();
90
+ timer.current = setInterval(tick, intervalMs);
91
+ return () => {
92
+ active = false;
93
+ clear();
94
+ };
95
+ }, [provider, chargeId, intervalMs]);
96
+ return status;
97
+ }
98
+
99
+ export { PaymentProviderContext, createPublicPaymentPlugin, useChargeStatus, usePaymentContext, usePixCharge };
100
+ //# sourceMappingURL=index.js.map
101
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/public/context.tsx","../../src/public/createPublicPaymentPlugin.ts","../../src/public/hooks.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext, type ReactNode } from 'react'\nimport type { PaymentProvider } from '@fayz-ai/core'\n\nexport interface PaymentContextValue {\n provider: PaymentProvider\n}\n\nconst PaymentContext = createContext<PaymentContextValue | null>(null)\n\nexport function PaymentProviderContext({ value, children }: { value: PaymentContextValue; children: ReactNode }) {\n return <PaymentContext.Provider value={value}>{children}</PaymentContext.Provider>\n}\n\nexport function usePaymentContext(): PaymentContextValue {\n const ctx = useContext(PaymentContext)\n if (!ctx) {\n throw new Error('[plugin-payments] usePaymentContext must be used within the payments Provider.')\n }\n return ctx\n}\n","import { createElement, type FC, type ReactNode } from 'react'\nimport type { PluginManifest, PluginScope, PaymentProvider } from '@fayz-ai/core'\nimport { createSafePaymentProvider } from '../index'\nimport type { MockPaymentOptions } from '../data/mock'\nimport { PaymentProviderContext, type PaymentContextValue } from './context'\n\n// ---------------------------------------------------------------------------\n// @fayz-ai/plugin-payments/public — website payment surface.\n//\n// Returns a { manifest, Provider, paymentProvider } bundle mirroring the other\n// website plugins. The host injects `paymentProvider` into the booking plugin;\n// the Provider/hooks are for a future standalone checkout page. No routes — a\n// payment is a service, not a screen.\n// ---------------------------------------------------------------------------\n\nexport interface PublicPaymentOptions {\n /** Currency for charges (informational; charges carry their own). */\n currency?: string\n /** Inject a custom provider (real gateway). Overrides the safe resolver. */\n paymentProvider?: PaymentProvider\n /** Tuning for the mock provider (auto-pay/expiry) when no real provider is set. */\n mock?: MockPaymentOptions\n scope?: PluginScope\n}\n\nexport interface PublicPaymentPlugin {\n manifest: PluginManifest\n Provider: FC<{ children: ReactNode }>\n paymentProvider: PaymentProvider\n}\n\nexport function createPublicPaymentPlugin(options?: PublicPaymentOptions): PublicPaymentPlugin {\n const paymentProvider = options?.paymentProvider ?? createSafePaymentProvider(options?.mock)\n\n const value: PaymentContextValue = { provider: paymentProvider }\n const Provider: FC<{ children: ReactNode }> = ({ children }) =>\n createElement(PaymentProviderContext, { value, children })\n Provider.displayName = 'PaymentPluginProvider'\n\n const manifest: PluginManifest = {\n id: 'payments',\n name: 'Pagamentos',\n icon: 'CreditCard',\n version: '0.1.0',\n scope: options?.scope ?? 'universal',\n scaffolds: ['website', 'landing_page'],\n defaultEnabled: true,\n dependencies: [],\n navigation: [],\n routes: [],\n widgets: [],\n }\n\n return { manifest, Provider, paymentProvider }\n}\n","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'\nimport { usePaymentContext } from './context'\n\nexport interface UsePixChargeResult {\n charge: PixCharge | null\n creating: boolean\n error: Error | null\n create: (input: CreateChargeInput) => Promise<PixCharge | null>\n reset: () => void\n}\n\n/**\n * Create a Pix charge on demand. For a standalone checkout page; the booking\n * widget uses its own injected provider directly (agenda depends only on core).\n */\nexport function usePixCharge(): UsePixChargeResult {\n const { provider } = usePaymentContext()\n const [charge, setCharge] = useState<PixCharge | null>(null)\n const [creating, setCreating] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n\n const create = useCallback(\n async (input: CreateChargeInput) => {\n setCreating(true)\n setError(null)\n try {\n const c = await provider.createCharge(input)\n setCharge(c)\n return c\n } catch (err) {\n setError(err instanceof Error ? err : new Error(String(err)))\n return null\n } finally {\n setCreating(false)\n }\n },\n [provider],\n )\n\n const reset = useCallback(() => {\n setCharge(null)\n setError(null)\n }, [])\n\n return { charge, creating, error, create, reset }\n}\n\n/**\n * Poll a charge's status until it settles. Cleans the interval on unmount,\n * chargeId change, and terminal states.\n */\nexport function useChargeStatus(chargeId: string | null, intervalMs = 2500): ChargeStatus | null {\n const { provider } = usePaymentContext()\n const [status, setStatus] = useState<ChargeStatus | null>(null)\n const timer = useRef<ReturnType<typeof setInterval> | null>(null)\n\n useEffect(() => {\n let active = true\n setStatus(null)\n if (!chargeId) return\n\n const clear = () => {\n if (timer.current) { clearInterval(timer.current); timer.current = null }\n }\n const tick = () => {\n provider\n .getChargeStatus(chargeId)\n .then((s) => {\n if (!active) return\n setStatus(s)\n if (s === 'paid' || s === 'expired' || s === 'failed') clear()\n })\n .catch(() => { /* keep polling on transient errors */ })\n }\n tick()\n timer.current = setInterval(tick, intervalMs)\n return () => { active = false; clear() }\n }, [provider, chargeId, intervalMs])\n\n return status\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@fayz-ai/plugin-payments",
3
+ "version": "0.1.0",
4
+ "description": "[experimental] Fayz SDK — payments plugin (Pix charge provider + website surface)",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "source": "./src/index.ts",
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ },
16
+ "./public": {
17
+ "source": "./src/public/index.ts",
18
+ "types": "./dist/public/index.d.ts",
19
+ "import": "./dist/public/index.js",
20
+ "require": "./dist/public/index.cjs"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "src"
26
+ ],
27
+ "peerDependencies": {
28
+ "react": "^18.0.0 || ^19.0.0",
29
+ "react-dom": "^18.0.0 || ^19.0.0"
30
+ },
31
+ "dependencies": {
32
+ "@fayz-ai/core": "^0.7.1"
33
+ },
34
+ "devDependencies": {
35
+ "@types/react": "^18.3.0",
36
+ "react": "^18.3.0",
37
+ "react-dom": "^18.3.0",
38
+ "tsup": "^8.2.0",
39
+ "typescript": "^5.5.0",
40
+ "@types/react-dom": "^18.3.0"
41
+ },
42
+ "license": "MIT",
43
+ "keywords": [
44
+ "fayz",
45
+ "fayz-plugin",
46
+ "fayz-sdk"
47
+ ],
48
+ "scripts": {
49
+ "build": "tsup && tsc --emitDeclarationOnly --declaration --declarationMap --noEmit false",
50
+ "dev": "tsup --watch",
51
+ "typecheck": "tsc --noEmit",
52
+ "clean": "rm -rf dist"
53
+ }
54
+ }
@@ -0,0 +1,3 @@
1
+ export { createMockPaymentProvider } from './mock'
2
+ export type { MockPaymentProvider, MockPaymentOptions } from './mock'
3
+ export { createSupabasePaymentProvider } from './supabase'
@@ -0,0 +1,84 @@
1
+ import type { PaymentProvider, CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'
2
+
3
+ /** Mock provider adds a demo-only `markPaid` shortcut on top of the contract. */
4
+ export interface MockPaymentProvider extends PaymentProvider {
5
+ /** Force a charge to 'paid' immediately (demo "Já paguei" button). */
6
+ markPaid(chargeId: string): void
7
+ }
8
+
9
+ export interface MockPaymentOptions {
10
+ /** Auto-confirm a pending charge after this many ms (simulates the gateway webhook). Default 6000. */
11
+ autoPayAfterMs?: number
12
+ /** Charge validity window in ms. Default 5 min. */
13
+ expiresAfterMs?: number
14
+ }
15
+
16
+ interface ChargeRecord {
17
+ charge: PixCharge
18
+ createdAt: number
19
+ autoPayAt: number
20
+ expiresAt: number
21
+ paid: boolean
22
+ }
23
+
24
+ let seq = 0
25
+
26
+ /** Build a realistic-looking (non-functional) Pix BR Code "copia e cola". */
27
+ function buildBrCode(amount: number, chargeId: string): string {
28
+ const amt = amount.toFixed(2)
29
+ // Simplified EMV-ish layout — enough to look/scan like a Pix payload in the POC.
30
+ return (
31
+ `00020126850014br.gov.bcb.pix2563qrcode.fayz.dev/pix/v2/${chargeId}` +
32
+ `520400005303986540${amt.length}${amt}5802BR5913HEMPDENT6009SAO PAULO62070503***6304FZ${(seq % 90 + 10)}`
33
+ )
34
+ }
35
+
36
+ export function createMockPaymentProvider(options?: MockPaymentOptions): MockPaymentProvider {
37
+ const autoPayAfterMs = options?.autoPayAfterMs ?? 6000
38
+ const expiresAfterMs = options?.expiresAfterMs ?? 5 * 60_000
39
+ const charges = new Map<string, ChargeRecord>()
40
+
41
+ function statusOf(rec: ChargeRecord): ChargeStatus {
42
+ if (rec.paid) return 'paid'
43
+ const now = Date.now()
44
+ if (now >= rec.autoPayAt) return 'paid'
45
+ if (now >= rec.expiresAt) return 'expired'
46
+ return 'pending'
47
+ }
48
+
49
+ return {
50
+ async createCharge(input: CreateChargeInput): Promise<PixCharge> {
51
+ const now = Date.now()
52
+ const chargeId = `mockpix-${++seq}-${input.orderId ?? 'na'}`
53
+ const brCode = buildBrCode(input.amount, chargeId)
54
+ const charge: PixCharge = {
55
+ chargeId,
56
+ status: 'pending',
57
+ amount: input.amount,
58
+ currency: input.currency,
59
+ pixQrCode: brCode,
60
+ pixCopyPaste: brCode,
61
+ expiresAt: new Date(now + expiresAfterMs).toISOString(),
62
+ }
63
+ charges.set(chargeId, {
64
+ charge,
65
+ createdAt: now,
66
+ autoPayAt: now + autoPayAfterMs,
67
+ expiresAt: now + expiresAfterMs,
68
+ paid: false,
69
+ })
70
+ return charge
71
+ },
72
+
73
+ async getChargeStatus(chargeId: string): Promise<ChargeStatus> {
74
+ const rec = charges.get(chargeId)
75
+ if (!rec) return 'failed'
76
+ return statusOf(rec)
77
+ },
78
+
79
+ markPaid(chargeId: string): void {
80
+ const rec = charges.get(chargeId)
81
+ if (rec) rec.paid = true
82
+ },
83
+ }
84
+ }
@@ -0,0 +1,24 @@
1
+ import type { PaymentProvider, CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Supabase/gateway-backed payment provider — STUB (deferred).
5
+ //
6
+ // Later: a real MercadoPago (or other PSP) Pix integration via a Supabase edge
7
+ // function (credentials server-side; actions create_charge | get_status |
8
+ // webhook), mirroring the plugbank-sync edge function. Swapping this in is a
9
+ // pure provider change — the booking widget and hooks are untouched because they
10
+ // depend only on the core PaymentProvider interface.
11
+ // ---------------------------------------------------------------------------
12
+
13
+ export function createSupabasePaymentProvider(): PaymentProvider {
14
+ const notImplemented = (): never => {
15
+ throw new Error(
16
+ '[plugin-payments] Supabase/MercadoPago provider not implemented yet — deferred. ' +
17
+ 'Run on the mock provider (no gateway configured) for now.',
18
+ )
19
+ }
20
+ return {
21
+ createCharge: (_input: CreateChargeInput): Promise<PixCharge> => notImplemented(),
22
+ getChargeStatus: (_chargeId: string): Promise<ChargeStatus> => notImplemented(),
23
+ }
24
+ }
package/src/index.ts ADDED
@@ -0,0 +1,25 @@
1
+ import { createSafeDataProvider } from '@fayz-ai/core'
2
+ import type { PaymentProvider } from '@fayz-ai/core'
3
+ import { createMockPaymentProvider, type MockPaymentOptions } from './data/mock'
4
+ import { createSupabasePaymentProvider } from './data/supabase'
5
+
6
+ // ---------------------------------------------------------------------------
7
+ // @fayz-ai/plugin-payments — gateway-agnostic charge provider (Pix today).
8
+ // Bookkeeping (invoices/movements/reconciliation) stays in plugin-financial;
9
+ // this plugin OWNS money-in initiation (create a charge → payable artifacts →
10
+ // status). Mirrors createSafeFinancialProvider.
11
+ // ---------------------------------------------------------------------------
12
+
13
+ /** Supabase/gateway when configured, else the mock provider. */
14
+ export function createSafePaymentProvider(mockOptions?: MockPaymentOptions): PaymentProvider {
15
+ return createSafeDataProvider(
16
+ () => createSupabasePaymentProvider(),
17
+ () => createMockPaymentProvider(mockOptions),
18
+ )
19
+ }
20
+
21
+ export { createMockPaymentProvider, createSupabasePaymentProvider } from './data'
22
+ export type { MockPaymentProvider, MockPaymentOptions } from './data'
23
+ export type {
24
+ PaymentProvider, PaymentMethod, ChargeStatus, CreateChargeInput, PixCharge,
25
+ } from '@fayz-ai/core'
@@ -0,0 +1,20 @@
1
+ import { createContext, useContext, type ReactNode } from 'react'
2
+ import type { PaymentProvider } from '@fayz-ai/core'
3
+
4
+ export interface PaymentContextValue {
5
+ provider: PaymentProvider
6
+ }
7
+
8
+ const PaymentContext = createContext<PaymentContextValue | null>(null)
9
+
10
+ export function PaymentProviderContext({ value, children }: { value: PaymentContextValue; children: ReactNode }) {
11
+ return <PaymentContext.Provider value={value}>{children}</PaymentContext.Provider>
12
+ }
13
+
14
+ export function usePaymentContext(): PaymentContextValue {
15
+ const ctx = useContext(PaymentContext)
16
+ if (!ctx) {
17
+ throw new Error('[plugin-payments] usePaymentContext must be used within the payments Provider.')
18
+ }
19
+ return ctx
20
+ }
@@ -0,0 +1,55 @@
1
+ import { createElement, type FC, type ReactNode } from 'react'
2
+ import type { PluginManifest, PluginScope, PaymentProvider } from '@fayz-ai/core'
3
+ import { createSafePaymentProvider } from '../index'
4
+ import type { MockPaymentOptions } from '../data/mock'
5
+ import { PaymentProviderContext, type PaymentContextValue } from './context'
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // @fayz-ai/plugin-payments/public — website payment surface.
9
+ //
10
+ // Returns a { manifest, Provider, paymentProvider } bundle mirroring the other
11
+ // website plugins. The host injects `paymentProvider` into the booking plugin;
12
+ // the Provider/hooks are for a future standalone checkout page. No routes — a
13
+ // payment is a service, not a screen.
14
+ // ---------------------------------------------------------------------------
15
+
16
+ export interface PublicPaymentOptions {
17
+ /** Currency for charges (informational; charges carry their own). */
18
+ currency?: string
19
+ /** Inject a custom provider (real gateway). Overrides the safe resolver. */
20
+ paymentProvider?: PaymentProvider
21
+ /** Tuning for the mock provider (auto-pay/expiry) when no real provider is set. */
22
+ mock?: MockPaymentOptions
23
+ scope?: PluginScope
24
+ }
25
+
26
+ export interface PublicPaymentPlugin {
27
+ manifest: PluginManifest
28
+ Provider: FC<{ children: ReactNode }>
29
+ paymentProvider: PaymentProvider
30
+ }
31
+
32
+ export function createPublicPaymentPlugin(options?: PublicPaymentOptions): PublicPaymentPlugin {
33
+ const paymentProvider = options?.paymentProvider ?? createSafePaymentProvider(options?.mock)
34
+
35
+ const value: PaymentContextValue = { provider: paymentProvider }
36
+ const Provider: FC<{ children: ReactNode }> = ({ children }) =>
37
+ createElement(PaymentProviderContext, { value, children })
38
+ Provider.displayName = 'PaymentPluginProvider'
39
+
40
+ const manifest: PluginManifest = {
41
+ id: 'payments',
42
+ name: 'Pagamentos',
43
+ icon: 'CreditCard',
44
+ version: '0.1.0',
45
+ scope: options?.scope ?? 'universal',
46
+ scaffolds: ['website', 'landing_page'],
47
+ defaultEnabled: true,
48
+ dependencies: [],
49
+ navigation: [],
50
+ routes: [],
51
+ widgets: [],
52
+ }
53
+
54
+ return { manifest, Provider, paymentProvider }
55
+ }
@@ -0,0 +1,82 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react'
2
+ import type { CreateChargeInput, PixCharge, ChargeStatus } from '@fayz-ai/core'
3
+ import { usePaymentContext } from './context'
4
+
5
+ export interface UsePixChargeResult {
6
+ charge: PixCharge | null
7
+ creating: boolean
8
+ error: Error | null
9
+ create: (input: CreateChargeInput) => Promise<PixCharge | null>
10
+ reset: () => void
11
+ }
12
+
13
+ /**
14
+ * Create a Pix charge on demand. For a standalone checkout page; the booking
15
+ * widget uses its own injected provider directly (agenda depends only on core).
16
+ */
17
+ export function usePixCharge(): UsePixChargeResult {
18
+ const { provider } = usePaymentContext()
19
+ const [charge, setCharge] = useState<PixCharge | null>(null)
20
+ const [creating, setCreating] = useState(false)
21
+ const [error, setError] = useState<Error | null>(null)
22
+
23
+ const create = useCallback(
24
+ async (input: CreateChargeInput) => {
25
+ setCreating(true)
26
+ setError(null)
27
+ try {
28
+ const c = await provider.createCharge(input)
29
+ setCharge(c)
30
+ return c
31
+ } catch (err) {
32
+ setError(err instanceof Error ? err : new Error(String(err)))
33
+ return null
34
+ } finally {
35
+ setCreating(false)
36
+ }
37
+ },
38
+ [provider],
39
+ )
40
+
41
+ const reset = useCallback(() => {
42
+ setCharge(null)
43
+ setError(null)
44
+ }, [])
45
+
46
+ return { charge, creating, error, create, reset }
47
+ }
48
+
49
+ /**
50
+ * Poll a charge's status until it settles. Cleans the interval on unmount,
51
+ * chargeId change, and terminal states.
52
+ */
53
+ export function useChargeStatus(chargeId: string | null, intervalMs = 2500): ChargeStatus | null {
54
+ const { provider } = usePaymentContext()
55
+ const [status, setStatus] = useState<ChargeStatus | null>(null)
56
+ const timer = useRef<ReturnType<typeof setInterval> | null>(null)
57
+
58
+ useEffect(() => {
59
+ let active = true
60
+ setStatus(null)
61
+ if (!chargeId) return
62
+
63
+ const clear = () => {
64
+ if (timer.current) { clearInterval(timer.current); timer.current = null }
65
+ }
66
+ const tick = () => {
67
+ provider
68
+ .getChargeStatus(chargeId)
69
+ .then((s) => {
70
+ if (!active) return
71
+ setStatus(s)
72
+ if (s === 'paid' || s === 'expired' || s === 'failed') clear()
73
+ })
74
+ .catch(() => { /* keep polling on transient errors */ })
75
+ }
76
+ tick()
77
+ timer.current = setInterval(tick, intervalMs)
78
+ return () => { active = false; clear() }
79
+ }, [provider, chargeId, intervalMs])
80
+
81
+ return status
82
+ }
@@ -0,0 +1,10 @@
1
+ export { createPublicPaymentPlugin } from './createPublicPaymentPlugin'
2
+ export type { PublicPaymentOptions, PublicPaymentPlugin } from './createPublicPaymentPlugin'
3
+ export { PaymentProviderContext, usePaymentContext } from './context'
4
+ export type { PaymentContextValue } from './context'
5
+ export { usePixCharge, useChargeStatus } from './hooks'
6
+ export type { UsePixChargeResult } from './hooks'
7
+ export { createSafePaymentProvider, createMockPaymentProvider } from '../index'
8
+ export type {
9
+ PaymentProvider, ChargeStatus, CreateChargeInput, PixCharge, MockPaymentProvider, MockPaymentOptions,
10
+ } from '../index'