@fayz-ai/plugin-payments 0.1.0 → 0.8.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 +43 -0
- package/dist/public/createPublicPaymentPlugin.d.ts +1 -1
- package/dist/public/createPublicPaymentPlugin.d.ts.map +1 -1
- package/dist/public/index.cjs +1 -1
- package/dist/public/index.cjs.map +1 -1
- package/dist/public/index.js +2 -2
- package/dist/public/index.js.map +1 -1
- package/package.json +4 -4
- package/src/public/createPublicPaymentPlugin.ts +7 -3
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# @fayz-ai/plugin-payments
|
|
2
|
+
|
|
3
|
+
> A Pix charge provider (and website payment surface) for Fayz apps and storefronts.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@fayz-ai/plugin-payments)
|
|
6
|
+
[](https://github.com/FayaLabs/fayz-sdk/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
**Status:** early / beta — pre-1.0. Ships a working Pix **mock** provider plus React hooks and a public payment surface; the real gateway (Supabase / MercadoPago) is deferred and not yet implemented — apps run on the mock until a gateway is wired. APIs may change before 1.0.
|
|
9
|
+
|
|
10
|
+
Taking money is the one thing every commerce build cannot fake, and in Brazil that means Pix. `plugin-payments` gives Fayz apps a single `PaymentProvider` abstraction for Pix charges — create a charge, get a QR / copy-paste code, poll its status — behind the same safe mock/real resolver used across the SDK. Build and demo the whole checkout flow today on the mock; swap in a real gateway later without touching the UI.
|
|
11
|
+
|
|
12
|
+
## What's inside
|
|
13
|
+
- **Payment provider** — `createSafePaymentProvider()` resolves a real gateway when configured, else `createMockPaymentProvider()`; `PaymentProvider` / `PixCharge` / `CreateChargeInput` / `ChargeStatus` types re-exported from `@fayz-ai/core`
|
|
14
|
+
- **Working mock** — generates a Pix BR code, auto-pays after a configurable delay (default 6s) and expires after a window (default 5min), so status polling is realistic
|
|
15
|
+
- **Public payment surface** (`@fayz-ai/plugin-payments/public`) — `createPublicPaymentPlugin(options)` returns `{ manifest, Provider, paymentProvider }`, plus `usePixCharge`, `useChargeStatus`, and `PaymentProviderContext` / `usePaymentContext`
|
|
16
|
+
- **Deferred real provider** — `createSupabasePaymentProvider()` is a stub that throws until the Supabase/MercadoPago gateway lands
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
```bash
|
|
20
|
+
npm install @fayz-ai/plugin-payments
|
|
21
|
+
```
|
|
22
|
+
Runtime dep: `@fayz-ai/core`. The `./public` subpath additionally needs `react` / `react-dom`.
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
```ts
|
|
26
|
+
// Headless: a charge provider anywhere
|
|
27
|
+
import { createSafePaymentProvider } from '@fayz-ai/plugin-payments'
|
|
28
|
+
|
|
29
|
+
const payments = createSafePaymentProvider()
|
|
30
|
+
const charge = await payments.createCharge({ amount: 49.9, currency: 'BRL', orderId: 'abc' })
|
|
31
|
+
// charge.pixCopyPaste, charge.pixQrCode, then poll payments.getChargeStatus(charge.chargeId)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
// Website surface: the payment plugin bundle
|
|
36
|
+
import { createPublicPaymentPlugin } from '@fayz-ai/plugin-payments/public'
|
|
37
|
+
|
|
38
|
+
const paymentPlugin = createPublicPaymentPlugin({ currency: 'BRL' })
|
|
39
|
+
// wrap your checkout tree in <paymentPlugin.Provider> and use usePixCharge()/useChargeStatus()
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Part of the Fayz SDK
|
|
43
|
+
The money seam. Feeds the storefront/checkout surfaces and pairs with `@fayz-ai/plugin-orders` and `@fayz-ai/plugin-shop`; composes alongside `@fayz-ai/plugin-blog` in bespoke website builds.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type FC, type ReactNode } from 'react';
|
|
2
2
|
import type { PluginManifest, PluginScope, PaymentProvider } from '@fayz-ai/core';
|
|
3
|
-
import type
|
|
3
|
+
import { type MockPaymentOptions } from '../data/mock';
|
|
4
4
|
export interface PublicPaymentOptions {
|
|
5
5
|
/** Currency for charges (informational; charges carry their own). */
|
|
6
6
|
currency?: string;
|
|
@@ -1 +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;
|
|
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;AACjF,OAAO,EAA6B,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAYjF,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,CA4B7F"}
|
package/dist/public/index.cjs
CHANGED
|
@@ -18,7 +18,7 @@ function usePaymentContext() {
|
|
|
18
18
|
|
|
19
19
|
// src/public/createPublicPaymentPlugin.ts
|
|
20
20
|
function createPublicPaymentPlugin(options) {
|
|
21
|
-
const paymentProvider = options?.paymentProvider ?? chunkRMA57VFG_cjs.
|
|
21
|
+
const paymentProvider = options?.paymentProvider ?? chunkRMA57VFG_cjs.createMockPaymentProvider(options?.mock);
|
|
22
22
|
const value = { provider: paymentProvider };
|
|
23
23
|
const Provider = ({ children }) => react.createElement(PaymentProviderContext, { value, children });
|
|
24
24
|
Provider.displayName = "PaymentPluginProvider";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/public/context.tsx","../../src/public/createPublicPaymentPlugin.ts","../../src/public/hooks.ts"],"names":["createContext","jsx","useContext","
|
|
1
|
+
{"version":3,"sources":["../../src/public/context.tsx","../../src/public/createPublicPaymentPlugin.ts","../../src/public/hooks.ts"],"names":["createContext","jsx","useContext","createMockPaymentProvider","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 { createMockPaymentProvider, 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 // Default is the MOCK provider even when a Supabase client is configured:\n // the Supabase payment path is still a stub (real gateway = MercadoPago edge\n // fn, deferred), so a real provider must be injected explicitly via\n // `paymentProvider`. Don't route through createSafePaymentProvider here or\n // any app with a configured Supabase client would hit the throwing stub.\n const paymentProvider = options?.paymentProvider ?? createMockPaymentProvider(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/dist/public/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createMockPaymentProvider } from '../chunk-CSJFAXHO.js';
|
|
2
2
|
export { createMockPaymentProvider, createSafePaymentProvider } from '../chunk-CSJFAXHO.js';
|
|
3
3
|
import { createContext, useContext, useState, useCallback, useRef, useEffect, createElement } from 'react';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
@@ -17,7 +17,7 @@ function usePaymentContext() {
|
|
|
17
17
|
|
|
18
18
|
// src/public/createPublicPaymentPlugin.ts
|
|
19
19
|
function createPublicPaymentPlugin(options) {
|
|
20
|
-
const paymentProvider = options?.paymentProvider ??
|
|
20
|
+
const paymentProvider = options?.paymentProvider ?? createMockPaymentProvider(options?.mock);
|
|
21
21
|
const value = { provider: paymentProvider };
|
|
22
22
|
const Provider = ({ children }) => createElement(PaymentProviderContext, { value, children });
|
|
23
23
|
Provider.displayName = "PaymentPluginProvider";
|
package/dist/public/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/public/context.tsx","../../src/public/createPublicPaymentPlugin.ts","../../src/public/hooks.ts"],"names":[],"mappings":";;;;;AAOA,IAAM,cAAA,GAAiB,cAA0C,IAAI,CAAA;AAE9D,SAAS,sBAAA,CAAuB,EAAE,KAAA,EAAO,QAAA,EAAS,EAAwD;AAC/G,EAAA,uBAAO,GAAA,CAAC,cAAA,CAAe,QAAA,EAAf,EAAwB,OAAe,QAAA,EAAS,CAAA;AAC1D;AAEO,SAAS,iBAAA,GAAyC;AACvD,EAAA,MAAM,GAAA,GAAM,WAAW,cAAc,CAAA;AACrC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,MAAM,gFAAgF,CAAA;AAAA,EAClG;AACA,EAAA,OAAO,GAAA;AACT;;;
|
|
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 { createMockPaymentProvider, 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 // Default is the MOCK provider even when a Supabase client is configured:\n // the Supabase payment path is still a stub (real gateway = MercadoPago edge\n // fn, deferred), so a real provider must be injected explicitly via\n // `paymentProvider`. Don't route through createSafePaymentProvider here or\n // any app with a configured Supabase client would hit the throwing stub.\n const paymentProvider = options?.paymentProvider ?? createMockPaymentProvider(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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fayz-ai/plugin-payments",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "[experimental] Fayz SDK — payments plugin (Pix charge provider + website surface)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -29,15 +29,15 @@
|
|
|
29
29
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@fayz-ai/core": "^0.
|
|
32
|
+
"@fayz-ai/core": "^0.8.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/react": "^18.3.0",
|
|
36
|
+
"@types/react-dom": "^18.3.0",
|
|
36
37
|
"react": "^18.3.0",
|
|
37
38
|
"react-dom": "^18.3.0",
|
|
38
39
|
"tsup": "^8.2.0",
|
|
39
|
-
"typescript": "^5.5.0"
|
|
40
|
-
"@types/react-dom": "^18.3.0"
|
|
40
|
+
"typescript": "^5.5.0"
|
|
41
41
|
},
|
|
42
42
|
"license": "MIT",
|
|
43
43
|
"keywords": [
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { createElement, type FC, type ReactNode } from 'react'
|
|
2
2
|
import type { PluginManifest, PluginScope, PaymentProvider } from '@fayz-ai/core'
|
|
3
|
-
import {
|
|
4
|
-
import type { MockPaymentOptions } from '../data/mock'
|
|
3
|
+
import { createMockPaymentProvider, type MockPaymentOptions } from '../data/mock'
|
|
5
4
|
import { PaymentProviderContext, type PaymentContextValue } from './context'
|
|
6
5
|
|
|
7
6
|
// ---------------------------------------------------------------------------
|
|
@@ -30,7 +29,12 @@ export interface PublicPaymentPlugin {
|
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export function createPublicPaymentPlugin(options?: PublicPaymentOptions): PublicPaymentPlugin {
|
|
33
|
-
|
|
32
|
+
// Default is the MOCK provider even when a Supabase client is configured:
|
|
33
|
+
// the Supabase payment path is still a stub (real gateway = MercadoPago edge
|
|
34
|
+
// fn, deferred), so a real provider must be injected explicitly via
|
|
35
|
+
// `paymentProvider`. Don't route through createSafePaymentProvider here or
|
|
36
|
+
// any app with a configured Supabase client would hit the throwing stub.
|
|
37
|
+
const paymentProvider = options?.paymentProvider ?? createMockPaymentProvider(options?.mock)
|
|
34
38
|
|
|
35
39
|
const value: PaymentContextValue = { provider: paymentProvider }
|
|
36
40
|
const Provider: FC<{ children: ReactNode }> = ({ children }) =>
|