@easypayment/medusa-paypal-ui 0.0.3
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 +1 -0
- package/README.md +53 -0
- package/dist/index.cjs +246 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +89 -0
- package/dist/index.d.ts +89 -0
- package/dist/index.mjs +238 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +49 -0
package/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIT License
|
package/README.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# @easypayment/medusa-paypal-ui (Enterprise Gold) — v1.0.3
|
|
2
|
+
|
|
3
|
+
Fixes included:
|
|
4
|
+
- Card Fields: uses `cardFieldsForm.submit()` (typed)
|
|
5
|
+
- Card Fields: `PayPalCardFieldsProvider` includes required `onError`
|
|
6
|
+
- Build: ESM outputs `dist/index.mjs` to match `package.json` exports
|
|
7
|
+
|
|
8
|
+
## Install (local file package)
|
|
9
|
+
|
|
10
|
+
In your storefront `package.json`:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@easypayment/medusa-paypal-ui": "file:./packages/medusa-paypal-ui-enterprise-gold",
|
|
16
|
+
"@paypal/react-paypal-js": "^8.8.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm i
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Build
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cd packages/medusa-paypal-ui-enterprise-gold
|
|
31
|
+
npm run build
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Use in Medusa Next checkout (recommended adapter)
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
import { MedusaNextPayPalAdapter } from "@easypayment/medusa-paypal-ui"
|
|
38
|
+
|
|
39
|
+
<MedusaNextPayPalAdapter
|
|
40
|
+
cartId={cart.id}
|
|
41
|
+
selectedProviderId={selectedProviderId}
|
|
42
|
+
baseUrl={process.env.NEXT_PUBLIC_MEDUSA_BACKEND_URL!}
|
|
43
|
+
publishableApiKey={process.env.NEXT_PUBLIC_MEDUSA_PUBLISHABLE_KEY}
|
|
44
|
+
providerIds={{ paypal: "paypal", paypalCard: "paypal_card" }}
|
|
45
|
+
onPaid={() => window.location.reload()}
|
|
46
|
+
/>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Tests
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm test
|
|
53
|
+
```
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
var reactPaypalJs = require('@paypal/react-paypal-js');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
// src/client/http.ts
|
|
8
|
+
function createHttpClient(opts) {
|
|
9
|
+
const base = opts.baseUrl.replace(/\/+$/, "");
|
|
10
|
+
async function request(path, init) {
|
|
11
|
+
const url = `${base}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
12
|
+
const headers = {
|
|
13
|
+
Accept: "application/json",
|
|
14
|
+
...init?.headers
|
|
15
|
+
};
|
|
16
|
+
if (opts.publishableApiKey) {
|
|
17
|
+
headers["x-publishable-api-key"] = opts.publishableApiKey;
|
|
18
|
+
}
|
|
19
|
+
const res = await fetch(url, { ...init, headers, credentials: "include" });
|
|
20
|
+
const text = await res.text().catch(() => "");
|
|
21
|
+
if (!res.ok) {
|
|
22
|
+
throw new Error(text || `Request failed (${res.status})`);
|
|
23
|
+
}
|
|
24
|
+
return text ? JSON.parse(text) : {};
|
|
25
|
+
}
|
|
26
|
+
return { request };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// src/client/paypal.ts
|
|
30
|
+
function createPayPalStoreApi(opts) {
|
|
31
|
+
const http = createHttpClient(opts);
|
|
32
|
+
return {
|
|
33
|
+
getConfig(cartId) {
|
|
34
|
+
const q = cartId ? `?cart_id=${encodeURIComponent(cartId)}` : "";
|
|
35
|
+
return http.request(`/store/paypal/config${q}`);
|
|
36
|
+
},
|
|
37
|
+
getSettings() {
|
|
38
|
+
return http.request(`/store/paypal/settings`);
|
|
39
|
+
},
|
|
40
|
+
createOrder(cartId) {
|
|
41
|
+
return http.request(`/store/paypal/create-order`, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: { "Content-Type": "application/json" },
|
|
44
|
+
body: JSON.stringify({ cart_id: cartId })
|
|
45
|
+
});
|
|
46
|
+
},
|
|
47
|
+
captureOrder(cartId, orderId) {
|
|
48
|
+
return http.request(`/store/paypal/capture-order`, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: { "Content-Type": "application/json" },
|
|
51
|
+
body: JSON.stringify({ cart_id: cartId, order_id: orderId })
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function usePayPalConfig({ baseUrl, publishableApiKey, cartId }) {
|
|
57
|
+
const api = react.useMemo(
|
|
58
|
+
() => createPayPalStoreApi({ baseUrl, publishableApiKey }),
|
|
59
|
+
[baseUrl, publishableApiKey]
|
|
60
|
+
);
|
|
61
|
+
const [config, setConfig] = react.useState(null);
|
|
62
|
+
const [loading, setLoading] = react.useState(false);
|
|
63
|
+
const [error, setError] = react.useState(null);
|
|
64
|
+
react.useEffect(() => {
|
|
65
|
+
let mounted = true;
|
|
66
|
+
(async () => {
|
|
67
|
+
try {
|
|
68
|
+
setLoading(true);
|
|
69
|
+
setError(null);
|
|
70
|
+
const cfg = await api.getConfig(cartId);
|
|
71
|
+
if (mounted) setConfig(cfg);
|
|
72
|
+
} catch (e) {
|
|
73
|
+
if (mounted) setError(e?.message || "Failed to load PayPal config");
|
|
74
|
+
} finally {
|
|
75
|
+
if (mounted) setLoading(false);
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
return () => {
|
|
79
|
+
mounted = false;
|
|
80
|
+
};
|
|
81
|
+
}, [api, cartId]);
|
|
82
|
+
return { config, loading, error };
|
|
83
|
+
}
|
|
84
|
+
function PayPalProvider(props) {
|
|
85
|
+
const { config, intent = "capture", children } = props;
|
|
86
|
+
const options = react.useMemo(() => {
|
|
87
|
+
return {
|
|
88
|
+
"client-id": config.client_id,
|
|
89
|
+
currency: config.currency,
|
|
90
|
+
intent,
|
|
91
|
+
components: config.client_token ? "buttons,card-fields" : "buttons",
|
|
92
|
+
"data-client-token": config.client_token || void 0
|
|
93
|
+
};
|
|
94
|
+
}, [config, intent]);
|
|
95
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactPaypalJs.PayPalScriptProvider, { options, children });
|
|
96
|
+
}
|
|
97
|
+
function PayPalCurrencyNotice({ config }) {
|
|
98
|
+
if (config.currency_supported) return null;
|
|
99
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: 12, border: "1px solid #ddd", borderRadius: 10 }, children: [
|
|
100
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "PayPal currency issue" }),
|
|
101
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: 18 }, children: (config.currency_errors || []).map((e, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: e }, i)) })
|
|
102
|
+
] });
|
|
103
|
+
}
|
|
104
|
+
function PayPalSmartButtons(props) {
|
|
105
|
+
const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props;
|
|
106
|
+
const api = react.useMemo(
|
|
107
|
+
() => createPayPalStoreApi({ baseUrl, publishableApiKey }),
|
|
108
|
+
[baseUrl, publishableApiKey]
|
|
109
|
+
);
|
|
110
|
+
const [error, setError] = react.useState(null);
|
|
111
|
+
if (!config.currency_supported) return null;
|
|
112
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
113
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
114
|
+
reactPaypalJs.PayPalButtons,
|
|
115
|
+
{
|
|
116
|
+
style: { layout: "vertical" },
|
|
117
|
+
createOrder: async () => {
|
|
118
|
+
setError(null);
|
|
119
|
+
const r = await api.createOrder(cartId);
|
|
120
|
+
return r.id;
|
|
121
|
+
},
|
|
122
|
+
onApprove: async (data) => {
|
|
123
|
+
setError(null);
|
|
124
|
+
const orderId = String(data?.orderID || "");
|
|
125
|
+
const result = await api.captureOrder(cartId, orderId);
|
|
126
|
+
onPaid?.(result);
|
|
127
|
+
},
|
|
128
|
+
onError: (err) => {
|
|
129
|
+
const msg = err?.message || "PayPal error";
|
|
130
|
+
setError(msg);
|
|
131
|
+
onError?.(msg);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
),
|
|
135
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginTop: 10, color: "crimson" }, children: error }) : null
|
|
136
|
+
] });
|
|
137
|
+
}
|
|
138
|
+
function SubmitButton({ disabled, label }) {
|
|
139
|
+
const { cardFieldsForm } = reactPaypalJs.usePayPalCardFields();
|
|
140
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
141
|
+
"button",
|
|
142
|
+
{
|
|
143
|
+
type: "button",
|
|
144
|
+
disabled: disabled || !cardFieldsForm,
|
|
145
|
+
onClick: () => cardFieldsForm?.submit(),
|
|
146
|
+
style: { padding: "10px 12px", borderRadius: 10, border: "1px solid #ddd" },
|
|
147
|
+
children: label
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
function PayPalAdvancedCard(props) {
|
|
152
|
+
const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props;
|
|
153
|
+
const api = react.useMemo(
|
|
154
|
+
() => createPayPalStoreApi({ baseUrl, publishableApiKey }),
|
|
155
|
+
[baseUrl, publishableApiKey]
|
|
156
|
+
);
|
|
157
|
+
const [error, setError] = react.useState(null);
|
|
158
|
+
const [submitting, setSubmitting] = react.useState(false);
|
|
159
|
+
if (!config.currency_supported) return null;
|
|
160
|
+
if (!config.client_token) {
|
|
161
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: 12, border: "1px solid #ddd", borderRadius: 10 }, children: "CardFields unavailable: missing client_token from backend." });
|
|
162
|
+
}
|
|
163
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
164
|
+
reactPaypalJs.PayPalCardFieldsProvider,
|
|
165
|
+
{
|
|
166
|
+
createOrder: async () => {
|
|
167
|
+
setError(null);
|
|
168
|
+
const r = await api.createOrder(cartId);
|
|
169
|
+
return r.id;
|
|
170
|
+
},
|
|
171
|
+
onApprove: async (data) => {
|
|
172
|
+
try {
|
|
173
|
+
setSubmitting(true);
|
|
174
|
+
setError(null);
|
|
175
|
+
const orderId = String(data?.orderID || "");
|
|
176
|
+
const result = await api.captureOrder(cartId, orderId);
|
|
177
|
+
onPaid?.(result);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
const msg = e?.message || "Card payment failed";
|
|
180
|
+
setError(msg);
|
|
181
|
+
onError?.(msg);
|
|
182
|
+
} finally {
|
|
183
|
+
setSubmitting(false);
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
onError: (e) => {
|
|
187
|
+
const msg = e?.message || "CardFields error";
|
|
188
|
+
setError(msg);
|
|
189
|
+
onError?.(msg);
|
|
190
|
+
},
|
|
191
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 10 }, children: [
|
|
192
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactPaypalJs.PayPalNameField, {}),
|
|
193
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactPaypalJs.PayPalNumberField, {}),
|
|
194
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }, children: [
|
|
195
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactPaypalJs.PayPalExpiryField, {}),
|
|
196
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactPaypalJs.PayPalCVVField, {})
|
|
197
|
+
] }),
|
|
198
|
+
/* @__PURE__ */ jsxRuntime.jsx(SubmitButton, { disabled: submitting, label: submitting ? "Processing..." : "Pay by Card" }),
|
|
199
|
+
error ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "crimson" }, children: error }) : null
|
|
200
|
+
] })
|
|
201
|
+
}
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
function MedusaNextPayPalAdapter(props) {
|
|
205
|
+
const { cartId, selectedProviderId, baseUrl, publishableApiKey, providerIds, onPaid } = props;
|
|
206
|
+
const paypalProviderId = providerIds?.paypal || "paypal";
|
|
207
|
+
const paypalCardProviderId = providerIds?.paypalCard || "paypal_card";
|
|
208
|
+
const shouldRender = selectedProviderId === paypalProviderId || selectedProviderId === paypalCardProviderId;
|
|
209
|
+
const { config, loading, error } = usePayPalConfig({ baseUrl, publishableApiKey, cartId });
|
|
210
|
+
if (!shouldRender) return null;
|
|
211
|
+
if (loading) return /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading PayPal\u2026" });
|
|
212
|
+
if (error) return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "crimson" }, children: error });
|
|
213
|
+
if (!config) return null;
|
|
214
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 12 }, children: [
|
|
215
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalCurrencyNotice, { config }),
|
|
216
|
+
/* @__PURE__ */ jsxRuntime.jsx(PayPalProvider, { config, intent: "capture", children: selectedProviderId === paypalCardProviderId ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
217
|
+
PayPalAdvancedCard,
|
|
218
|
+
{
|
|
219
|
+
baseUrl,
|
|
220
|
+
publishableApiKey,
|
|
221
|
+
cartId,
|
|
222
|
+
config,
|
|
223
|
+
onPaid
|
|
224
|
+
}
|
|
225
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
226
|
+
PayPalSmartButtons,
|
|
227
|
+
{
|
|
228
|
+
baseUrl,
|
|
229
|
+
publishableApiKey,
|
|
230
|
+
cartId,
|
|
231
|
+
config,
|
|
232
|
+
onPaid
|
|
233
|
+
}
|
|
234
|
+
) })
|
|
235
|
+
] });
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
exports.MedusaNextPayPalAdapter = MedusaNextPayPalAdapter;
|
|
239
|
+
exports.PayPalAdvancedCard = PayPalAdvancedCard;
|
|
240
|
+
exports.PayPalCurrencyNotice = PayPalCurrencyNotice;
|
|
241
|
+
exports.PayPalProvider = PayPalProvider;
|
|
242
|
+
exports.PayPalSmartButtons = PayPalSmartButtons;
|
|
243
|
+
exports.createPayPalStoreApi = createPayPalStoreApi;
|
|
244
|
+
exports.usePayPalConfig = usePayPalConfig;
|
|
245
|
+
//# sourceMappingURL=index.cjs.map
|
|
246
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/http.ts","../src/client/paypal.ts","../src/hooks/usePayPalConfig.ts","../src/components/PayPalProvider.tsx","../src/components/PayPalCurrencyNotice.tsx","../src/components/PayPalSmartButtons.tsx","../src/components/PayPalAdvancedCard.tsx","../src/adapters/MedusaNextPayPalAdapter.tsx"],"names":["useMemo","useState","useEffect","jsx","PayPalScriptProvider","jsxs","PayPalButtons","usePayPalCardFields","PayPalCardFieldsProvider","PayPalNameField","PayPalNumberField","PayPalExpiryField","PayPalCVVField"],"mappings":"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","file":"index.cjs","sourcesContent":["export type HttpOptions = {\n baseUrl: string\n publishableApiKey?: string\n}\n\nexport function createHttpClient(opts: HttpOptions) {\n const base = opts.baseUrl.replace(/\\/+$/, \"\")\n\n async function request<T>(path: string, init?: RequestInit): Promise<T> {\n const url = `${base}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...(init?.headers as any),\n }\n\n if (opts.publishableApiKey) {\n headers[\"x-publishable-api-key\"] = opts.publishableApiKey\n }\n\n const res = await fetch(url, { ...init, headers, credentials: \"include\" })\n const text = await res.text().catch(() => \"\")\n\n if (!res.ok) {\n throw new Error(text || `Request failed (${res.status})`)\n }\n\n return (text ? JSON.parse(text) : {}) as T\n }\n\n return { request }\n}\n","import type { PayPalConfig, PayPalSettingsResponse } from \"./types\"\nimport { createHttpClient, type HttpOptions } from \"./http\"\n\nexport function createPayPalStoreApi(opts: HttpOptions) {\n const http = createHttpClient(opts)\n\n return {\n getConfig(cartId?: string) {\n const q = cartId ? `?cart_id=${encodeURIComponent(cartId)}` : \"\"\n return http.request<PayPalConfig>(`/store/paypal/config${q}`)\n },\n\n getSettings() {\n return http.request<PayPalSettingsResponse>(`/store/paypal/settings`)\n },\n\n createOrder(cartId: string) {\n return http.request<{ id: string }>(`/store/paypal/create-order`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ cart_id: cartId }),\n })\n },\n\n captureOrder(cartId: string, orderId: string) {\n return http.request<any>(`/store/paypal/capture-order`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ cart_id: cartId, order_id: orderId }),\n })\n },\n }\n}\n","import { useEffect, useMemo, useState } from \"react\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\n\ntype Args = {\n baseUrl: string\n publishableApiKey?: string\n cartId?: string\n}\n\nexport function usePayPalConfig({ baseUrl, publishableApiKey, cartId }: Args) {\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const [config, setConfig] = useState<PayPalConfig | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n let mounted = true\n ;(async () => {\n try {\n setLoading(true)\n setError(null)\n const cfg = await api.getConfig(cartId)\n if (mounted) setConfig(cfg)\n } catch (e: any) {\n if (mounted) setError(e?.message || \"Failed to load PayPal config\")\n } finally {\n if (mounted) setLoading(false)\n }\n })()\n\n return () => {\n mounted = false\n }\n }, [api, cartId])\n\n return { config, loading, error }\n}\n","\"use client\"\n\nimport React, { useMemo } from \"react\"\nimport { PayPalScriptProvider } from \"@paypal/react-paypal-js\"\nimport type { PayPalConfig } from \"../client/types\"\n\nexport function PayPalProvider(props: {\n config: PayPalConfig\n intent?: \"capture\" | \"authorize\"\n children: React.ReactNode\n}) {\n const { config, intent = \"capture\", children } = props\n\n const options = useMemo(() => {\n return {\n \"client-id\": config.client_id,\n currency: config.currency,\n intent,\n components: config.client_token ? \"buttons,card-fields\" : \"buttons\",\n \"data-client-token\": config.client_token || undefined,\n } as any\n }, [config, intent])\n\n return <PayPalScriptProvider options={options}>{children}</PayPalScriptProvider>\n}\n","\"use client\"\n\nimport React from \"react\"\nimport type { PayPalConfig } from \"../client/types\"\n\nexport function PayPalCurrencyNotice({ config }: { config: PayPalConfig }) {\n if (config.currency_supported) return null\n\n return (\n <div style={{ padding: 12, border: \"1px solid #ddd\", borderRadius: 10 }}>\n <div style={{ fontWeight: 600, marginBottom: 6 }}>PayPal currency issue</div>\n <ul style={{ margin: 0, paddingLeft: 18 }}>\n {(config.currency_errors || []).map((e, i) => (\n <li key={i}>{e}</li>\n ))}\n </ul>\n </div>\n )\n}\n","\"use client\"\n\nimport React, { useMemo, useState } from \"react\"\nimport { PayPalButtons } from \"@paypal/react-paypal-js\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\n\nexport function PayPalSmartButtons(props: {\n baseUrl: string\n publishableApiKey?: string\n cartId: string\n config: PayPalConfig\n onPaid?: (result: any) => void\n onError?: (message: string) => void\n}) {\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const [error, setError] = useState<string | null>(null)\n\n if (!config.currency_supported) return null\n\n return (\n <div>\n <PayPalButtons\n style={{ layout: \"vertical\" }}\n createOrder={async () => {\n setError(null)\n const r = await api.createOrder(cartId)\n return r.id\n }}\n onApprove={async (data: any) => {\n setError(null)\n const orderId = String(data?.orderID || \"\")\n const result = await api.captureOrder(cartId, orderId)\n onPaid?.(result)\n }}\n onError={(err: any) => {\n const msg = err?.message || \"PayPal error\"\n setError(msg)\n onError?.(msg)\n }}\n />\n {error ? <div style={{ marginTop: 10, color: \"crimson\" }}>{error}</div> : null}\n </div>\n )\n}\n","\"use client\"\n\nimport React, { useMemo, useState } from \"react\"\nimport {\n PayPalCardFieldsProvider,\n PayPalNameField,\n PayPalNumberField,\n PayPalExpiryField,\n PayPalCVVField,\n usePayPalCardFields,\n} from \"@paypal/react-paypal-js\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\n\nfunction SubmitButton({ disabled, label }: { disabled: boolean; label: string }) {\n const { cardFieldsForm } = usePayPalCardFields()\n\n return (\n <button\n type=\"button\"\n disabled={disabled || !cardFieldsForm}\n onClick={() => cardFieldsForm?.submit()}\n style={{ padding: \"10px 12px\", borderRadius: 10, border: \"1px solid #ddd\" }}\n >\n {label}\n </button>\n )\n}\n\nexport function PayPalAdvancedCard(props: {\n baseUrl: string\n publishableApiKey?: string\n cartId: string\n config: PayPalConfig\n onPaid?: (result: any) => void\n onError?: (message: string) => void\n}) {\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const [error, setError] = useState<string | null>(null)\n const [submitting, setSubmitting] = useState(false)\n\n if (!config.currency_supported) return null\n\n if (!config.client_token) {\n return (\n <div style={{ padding: 12, border: \"1px solid #ddd\", borderRadius: 10 }}>\n CardFields unavailable: missing client_token from backend.\n </div>\n )\n }\n\n return (\n <PayPalCardFieldsProvider\n createOrder={async () => {\n setError(null)\n const r = await api.createOrder(cartId)\n return r.id\n }}\n onApprove={async (data: any) => {\n try {\n setSubmitting(true)\n setError(null)\n const orderId = String(data?.orderID || \"\")\n const result = await api.captureOrder(cartId, orderId)\n onPaid?.(result)\n } catch (e: any) {\n const msg = e?.message || \"Card payment failed\"\n setError(msg)\n onError?.(msg)\n } finally {\n setSubmitting(false)\n }\n }}\n onError={(e: any) => {\n const msg = e?.message || \"CardFields error\"\n setError(msg)\n onError?.(msg)\n }}\n >\n <div style={{ display: \"grid\", gap: 10 }}>\n <PayPalNameField />\n <PayPalNumberField />\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: 10 }}>\n <PayPalExpiryField />\n <PayPalCVVField />\n </div>\n\n <SubmitButton disabled={submitting} label={submitting ? \"Processing...\" : \"Pay by Card\"} />\n\n {error ? <div style={{ color: \"crimson\" }}>{error}</div> : null}\n </div>\n </PayPalCardFieldsProvider>\n )\n}\n","\"use client\"\n\nimport React from \"react\"\nimport type { PayPalConfig } from \"../client/types\"\nimport { usePayPalConfig } from \"../hooks/usePayPalConfig\"\nimport { PayPalProvider } from \"../components/PayPalProvider\"\nimport { PayPalCurrencyNotice } from \"../components/PayPalCurrencyNotice\"\nimport { PayPalSmartButtons } from \"../components/PayPalSmartButtons\"\nimport { PayPalAdvancedCard } from \"../components/PayPalAdvancedCard\"\n\nexport type MedusaNextPayPalAdapterProps = {\n cartId: string\n selectedProviderId: string | null | undefined\n baseUrl: string\n publishableApiKey?: string\n providerIds?: {\n paypal?: string\n paypalCard?: string\n }\n onPaid?: (result: any) => void\n}\n\nexport function MedusaNextPayPalAdapter(props: MedusaNextPayPalAdapterProps) {\n const { cartId, selectedProviderId, baseUrl, publishableApiKey, providerIds, onPaid } = props\n\n const paypalProviderId = providerIds?.paypal || \"paypal\"\n const paypalCardProviderId = providerIds?.paypalCard || \"paypal_card\"\n\n const shouldRender =\n selectedProviderId === paypalProviderId || selectedProviderId === paypalCardProviderId\n\n const { config, loading, error } = usePayPalConfig({ baseUrl, publishableApiKey, cartId })\n\n if (!shouldRender) return null\n if (loading) return <div>Loading PayPal…</div>\n if (error) return <div style={{ color: \"crimson\" }}>{error}</div>\n if (!config) return null\n\n return (\n <div style={{ display: \"grid\", gap: 12 }}>\n <PayPalCurrencyNotice config={config as PayPalConfig} />\n\n <PayPalProvider config={config as PayPalConfig} intent=\"capture\">\n {selectedProviderId === paypalCardProviderId ? (\n <PayPalAdvancedCard\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n cartId={cartId}\n config={config as PayPalConfig}\n onPaid={onPaid}\n />\n ) : (\n <PayPalSmartButtons\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n cartId={cartId}\n config={config as PayPalConfig}\n onPaid={onPaid}\n />\n )}\n </PayPalProvider>\n </div>\n )\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type PayPalConfig = {
|
|
5
|
+
environment: "sandbox" | "live";
|
|
6
|
+
client_id: string;
|
|
7
|
+
currency: string;
|
|
8
|
+
currency_supported: boolean;
|
|
9
|
+
currency_errors: string[];
|
|
10
|
+
supported_currencies: string[];
|
|
11
|
+
client_token?: string;
|
|
12
|
+
};
|
|
13
|
+
type PayPalSettingsResponse = {
|
|
14
|
+
data?: {
|
|
15
|
+
api_details?: {
|
|
16
|
+
currency_code?: string;
|
|
17
|
+
};
|
|
18
|
+
paypal_settings?: Record<string, any>;
|
|
19
|
+
onboarding_config?: Record<string, any>;
|
|
20
|
+
};
|
|
21
|
+
} | any;
|
|
22
|
+
|
|
23
|
+
type HttpOptions = {
|
|
24
|
+
baseUrl: string;
|
|
25
|
+
publishableApiKey?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
declare function createPayPalStoreApi(opts: HttpOptions): {
|
|
29
|
+
getConfig(cartId?: string): Promise<PayPalConfig>;
|
|
30
|
+
getSettings(): Promise<any>;
|
|
31
|
+
createOrder(cartId: string): Promise<{
|
|
32
|
+
id: string;
|
|
33
|
+
}>;
|
|
34
|
+
captureOrder(cartId: string, orderId: string): Promise<any>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type Args = {
|
|
38
|
+
baseUrl: string;
|
|
39
|
+
publishableApiKey?: string;
|
|
40
|
+
cartId?: string;
|
|
41
|
+
};
|
|
42
|
+
declare function usePayPalConfig({ baseUrl, publishableApiKey, cartId }: Args): {
|
|
43
|
+
config: PayPalConfig | null;
|
|
44
|
+
loading: boolean;
|
|
45
|
+
error: string | null;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
declare function PayPalProvider(props: {
|
|
49
|
+
config: PayPalConfig;
|
|
50
|
+
intent?: "capture" | "authorize";
|
|
51
|
+
children: React.ReactNode;
|
|
52
|
+
}): react_jsx_runtime.JSX.Element;
|
|
53
|
+
|
|
54
|
+
declare function PayPalCurrencyNotice({ config }: {
|
|
55
|
+
config: PayPalConfig;
|
|
56
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
57
|
+
|
|
58
|
+
declare function PayPalSmartButtons(props: {
|
|
59
|
+
baseUrl: string;
|
|
60
|
+
publishableApiKey?: string;
|
|
61
|
+
cartId: string;
|
|
62
|
+
config: PayPalConfig;
|
|
63
|
+
onPaid?: (result: any) => void;
|
|
64
|
+
onError?: (message: string) => void;
|
|
65
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
66
|
+
|
|
67
|
+
declare function PayPalAdvancedCard(props: {
|
|
68
|
+
baseUrl: string;
|
|
69
|
+
publishableApiKey?: string;
|
|
70
|
+
cartId: string;
|
|
71
|
+
config: PayPalConfig;
|
|
72
|
+
onPaid?: (result: any) => void;
|
|
73
|
+
onError?: (message: string) => void;
|
|
74
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
75
|
+
|
|
76
|
+
type MedusaNextPayPalAdapterProps = {
|
|
77
|
+
cartId: string;
|
|
78
|
+
selectedProviderId: string | null | undefined;
|
|
79
|
+
baseUrl: string;
|
|
80
|
+
publishableApiKey?: string;
|
|
81
|
+
providerIds?: {
|
|
82
|
+
paypal?: string;
|
|
83
|
+
paypalCard?: string;
|
|
84
|
+
};
|
|
85
|
+
onPaid?: (result: any) => void;
|
|
86
|
+
};
|
|
87
|
+
declare function MedusaNextPayPalAdapter(props: MedusaNextPayPalAdapterProps): react_jsx_runtime.JSX.Element | null;
|
|
88
|
+
|
|
89
|
+
export { MedusaNextPayPalAdapter, type MedusaNextPayPalAdapterProps, PayPalAdvancedCard, type PayPalConfig, PayPalCurrencyNotice, PayPalProvider, type PayPalSettingsResponse, PayPalSmartButtons, createPayPalStoreApi, usePayPalConfig };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
type PayPalConfig = {
|
|
5
|
+
environment: "sandbox" | "live";
|
|
6
|
+
client_id: string;
|
|
7
|
+
currency: string;
|
|
8
|
+
currency_supported: boolean;
|
|
9
|
+
currency_errors: string[];
|
|
10
|
+
supported_currencies: string[];
|
|
11
|
+
client_token?: string;
|
|
12
|
+
};
|
|
13
|
+
type PayPalSettingsResponse = {
|
|
14
|
+
data?: {
|
|
15
|
+
api_details?: {
|
|
16
|
+
currency_code?: string;
|
|
17
|
+
};
|
|
18
|
+
paypal_settings?: Record<string, any>;
|
|
19
|
+
onboarding_config?: Record<string, any>;
|
|
20
|
+
};
|
|
21
|
+
} | any;
|
|
22
|
+
|
|
23
|
+
type HttpOptions = {
|
|
24
|
+
baseUrl: string;
|
|
25
|
+
publishableApiKey?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
declare function createPayPalStoreApi(opts: HttpOptions): {
|
|
29
|
+
getConfig(cartId?: string): Promise<PayPalConfig>;
|
|
30
|
+
getSettings(): Promise<any>;
|
|
31
|
+
createOrder(cartId: string): Promise<{
|
|
32
|
+
id: string;
|
|
33
|
+
}>;
|
|
34
|
+
captureOrder(cartId: string, orderId: string): Promise<any>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
type Args = {
|
|
38
|
+
baseUrl: string;
|
|
39
|
+
publishableApiKey?: string;
|
|
40
|
+
cartId?: string;
|
|
41
|
+
};
|
|
42
|
+
declare function usePayPalConfig({ baseUrl, publishableApiKey, cartId }: Args): {
|
|
43
|
+
config: PayPalConfig | null;
|
|
44
|
+
loading: boolean;
|
|
45
|
+
error: string | null;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
declare function PayPalProvider(props: {
|
|
49
|
+
config: PayPalConfig;
|
|
50
|
+
intent?: "capture" | "authorize";
|
|
51
|
+
children: React.ReactNode;
|
|
52
|
+
}): react_jsx_runtime.JSX.Element;
|
|
53
|
+
|
|
54
|
+
declare function PayPalCurrencyNotice({ config }: {
|
|
55
|
+
config: PayPalConfig;
|
|
56
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
57
|
+
|
|
58
|
+
declare function PayPalSmartButtons(props: {
|
|
59
|
+
baseUrl: string;
|
|
60
|
+
publishableApiKey?: string;
|
|
61
|
+
cartId: string;
|
|
62
|
+
config: PayPalConfig;
|
|
63
|
+
onPaid?: (result: any) => void;
|
|
64
|
+
onError?: (message: string) => void;
|
|
65
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
66
|
+
|
|
67
|
+
declare function PayPalAdvancedCard(props: {
|
|
68
|
+
baseUrl: string;
|
|
69
|
+
publishableApiKey?: string;
|
|
70
|
+
cartId: string;
|
|
71
|
+
config: PayPalConfig;
|
|
72
|
+
onPaid?: (result: any) => void;
|
|
73
|
+
onError?: (message: string) => void;
|
|
74
|
+
}): react_jsx_runtime.JSX.Element | null;
|
|
75
|
+
|
|
76
|
+
type MedusaNextPayPalAdapterProps = {
|
|
77
|
+
cartId: string;
|
|
78
|
+
selectedProviderId: string | null | undefined;
|
|
79
|
+
baseUrl: string;
|
|
80
|
+
publishableApiKey?: string;
|
|
81
|
+
providerIds?: {
|
|
82
|
+
paypal?: string;
|
|
83
|
+
paypalCard?: string;
|
|
84
|
+
};
|
|
85
|
+
onPaid?: (result: any) => void;
|
|
86
|
+
};
|
|
87
|
+
declare function MedusaNextPayPalAdapter(props: MedusaNextPayPalAdapterProps): react_jsx_runtime.JSX.Element | null;
|
|
88
|
+
|
|
89
|
+
export { MedusaNextPayPalAdapter, type MedusaNextPayPalAdapterProps, PayPalAdvancedCard, type PayPalConfig, PayPalCurrencyNotice, PayPalProvider, type PayPalSettingsResponse, PayPalSmartButtons, createPayPalStoreApi, usePayPalConfig };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { useMemo, useState, useEffect } from 'react';
|
|
2
|
+
import { PayPalScriptProvider, PayPalButtons, PayPalCardFieldsProvider, PayPalNameField, PayPalNumberField, PayPalExpiryField, PayPalCVVField, usePayPalCardFields } from '@paypal/react-paypal-js';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/client/http.ts
|
|
6
|
+
function createHttpClient(opts) {
|
|
7
|
+
const base = opts.baseUrl.replace(/\/+$/, "");
|
|
8
|
+
async function request(path, init) {
|
|
9
|
+
const url = `${base}${path.startsWith("/") ? "" : "/"}${path}`;
|
|
10
|
+
const headers = {
|
|
11
|
+
Accept: "application/json",
|
|
12
|
+
...init?.headers
|
|
13
|
+
};
|
|
14
|
+
if (opts.publishableApiKey) {
|
|
15
|
+
headers["x-publishable-api-key"] = opts.publishableApiKey;
|
|
16
|
+
}
|
|
17
|
+
const res = await fetch(url, { ...init, headers, credentials: "include" });
|
|
18
|
+
const text = await res.text().catch(() => "");
|
|
19
|
+
if (!res.ok) {
|
|
20
|
+
throw new Error(text || `Request failed (${res.status})`);
|
|
21
|
+
}
|
|
22
|
+
return text ? JSON.parse(text) : {};
|
|
23
|
+
}
|
|
24
|
+
return { request };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// src/client/paypal.ts
|
|
28
|
+
function createPayPalStoreApi(opts) {
|
|
29
|
+
const http = createHttpClient(opts);
|
|
30
|
+
return {
|
|
31
|
+
getConfig(cartId) {
|
|
32
|
+
const q = cartId ? `?cart_id=${encodeURIComponent(cartId)}` : "";
|
|
33
|
+
return http.request(`/store/paypal/config${q}`);
|
|
34
|
+
},
|
|
35
|
+
getSettings() {
|
|
36
|
+
return http.request(`/store/paypal/settings`);
|
|
37
|
+
},
|
|
38
|
+
createOrder(cartId) {
|
|
39
|
+
return http.request(`/store/paypal/create-order`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: { "Content-Type": "application/json" },
|
|
42
|
+
body: JSON.stringify({ cart_id: cartId })
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
captureOrder(cartId, orderId) {
|
|
46
|
+
return http.request(`/store/paypal/capture-order`, {
|
|
47
|
+
method: "POST",
|
|
48
|
+
headers: { "Content-Type": "application/json" },
|
|
49
|
+
body: JSON.stringify({ cart_id: cartId, order_id: orderId })
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function usePayPalConfig({ baseUrl, publishableApiKey, cartId }) {
|
|
55
|
+
const api = useMemo(
|
|
56
|
+
() => createPayPalStoreApi({ baseUrl, publishableApiKey }),
|
|
57
|
+
[baseUrl, publishableApiKey]
|
|
58
|
+
);
|
|
59
|
+
const [config, setConfig] = useState(null);
|
|
60
|
+
const [loading, setLoading] = useState(false);
|
|
61
|
+
const [error, setError] = useState(null);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
let mounted = true;
|
|
64
|
+
(async () => {
|
|
65
|
+
try {
|
|
66
|
+
setLoading(true);
|
|
67
|
+
setError(null);
|
|
68
|
+
const cfg = await api.getConfig(cartId);
|
|
69
|
+
if (mounted) setConfig(cfg);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
if (mounted) setError(e?.message || "Failed to load PayPal config");
|
|
72
|
+
} finally {
|
|
73
|
+
if (mounted) setLoading(false);
|
|
74
|
+
}
|
|
75
|
+
})();
|
|
76
|
+
return () => {
|
|
77
|
+
mounted = false;
|
|
78
|
+
};
|
|
79
|
+
}, [api, cartId]);
|
|
80
|
+
return { config, loading, error };
|
|
81
|
+
}
|
|
82
|
+
function PayPalProvider(props) {
|
|
83
|
+
const { config, intent = "capture", children } = props;
|
|
84
|
+
const options = useMemo(() => {
|
|
85
|
+
return {
|
|
86
|
+
"client-id": config.client_id,
|
|
87
|
+
currency: config.currency,
|
|
88
|
+
intent,
|
|
89
|
+
components: config.client_token ? "buttons,card-fields" : "buttons",
|
|
90
|
+
"data-client-token": config.client_token || void 0
|
|
91
|
+
};
|
|
92
|
+
}, [config, intent]);
|
|
93
|
+
return /* @__PURE__ */ jsx(PayPalScriptProvider, { options, children });
|
|
94
|
+
}
|
|
95
|
+
function PayPalCurrencyNotice({ config }) {
|
|
96
|
+
if (config.currency_supported) return null;
|
|
97
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: 12, border: "1px solid #ddd", borderRadius: 10 }, children: [
|
|
98
|
+
/* @__PURE__ */ jsx("div", { style: { fontWeight: 600, marginBottom: 6 }, children: "PayPal currency issue" }),
|
|
99
|
+
/* @__PURE__ */ jsx("ul", { style: { margin: 0, paddingLeft: 18 }, children: (config.currency_errors || []).map((e, i) => /* @__PURE__ */ jsx("li", { children: e }, i)) })
|
|
100
|
+
] });
|
|
101
|
+
}
|
|
102
|
+
function PayPalSmartButtons(props) {
|
|
103
|
+
const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props;
|
|
104
|
+
const api = useMemo(
|
|
105
|
+
() => createPayPalStoreApi({ baseUrl, publishableApiKey }),
|
|
106
|
+
[baseUrl, publishableApiKey]
|
|
107
|
+
);
|
|
108
|
+
const [error, setError] = useState(null);
|
|
109
|
+
if (!config.currency_supported) return null;
|
|
110
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
111
|
+
/* @__PURE__ */ jsx(
|
|
112
|
+
PayPalButtons,
|
|
113
|
+
{
|
|
114
|
+
style: { layout: "vertical" },
|
|
115
|
+
createOrder: async () => {
|
|
116
|
+
setError(null);
|
|
117
|
+
const r = await api.createOrder(cartId);
|
|
118
|
+
return r.id;
|
|
119
|
+
},
|
|
120
|
+
onApprove: async (data) => {
|
|
121
|
+
setError(null);
|
|
122
|
+
const orderId = String(data?.orderID || "");
|
|
123
|
+
const result = await api.captureOrder(cartId, orderId);
|
|
124
|
+
onPaid?.(result);
|
|
125
|
+
},
|
|
126
|
+
onError: (err) => {
|
|
127
|
+
const msg = err?.message || "PayPal error";
|
|
128
|
+
setError(msg);
|
|
129
|
+
onError?.(msg);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
),
|
|
133
|
+
error ? /* @__PURE__ */ jsx("div", { style: { marginTop: 10, color: "crimson" }, children: error }) : null
|
|
134
|
+
] });
|
|
135
|
+
}
|
|
136
|
+
function SubmitButton({ disabled, label }) {
|
|
137
|
+
const { cardFieldsForm } = usePayPalCardFields();
|
|
138
|
+
return /* @__PURE__ */ jsx(
|
|
139
|
+
"button",
|
|
140
|
+
{
|
|
141
|
+
type: "button",
|
|
142
|
+
disabled: disabled || !cardFieldsForm,
|
|
143
|
+
onClick: () => cardFieldsForm?.submit(),
|
|
144
|
+
style: { padding: "10px 12px", borderRadius: 10, border: "1px solid #ddd" },
|
|
145
|
+
children: label
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
function PayPalAdvancedCard(props) {
|
|
150
|
+
const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props;
|
|
151
|
+
const api = useMemo(
|
|
152
|
+
() => createPayPalStoreApi({ baseUrl, publishableApiKey }),
|
|
153
|
+
[baseUrl, publishableApiKey]
|
|
154
|
+
);
|
|
155
|
+
const [error, setError] = useState(null);
|
|
156
|
+
const [submitting, setSubmitting] = useState(false);
|
|
157
|
+
if (!config.currency_supported) return null;
|
|
158
|
+
if (!config.client_token) {
|
|
159
|
+
return /* @__PURE__ */ jsx("div", { style: { padding: 12, border: "1px solid #ddd", borderRadius: 10 }, children: "CardFields unavailable: missing client_token from backend." });
|
|
160
|
+
}
|
|
161
|
+
return /* @__PURE__ */ jsx(
|
|
162
|
+
PayPalCardFieldsProvider,
|
|
163
|
+
{
|
|
164
|
+
createOrder: async () => {
|
|
165
|
+
setError(null);
|
|
166
|
+
const r = await api.createOrder(cartId);
|
|
167
|
+
return r.id;
|
|
168
|
+
},
|
|
169
|
+
onApprove: async (data) => {
|
|
170
|
+
try {
|
|
171
|
+
setSubmitting(true);
|
|
172
|
+
setError(null);
|
|
173
|
+
const orderId = String(data?.orderID || "");
|
|
174
|
+
const result = await api.captureOrder(cartId, orderId);
|
|
175
|
+
onPaid?.(result);
|
|
176
|
+
} catch (e) {
|
|
177
|
+
const msg = e?.message || "Card payment failed";
|
|
178
|
+
setError(msg);
|
|
179
|
+
onError?.(msg);
|
|
180
|
+
} finally {
|
|
181
|
+
setSubmitting(false);
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
onError: (e) => {
|
|
185
|
+
const msg = e?.message || "CardFields error";
|
|
186
|
+
setError(msg);
|
|
187
|
+
onError?.(msg);
|
|
188
|
+
},
|
|
189
|
+
children: /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 10 }, children: [
|
|
190
|
+
/* @__PURE__ */ jsx(PayPalNameField, {}),
|
|
191
|
+
/* @__PURE__ */ jsx(PayPalNumberField, {}),
|
|
192
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }, children: [
|
|
193
|
+
/* @__PURE__ */ jsx(PayPalExpiryField, {}),
|
|
194
|
+
/* @__PURE__ */ jsx(PayPalCVVField, {})
|
|
195
|
+
] }),
|
|
196
|
+
/* @__PURE__ */ jsx(SubmitButton, { disabled: submitting, label: submitting ? "Processing..." : "Pay by Card" }),
|
|
197
|
+
error ? /* @__PURE__ */ jsx("div", { style: { color: "crimson" }, children: error }) : null
|
|
198
|
+
] })
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
function MedusaNextPayPalAdapter(props) {
|
|
203
|
+
const { cartId, selectedProviderId, baseUrl, publishableApiKey, providerIds, onPaid } = props;
|
|
204
|
+
const paypalProviderId = providerIds?.paypal || "paypal";
|
|
205
|
+
const paypalCardProviderId = providerIds?.paypalCard || "paypal_card";
|
|
206
|
+
const shouldRender = selectedProviderId === paypalProviderId || selectedProviderId === paypalCardProviderId;
|
|
207
|
+
const { config, loading, error } = usePayPalConfig({ baseUrl, publishableApiKey, cartId });
|
|
208
|
+
if (!shouldRender) return null;
|
|
209
|
+
if (loading) return /* @__PURE__ */ jsx("div", { children: "Loading PayPal\u2026" });
|
|
210
|
+
if (error) return /* @__PURE__ */ jsx("div", { style: { color: "crimson" }, children: error });
|
|
211
|
+
if (!config) return null;
|
|
212
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 12 }, children: [
|
|
213
|
+
/* @__PURE__ */ jsx(PayPalCurrencyNotice, { config }),
|
|
214
|
+
/* @__PURE__ */ jsx(PayPalProvider, { config, intent: "capture", children: selectedProviderId === paypalCardProviderId ? /* @__PURE__ */ jsx(
|
|
215
|
+
PayPalAdvancedCard,
|
|
216
|
+
{
|
|
217
|
+
baseUrl,
|
|
218
|
+
publishableApiKey,
|
|
219
|
+
cartId,
|
|
220
|
+
config,
|
|
221
|
+
onPaid
|
|
222
|
+
}
|
|
223
|
+
) : /* @__PURE__ */ jsx(
|
|
224
|
+
PayPalSmartButtons,
|
|
225
|
+
{
|
|
226
|
+
baseUrl,
|
|
227
|
+
publishableApiKey,
|
|
228
|
+
cartId,
|
|
229
|
+
config,
|
|
230
|
+
onPaid
|
|
231
|
+
}
|
|
232
|
+
) })
|
|
233
|
+
] });
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export { MedusaNextPayPalAdapter, PayPalAdvancedCard, PayPalCurrencyNotice, PayPalProvider, PayPalSmartButtons, createPayPalStoreApi, usePayPalConfig };
|
|
237
|
+
//# sourceMappingURL=index.mjs.map
|
|
238
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/http.ts","../src/client/paypal.ts","../src/hooks/usePayPalConfig.ts","../src/components/PayPalProvider.tsx","../src/components/PayPalCurrencyNotice.tsx","../src/components/PayPalSmartButtons.tsx","../src/components/PayPalAdvancedCard.tsx","../src/adapters/MedusaNextPayPalAdapter.tsx"],"names":["useMemo","jsx","useState","jsxs"],"mappings":"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","file":"index.mjs","sourcesContent":["export type HttpOptions = {\n baseUrl: string\n publishableApiKey?: string\n}\n\nexport function createHttpClient(opts: HttpOptions) {\n const base = opts.baseUrl.replace(/\\/+$/, \"\")\n\n async function request<T>(path: string, init?: RequestInit): Promise<T> {\n const url = `${base}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`\n const headers: Record<string, string> = {\n Accept: \"application/json\",\n ...(init?.headers as any),\n }\n\n if (opts.publishableApiKey) {\n headers[\"x-publishable-api-key\"] = opts.publishableApiKey\n }\n\n const res = await fetch(url, { ...init, headers, credentials: \"include\" })\n const text = await res.text().catch(() => \"\")\n\n if (!res.ok) {\n throw new Error(text || `Request failed (${res.status})`)\n }\n\n return (text ? JSON.parse(text) : {}) as T\n }\n\n return { request }\n}\n","import type { PayPalConfig, PayPalSettingsResponse } from \"./types\"\nimport { createHttpClient, type HttpOptions } from \"./http\"\n\nexport function createPayPalStoreApi(opts: HttpOptions) {\n const http = createHttpClient(opts)\n\n return {\n getConfig(cartId?: string) {\n const q = cartId ? `?cart_id=${encodeURIComponent(cartId)}` : \"\"\n return http.request<PayPalConfig>(`/store/paypal/config${q}`)\n },\n\n getSettings() {\n return http.request<PayPalSettingsResponse>(`/store/paypal/settings`)\n },\n\n createOrder(cartId: string) {\n return http.request<{ id: string }>(`/store/paypal/create-order`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ cart_id: cartId }),\n })\n },\n\n captureOrder(cartId: string, orderId: string) {\n return http.request<any>(`/store/paypal/capture-order`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ cart_id: cartId, order_id: orderId }),\n })\n },\n }\n}\n","import { useEffect, useMemo, useState } from \"react\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\n\ntype Args = {\n baseUrl: string\n publishableApiKey?: string\n cartId?: string\n}\n\nexport function usePayPalConfig({ baseUrl, publishableApiKey, cartId }: Args) {\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const [config, setConfig] = useState<PayPalConfig | null>(null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n let mounted = true\n ;(async () => {\n try {\n setLoading(true)\n setError(null)\n const cfg = await api.getConfig(cartId)\n if (mounted) setConfig(cfg)\n } catch (e: any) {\n if (mounted) setError(e?.message || \"Failed to load PayPal config\")\n } finally {\n if (mounted) setLoading(false)\n }\n })()\n\n return () => {\n mounted = false\n }\n }, [api, cartId])\n\n return { config, loading, error }\n}\n","\"use client\"\n\nimport React, { useMemo } from \"react\"\nimport { PayPalScriptProvider } from \"@paypal/react-paypal-js\"\nimport type { PayPalConfig } from \"../client/types\"\n\nexport function PayPalProvider(props: {\n config: PayPalConfig\n intent?: \"capture\" | \"authorize\"\n children: React.ReactNode\n}) {\n const { config, intent = \"capture\", children } = props\n\n const options = useMemo(() => {\n return {\n \"client-id\": config.client_id,\n currency: config.currency,\n intent,\n components: config.client_token ? \"buttons,card-fields\" : \"buttons\",\n \"data-client-token\": config.client_token || undefined,\n } as any\n }, [config, intent])\n\n return <PayPalScriptProvider options={options}>{children}</PayPalScriptProvider>\n}\n","\"use client\"\n\nimport React from \"react\"\nimport type { PayPalConfig } from \"../client/types\"\n\nexport function PayPalCurrencyNotice({ config }: { config: PayPalConfig }) {\n if (config.currency_supported) return null\n\n return (\n <div style={{ padding: 12, border: \"1px solid #ddd\", borderRadius: 10 }}>\n <div style={{ fontWeight: 600, marginBottom: 6 }}>PayPal currency issue</div>\n <ul style={{ margin: 0, paddingLeft: 18 }}>\n {(config.currency_errors || []).map((e, i) => (\n <li key={i}>{e}</li>\n ))}\n </ul>\n </div>\n )\n}\n","\"use client\"\n\nimport React, { useMemo, useState } from \"react\"\nimport { PayPalButtons } from \"@paypal/react-paypal-js\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\n\nexport function PayPalSmartButtons(props: {\n baseUrl: string\n publishableApiKey?: string\n cartId: string\n config: PayPalConfig\n onPaid?: (result: any) => void\n onError?: (message: string) => void\n}) {\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const [error, setError] = useState<string | null>(null)\n\n if (!config.currency_supported) return null\n\n return (\n <div>\n <PayPalButtons\n style={{ layout: \"vertical\" }}\n createOrder={async () => {\n setError(null)\n const r = await api.createOrder(cartId)\n return r.id\n }}\n onApprove={async (data: any) => {\n setError(null)\n const orderId = String(data?.orderID || \"\")\n const result = await api.captureOrder(cartId, orderId)\n onPaid?.(result)\n }}\n onError={(err: any) => {\n const msg = err?.message || \"PayPal error\"\n setError(msg)\n onError?.(msg)\n }}\n />\n {error ? <div style={{ marginTop: 10, color: \"crimson\" }}>{error}</div> : null}\n </div>\n )\n}\n","\"use client\"\n\nimport React, { useMemo, useState } from \"react\"\nimport {\n PayPalCardFieldsProvider,\n PayPalNameField,\n PayPalNumberField,\n PayPalExpiryField,\n PayPalCVVField,\n usePayPalCardFields,\n} from \"@paypal/react-paypal-js\"\nimport { createPayPalStoreApi } from \"../client/paypal\"\nimport type { PayPalConfig } from \"../client/types\"\n\nfunction SubmitButton({ disabled, label }: { disabled: boolean; label: string }) {\n const { cardFieldsForm } = usePayPalCardFields()\n\n return (\n <button\n type=\"button\"\n disabled={disabled || !cardFieldsForm}\n onClick={() => cardFieldsForm?.submit()}\n style={{ padding: \"10px 12px\", borderRadius: 10, border: \"1px solid #ddd\" }}\n >\n {label}\n </button>\n )\n}\n\nexport function PayPalAdvancedCard(props: {\n baseUrl: string\n publishableApiKey?: string\n cartId: string\n config: PayPalConfig\n onPaid?: (result: any) => void\n onError?: (message: string) => void\n}) {\n const { baseUrl, publishableApiKey, cartId, config, onPaid, onError } = props\n const api = useMemo(\n () => createPayPalStoreApi({ baseUrl, publishableApiKey }),\n [baseUrl, publishableApiKey]\n )\n\n const [error, setError] = useState<string | null>(null)\n const [submitting, setSubmitting] = useState(false)\n\n if (!config.currency_supported) return null\n\n if (!config.client_token) {\n return (\n <div style={{ padding: 12, border: \"1px solid #ddd\", borderRadius: 10 }}>\n CardFields unavailable: missing client_token from backend.\n </div>\n )\n }\n\n return (\n <PayPalCardFieldsProvider\n createOrder={async () => {\n setError(null)\n const r = await api.createOrder(cartId)\n return r.id\n }}\n onApprove={async (data: any) => {\n try {\n setSubmitting(true)\n setError(null)\n const orderId = String(data?.orderID || \"\")\n const result = await api.captureOrder(cartId, orderId)\n onPaid?.(result)\n } catch (e: any) {\n const msg = e?.message || \"Card payment failed\"\n setError(msg)\n onError?.(msg)\n } finally {\n setSubmitting(false)\n }\n }}\n onError={(e: any) => {\n const msg = e?.message || \"CardFields error\"\n setError(msg)\n onError?.(msg)\n }}\n >\n <div style={{ display: \"grid\", gap: 10 }}>\n <PayPalNameField />\n <PayPalNumberField />\n <div style={{ display: \"grid\", gridTemplateColumns: \"1fr 1fr\", gap: 10 }}>\n <PayPalExpiryField />\n <PayPalCVVField />\n </div>\n\n <SubmitButton disabled={submitting} label={submitting ? \"Processing...\" : \"Pay by Card\"} />\n\n {error ? <div style={{ color: \"crimson\" }}>{error}</div> : null}\n </div>\n </PayPalCardFieldsProvider>\n )\n}\n","\"use client\"\n\nimport React from \"react\"\nimport type { PayPalConfig } from \"../client/types\"\nimport { usePayPalConfig } from \"../hooks/usePayPalConfig\"\nimport { PayPalProvider } from \"../components/PayPalProvider\"\nimport { PayPalCurrencyNotice } from \"../components/PayPalCurrencyNotice\"\nimport { PayPalSmartButtons } from \"../components/PayPalSmartButtons\"\nimport { PayPalAdvancedCard } from \"../components/PayPalAdvancedCard\"\n\nexport type MedusaNextPayPalAdapterProps = {\n cartId: string\n selectedProviderId: string | null | undefined\n baseUrl: string\n publishableApiKey?: string\n providerIds?: {\n paypal?: string\n paypalCard?: string\n }\n onPaid?: (result: any) => void\n}\n\nexport function MedusaNextPayPalAdapter(props: MedusaNextPayPalAdapterProps) {\n const { cartId, selectedProviderId, baseUrl, publishableApiKey, providerIds, onPaid } = props\n\n const paypalProviderId = providerIds?.paypal || \"paypal\"\n const paypalCardProviderId = providerIds?.paypalCard || \"paypal_card\"\n\n const shouldRender =\n selectedProviderId === paypalProviderId || selectedProviderId === paypalCardProviderId\n\n const { config, loading, error } = usePayPalConfig({ baseUrl, publishableApiKey, cartId })\n\n if (!shouldRender) return null\n if (loading) return <div>Loading PayPal…</div>\n if (error) return <div style={{ color: \"crimson\" }}>{error}</div>\n if (!config) return null\n\n return (\n <div style={{ display: \"grid\", gap: 12 }}>\n <PayPalCurrencyNotice config={config as PayPalConfig} />\n\n <PayPalProvider config={config as PayPalConfig} intent=\"capture\">\n {selectedProviderId === paypalCardProviderId ? (\n <PayPalAdvancedCard\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n cartId={cartId}\n config={config as PayPalConfig}\n onPaid={onPaid}\n />\n ) : (\n <PayPalSmartButtons\n baseUrl={baseUrl}\n publishableApiKey={publishableApiKey}\n cartId={cartId}\n config={config as PayPalConfig}\n onPaid={onPaid}\n />\n )}\n </PayPalProvider>\n </div>\n )\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@easypayment/medusa-paypal-ui",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "Enterprise Gold PayPal UI module for Medusa v2 storefront (Next.js)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.cjs"
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"next": ">=14",
|
|
26
|
+
"react": ">=18",
|
|
27
|
+
"react-dom": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@paypal/react-paypal-js": "^8.8.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@testing-library/jest-dom": "^6.5.0",
|
|
34
|
+
"@testing-library/react": "^16.0.0",
|
|
35
|
+
"@types/react": "^19.2.14",
|
|
36
|
+
"@types/react-dom": "^19.2.3",
|
|
37
|
+
"jsdom": "^24.0.0",
|
|
38
|
+
"tsup": "^8.0.0",
|
|
39
|
+
"typescript": "^5.0.0",
|
|
40
|
+
"vitest": "^2.0.5"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsup",
|
|
44
|
+
"dev": "tsup --watch",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"prepublishOnly": "npm run build"
|
|
48
|
+
}
|
|
49
|
+
}
|