@morapay/nextjs 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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +42 -0
  3. package/dist/client/loadWidget.d.ts +3 -0
  4. package/dist/client/loadWidget.d.ts.map +1 -0
  5. package/dist/client/loadWidget.js +2 -0
  6. package/dist/client/openPaymentLinkCheckout.d.ts +3 -0
  7. package/dist/client/openPaymentLinkCheckout.d.ts.map +1 -0
  8. package/dist/client/openPaymentLinkCheckout.js +2 -0
  9. package/dist/constants.d.ts +5 -0
  10. package/dist/constants.d.ts.map +1 -0
  11. package/dist/constants.js +4 -0
  12. package/dist/features/publicApi/index.d.ts +2 -0
  13. package/dist/features/publicApi/index.d.ts.map +1 -0
  14. package/dist/features/publicApi/index.js +1 -0
  15. package/dist/features/publicApi/server/catalogSquidProxy.d.ts +19 -0
  16. package/dist/features/publicApi/server/catalogSquidProxy.d.ts.map +1 -0
  17. package/dist/features/publicApi/server/catalogSquidProxy.js +137 -0
  18. package/dist/features/publicApi/server/index.d.ts +3 -0
  19. package/dist/features/publicApi/server/index.d.ts.map +1 -0
  20. package/dist/features/publicApi/server/index.js +2 -0
  21. package/dist/features/publicApi/server/proxyPublicApi.d.ts +20 -0
  22. package/dist/features/publicApi/server/proxyPublicApi.d.ts.map +1 -0
  23. package/dist/features/publicApi/server/proxyPublicApi.js +208 -0
  24. package/dist/features/widget/client/index.d.ts +3 -0
  25. package/dist/features/widget/client/index.d.ts.map +1 -0
  26. package/dist/features/widget/client/index.js +2 -0
  27. package/dist/features/widget/client/loadWidget.d.ts +23 -0
  28. package/dist/features/widget/client/loadWidget.d.ts.map +1 -0
  29. package/dist/features/widget/client/loadWidget.js +42 -0
  30. package/dist/features/widget/client/openPaymentLinkCheckout.d.ts +37 -0
  31. package/dist/features/widget/client/openPaymentLinkCheckout.d.ts.map +1 -0
  32. package/dist/features/widget/client/openPaymentLinkCheckout.js +57 -0
  33. package/dist/features/widget/index.d.ts +2 -0
  34. package/dist/features/widget/index.d.ts.map +1 -0
  35. package/dist/features/widget/index.js +1 -0
  36. package/dist/server/catalogSquidProxy.d.ts +2 -0
  37. package/dist/server/catalogSquidProxy.d.ts.map +1 -0
  38. package/dist/server/catalogSquidProxy.js +1 -0
  39. package/dist/server/proxyPublicApi.d.ts +3 -0
  40. package/dist/server/proxyPublicApi.d.ts.map +1 -0
  41. package/dist/server/proxyPublicApi.js +2 -0
  42. package/package.json +76 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Morapay
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.
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # @morapay/nextjs
2
+
3
+ Next.js App Router helpers for Morapay public BFF routes (payment links, fiat, catalog).
4
+
5
+ ```bash
6
+ npm install @morapay/sdk @morapay/nextjs
7
+ ```
8
+
9
+ Peer dependency: `@morapay/sdk@^0.1.0`.
10
+
11
+ ## Browser checkout
12
+
13
+ Prefer **`@morapay/sdk/widget`** for opening checkout (widget + redirect):
14
+
15
+ ```ts
16
+ import { openPaymentLinkCheckout } from "@morapay/sdk/widget";
17
+
18
+ await openPaymentLinkCheckout({
19
+ publicCode: link.publicCode,
20
+ checkoutMode: "widget",
21
+ widgetExperience: "live",
22
+ checkoutBaseUrl: process.env.NEXT_PUBLIC_CHECKOUT_BASE_URL,
23
+ });
24
+ ```
25
+
26
+ ## Public API BFF
27
+
28
+ Wire route handlers to these proxies (same paths as `create-morapay-app` Next templates):
29
+
30
+ ```ts
31
+ import { proxyPublicPaymentLinkGet } from "@morapay/nextjs/server/proxyPublicApi";
32
+ // also: proxyPublicFiatInitializePost, proxyPublicCatalogGet, …
33
+ ```
34
+
35
+ | Your route | Helper |
36
+ |------------|--------|
37
+ | `GET /api/public/payment-links/[code]` | `proxyPublicPaymentLinkGet` |
38
+ | `POST /api/public/payment-links/[code]/sessions` | `proxyPublicPaymentLinkSessionPost` |
39
+ | `POST /api/public/fiat/payments/initialize` | `proxyPublicFiatInitializePost` |
40
+ | `GET /api/public/catalog/chains` \| `tokens` | `proxyPublicCatalogGet` |
41
+
42
+ Default widget script: `https://checkout.morapay.io/widget/morapay-checkout.js`.
@@ -0,0 +1,3 @@
1
+ /** @deprecated Import from `../features/widget/client` — backward-compatible path. */
2
+ export * from "../features/widget/client/loadWidget.js";
3
+ //# sourceMappingURL=loadWidget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadWidget.d.ts","sourceRoot":"","sources":["../../client/loadWidget.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,cAAc,yCAAyC,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** @deprecated Import from `../features/widget/client` — backward-compatible path. */
2
+ export * from "../features/widget/client/loadWidget.js";
@@ -0,0 +1,3 @@
1
+ /** @deprecated Import from `../features/widget/client` — backward-compatible path. */
2
+ export * from "../features/widget/client/openPaymentLinkCheckout.js";
3
+ //# sourceMappingURL=openPaymentLinkCheckout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openPaymentLinkCheckout.d.ts","sourceRoot":"","sources":["../../client/openPaymentLinkCheckout.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,cAAc,sDAAsD,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** @deprecated Import from `../features/widget/client` — backward-compatible path. */
2
+ export * from "../features/widget/client/openPaymentLinkCheckout.js";
@@ -0,0 +1,5 @@
1
+ /** Default hosted widget script — drop-in, no npm install for the bundle itself. */
2
+ export declare const MORAPAY_WIDGET_SCRIPT_URL = "https://checkout.morapay.io/widget/morapay-checkout.js";
3
+ /** Same-origin BFF prefix for widget preview (payment link + quotes). */
4
+ export declare const MORAPAY_PUBLIC_API_BASE = "/api/public";
5
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../constants.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,eAAO,MAAM,yBAAyB,2DACoB,CAAC;AAE3D,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,gBAAgB,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** Default hosted widget script — drop-in, no npm install for the bundle itself. */
2
+ export const MORAPAY_WIDGET_SCRIPT_URL = "https://checkout.morapay.io/widget/morapay-checkout.js";
3
+ /** Same-origin BFF prefix for widget preview (payment link + quotes). */
4
+ export const MORAPAY_PUBLIC_API_BASE = "/api/public";
@@ -0,0 +1,2 @@
1
+ export * from "./server/index.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../features/publicApi/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./server/index.js";
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Hosted checkout uses /api/squid/chains|tokens (full Squid catalog).
3
+ * Widget BFF prefers that source over Morapay public catalog (~15 DB tokens).
4
+ */
5
+ type UnknownRecord = Record<string, unknown>;
6
+ export declare function mapSquidChainsToPublicCatalog(payload: unknown): UnknownRecord[];
7
+ export declare function mapSquidTokensToPublicCatalog(payload: unknown): UnknownRecord[];
8
+ export declare function fetchCheckoutSquidCatalog(checkoutBaseUrl: string, resource: "chains" | "tokens", environment: "TEST" | "LIVE"): Promise<UnknownRecord[] | null>;
9
+ export type CheckoutPickerCatalogPayload = {
10
+ environment: "TEST" | "LIVE";
11
+ selectorFiltered: boolean;
12
+ chains: UnknownRecord[];
13
+ tokens: UnknownRecord[];
14
+ featured: UnknownRecord | null;
15
+ };
16
+ /** Unified selector-filtered catalog from backend (preferred over raw Squid + client filter). */
17
+ export declare function fetchCheckoutPickerCatalog(apiBaseUrl: string, environment: "TEST" | "LIVE"): Promise<CheckoutPickerCatalogPayload | null>;
18
+ export {};
19
+ //# sourceMappingURL=catalogSquidProxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalogSquidProxy.d.ts","sourceRoot":"","sources":["../../../../features/publicApi/server/catalogSquidProxy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA2B7C,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,EAAE,CA0B/E;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,OAAO,GAAG,aAAa,EAAE,CAsB/E;AAED,wBAAsB,yBAAyB,CAC7C,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,GAAG,QAAQ,EAC7B,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,OAAO,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,CAgBjC;AAED,MAAM,MAAM,4BAA4B,GAAG;IACzC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,iGAAiG;AACjG,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,OAAO,CAAC,4BAA4B,GAAG,IAAI,CAAC,CA6B9C"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Hosted checkout uses /api/squid/chains|tokens (full Squid catalog).
3
+ * Widget BFF prefers that source over Morapay public catalog (~15 DB tokens).
4
+ */
5
+ function pickArray(payload, keys) {
6
+ if (Array.isArray(payload))
7
+ return payload;
8
+ if (!payload || typeof payload !== "object")
9
+ return [];
10
+ const record = payload;
11
+ for (const key of keys) {
12
+ const direct = record[key];
13
+ if (Array.isArray(direct))
14
+ return direct;
15
+ }
16
+ const data = record.data;
17
+ if (data && typeof data === "object") {
18
+ const nested = data;
19
+ for (const key of keys) {
20
+ const arr = nested[key];
21
+ if (Array.isArray(arr))
22
+ return arr;
23
+ }
24
+ }
25
+ return [];
26
+ }
27
+ function chainIdStr(value) {
28
+ if (value == null)
29
+ return "";
30
+ if (typeof value === "number" && Number.isFinite(value))
31
+ return String(value);
32
+ return String(value).trim();
33
+ }
34
+ export function mapSquidChainsToPublicCatalog(payload) {
35
+ return pickArray(payload, ["chains"]).flatMap((row) => {
36
+ if (!row || typeof row !== "object")
37
+ return [];
38
+ const item = row;
39
+ const chainId = chainIdStr(item.chainId);
40
+ const name = String(item.chainName ?? item.networkName ?? item.name ?? "").trim();
41
+ if (!chainId || !name)
42
+ return [];
43
+ const iconUrl = String(item.chainIconURI ?? item.chainIconUri ?? item.iconURI ?? item.iconUri ?? "").trim();
44
+ const native = item.nativeCurrency;
45
+ const nativeSymbol = native && typeof native === "object"
46
+ ? String(native.symbol ?? "").trim()
47
+ : "";
48
+ const shortName = String(item.shortName ?? nativeSymbol ?? name).trim();
49
+ return [
50
+ {
51
+ id: chainId,
52
+ chainId,
53
+ name,
54
+ shortName,
55
+ chainIconURI: iconUrl,
56
+ },
57
+ ];
58
+ });
59
+ }
60
+ export function mapSquidTokensToPublicCatalog(payload) {
61
+ return pickArray(payload, ["tokens"]).flatMap((row) => {
62
+ if (!row || typeof row !== "object")
63
+ return [];
64
+ const item = row;
65
+ const chainId = chainIdStr(item.chainId);
66
+ const symbol = String(item.symbol ?? "").trim();
67
+ const address = String(item.address ?? item.tokenAddress ?? "").trim();
68
+ if (!chainId || !symbol)
69
+ return [];
70
+ const name = String(item.name ?? symbol).trim();
71
+ const logoUrl = String(item.logoURI ?? item.logoUri ?? "").trim();
72
+ const id = address ? `${address}-${chainId}` : `${symbol}-${chainId}`.toLowerCase();
73
+ return [
74
+ {
75
+ id,
76
+ chainId,
77
+ symbol: symbol.toUpperCase(),
78
+ name,
79
+ address,
80
+ logoURI: logoUrl,
81
+ },
82
+ ];
83
+ });
84
+ }
85
+ export async function fetchCheckoutSquidCatalog(checkoutBaseUrl, resource, environment) {
86
+ const base = checkoutBaseUrl.replace(/\/+$/, "");
87
+ const qs = new URLSearchParams({ environment });
88
+ const res = await fetch(`${base}/api/squid/${resource}?${qs}`, {
89
+ method: "GET",
90
+ headers: { Accept: "application/json" },
91
+ cache: "no-store",
92
+ });
93
+ if (!res.ok)
94
+ return null;
95
+ const payload = await res.json().catch(() => null);
96
+ if (!payload)
97
+ return null;
98
+ const rows = resource === "chains"
99
+ ? mapSquidChainsToPublicCatalog(payload)
100
+ : mapSquidTokensToPublicCatalog(payload);
101
+ return rows.length > 0 ? rows : null;
102
+ }
103
+ /** Unified selector-filtered catalog from backend (preferred over raw Squid + client filter). */
104
+ export async function fetchCheckoutPickerCatalog(apiBaseUrl, environment) {
105
+ const base = apiBaseUrl.replace(/\/+$/, "");
106
+ const qs = new URLSearchParams({ environment });
107
+ const res = await fetch(`${base}/api/public/catalog/checkout?${qs}`, {
108
+ method: "GET",
109
+ headers: { Accept: "application/json" },
110
+ cache: "no-store",
111
+ });
112
+ if (!res.ok)
113
+ return null;
114
+ const payload = await res.json().catch(() => null);
115
+ if (!payload || typeof payload !== "object")
116
+ return null;
117
+ const record = payload;
118
+ if (record.success === false)
119
+ return null;
120
+ const data = record.data;
121
+ if (!data || typeof data !== "object")
122
+ return null;
123
+ const catalog = data;
124
+ const chains = Array.isArray(catalog.chains) ? catalog.chains : [];
125
+ const tokens = Array.isArray(catalog.tokens) ? catalog.tokens : [];
126
+ if (chains.length === 0 && tokens.length === 0)
127
+ return null;
128
+ return {
129
+ environment: catalog.environment === "TEST" ? "TEST" : "LIVE",
130
+ selectorFiltered: catalog.selectorFiltered === true,
131
+ chains: chains,
132
+ tokens: tokens,
133
+ featured: catalog.featured && typeof catalog.featured === "object"
134
+ ? catalog.featured
135
+ : null,
136
+ };
137
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./proxyPublicApi.js";
2
+ export * from "./catalogSquidProxy.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../features/publicApi/server/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./proxyPublicApi.js";
2
+ export * from "./catalogSquidProxy.js";
@@ -0,0 +1,20 @@
1
+ type ApiBaseUrlResolver = () => string;
2
+ type CheckoutBaseUrlResolver = () => string;
3
+ /** GET /api/public/payment-links/:code — widget preview loads link details here. */
4
+ export declare function proxyPublicPaymentLinkGet(request: Request, code: string, getApiBaseUrl: ApiBaseUrlResolver): Promise<Response>;
5
+ /** GET /api/public/catalog/chains|tokens — widget token picker catalog. */
6
+ export declare function proxyPublicCatalogGet(request: Request, resource: "chains" | "tokens", getApiBaseUrl: ApiBaseUrlResolver, getCheckoutBaseUrl?: CheckoutBaseUrlResolver): Promise<Response>;
7
+ /** POST /api/public/quotes/checkout — widget preview loads token rows here. */
8
+ export declare function proxyPublicQuotesCheckoutPost(request: Request, getApiBaseUrl: ApiBaseUrlResolver): Promise<Response>;
9
+ /** POST /api/public/payment-links/:code/sessions — ephemeral checkout session before fiat pay. */
10
+ export declare function proxyPublicPaymentLinkSessionPost(request: Request, code: string, getApiBaseUrl: ApiBaseUrlResolver): Promise<Response>;
11
+ /** POST /api/public/commerce/fiat — payer fiat quote for cross-currency checkout. */
12
+ export declare function proxyPublicCommerceFiatPost(request: Request, getApiBaseUrl: ApiBaseUrlResolver): Promise<Response>;
13
+ /** POST /api/public/fiat/payments/initialize — MoMo, bank, or card checkout. */
14
+ export declare function proxyPublicFiatInitializePost(request: Request, getApiBaseUrl: ApiBaseUrlResolver): Promise<Response>;
15
+ /** GET /api/public/fiat/transactions/verify/:reference — poll payment status. */
16
+ export declare function proxyPublicFiatVerifyGet(request: Request, reference: string, getApiBaseUrl: ApiBaseUrlResolver): Promise<Response>;
17
+ /** POST /api/public/fiat/payments/test-confirm — TEST bank transfer confirm. */
18
+ export declare function proxyPublicFiatTestConfirmPost(request: Request, getApiBaseUrl: ApiBaseUrlResolver): Promise<Response>;
19
+ export {};
20
+ //# sourceMappingURL=proxyPublicApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxyPublicApi.d.ts","sourceRoot":"","sources":["../../../../features/publicApi/server/proxyPublicApi.ts"],"names":[],"mappings":"AAMA,KAAK,kBAAkB,GAAG,MAAM,MAAM,CAAC;AACvC,KAAK,uBAAuB,GAAG,MAAM,MAAM,CAAC;AAqB5C,oFAAoF;AACpF,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,kBAAkB,qBA0BlC;AAED,2EAA2E;AAC3E,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,GAAG,QAAQ,EAC7B,aAAa,EAAE,kBAAkB,EACjC,kBAAkB,CAAC,EAAE,uBAAuB,qBAsD7C;AAED,+EAA+E;AAC/E,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,kBAAkB,qBAiBlC;AAED,kGAAkG;AAClG,wBAAsB,iCAAiC,CACrD,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,kBAAkB,qBAwBlC;AAED,qFAAqF;AACrF,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,kBAAkB,qBAiBlC;AAED,gFAAgF;AAChF,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,kBAAkB,qBAiBlC;AAED,iFAAiF;AACjF,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,kBAAkB,qBAoBlC;AAED,gFAAgF;AAChF,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,kBAAkB,qBAiBlC"}
@@ -0,0 +1,208 @@
1
+ import { isMorapayError } from "@morapay/sdk";
2
+ import { fetchCheckoutPickerCatalog, fetchCheckoutSquidCatalog, mapSquidChainsToPublicCatalog, mapSquidTokensToPublicCatalog } from "./catalogSquidProxy.js";
3
+ function morapayErrorResponse(err) {
4
+ if (isMorapayError(err)) {
5
+ return Response.json({
6
+ success: false,
7
+ error: err.displayMessage,
8
+ safeMessage: err.safeMessage,
9
+ displayMessage: err.displayMessage,
10
+ uiHint: err.uiHint,
11
+ code: err.code,
12
+ requestId: err.requestId,
13
+ }, { status: err.status >= 400 ? err.status : 500 });
14
+ }
15
+ const message = err instanceof Error ? err.message : "Request failed.";
16
+ return Response.json({ success: false, error: message }, { status: 500 });
17
+ }
18
+ /** GET /api/public/payment-links/:code — widget preview loads link details here. */
19
+ export async function proxyPublicPaymentLinkGet(request, code, getApiBaseUrl) {
20
+ const trimmed = code?.trim();
21
+ if (!trimmed) {
22
+ return Response.json({ success: false, error: "Invalid code." }, { status: 400 });
23
+ }
24
+ try {
25
+ const { searchParams } = new URL(request.url);
26
+ const base = getApiBaseUrl().replace(/\/+$/, "");
27
+ const fwd = new URLSearchParams();
28
+ const wallet = searchParams.get("wallet");
29
+ const checkoutSessionId = searchParams.get("checkoutSessionId");
30
+ if (wallet?.trim())
31
+ fwd.set("wallet", wallet.trim());
32
+ if (checkoutSessionId?.trim())
33
+ fwd.set("checkoutSessionId", checkoutSessionId.trim());
34
+ const qs = fwd.toString();
35
+ const res = await fetch(`${base}/api/public/payment-links/${encodeURIComponent(trimmed)}${qs ? `?${qs}` : ""}`, { method: "GET", headers: { Accept: "application/json" }, cache: "no-store" });
36
+ const payload = await res.json().catch(() => ({}));
37
+ return Response.json(payload, { status: res.status });
38
+ }
39
+ catch (err) {
40
+ const message = err instanceof Error ? err.message : "Could not reach the Morapay API.";
41
+ return Response.json({ success: false, error: message }, { status: 502 });
42
+ }
43
+ }
44
+ /** GET /api/public/catalog/chains|tokens — widget token picker catalog. */
45
+ export async function proxyPublicCatalogGet(request, resource, getApiBaseUrl, getCheckoutBaseUrl) {
46
+ try {
47
+ const { searchParams } = new URL(request.url);
48
+ const environment = searchParams.get("environment")?.trim().toUpperCase() === "TEST" ? "TEST" : "LIVE";
49
+ const unified = await fetchCheckoutPickerCatalog(getApiBaseUrl(), environment);
50
+ if (unified?.selectorFiltered) {
51
+ const rows = resource === "chains"
52
+ ? mapSquidChainsToPublicCatalog({ chains: unified.chains })
53
+ : mapSquidTokensToPublicCatalog({ tokens: unified.tokens });
54
+ return Response.json({
55
+ success: true,
56
+ data: resource === "chains"
57
+ ? { chains: rows, selectorFiltered: true }
58
+ : { tokens: rows, selectorFiltered: true },
59
+ });
60
+ }
61
+ if (getCheckoutBaseUrl) {
62
+ try {
63
+ const rows = await fetchCheckoutSquidCatalog(getCheckoutBaseUrl(), resource, environment);
64
+ if (rows) {
65
+ return Response.json({
66
+ success: true,
67
+ data: resource === "chains" ? { chains: rows } : { tokens: rows },
68
+ });
69
+ }
70
+ }
71
+ catch {
72
+ // Fall through to Morapay public catalog.
73
+ }
74
+ }
75
+ const base = getApiBaseUrl().replace(/\/+$/, "");
76
+ const qs = searchParams.toString();
77
+ const path = `${base}/api/public/catalog/${resource}${qs ? `?${qs}` : ""}`;
78
+ const res = await fetch(path, {
79
+ method: "GET",
80
+ headers: { Accept: "application/json" },
81
+ cache: "no-store",
82
+ });
83
+ const payload = await res.json().catch(() => ({}));
84
+ return Response.json(payload, { status: res.status });
85
+ }
86
+ catch (err) {
87
+ const message = err instanceof Error ? err.message : "Could not reach the Morapay API.";
88
+ return Response.json({ success: false, error: message }, { status: 502 });
89
+ }
90
+ }
91
+ /** POST /api/public/quotes/checkout — widget preview loads token rows here. */
92
+ export async function proxyPublicQuotesCheckoutPost(request, getApiBaseUrl) {
93
+ try {
94
+ const body = await request.json();
95
+ const base = getApiBaseUrl().replace(/\/+$/, "");
96
+ const res = await fetch(`${base}/api/public/quotes/checkout`, {
97
+ method: "POST",
98
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
99
+ body: JSON.stringify(body),
100
+ cache: "no-store",
101
+ });
102
+ const payload = await res.json().catch(() => ({}));
103
+ return Response.json(payload, { status: res.status });
104
+ }
105
+ catch (err) {
106
+ const message = err instanceof Error ? err.message : "Could not reach the Morapay API.";
107
+ return Response.json({ success: false, error: message }, { status: 502 });
108
+ }
109
+ }
110
+ /** POST /api/public/payment-links/:code/sessions — ephemeral checkout session before fiat pay. */
111
+ export async function proxyPublicPaymentLinkSessionPost(request, code, getApiBaseUrl) {
112
+ const trimmed = code?.trim();
113
+ if (!trimmed) {
114
+ return Response.json({ success: false, error: "Invalid code." }, { status: 400 });
115
+ }
116
+ try {
117
+ const body = await request.json().catch(() => ({}));
118
+ const base = getApiBaseUrl().replace(/\/+$/, "");
119
+ const res = await fetch(`${base}/api/public/payment-links/${encodeURIComponent(trimmed)}/sessions`, {
120
+ method: "POST",
121
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
122
+ body: JSON.stringify(body),
123
+ cache: "no-store",
124
+ });
125
+ const payload = await res.json().catch(() => ({}));
126
+ return Response.json(payload, { status: res.status });
127
+ }
128
+ catch (err) {
129
+ const message = err instanceof Error ? err.message : "Could not reach the Morapay API.";
130
+ return Response.json({ success: false, error: message }, { status: 502 });
131
+ }
132
+ }
133
+ /** POST /api/public/commerce/fiat — payer fiat quote for cross-currency checkout. */
134
+ export async function proxyPublicCommerceFiatPost(request, getApiBaseUrl) {
135
+ try {
136
+ const body = await request.json();
137
+ const base = getApiBaseUrl().replace(/\/+$/, "");
138
+ const res = await fetch(`${base}/api/public/commerce/fiat`, {
139
+ method: "POST",
140
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
141
+ body: JSON.stringify(body),
142
+ cache: "no-store",
143
+ });
144
+ const payload = await res.json().catch(() => ({}));
145
+ return Response.json(payload, { status: res.status });
146
+ }
147
+ catch (err) {
148
+ const message = err instanceof Error ? err.message : "Could not reach the Morapay API.";
149
+ return Response.json({ success: false, error: message }, { status: 502 });
150
+ }
151
+ }
152
+ /** POST /api/public/fiat/payments/initialize — MoMo, bank, or card checkout. */
153
+ export async function proxyPublicFiatInitializePost(request, getApiBaseUrl) {
154
+ try {
155
+ const body = await request.json();
156
+ const base = getApiBaseUrl().replace(/\/+$/, "");
157
+ const res = await fetch(`${base}/api/public/fiat/payments/initialize`, {
158
+ method: "POST",
159
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
160
+ body: JSON.stringify(body),
161
+ cache: "no-store",
162
+ });
163
+ const payload = await res.json().catch(() => ({}));
164
+ return Response.json(payload, { status: res.status });
165
+ }
166
+ catch (err) {
167
+ const message = err instanceof Error ? err.message : "Could not reach the Morapay API.";
168
+ return Response.json({ success: false, error: message }, { status: 502 });
169
+ }
170
+ }
171
+ /** GET /api/public/fiat/transactions/verify/:reference — poll payment status. */
172
+ export async function proxyPublicFiatVerifyGet(request, reference, getApiBaseUrl) {
173
+ const trimmed = reference?.trim();
174
+ if (!trimmed) {
175
+ return Response.json({ success: false, error: "Invalid reference." }, { status: 400 });
176
+ }
177
+ try {
178
+ const { searchParams } = new URL(request.url);
179
+ const base = getApiBaseUrl().replace(/\/+$/, "");
180
+ const qs = searchParams.toString();
181
+ const res = await fetch(`${base}/api/public/fiat/transactions/verify/${encodeURIComponent(trimmed)}${qs ? `?${qs}` : ""}`, { method: "GET", headers: { Accept: "application/json" }, cache: "no-store" });
182
+ const payload = await res.json().catch(() => ({}));
183
+ return Response.json(payload, { status: res.status });
184
+ }
185
+ catch (err) {
186
+ const message = err instanceof Error ? err.message : "Could not reach the Morapay API.";
187
+ return Response.json({ success: false, error: message }, { status: 502 });
188
+ }
189
+ }
190
+ /** POST /api/public/fiat/payments/test-confirm — TEST bank transfer confirm. */
191
+ export async function proxyPublicFiatTestConfirmPost(request, getApiBaseUrl) {
192
+ try {
193
+ const body = await request.json();
194
+ const base = getApiBaseUrl().replace(/\/+$/, "");
195
+ const res = await fetch(`${base}/api/public/fiat/payments/test-confirm`, {
196
+ method: "POST",
197
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
198
+ body: JSON.stringify(body),
199
+ cache: "no-store",
200
+ });
201
+ const payload = await res.json().catch(() => ({}));
202
+ return Response.json(payload, { status: res.status });
203
+ }
204
+ catch (err) {
205
+ const message = err instanceof Error ? err.message : "Could not reach the Morapay API.";
206
+ return Response.json({ success: false, error: message }, { status: 502 });
207
+ }
208
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./loadWidget.js";
2
+ export * from "./openPaymentLinkCheckout.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../features/widget/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,8BAA8B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "./loadWidget.js";
2
+ export * from "./openPaymentLinkCheckout.js";
@@ -0,0 +1,23 @@
1
+ export type MorapayWidgetCustomization = {
2
+ theme?: string;
3
+ colorMode?: "light" | "dark";
4
+ accentColor?: string;
5
+ borderRadius?: "none" | "sm" | "md" | "lg" | "xl";
6
+ fontScale?: "compact" | "default" | "large";
7
+ showMerchantLogo?: boolean;
8
+ /** Shell layout — bottom sheet on mobile when `auto`. */
9
+ presentation?: "auto" | "bottom-sheet" | "modal";
10
+ };
11
+ export type MorapayCheckoutWidget = {
12
+ openPreviewModal?: (options: Record<string, unknown>) => HTMLElement;
13
+ closePreviewModal?: () => void;
14
+ openModal?: (options: Record<string, unknown>) => HTMLElement;
15
+ closeModal?: () => void;
16
+ };
17
+ declare global {
18
+ interface Window {
19
+ MorapayCheckout?: MorapayCheckoutWidget;
20
+ }
21
+ }
22
+ export declare function loadMorapayWidget(scriptUrl: string): Promise<MorapayCheckoutWidget>;
23
+ //# sourceMappingURL=loadWidget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loadWidget.d.ts","sourceRoot":"","sources":["../../../../features/widget/client/loadWidget.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAClD,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IAC5C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,WAAW,CAAC;IACrE,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,WAAW,CAAC;IAC9D,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,eAAe,CAAC,EAAE,qBAAqB,CAAC;KACzC;CACF;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAgDnF"}
@@ -0,0 +1,42 @@
1
+ export function loadMorapayWidget(scriptUrl) {
2
+ if (typeof document === "undefined") {
3
+ return Promise.reject(new Error("loadMorapayWidget requires a browser environment."));
4
+ }
5
+ return new Promise((resolve, reject) => {
6
+ const ready = () => {
7
+ const widget = window.MorapayCheckout;
8
+ if (widget?.openPreviewModal && widget?.openModal) {
9
+ resolve(widget);
10
+ return;
11
+ }
12
+ if (widget?.openModal) {
13
+ resolve(widget);
14
+ return;
15
+ }
16
+ fail(`MorapayCheckout widget failed to initialize. Expected openModal from ${scriptUrl}.`);
17
+ };
18
+ const fail = (message) => {
19
+ document.querySelector('script[data-morapay-widget="1"]')?.remove();
20
+ reject(new Error(message));
21
+ };
22
+ if (window.MorapayCheckout?.openModal || window.MorapayCheckout?.openPreviewModal) {
23
+ ready();
24
+ return;
25
+ }
26
+ const existing = document.querySelector('script[data-morapay-widget="1"]');
27
+ if (existing) {
28
+ existing.addEventListener("load", ready, { once: true });
29
+ existing.addEventListener("error", () => fail(`Could not load widget from ${scriptUrl}`), {
30
+ once: true,
31
+ });
32
+ return;
33
+ }
34
+ const script = document.createElement("script");
35
+ script.src = scriptUrl;
36
+ script.async = true;
37
+ script.dataset.morapayWidget = "1";
38
+ script.onload = ready;
39
+ script.onerror = () => fail(`Could not load widget from ${scriptUrl}`);
40
+ document.body.appendChild(script);
41
+ });
42
+ }
@@ -0,0 +1,37 @@
1
+ import { type MorapayWidgetCustomization } from "./loadWidget.js";
2
+ export type PaymentLinkCheckoutMode = "preview" | "live";
3
+ export type OpenPaymentLinkCheckoutParams = {
4
+ /** Public payment link code from `link.create()` / `products.link()` — not the internal UUID. */
5
+ publicCode: string;
6
+ widgetScriptUrl: string;
7
+ /** Preview: loads link + quotes via your BFF. Live: opens checkout iframe. */
8
+ mode: PaymentLinkCheckoutMode;
9
+ /** Required for live mode — hosted checkout host (e.g. http://localhost:3002). */
10
+ checkoutBaseUrl?: string;
11
+ /** BFF prefix on your app. Default `/api/public`. */
12
+ apiBaseUrl?: string;
13
+ customization?: MorapayWidgetCustomization;
14
+ /** Shell layout — overrides `customization.presentation`. Default `auto`. */
15
+ presentation?: "auto" | "bottom-sheet" | "modal";
16
+ /** Optional fallbacks before preview fetch completes. */
17
+ businessName?: string;
18
+ linkTitle?: string;
19
+ amount?: string | null;
20
+ currency?: string;
21
+ onSuccess?: (payload: unknown) => void;
22
+ onFailure?: (payload: {
23
+ code: string;
24
+ message: string;
25
+ }) => void;
26
+ onClose?: () => void;
27
+ onWalletConnected?: (address: string) => void;
28
+ onTokenSelect?: (rowId: string) => void;
29
+ };
30
+ /**
31
+ * Single entry point for payment-link checkout — preview (staging) or live (iframe).
32
+ *
33
+ * Preview passes `publicCode` + `apiBaseUrl`; the widget fetches authoritative link data.
34
+ * Live passes `publicCode` + `checkoutBaseUrl` for real payments.
35
+ */
36
+ export declare function openPaymentLinkCheckout(params: OpenPaymentLinkCheckoutParams): Promise<void>;
37
+ //# sourceMappingURL=openPaymentLinkCheckout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openPaymentLinkCheckout.d.ts","sourceRoot":"","sources":["../../../../features/widget/client/openPaymentLinkCheckout.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAErF,MAAM,MAAM,uBAAuB,GAAG,SAAS,GAAG,MAAM,CAAC;AAEzD,MAAM,MAAM,6BAA6B,GAAG;IAC1C,iGAAiG;IACjG,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,IAAI,EAAE,uBAAuB,CAAC;IAC9B,kFAAkF;IAClF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,0BAA0B,CAAC;IAC3C,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,OAAO,CAAC;IACjD,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACjE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC;AAEF;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,IAAI,CAAC,CAmDf"}
@@ -0,0 +1,57 @@
1
+ import { MORAPAY_PUBLIC_API_BASE } from "../../../constants.js";
2
+ import { loadMorapayWidget } from "./loadWidget.js";
3
+ /**
4
+ * Single entry point for payment-link checkout — preview (staging) or live (iframe).
5
+ *
6
+ * Preview passes `publicCode` + `apiBaseUrl`; the widget fetches authoritative link data.
7
+ * Live passes `publicCode` + `checkoutBaseUrl` for real payments.
8
+ */
9
+ export async function openPaymentLinkCheckout(params) {
10
+ const code = params.publicCode.trim();
11
+ if (!code)
12
+ throw new Error("publicCode is required.");
13
+ const widget = await loadMorapayWidget(params.widgetScriptUrl);
14
+ const apiBaseUrl = (params.apiBaseUrl ?? MORAPAY_PUBLIC_API_BASE).replace(/\/+$/, "");
15
+ if (params.mode === "preview") {
16
+ if (!widget.openPreviewModal) {
17
+ throw new Error("MorapayCheckout.openPreviewModal is not available on this widget build.");
18
+ }
19
+ window.MorapayCheckout?.closePreviewModal?.();
20
+ widget.openPreviewModal({
21
+ businessName: params.businessName?.trim() || "Merchant",
22
+ linkTitle: params.linkTitle?.trim() || "Payment",
23
+ amount: params.amount ?? null,
24
+ currency: params.currency ?? "USD",
25
+ customization: params.customization,
26
+ presentation: params.presentation ?? params.customization?.presentation,
27
+ publicCode: code,
28
+ apiBaseUrl,
29
+ checkoutBaseUrl: params.checkoutBaseUrl?.trim(),
30
+ onWalletConnected: params.onWalletConnected,
31
+ onTokenSelect: params.onTokenSelect,
32
+ onClose: params.onClose,
33
+ onSuccess: params.onSuccess,
34
+ onFailure: params.onFailure,
35
+ });
36
+ return;
37
+ }
38
+ if (!widget.openModal) {
39
+ throw new Error("MorapayCheckout.openModal is not available on this widget build.");
40
+ }
41
+ const checkoutBaseUrl = params.checkoutBaseUrl?.trim();
42
+ if (!checkoutBaseUrl) {
43
+ throw new Error("checkoutBaseUrl is required for live checkout.");
44
+ }
45
+ window.MorapayCheckout?.closeModal?.();
46
+ widget.openModal({
47
+ mode: "payment-link",
48
+ title: params.linkTitle?.trim() || "Checkout",
49
+ checkoutBaseUrl,
50
+ publicCode: code,
51
+ customization: params.customization,
52
+ presentation: params.presentation ?? params.customization?.presentation,
53
+ onSuccess: params.onSuccess,
54
+ onFailure: params.onFailure,
55
+ onClose: params.onClose,
56
+ });
57
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./client/index.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../features/widget/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "./client/index.js";
@@ -0,0 +1,2 @@
1
+ export * from "../features/publicApi/server/catalogSquidProxy.js";
2
+ //# sourceMappingURL=catalogSquidProxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalogSquidProxy.d.ts","sourceRoot":"","sources":["../../server/catalogSquidProxy.ts"],"names":[],"mappings":"AAAA,cAAc,mDAAmD,CAAC"}
@@ -0,0 +1 @@
1
+ export * from "../features/publicApi/server/catalogSquidProxy.js";
@@ -0,0 +1,3 @@
1
+ export * from "../features/publicApi/server/proxyPublicApi.js";
2
+ export * from "../features/publicApi/server/catalogSquidProxy.js";
3
+ //# sourceMappingURL=proxyPublicApi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxyPublicApi.d.ts","sourceRoot":"","sources":["../../server/proxyPublicApi.ts"],"names":[],"mappings":"AAAA,cAAc,gDAAgD,CAAC;AAC/D,cAAc,mDAAmD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from "../features/publicApi/server/proxyPublicApi.js";
2
+ export * from "../features/publicApi/server/catalogSquidProxy.js";
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@morapay/nextjs",
3
+ "version": "0.1.0",
4
+ "description": "Next.js BFF helpers for Morapay public API proxies (payment links, fiat, catalog)",
5
+ "license": "MIT",
6
+ "homepage": "https://docs.morapay.io/products/sdk",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/morapay-app/sdk.git",
10
+ "directory": "nextjs"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public",
14
+ "registry": "https://registry.npmjs.org/"
15
+ },
16
+ "type": "module",
17
+ "main": "./dist/features/publicApi/server/index.js",
18
+ "types": "./dist/features/publicApi/server/index.d.ts",
19
+ "exports": {
20
+ "./server/proxyPublicApi": {
21
+ "types": "./dist/server/proxyPublicApi.d.ts",
22
+ "import": "./dist/server/proxyPublicApi.js"
23
+ },
24
+ "./server/catalogSquidProxy": {
25
+ "types": "./dist/server/catalogSquidProxy.d.ts",
26
+ "import": "./dist/server/catalogSquidProxy.js"
27
+ },
28
+ "./features/publicApi/server": {
29
+ "types": "./dist/features/publicApi/server/index.d.ts",
30
+ "import": "./dist/features/publicApi/server/index.js"
31
+ },
32
+ "./features/publicApi/server/*": {
33
+ "types": "./dist/features/publicApi/server/*.d.ts",
34
+ "import": "./dist/features/publicApi/server/*.js"
35
+ },
36
+ "./client/loadWidget": {
37
+ "types": "./dist/client/loadWidget.d.ts",
38
+ "import": "./dist/client/loadWidget.js"
39
+ },
40
+ "./client/openPaymentLinkCheckout": {
41
+ "types": "./dist/client/openPaymentLinkCheckout.d.ts",
42
+ "import": "./dist/client/openPaymentLinkCheckout.js"
43
+ },
44
+ "./constants": {
45
+ "types": "./dist/constants.d.ts",
46
+ "import": "./dist/constants.js"
47
+ }
48
+ },
49
+ "files": [
50
+ "dist",
51
+ "README.md",
52
+ "LICENSE"
53
+ ],
54
+ "scripts": {
55
+ "build": "tsc -p tsconfig.json",
56
+ "lint": "tsc -p tsconfig.json --noEmit",
57
+ "prepublishOnly": "pnpm run build"
58
+ },
59
+ "peerDependencies": {
60
+ "@morapay/sdk": "^0.1.0"
61
+ },
62
+ "devDependencies": {
63
+ "@morapay/sdk": "workspace:*",
64
+ "@types/node": "^22.15.0",
65
+ "typescript": "^5.9.3"
66
+ },
67
+ "keywords": [
68
+ "morapay",
69
+ "nextjs",
70
+ "payments",
71
+ "checkout"
72
+ ],
73
+ "engines": {
74
+ "node": ">=20"
75
+ }
76
+ }