payluk-escrow-inline-checkout 0.2.4 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -6
- package/dist/{chunk-D6ZMSUAT.js → chunk-5YI7ZPIC.js} +4 -3
- package/dist/chunk-5YI7ZPIC.js.map +1 -0
- package/dist/index.cjs +2 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/react/index.cjs +7 -4
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +6 -4
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-D6ZMSUAT.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Escrow Checkout JS/TS SDK
|
|
2
2
|
|
|
3
|
-
A lightweight client SDK that initializes your checkout configuration, creates a session
|
|
3
|
+
A lightweight client SDK that initializes your checkout configuration, creates a session, and launches the escrow checkout widget. Includes a React hook for easy integration in React apps.
|
|
4
4
|
|
|
5
5
|
- Zero manual script tags: the widget script is loaded automatically.
|
|
6
6
|
- Promise-based API.
|
|
@@ -29,10 +29,11 @@ async function onPayClick() {
|
|
|
29
29
|
try {
|
|
30
30
|
await pay({
|
|
31
31
|
paymentToken: '<PAYMENT_TOKEN>',
|
|
32
|
-
reference: '<
|
|
32
|
+
reference: '<REFERENCE_ID>',
|
|
33
33
|
redirectUrl: 'https://your-app.example.com/checkout/complete',
|
|
34
|
-
logoUrl: 'https://
|
|
34
|
+
logoUrl: 'https://mediacloud.me/media/W8HU9TK245QF528ZULCFSJXX2SBBLT.jpg', // optional
|
|
35
35
|
brand: 'YourBrand', // optional
|
|
36
|
+
customerId: 'YourBrand', // optional only for merchants using customer vaulting
|
|
36
37
|
callback: (result) => {
|
|
37
38
|
console.log('Checkout result:', result);
|
|
38
39
|
},
|
|
@@ -46,6 +47,71 @@ async function onPayClick() {
|
|
|
46
47
|
}
|
|
47
48
|
```
|
|
48
49
|
|
|
50
|
+
## Inline Usage
|
|
51
|
+
```html
|
|
52
|
+
<!DOCTYPE html>
|
|
53
|
+
<html lang="en">
|
|
54
|
+
|
|
55
|
+
<head>
|
|
56
|
+
<title>Checkout Demo</title>
|
|
57
|
+
</head>
|
|
58
|
+
|
|
59
|
+
<body>
|
|
60
|
+
<h1>Checkout Demo</h1>
|
|
61
|
+
<!-- HTML -->
|
|
62
|
+
<script src="https://checkout.payluk.ng/escrow-checkout.min.js"></script>
|
|
63
|
+
<button id="pay">Pay via Wallet(Business) or Debit Card (Merchant)</button>
|
|
64
|
+
<script>
|
|
65
|
+
const PUBLISHABLE_KEY = 'pk_live_f1yCEbpo980rDMWUAMH0Ho0NC7gzkqSr'; // Public Key
|
|
66
|
+
let navigated = false;
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
async function openEscrowCheckout() {
|
|
70
|
+
const baseUrl = window.EscrowCheckout.baseUrl
|
|
71
|
+
const resp = await fetch(`${baseUrl}/v1/checkout/session`, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: { 'Content-Type': 'application/json' },
|
|
74
|
+
body: JSON.stringify({
|
|
75
|
+
paymentToken: 'PY_vevIhjtQ3000',
|
|
76
|
+
reference: "Reference",
|
|
77
|
+
publicKey: PUBLISHABLE_KEY,
|
|
78
|
+
redirectUrl: 'http://localhost:63342/payluk-inlinejs/thank-you.html',
|
|
79
|
+
customerId: '6933b6353e4615c1cabdd1d9' // Optional: For merchant business only
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
82
|
+
if (!resp.ok) {
|
|
83
|
+
const err = await resp.json().catch(() => ({}));
|
|
84
|
+
return alert(err.message || 'Failed to create session');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const { session } = await resp.json();
|
|
88
|
+
|
|
89
|
+
// Initialize the widget
|
|
90
|
+
EscrowCheckout({
|
|
91
|
+
session,
|
|
92
|
+
logoUrl: "https://mediacloud.me/media/W8HU9TK245QF528ZULCFSJXX2SBBLT.jpg",
|
|
93
|
+
brand: "Business Name",
|
|
94
|
+
publicKey: PUBLISHABLE_KEY,
|
|
95
|
+
customerId: '6933b6353e4615c1cabdd1d9' // Optional: For merchant business only
|
|
96
|
+
callback: ({ paymentId }) => {
|
|
97
|
+
console.log('Payment token received', paymentId);
|
|
98
|
+
navigated = true;
|
|
99
|
+
const url = `/payluk-inlinejs/thank-you.html?paymentId=${encodeURIComponent(paymentId)}`;
|
|
100
|
+
window.location.replace(url);
|
|
101
|
+
},
|
|
102
|
+
onClose: function () {
|
|
103
|
+
console.log('Checkout closed');
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
document.getElementById('pay').addEventListener('click', openEscrowCheckout);
|
|
109
|
+
</script>
|
|
110
|
+
</body>
|
|
111
|
+
|
|
112
|
+
</html>
|
|
113
|
+
```
|
|
114
|
+
|
|
49
115
|
## React Usage
|
|
50
116
|
|
|
51
117
|
```tsx
|
|
@@ -85,11 +151,12 @@ export function CheckoutButton() {
|
|
|
85
151
|
try {
|
|
86
152
|
await pay({
|
|
87
153
|
paymentToken: '<PAYMENT_TOKEN>',
|
|
88
|
-
reference: '<
|
|
154
|
+
reference: '<REFERENCE_ID>',
|
|
89
155
|
redirectUrl: 'https://your-app.example.com/checkout/complete',
|
|
90
|
-
logoUrl: 'https://
|
|
156
|
+
logoUrl: 'https://mediacloud.me/media/W8HU9TK245QF528ZULCFSJXX2SBBLT.jpg',
|
|
91
157
|
brand: 'YourBrand',
|
|
92
158
|
extra: { theme: 'light' },
|
|
159
|
+
customerId: 'YourBrand', // optional only for merchants using customer vaulting
|
|
93
160
|
callback: (result) => console.log(result)
|
|
94
161
|
});
|
|
95
162
|
} catch {
|
|
@@ -146,6 +213,7 @@ Creates a checkout session via your backend and opens the widget.
|
|
|
146
213
|
|
|
147
214
|
**Optional:**
|
|
148
215
|
- `logoUrl?`: `string`
|
|
216
|
+
- `customerId?`: `string` — only for merchants using customer vaulting
|
|
149
217
|
- `brand?`: `string`
|
|
150
218
|
- `callback?`: `(result: unknown) => void`
|
|
151
219
|
- `onClose?`: `() => void`
|
|
@@ -208,4 +276,4 @@ This package ships with TypeScript types. No additional type packages are requir
|
|
|
208
276
|
|
|
209
277
|
## License
|
|
210
278
|
|
|
211
|
-
MIT (or your chosen license)
|
|
279
|
+
MIT (or your chosen license)
|
|
@@ -50,7 +50,7 @@ async function loadWidget() {
|
|
|
50
50
|
async function createSession(input) {
|
|
51
51
|
assertConfigured(CONFIG);
|
|
52
52
|
const { publicKey } = CONFIG;
|
|
53
|
-
const apiBaseUrl = "https://live.payluk.ng";
|
|
53
|
+
const apiBaseUrl = publicKey.startsWith("pk_live_") ? "https://live.payluk.ng" : "https://staging.live.payluk.ng";
|
|
54
54
|
const resp = await fetch(`${apiBaseUrl}/v1/checkout/session`, {
|
|
55
55
|
method: "POST",
|
|
56
56
|
headers: { "Content-Type": "application/json" },
|
|
@@ -78,10 +78,11 @@ async function pay(input) {
|
|
|
78
78
|
brand: input.brand,
|
|
79
79
|
callback: input.callback,
|
|
80
80
|
onClose: input.onClose,
|
|
81
|
+
customerId: input.customerId,
|
|
81
82
|
...input.extra ?? {}
|
|
82
83
|
});
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
export { initEscrowCheckout, pay };
|
|
86
|
-
//# sourceMappingURL=chunk-
|
|
87
|
-
//# sourceMappingURL=chunk-
|
|
87
|
+
//# sourceMappingURL=chunk-5YI7ZPIC.js.map
|
|
88
|
+
//# sourceMappingURL=chunk-5YI7ZPIC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"chunk-5YI7ZPIC.js","sourcesContent":["export type EscrowWidget = (options: Record<string, unknown>) => void;\r\n\r\nexport interface InitConfig {\r\n publicKey: string; // publishable key only\r\n /**\r\n * Optional overrides for experts. End users don't need to set these.\r\n */\r\n scriptUrlOverride?: string;\r\n globalName?: string; // default 'EscrowCheckout'\r\n crossOrigin?: '' | 'anonymous' | 'use-credentials';\r\n}\r\n\r\nexport interface PayInput {\r\n paymentToken: string;\r\n reference: string;\r\n redirectUrl: string;\r\n logoUrl?: string;\r\n brand?: string;\r\n customerId?: string;\r\n /**\r\n * Extra fields supported by the widget.\r\n */\r\n extra?: Record<string, unknown>;\r\n callback?: (result: any) => void;\r\n onClose?: () => void;\r\n}\r\n\r\nexport interface SessionResponse {\r\n session: unknown;\r\n}\r\n\r\nconst DEFAULT_SCRIPT_URL = 'https://checkout.payluk.ng/escrow-checkout.min.js';\r\nconst DEFAULT_GLOBAL_NAME = 'EscrowCheckout';\r\n\r\ntype ResolvedConfig = Required<Pick<InitConfig, 'publicKey'>> & {\r\n scriptUrl: string;\r\n globalName: string;\r\n crossOrigin: '' | 'anonymous' | 'use-credentials';\r\n};\r\n\r\nlet CONFIG: ResolvedConfig | null = null;\r\n\r\n/**\r\n * Initialize the library once (e.g., in app bootstrap).\r\n * Hides script URL and session creation from consumers.\r\n */\r\nexport function initEscrowCheckout(config: InitConfig): void {\r\n if (!config?.publicKey) throw new Error('initEscrowCheckout: \"publicKey\" is required.');\r\n CONFIG = {\r\n publicKey: config.publicKey,\r\n scriptUrl: config.scriptUrlOverride || DEFAULT_SCRIPT_URL,\r\n globalName: config.globalName || DEFAULT_GLOBAL_NAME,\r\n crossOrigin: config.crossOrigin ?? 'anonymous'\r\n };\r\n}\r\n\r\n/**\r\n * Narrow a provided config to ResolvedConfig or throw if not initialized.\r\n */\r\nfunction assertConfigured(config: ResolvedConfig | null): asserts config is ResolvedConfig {\r\n if (!config) {\r\n throw new Error('Escrow checkout not initialized. Call initEscrowCheckout({ apiBaseUrl, publicKey }) first.');\r\n }\r\n}\r\n\r\n/**\r\n * Internal: load the widget script once and return the global function.\r\n */\r\nasync function loadWidget(): Promise<EscrowWidget> {\r\n assertConfigured(CONFIG);\r\n const { scriptUrl, globalName, crossOrigin } = CONFIG;\r\n\r\n if (typeof window === 'undefined') {\r\n throw new Error('EscrowCheckout can only be loaded in the browser.');\r\n }\r\n\r\n const win = window as any;\r\n win.__escrowCheckoutLoader ??= {};\r\n\r\n if (win.__escrowCheckoutLoader[scriptUrl]) {\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n }\r\n\r\n if (typeof win[globalName] === 'function') {\r\n const fn = win[globalName] as EscrowWidget;\r\n win.__escrowCheckoutLoader[scriptUrl] = Promise.resolve(fn);\r\n return fn;\r\n }\r\n\r\n win.__escrowCheckoutLoader[scriptUrl] = new Promise<EscrowWidget>((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = scriptUrl;\r\n script.async = true;\r\n if (crossOrigin) script.crossOrigin = crossOrigin;\r\n\r\n script.onload = () => {\r\n const fn = win[globalName];\r\n if (typeof fn === 'function') resolve(fn as EscrowWidget);\r\n else reject(new Error(`Escrow checkout script loaded, but window.${globalName} is not a function.`));\r\n };\r\n\r\n script.onerror = () => reject(new Error(`Failed to load escrow checkout script: ${scriptUrl}`));\r\n\r\n document.head.appendChild(script);\r\n });\r\n\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n}\r\n\r\n/**\r\n * Internal: create a checkout session by calling your API.\r\n * This is intentionally inside the lib (user doesn't implement it).\r\n */\r\nasync function createSession(input: PayInput): Promise<SessionResponse> {\r\n assertConfigured(CONFIG);\r\n const { publicKey } = CONFIG;\r\n const apiBaseUrl = publicKey.startsWith(\"pk_live_\") ? 'https://live.payluk.ng' : 'https://staging.live.payluk.ng';\r\n\r\n const resp = await fetch(`${apiBaseUrl}/v1/checkout/session`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n paymentToken: input.paymentToken,\r\n redirectUrl: input.redirectUrl,\r\n reference: input.reference,\r\n publicKey\r\n })\r\n });\r\n\r\n if (!resp.ok) {\r\n const err = await resp.json().catch(() => ({}));\r\n throw new Error(err.message || 'Failed to create session');\r\n }\r\n\r\n return (await resp.json()) as SessionResponse;\r\n}\r\n\r\n/**\r\n * Public API: create the session and open the widget.\r\n * Consumers only supply business inputs (no script URL, no API calls).\r\n */\r\nexport async function pay(input: PayInput): Promise<void> {\r\n if (typeof window === 'undefined') {\r\n throw new Error('pay(...) can only run in the browser.');\r\n }\r\n\r\n const [{ session }, widget] = await Promise.all([createSession(input), loadWidget()]);\r\n\r\n widget({\r\n session,\r\n logoUrl: input.logoUrl,\r\n brand: input.brand,\r\n callback: input.callback,\r\n onClose: input.onClose,\r\n customerId: input.customerId,\r\n ...(input.extra ?? {})\r\n });\r\n}"]}
|
package/dist/index.cjs
CHANGED
|
@@ -52,7 +52,7 @@ async function loadWidget() {
|
|
|
52
52
|
async function createSession(input) {
|
|
53
53
|
assertConfigured(CONFIG);
|
|
54
54
|
const { publicKey } = CONFIG;
|
|
55
|
-
const apiBaseUrl = "https://live.payluk.ng";
|
|
55
|
+
const apiBaseUrl = publicKey.startsWith("pk_live_") ? "https://live.payluk.ng" : "https://staging.live.payluk.ng";
|
|
56
56
|
const resp = await fetch(`${apiBaseUrl}/v1/checkout/session`, {
|
|
57
57
|
method: "POST",
|
|
58
58
|
headers: { "Content-Type": "application/json" },
|
|
@@ -80,6 +80,7 @@ async function pay(input) {
|
|
|
80
80
|
brand: input.brand,
|
|
81
81
|
callback: input.callback,
|
|
82
82
|
onClose: input.onClose,
|
|
83
|
+
customerId: input.customerId,
|
|
83
84
|
...input.extra ?? {}
|
|
84
85
|
});
|
|
85
86
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export type EscrowWidget = (options: Record<string, unknown>) => void;\r\n\r\nexport interface InitConfig {\r\n publicKey: string; // publishable key only\r\n /**\r\n * Optional overrides for experts. End users don't need to set these.\r\n */\r\n scriptUrlOverride?: string;\r\n globalName?: string; // default 'EscrowCheckout'\r\n crossOrigin?: '' | 'anonymous' | 'use-credentials';\r\n}\r\n\r\nexport interface PayInput {\r\n paymentToken: string;\r\n reference: string;\r\n redirectUrl: string;\r\n logoUrl?: string;\r\n brand?: string;\r\n customerId?: string;\r\n /**\r\n * Extra fields supported by the widget.\r\n */\r\n extra?: Record<string, unknown>;\r\n callback?: (result: any) => void;\r\n onClose?: () => void;\r\n}\r\n\r\nexport interface SessionResponse {\r\n session: unknown;\r\n}\r\n\r\nconst DEFAULT_SCRIPT_URL = 'https://checkout.payluk.ng/escrow-checkout.min.js';\r\nconst DEFAULT_GLOBAL_NAME = 'EscrowCheckout';\r\n\r\ntype ResolvedConfig = Required<Pick<InitConfig, 'publicKey'>> & {\r\n scriptUrl: string;\r\n globalName: string;\r\n crossOrigin: '' | 'anonymous' | 'use-credentials';\r\n};\r\n\r\nlet CONFIG: ResolvedConfig | null = null;\r\n\r\n/**\r\n * Initialize the library once (e.g., in app bootstrap).\r\n * Hides script URL and session creation from consumers.\r\n */\r\nexport function initEscrowCheckout(config: InitConfig): void {\r\n if (!config?.publicKey) throw new Error('initEscrowCheckout: \"publicKey\" is required.');\r\n CONFIG = {\r\n publicKey: config.publicKey,\r\n scriptUrl: config.scriptUrlOverride || DEFAULT_SCRIPT_URL,\r\n globalName: config.globalName || DEFAULT_GLOBAL_NAME,\r\n crossOrigin: config.crossOrigin ?? 'anonymous'\r\n };\r\n}\r\n\r\n/**\r\n * Narrow a provided config to ResolvedConfig or throw if not initialized.\r\n */\r\nfunction assertConfigured(config: ResolvedConfig | null): asserts config is ResolvedConfig {\r\n if (!config) {\r\n throw new Error('Escrow checkout not initialized. Call initEscrowCheckout({ apiBaseUrl, publicKey }) first.');\r\n }\r\n}\r\n\r\n/**\r\n * Internal: load the widget script once and return the global function.\r\n */\r\nasync function loadWidget(): Promise<EscrowWidget> {\r\n assertConfigured(CONFIG);\r\n const { scriptUrl, globalName, crossOrigin } = CONFIG;\r\n\r\n if (typeof window === 'undefined') {\r\n throw new Error('EscrowCheckout can only be loaded in the browser.');\r\n }\r\n\r\n const win = window as any;\r\n win.__escrowCheckoutLoader ??= {};\r\n\r\n if (win.__escrowCheckoutLoader[scriptUrl]) {\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n }\r\n\r\n if (typeof win[globalName] === 'function') {\r\n const fn = win[globalName] as EscrowWidget;\r\n win.__escrowCheckoutLoader[scriptUrl] = Promise.resolve(fn);\r\n return fn;\r\n }\r\n\r\n win.__escrowCheckoutLoader[scriptUrl] = new Promise<EscrowWidget>((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = scriptUrl;\r\n script.async = true;\r\n if (crossOrigin) script.crossOrigin = crossOrigin;\r\n\r\n script.onload = () => {\r\n const fn = win[globalName];\r\n if (typeof fn === 'function') resolve(fn as EscrowWidget);\r\n else reject(new Error(`Escrow checkout script loaded, but window.${globalName} is not a function.`));\r\n };\r\n\r\n script.onerror = () => reject(new Error(`Failed to load escrow checkout script: ${scriptUrl}`));\r\n\r\n document.head.appendChild(script);\r\n });\r\n\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n}\r\n\r\n/**\r\n * Internal: create a checkout session by calling your API.\r\n * This is intentionally inside the lib (user doesn't implement it).\r\n */\r\nasync function createSession(input: PayInput): Promise<SessionResponse> {\r\n assertConfigured(CONFIG);\r\n const { publicKey } = CONFIG;\r\n const apiBaseUrl = publicKey.startsWith(\"pk_live_\") ? 'https://live.payluk.ng' : 'https://staging.live.payluk.ng';\r\n\r\n const resp = await fetch(`${apiBaseUrl}/v1/checkout/session`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n paymentToken: input.paymentToken,\r\n redirectUrl: input.redirectUrl,\r\n reference: input.reference,\r\n publicKey\r\n })\r\n });\r\n\r\n if (!resp.ok) {\r\n const err = await resp.json().catch(() => ({}));\r\n throw new Error(err.message || 'Failed to create session');\r\n }\r\n\r\n return (await resp.json()) as SessionResponse;\r\n}\r\n\r\n/**\r\n * Public API: create the session and open the widget.\r\n * Consumers only supply business inputs (no script URL, no API calls).\r\n */\r\nexport async function pay(input: PayInput): Promise<void> {\r\n if (typeof window === 'undefined') {\r\n throw new Error('pay(...) can only run in the browser.');\r\n }\r\n\r\n const [{ session }, widget] = await Promise.all([createSession(input), loadWidget()]);\r\n\r\n widget({\r\n session,\r\n logoUrl: input.logoUrl,\r\n brand: input.brand,\r\n callback: input.callback,\r\n onClose: input.onClose,\r\n customerId: input.customerId,\r\n ...(input.extra ?? {})\r\n });\r\n}"]}
|
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/react/index.cjs
CHANGED
|
@@ -46,7 +46,7 @@ async function loadWidget() {
|
|
|
46
46
|
async function createSession(input) {
|
|
47
47
|
assertConfigured();
|
|
48
48
|
const { publicKey } = CONFIG;
|
|
49
|
-
const apiBaseUrl = "https://live.payluk.ng";
|
|
49
|
+
const apiBaseUrl = publicKey.startsWith("pk_live_") ? "https://live.payluk.ng" : "https://staging.live.payluk.ng";
|
|
50
50
|
const resp = await fetch(`${apiBaseUrl}/v1/checkout/session`, {
|
|
51
51
|
method: "POST",
|
|
52
52
|
headers: { "Content-Type": "application/json" },
|
|
@@ -74,6 +74,7 @@ async function pay(input) {
|
|
|
74
74
|
brand: input.brand,
|
|
75
75
|
callback: input.callback,
|
|
76
76
|
onClose: input.onClose,
|
|
77
|
+
customerId: input.customerId,
|
|
77
78
|
...input.extra ?? {}
|
|
78
79
|
});
|
|
79
80
|
}
|
|
@@ -115,7 +116,8 @@ function EscrowCheckoutButton({
|
|
|
115
116
|
children = "Pay",
|
|
116
117
|
disabled,
|
|
117
118
|
className,
|
|
118
|
-
title
|
|
119
|
+
title,
|
|
120
|
+
customerId
|
|
119
121
|
}) {
|
|
120
122
|
const { ready, loading, error, pay: pay2 } = useEscrowCheckout();
|
|
121
123
|
const handleClick = react.useCallback(async () => {
|
|
@@ -127,9 +129,10 @@ function EscrowCheckoutButton({
|
|
|
127
129
|
logoUrl,
|
|
128
130
|
callback,
|
|
129
131
|
onClose,
|
|
130
|
-
extra
|
|
132
|
+
extra,
|
|
133
|
+
customerId
|
|
131
134
|
});
|
|
132
|
-
}, [pay2, paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra]);
|
|
135
|
+
}, [pay2, paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra, customerId]);
|
|
133
136
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
134
137
|
"button",
|
|
135
138
|
{
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.ts","../../src/react/useEscrowCheckout.ts","../../src/react/EscrowCheckoutButton.tsx"],"names":["useState","pay","useCallback","useEffect","useMemo","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["export type EscrowWidget = (options: Record<string, unknown>) => void;\r\n\r\nexport interface InitConfig {\r\n publicKey: string; // publishable key only\r\n /**\r\n * Optional overrides for experts. End users don't need to set these.\r\n */\r\n scriptUrlOverride?: string;\r\n globalName?: string; // default 'EscrowCheckout'\r\n crossOrigin?: '' | 'anonymous' | 'use-credentials';\r\n}\r\n\r\nexport interface PayInput {\r\n paymentToken: string;\r\n reference: string;\r\n redirectUrl: string;\r\n logoUrl?: string;\r\n brand?: string;\r\n /**\r\n * Extra fields supported by the widget.\r\n */\r\n extra?: Record<string, unknown>;\r\n callback?: (result: any) => void;\r\n onClose?: () => void;\r\n}\r\n\r\nexport interface SessionResponse {\r\n session: unknown;\r\n}\r\n\r\nconst DEFAULT_SCRIPT_URL = 'https://checkout.payluk.ng/escrow-checkout.min.js';\r\nconst DEFAULT_GLOBAL_NAME = 'EscrowCheckout';\r\n\r\ntype ResolvedConfig = Required<Pick<InitConfig, 'publicKey'>> & {\r\n scriptUrl: string;\r\n globalName: string;\r\n crossOrigin: '' | 'anonymous' | 'use-credentials';\r\n};\r\n\r\nlet CONFIG: ResolvedConfig | null = null;\r\n\r\n/**\r\n * Initialize the library once (e.g., in app bootstrap).\r\n * Hides script URL and session creation from consumers.\r\n */\r\nexport function initEscrowCheckout(config: InitConfig): void {\r\n if (!config?.publicKey) throw new Error('initEscrowCheckout: \"publicKey\" is required.');\r\n CONFIG = {\r\n publicKey: config.publicKey,\r\n scriptUrl: config.scriptUrlOverride || DEFAULT_SCRIPT_URL,\r\n globalName: config.globalName || DEFAULT_GLOBAL_NAME,\r\n crossOrigin: config.crossOrigin ?? 'anonymous'\r\n };\r\n}\r\n\r\n/**\r\n * Narrow a provided config to ResolvedConfig or throw if not initialized.\r\n */\r\nfunction assertConfigured(config: ResolvedConfig | null): asserts config is ResolvedConfig {\r\n if (!config) {\r\n throw new Error('Escrow checkout not initialized. Call initEscrowCheckout({ apiBaseUrl, publicKey }) first.');\r\n }\r\n}\r\n\r\n/**\r\n * Internal: load the widget script once and return the global function.\r\n */\r\nasync function loadWidget(): Promise<EscrowWidget> {\r\n assertConfigured(CONFIG);\r\n const { scriptUrl, globalName, crossOrigin } = CONFIG;\r\n\r\n if (typeof window === 'undefined') {\r\n throw new Error('EscrowCheckout can only be loaded in the browser.');\r\n }\r\n\r\n const win = window as any;\r\n win.__escrowCheckoutLoader ??= {};\r\n\r\n if (win.__escrowCheckoutLoader[scriptUrl]) {\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n }\r\n\r\n if (typeof win[globalName] === 'function') {\r\n const fn = win[globalName] as EscrowWidget;\r\n win.__escrowCheckoutLoader[scriptUrl] = Promise.resolve(fn);\r\n return fn;\r\n }\r\n\r\n win.__escrowCheckoutLoader[scriptUrl] = new Promise<EscrowWidget>((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = scriptUrl;\r\n script.async = true;\r\n if (crossOrigin) script.crossOrigin = crossOrigin;\r\n\r\n script.onload = () => {\r\n const fn = win[globalName];\r\n if (typeof fn === 'function') resolve(fn as EscrowWidget);\r\n else reject(new Error(`Escrow checkout script loaded, but window.${globalName} is not a function.`));\r\n };\r\n\r\n script.onerror = () => reject(new Error(`Failed to load escrow checkout script: ${scriptUrl}`));\r\n\r\n document.head.appendChild(script);\r\n });\r\n\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n}\r\n\r\n/**\r\n * Internal: create a checkout session by calling your API.\r\n * This is intentionally inside the lib (user doesn't implement it).\r\n */\r\nasync function createSession(input: PayInput): Promise<SessionResponse> {\r\n assertConfigured(CONFIG);\r\n const { publicKey } = CONFIG;\r\n const apiBaseUrl = 'https://live.payluk.ng';\r\n\r\n const resp = await fetch(`${apiBaseUrl}/v1/checkout/session`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n paymentToken: input.paymentToken,\r\n redirectUrl: input.redirectUrl,\r\n reference: input.reference,\r\n publicKey\r\n })\r\n });\r\n\r\n if (!resp.ok) {\r\n const err = await resp.json().catch(() => ({}));\r\n throw new Error(err.message || 'Failed to create session');\r\n }\r\n\r\n return (await resp.json()) as SessionResponse;\r\n}\r\n\r\n/**\r\n * Public API: create the session and open the widget.\r\n * Consumers only supply business inputs (no script URL, no API calls).\r\n */\r\nexport async function pay(input: PayInput): Promise<void> {\r\n if (typeof window === 'undefined') {\r\n throw new Error('pay(...) can only run in the browser.');\r\n }\r\n\r\n const [{ session }, widget] = await Promise.all([createSession(input), loadWidget()]);\r\n\r\n widget({\r\n session,\r\n logoUrl: input.logoUrl,\r\n brand: input.brand,\r\n callback: input.callback,\r\n onClose: input.onClose,\r\n ...(input.extra ?? {})\r\n });\r\n}","import { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { pay as corePay } from '../index';\r\n\r\nexport interface UseEscrowCheckoutResult {\r\n ready: boolean;\r\n loading: boolean;\r\n error: Error | null;\r\n pay: typeof corePay;\r\n}\r\n\r\n/**\r\n * React hook that preloads the widget script (implicitly via pay) and exposes pay(...)\r\n * Since the library abstracts script loading and session creation, the hook is thin.\r\n */\r\nexport function useEscrowCheckout(): UseEscrowCheckoutResult {\r\n const [ready, setReady] = useState(false);\r\n const [loading, setLoading] = useState<boolean>(() => typeof window !== 'undefined');\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n // Lazy mark \"ready\" after first successful pay or script load attempt.\r\n // If you want to preload the script earlier, you may trigger a no-op pay with a dry-run endpoint on your side.\r\n\r\n // Provide a stable pay function that reports loading state.\r\n const pay = useCallback<typeof corePay>(async (input) => {\r\n setLoading(true);\r\n try {\r\n await corePay(input);\r\n setReady(true);\r\n setError(null);\r\n } catch (e) {\r\n setError(e as Error);\r\n throw e;\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n // In SSR, mark not loading\r\n useEffect(() => {\r\n if (typeof window === 'undefined') {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n return useMemo(() => ({ ready, loading, error, pay }), [ready, loading, error, pay]);\r\n}","import React, { useCallback } from 'react';\r\nimport { useEscrowCheckout } from './useEscrowCheckout';\r\n\r\nexport interface EscrowCheckoutButtonProps {\r\n paymentToken: string;\r\n reference: string;\r\n redirectUrl: string;\r\n children?: React.ReactNode;\r\n disabled?: boolean;\r\n className?: string;\r\n title?: string;\r\n\r\n brand?: string;\r\n logoUrl?: string;\r\n callback?: (result: any) => void;\r\n onClose?: () => void;\r\n extra?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Button that triggers pay(...) with your provided inputs.\r\n * The library handles both session creation and widget loading.\r\n */\r\nexport function EscrowCheckoutButton({\r\n paymentToken,\r\n reference,\r\n redirectUrl,\r\n brand,\r\n logoUrl,\r\n callback,\r\n onClose,\r\n extra,\r\n children = 'Pay',\r\n disabled,\r\n className,\r\n title\r\n }: EscrowCheckoutButtonProps) {\r\n const { ready, loading, error, pay } = useEscrowCheckout();\r\n\r\n const handleClick = useCallback(async () => {\r\n await pay({\r\n paymentToken,\r\n reference,\r\n redirectUrl,\r\n brand,\r\n logoUrl,\r\n callback,\r\n onClose,\r\n extra\r\n });\r\n }, [pay, paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra]);\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleClick}\r\n disabled={disabled || loading || !ready /* ready becomes true after first successful load */}\r\n className={className}\r\n aria-disabled={disabled || loading || !ready}\r\n title={title ?? (error ? error.message : undefined)}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.ts","../../src/react/useEscrowCheckout.ts","../../src/react/EscrowCheckoutButton.tsx"],"names":["useState","pay","useCallback","useEffect","useMemo","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["export type EscrowWidget = (options: Record<string, unknown>) => void;\r\n\r\nexport interface InitConfig {\r\n publicKey: string; // publishable key only\r\n /**\r\n * Optional overrides for experts. End users don't need to set these.\r\n */\r\n scriptUrlOverride?: string;\r\n globalName?: string; // default 'EscrowCheckout'\r\n crossOrigin?: '' | 'anonymous' | 'use-credentials';\r\n}\r\n\r\nexport interface PayInput {\r\n paymentToken: string;\r\n reference: string;\r\n redirectUrl: string;\r\n logoUrl?: string;\r\n brand?: string;\r\n customerId?: string;\r\n /**\r\n * Extra fields supported by the widget.\r\n */\r\n extra?: Record<string, unknown>;\r\n callback?: (result: any) => void;\r\n onClose?: () => void;\r\n}\r\n\r\nexport interface SessionResponse {\r\n session: unknown;\r\n}\r\n\r\nconst DEFAULT_SCRIPT_URL = 'https://checkout.payluk.ng/escrow-checkout.min.js';\r\nconst DEFAULT_GLOBAL_NAME = 'EscrowCheckout';\r\n\r\ntype ResolvedConfig = Required<Pick<InitConfig, 'publicKey'>> & {\r\n scriptUrl: string;\r\n globalName: string;\r\n crossOrigin: '' | 'anonymous' | 'use-credentials';\r\n};\r\n\r\nlet CONFIG: ResolvedConfig | null = null;\r\n\r\n/**\r\n * Initialize the library once (e.g., in app bootstrap).\r\n * Hides script URL and session creation from consumers.\r\n */\r\nexport function initEscrowCheckout(config: InitConfig): void {\r\n if (!config?.publicKey) throw new Error('initEscrowCheckout: \"publicKey\" is required.');\r\n CONFIG = {\r\n publicKey: config.publicKey,\r\n scriptUrl: config.scriptUrlOverride || DEFAULT_SCRIPT_URL,\r\n globalName: config.globalName || DEFAULT_GLOBAL_NAME,\r\n crossOrigin: config.crossOrigin ?? 'anonymous'\r\n };\r\n}\r\n\r\n/**\r\n * Narrow a provided config to ResolvedConfig or throw if not initialized.\r\n */\r\nfunction assertConfigured(config: ResolvedConfig | null): asserts config is ResolvedConfig {\r\n if (!config) {\r\n throw new Error('Escrow checkout not initialized. Call initEscrowCheckout({ apiBaseUrl, publicKey }) first.');\r\n }\r\n}\r\n\r\n/**\r\n * Internal: load the widget script once and return the global function.\r\n */\r\nasync function loadWidget(): Promise<EscrowWidget> {\r\n assertConfigured(CONFIG);\r\n const { scriptUrl, globalName, crossOrigin } = CONFIG;\r\n\r\n if (typeof window === 'undefined') {\r\n throw new Error('EscrowCheckout can only be loaded in the browser.');\r\n }\r\n\r\n const win = window as any;\r\n win.__escrowCheckoutLoader ??= {};\r\n\r\n if (win.__escrowCheckoutLoader[scriptUrl]) {\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n }\r\n\r\n if (typeof win[globalName] === 'function') {\r\n const fn = win[globalName] as EscrowWidget;\r\n win.__escrowCheckoutLoader[scriptUrl] = Promise.resolve(fn);\r\n return fn;\r\n }\r\n\r\n win.__escrowCheckoutLoader[scriptUrl] = new Promise<EscrowWidget>((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = scriptUrl;\r\n script.async = true;\r\n if (crossOrigin) script.crossOrigin = crossOrigin;\r\n\r\n script.onload = () => {\r\n const fn = win[globalName];\r\n if (typeof fn === 'function') resolve(fn as EscrowWidget);\r\n else reject(new Error(`Escrow checkout script loaded, but window.${globalName} is not a function.`));\r\n };\r\n\r\n script.onerror = () => reject(new Error(`Failed to load escrow checkout script: ${scriptUrl}`));\r\n\r\n document.head.appendChild(script);\r\n });\r\n\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n}\r\n\r\n/**\r\n * Internal: create a checkout session by calling your API.\r\n * This is intentionally inside the lib (user doesn't implement it).\r\n */\r\nasync function createSession(input: PayInput): Promise<SessionResponse> {\r\n assertConfigured(CONFIG);\r\n const { publicKey } = CONFIG;\r\n const apiBaseUrl = publicKey.startsWith(\"pk_live_\") ? 'https://live.payluk.ng' : 'https://staging.live.payluk.ng';\r\n\r\n const resp = await fetch(`${apiBaseUrl}/v1/checkout/session`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n paymentToken: input.paymentToken,\r\n redirectUrl: input.redirectUrl,\r\n reference: input.reference,\r\n publicKey\r\n })\r\n });\r\n\r\n if (!resp.ok) {\r\n const err = await resp.json().catch(() => ({}));\r\n throw new Error(err.message || 'Failed to create session');\r\n }\r\n\r\n return (await resp.json()) as SessionResponse;\r\n}\r\n\r\n/**\r\n * Public API: create the session and open the widget.\r\n * Consumers only supply business inputs (no script URL, no API calls).\r\n */\r\nexport async function pay(input: PayInput): Promise<void> {\r\n if (typeof window === 'undefined') {\r\n throw new Error('pay(...) can only run in the browser.');\r\n }\r\n\r\n const [{ session }, widget] = await Promise.all([createSession(input), loadWidget()]);\r\n\r\n widget({\r\n session,\r\n logoUrl: input.logoUrl,\r\n brand: input.brand,\r\n callback: input.callback,\r\n onClose: input.onClose,\r\n customerId: input.customerId,\r\n ...(input.extra ?? {})\r\n });\r\n}","import { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { pay as corePay } from '../index';\r\n\r\nexport interface UseEscrowCheckoutResult {\r\n ready: boolean;\r\n loading: boolean;\r\n error: Error | null;\r\n pay: typeof corePay;\r\n}\r\n\r\n/**\r\n * React hook that preloads the widget script (implicitly via pay) and exposes pay(...)\r\n * Since the library abstracts script loading and session creation, the hook is thin.\r\n */\r\nexport function useEscrowCheckout(): UseEscrowCheckoutResult {\r\n const [ready, setReady] = useState(false);\r\n const [loading, setLoading] = useState<boolean>(() => typeof window !== 'undefined');\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n // Lazy mark \"ready\" after first successful pay or script load attempt.\r\n // If you want to preload the script earlier, you may trigger a no-op pay with a dry-run endpoint on your side.\r\n\r\n // Provide a stable pay function that reports loading state.\r\n const pay = useCallback<typeof corePay>(async (input) => {\r\n setLoading(true);\r\n try {\r\n await corePay(input);\r\n setReady(true);\r\n setError(null);\r\n } catch (e) {\r\n setError(e as Error);\r\n throw e;\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n // In SSR, mark not loading\r\n useEffect(() => {\r\n if (typeof window === 'undefined') {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n return useMemo(() => ({ ready, loading, error, pay }), [ready, loading, error, pay]);\r\n}","import React, { useCallback } from 'react';\r\nimport { useEscrowCheckout } from './useEscrowCheckout';\r\n\r\nexport interface EscrowCheckoutButtonProps {\r\n paymentToken: string;\r\n reference: string;\r\n redirectUrl: string;\r\n children?: React.ReactNode;\r\n disabled?: boolean;\r\n className?: string;\r\n title?: string;\r\n\r\n brand?: string;\r\n customerId?: string;\r\n logoUrl?: string;\r\n callback?: (result: any) => void;\r\n onClose?: () => void;\r\n extra?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Button that triggers pay(...) with your provided inputs.\r\n * The library handles both session creation and widget loading.\r\n */\r\nexport function EscrowCheckoutButton({\r\n paymentToken,\r\n reference,\r\n redirectUrl,\r\n brand,\r\n logoUrl,\r\n callback,\r\n onClose,\r\n extra,\r\n children = 'Pay',\r\n disabled,\r\n className,\r\n title,\r\n customerId\r\n }: EscrowCheckoutButtonProps) {\r\n const { ready, loading, error, pay } = useEscrowCheckout();\r\n\r\n const handleClick = useCallback(async () => {\r\n await pay({\r\n paymentToken,\r\n reference,\r\n redirectUrl,\r\n brand,\r\n logoUrl,\r\n callback,\r\n onClose,\r\n extra,\r\n customerId\r\n });\r\n }, [pay, paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra, customerId]);\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleClick}\r\n disabled={disabled || loading || !ready /* ready becomes true after first successful load */}\r\n className={className}\r\n aria-disabled={disabled || loading || !ready}\r\n title={title ?? (error ? error.message : undefined)}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}"]}
|
package/dist/react/index.d.cts
CHANGED
|
@@ -23,6 +23,7 @@ interface EscrowCheckoutButtonProps {
|
|
|
23
23
|
className?: string;
|
|
24
24
|
title?: string;
|
|
25
25
|
brand?: string;
|
|
26
|
+
customerId?: string;
|
|
26
27
|
logoUrl?: string;
|
|
27
28
|
callback?: (result: any) => void;
|
|
28
29
|
onClose?: () => void;
|
|
@@ -32,6 +33,6 @@ interface EscrowCheckoutButtonProps {
|
|
|
32
33
|
* Button that triggers pay(...) with your provided inputs.
|
|
33
34
|
* The library handles both session creation and widget loading.
|
|
34
35
|
*/
|
|
35
|
-
declare function EscrowCheckoutButton({ paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra, children, disabled, className, title }: EscrowCheckoutButtonProps): react_jsx_runtime.JSX.Element;
|
|
36
|
+
declare function EscrowCheckoutButton({ paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra, children, disabled, className, title, customerId }: EscrowCheckoutButtonProps): react_jsx_runtime.JSX.Element;
|
|
36
37
|
|
|
37
38
|
export { EscrowCheckoutButton, type EscrowCheckoutButtonProps, useEscrowCheckout };
|
package/dist/react/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ interface EscrowCheckoutButtonProps {
|
|
|
23
23
|
className?: string;
|
|
24
24
|
title?: string;
|
|
25
25
|
brand?: string;
|
|
26
|
+
customerId?: string;
|
|
26
27
|
logoUrl?: string;
|
|
27
28
|
callback?: (result: any) => void;
|
|
28
29
|
onClose?: () => void;
|
|
@@ -32,6 +33,6 @@ interface EscrowCheckoutButtonProps {
|
|
|
32
33
|
* Button that triggers pay(...) with your provided inputs.
|
|
33
34
|
* The library handles both session creation and widget loading.
|
|
34
35
|
*/
|
|
35
|
-
declare function EscrowCheckoutButton({ paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra, children, disabled, className, title }: EscrowCheckoutButtonProps): react_jsx_runtime.JSX.Element;
|
|
36
|
+
declare function EscrowCheckoutButton({ paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra, children, disabled, className, title, customerId }: EscrowCheckoutButtonProps): react_jsx_runtime.JSX.Element;
|
|
36
37
|
|
|
37
38
|
export { EscrowCheckoutButton, type EscrowCheckoutButtonProps, useEscrowCheckout };
|
package/dist/react/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pay } from '../chunk-
|
|
1
|
+
import { pay } from '../chunk-5YI7ZPIC.js';
|
|
2
2
|
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -38,7 +38,8 @@ function EscrowCheckoutButton({
|
|
|
38
38
|
children = "Pay",
|
|
39
39
|
disabled,
|
|
40
40
|
className,
|
|
41
|
-
title
|
|
41
|
+
title,
|
|
42
|
+
customerId
|
|
42
43
|
}) {
|
|
43
44
|
const { ready, loading, error, pay: pay2 } = useEscrowCheckout();
|
|
44
45
|
const handleClick = useCallback(async () => {
|
|
@@ -50,9 +51,10 @@ function EscrowCheckoutButton({
|
|
|
50
51
|
logoUrl,
|
|
51
52
|
callback,
|
|
52
53
|
onClose,
|
|
53
|
-
extra
|
|
54
|
+
extra,
|
|
55
|
+
customerId
|
|
54
56
|
});
|
|
55
|
-
}, [pay2, paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra]);
|
|
57
|
+
}, [pay2, paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra, customerId]);
|
|
56
58
|
return /* @__PURE__ */ jsx(
|
|
57
59
|
"button",
|
|
58
60
|
{
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/react/useEscrowCheckout.ts","../../src/react/EscrowCheckoutButton.tsx"],"names":["pay","useCallback"],"mappings":";;;;AAcO,SAAS,iBAAA,GAA6C;AACzD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,KAAK,CAAA;AACxC,EAAA,MAAM,CAAC,SAAS,UAAU,CAAA,GAAI,SAAkB,MAAM,OAAO,WAAW,WAAW,CAAA;AACnF,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAMrD,EAAA,MAAMA,IAAAA,GAAM,WAAA,CAA4B,OAAO,KAAA,KAAU;AACrD,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACA,MAAA,MAAM,IAAQ,KAAK,CAAA;AACnB,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,IACjB,SAAS,CAAA,EAAG;AACR,MAAA,QAAA,CAAS,CAAU,CAAA;AACnB,MAAA,MAAM,CAAA;AAAA,IACV,CAAA,SAAE;AACE,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IACpB;AAAA,EACJ,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAC/B,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IACpB;AAAA,EACJ,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,OAAA,CAAQ,OAAO,EAAE,KAAA,EAAO,SAAS,KAAA,EAAO,GAAA,EAAAA,IAAAA,EAAI,CAAA,EAAI,CAAC,KAAA,EAAO,OAAA,EAAS,KAAA,EAAOA,IAAG,CAAC,CAAA;AACvF;
|
|
1
|
+
{"version":3,"sources":["../../src/react/useEscrowCheckout.ts","../../src/react/EscrowCheckoutButton.tsx"],"names":["pay","useCallback"],"mappings":";;;;AAcO,SAAS,iBAAA,GAA6C;AACzD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAS,KAAK,CAAA;AACxC,EAAA,MAAM,CAAC,SAAS,UAAU,CAAA,GAAI,SAAkB,MAAM,OAAO,WAAW,WAAW,CAAA;AACnF,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAMrD,EAAA,MAAMA,IAAAA,GAAM,WAAA,CAA4B,OAAO,KAAA,KAAU;AACrD,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACA,MAAA,MAAM,IAAQ,KAAK,CAAA;AACnB,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,IACjB,SAAS,CAAA,EAAG;AACR,MAAA,QAAA,CAAS,CAAU,CAAA;AACnB,MAAA,MAAM,CAAA;AAAA,IACV,CAAA,SAAE;AACE,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IACpB;AAAA,EACJ,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AAC/B,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IACpB;AAAA,EACJ,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,OAAA,CAAQ,OAAO,EAAE,KAAA,EAAO,SAAS,KAAA,EAAO,GAAA,EAAAA,IAAAA,EAAI,CAAA,EAAI,CAAC,KAAA,EAAO,OAAA,EAAS,KAAA,EAAOA,IAAG,CAAC,CAAA;AACvF;ACrBO,SAAS,oBAAA,CAAqB;AAAA,EACI,YAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,KAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,QAAA;AAAA,EACA,SAAA;AAAA,EACA,KAAA;AAAA,EACA;AACJ,CAAA,EAA8B;AAC/D,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,GAAA,EAAAA,IAAAA,KAAQ,iBAAA,EAAkB;AAEzD,EAAA,MAAM,WAAA,GAAcC,YAAY,YAAY;AACxC,IAAA,MAAMD,IAAAA,CAAI;AAAA,MACN,YAAA;AAAA,MACA,SAAA;AAAA,MACA,WAAA;AAAA,MACA,KAAA;AAAA,MACA,OAAA;AAAA,MACA,QAAA;AAAA,MACA,OAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACH,CAAA;AAAA,EACL,CAAA,EAAG,CAACA,IAAAA,EAAK,YAAA,EAAc,SAAA,EAAW,WAAA,EAAa,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU,OAAA,EAAS,KAAA,EAAO,UAAU,CAAC,CAAA;AAEpG,EAAA,uBACI,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACG,IAAA,EAAK,QAAA;AAAA,MACL,OAAA,EAAS,WAAA;AAAA,MACT,QAAA,EAAU,QAAA,IAAY,OAAA,IAAW,CAAC,KAAA;AAAA,MAClC,SAAA;AAAA,MACA,eAAA,EAAe,QAAA,IAAY,OAAA,IAAW,CAAC,KAAA;AAAA,MACvC,KAAA,EAAO,KAAA,KAAU,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,MAAA,CAAA;AAAA,MAExC;AAAA;AAAA,GACL;AAER","file":"index.js","sourcesContent":["import { useCallback, useEffect, useMemo, useState } from 'react';\r\nimport { pay as corePay } from '../index';\r\n\r\nexport interface UseEscrowCheckoutResult {\r\n ready: boolean;\r\n loading: boolean;\r\n error: Error | null;\r\n pay: typeof corePay;\r\n}\r\n\r\n/**\r\n * React hook that preloads the widget script (implicitly via pay) and exposes pay(...)\r\n * Since the library abstracts script loading and session creation, the hook is thin.\r\n */\r\nexport function useEscrowCheckout(): UseEscrowCheckoutResult {\r\n const [ready, setReady] = useState(false);\r\n const [loading, setLoading] = useState<boolean>(() => typeof window !== 'undefined');\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n // Lazy mark \"ready\" after first successful pay or script load attempt.\r\n // If you want to preload the script earlier, you may trigger a no-op pay with a dry-run endpoint on your side.\r\n\r\n // Provide a stable pay function that reports loading state.\r\n const pay = useCallback<typeof corePay>(async (input) => {\r\n setLoading(true);\r\n try {\r\n await corePay(input);\r\n setReady(true);\r\n setError(null);\r\n } catch (e) {\r\n setError(e as Error);\r\n throw e;\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n // In SSR, mark not loading\r\n useEffect(() => {\r\n if (typeof window === 'undefined') {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n return useMemo(() => ({ ready, loading, error, pay }), [ready, loading, error, pay]);\r\n}","import React, { useCallback } from 'react';\r\nimport { useEscrowCheckout } from './useEscrowCheckout';\r\n\r\nexport interface EscrowCheckoutButtonProps {\r\n paymentToken: string;\r\n reference: string;\r\n redirectUrl: string;\r\n children?: React.ReactNode;\r\n disabled?: boolean;\r\n className?: string;\r\n title?: string;\r\n\r\n brand?: string;\r\n customerId?: string;\r\n logoUrl?: string;\r\n callback?: (result: any) => void;\r\n onClose?: () => void;\r\n extra?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Button that triggers pay(...) with your provided inputs.\r\n * The library handles both session creation and widget loading.\r\n */\r\nexport function EscrowCheckoutButton({\r\n paymentToken,\r\n reference,\r\n redirectUrl,\r\n brand,\r\n logoUrl,\r\n callback,\r\n onClose,\r\n extra,\r\n children = 'Pay',\r\n disabled,\r\n className,\r\n title,\r\n customerId\r\n }: EscrowCheckoutButtonProps) {\r\n const { ready, loading, error, pay } = useEscrowCheckout();\r\n\r\n const handleClick = useCallback(async () => {\r\n await pay({\r\n paymentToken,\r\n reference,\r\n redirectUrl,\r\n brand,\r\n logoUrl,\r\n callback,\r\n onClose,\r\n extra,\r\n customerId\r\n });\r\n }, [pay, paymentToken, reference, redirectUrl, brand, logoUrl, callback, onClose, extra, customerId]);\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n onClick={handleClick}\r\n disabled={disabled || loading || !ready /* ready becomes true after first successful load */}\r\n className={className}\r\n aria-disabled={disabled || loading || !ready}\r\n title={title ?? (error ? error.message : undefined)}\r\n >\r\n {children}\r\n </button>\r\n );\r\n}"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"chunk-D6ZMSUAT.js","sourcesContent":["export type EscrowWidget = (options: Record<string, unknown>) => void;\r\n\r\nexport interface InitConfig {\r\n publicKey: string; // publishable key only\r\n /**\r\n * Optional overrides for experts. End users don't need to set these.\r\n */\r\n scriptUrlOverride?: string;\r\n globalName?: string; // default 'EscrowCheckout'\r\n crossOrigin?: '' | 'anonymous' | 'use-credentials';\r\n}\r\n\r\nexport interface PayInput {\r\n paymentToken: string;\r\n reference: string;\r\n redirectUrl: string;\r\n logoUrl?: string;\r\n brand?: string;\r\n /**\r\n * Extra fields supported by the widget.\r\n */\r\n extra?: Record<string, unknown>;\r\n callback?: (result: any) => void;\r\n onClose?: () => void;\r\n}\r\n\r\nexport interface SessionResponse {\r\n session: unknown;\r\n}\r\n\r\nconst DEFAULT_SCRIPT_URL = 'https://checkout.payluk.ng/escrow-checkout.min.js';\r\nconst DEFAULT_GLOBAL_NAME = 'EscrowCheckout';\r\n\r\ntype ResolvedConfig = Required<Pick<InitConfig, 'publicKey'>> & {\r\n scriptUrl: string;\r\n globalName: string;\r\n crossOrigin: '' | 'anonymous' | 'use-credentials';\r\n};\r\n\r\nlet CONFIG: ResolvedConfig | null = null;\r\n\r\n/**\r\n * Initialize the library once (e.g., in app bootstrap).\r\n * Hides script URL and session creation from consumers.\r\n */\r\nexport function initEscrowCheckout(config: InitConfig): void {\r\n if (!config?.publicKey) throw new Error('initEscrowCheckout: \"publicKey\" is required.');\r\n CONFIG = {\r\n publicKey: config.publicKey,\r\n scriptUrl: config.scriptUrlOverride || DEFAULT_SCRIPT_URL,\r\n globalName: config.globalName || DEFAULT_GLOBAL_NAME,\r\n crossOrigin: config.crossOrigin ?? 'anonymous'\r\n };\r\n}\r\n\r\n/**\r\n * Narrow a provided config to ResolvedConfig or throw if not initialized.\r\n */\r\nfunction assertConfigured(config: ResolvedConfig | null): asserts config is ResolvedConfig {\r\n if (!config) {\r\n throw new Error('Escrow checkout not initialized. Call initEscrowCheckout({ apiBaseUrl, publicKey }) first.');\r\n }\r\n}\r\n\r\n/**\r\n * Internal: load the widget script once and return the global function.\r\n */\r\nasync function loadWidget(): Promise<EscrowWidget> {\r\n assertConfigured(CONFIG);\r\n const { scriptUrl, globalName, crossOrigin } = CONFIG;\r\n\r\n if (typeof window === 'undefined') {\r\n throw new Error('EscrowCheckout can only be loaded in the browser.');\r\n }\r\n\r\n const win = window as any;\r\n win.__escrowCheckoutLoader ??= {};\r\n\r\n if (win.__escrowCheckoutLoader[scriptUrl]) {\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n }\r\n\r\n if (typeof win[globalName] === 'function') {\r\n const fn = win[globalName] as EscrowWidget;\r\n win.__escrowCheckoutLoader[scriptUrl] = Promise.resolve(fn);\r\n return fn;\r\n }\r\n\r\n win.__escrowCheckoutLoader[scriptUrl] = new Promise<EscrowWidget>((resolve, reject) => {\r\n const script = document.createElement('script');\r\n script.src = scriptUrl;\r\n script.async = true;\r\n if (crossOrigin) script.crossOrigin = crossOrigin;\r\n\r\n script.onload = () => {\r\n const fn = win[globalName];\r\n if (typeof fn === 'function') resolve(fn as EscrowWidget);\r\n else reject(new Error(`Escrow checkout script loaded, but window.${globalName} is not a function.`));\r\n };\r\n\r\n script.onerror = () => reject(new Error(`Failed to load escrow checkout script: ${scriptUrl}`));\r\n\r\n document.head.appendChild(script);\r\n });\r\n\r\n return win.__escrowCheckoutLoader[scriptUrl];\r\n}\r\n\r\n/**\r\n * Internal: create a checkout session by calling your API.\r\n * This is intentionally inside the lib (user doesn't implement it).\r\n */\r\nasync function createSession(input: PayInput): Promise<SessionResponse> {\r\n assertConfigured(CONFIG);\r\n const { publicKey } = CONFIG;\r\n const apiBaseUrl = 'https://live.payluk.ng';\r\n\r\n const resp = await fetch(`${apiBaseUrl}/v1/checkout/session`, {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({\r\n paymentToken: input.paymentToken,\r\n redirectUrl: input.redirectUrl,\r\n reference: input.reference,\r\n publicKey\r\n })\r\n });\r\n\r\n if (!resp.ok) {\r\n const err = await resp.json().catch(() => ({}));\r\n throw new Error(err.message || 'Failed to create session');\r\n }\r\n\r\n return (await resp.json()) as SessionResponse;\r\n}\r\n\r\n/**\r\n * Public API: create the session and open the widget.\r\n * Consumers only supply business inputs (no script URL, no API calls).\r\n */\r\nexport async function pay(input: PayInput): Promise<void> {\r\n if (typeof window === 'undefined') {\r\n throw new Error('pay(...) can only run in the browser.');\r\n }\r\n\r\n const [{ session }, widget] = await Promise.all([createSession(input), loadWidget()]);\r\n\r\n widget({\r\n session,\r\n logoUrl: input.logoUrl,\r\n brand: input.brand,\r\n callback: input.callback,\r\n onClose: input.onClose,\r\n ...(input.extra ?? {})\r\n });\r\n}"]}
|