bkash-client 0.1.0-alpha.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +30 -70
- package/dist/angular.cjs +1 -1
- package/dist/angular.cjs.map +1 -1
- package/dist/angular.js +1 -1
- package/dist/bkash-client.browser.global.js +1 -1
- package/dist/bkash-client.browser.global.js.map +1 -1
- package/dist/{chunk-L3C2S2EZ.js → chunk-FXLW32P4.js} +3 -3
- package/dist/chunk-FXLW32P4.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/svelte.cjs +1 -1
- package/dist/svelte.cjs.map +1 -1
- package/dist/svelte.js +1 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.cjs.map +1 -1
- package/dist/vue.js +1 -1
- package/package.json +25 -12
- package/dist/chunk-L3C2S2EZ.js.map +0 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2026
|
|
3
|
+
Copyright (c) 2026 Open Source & Contributors
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -1,103 +1,63 @@
|
|
|
1
1
|
# bkash-client
|
|
2
2
|
|
|
3
|
-
[
|
|
4
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://www.npmjs.com/package/bkash-client)
|
|
6
|
-
|
|
7
|
-
Universal, headless, tree-shakeable frontend client SDK for bKash payment integrations. Works with React, React Native, Vue, Svelte, Angular, and vanilla HTML `<script>` tags.
|
|
3
|
+
Headless checkout bindings for [bKash](https://www.bkash.com) payments: React, React Native, Vue 3, Svelte, Angular and plain JavaScript. Pairs with [`bkash-server`](https://www.npmjs.com/package/bkash-server).
|
|
8
4
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
[](https://github.com/iamtashanto/Bkash/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/bkash-client)
|
|
7
|
+
[](https://github.com/iamtashanto/Bkash/blob/main/LICENSE)
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
> **Unofficial.** Not affiliated with, endorsed by, or sponsored by bKash Limited. "bKash" is a trademark of bKash Limited.
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
- **Client States:** Fully typed state machine (`idle`, `creating`, `awaiting_user`, `verifying`, `success`, `pending`, `cancelled`, `timeout`, `offline`, `error`). Unknown or timed-out transactions present "payment pending, do not pay again" rather than false errors.
|
|
17
|
-
- **Zero Frontend Secrets:** Never touches merchant credentials or API keys; communicates strictly with your backend routes.
|
|
18
|
-
- **Framework Bindings:** First-class bindings for React (`useBkash`, `<BkashButton />`), React Native (`<BkashCheckout />`), Vue 3 (`useBkash` with deep Refs), Svelte store (`createBkashStore`), and Angular service (`BkashService`).
|
|
19
|
-
- **Drop-in Script Tag:** Standalone IIFE bundle for plain HTML/JS websites.
|
|
11
|
+
**Documentation:** <https://bkash-sdk.tashanto.com/docs/client-guide/> · **Issues:** <https://github.com/iamtashanto/Bkash/issues>
|
|
20
12
|
|
|
21
|
-
|
|
13
|
+
## Why
|
|
22
14
|
|
|
23
|
-
|
|
15
|
+
- **Never holds secrets or prices.** It only calls your own `/create` route; the server decides the amount.
|
|
16
|
+
- **States that tell the truth.** `idle`, `creating`, `awaiting_user`, `verifying`, `success`, `pending`, `timeout`, `offline`, `cancelled`, `error`. An unknown outcome shows "payment pending, do not pay again", not a failure.
|
|
17
|
+
- **Headless.** No CSS, no modal: you own the markup and the brand.
|
|
24
18
|
|
|
25
|
-
##
|
|
19
|
+
## Install
|
|
26
20
|
|
|
27
21
|
```bash
|
|
28
|
-
# npm
|
|
29
22
|
npm install bkash-client
|
|
30
|
-
|
|
31
|
-
# pnpm
|
|
32
|
-
pnpm add bkash-client
|
|
33
|
-
|
|
34
|
-
# bun
|
|
35
|
-
bun add bkash-client
|
|
36
23
|
```
|
|
37
24
|
|
|
38
|
-
|
|
25
|
+
Optional peers: `react`, `vue`, `react-native` and `react-native-webview` (only for the matching binding).
|
|
39
26
|
|
|
40
27
|
## Quickstart (React)
|
|
41
28
|
|
|
42
29
|
```tsx
|
|
43
|
-
import React from 'react';
|
|
44
30
|
import { useBkash, BkashButton } from 'bkash-client/react';
|
|
45
31
|
|
|
46
32
|
export function CheckoutPage() {
|
|
47
|
-
const { state, error
|
|
48
|
-
createUrl: '/api/bkash/create',
|
|
49
|
-
});
|
|
50
|
-
|
|
33
|
+
const { state, error } = useBkash({ createUrl: '/api/bkash/create' });
|
|
51
34
|
return (
|
|
52
35
|
<div>
|
|
53
|
-
<
|
|
54
|
-
<
|
|
55
|
-
|
|
56
|
-
invoiceNumber="INV_1001"
|
|
57
|
-
orderId="ORD_555"
|
|
58
|
-
className="btn-bkash"
|
|
59
|
-
>
|
|
60
|
-
Pay 1,550 BDT with bKash
|
|
61
|
-
</BkashButton>
|
|
62
|
-
{error && <p className="error">{error.message}</p>}
|
|
36
|
+
<BkashButton>Pay with bKash</BkashButton>
|
|
37
|
+
{state === 'pending' && <p>Payment pending. Do not pay again.</p>}
|
|
38
|
+
{error && <p>{error.message}</p>}
|
|
63
39
|
</div>
|
|
64
40
|
);
|
|
65
41
|
}
|
|
66
42
|
```
|
|
67
43
|
|
|
68
|
-
|
|
44
|
+
Other bindings (React Native, Vue, Svelte, Angular, vanilla) are in the [client guide](https://bkash-sdk.tashanto.com/docs/client-guide/).
|
|
69
45
|
|
|
70
|
-
##
|
|
46
|
+
## What is supported
|
|
71
47
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
redirectUrl={redirectUrl}
|
|
83
|
-
callbackUrl="https://merchant.example.com/api/bkash/callback"
|
|
84
|
-
WebViewComponent={WebView}
|
|
85
|
-
onSuccess={(paymentId) => {
|
|
86
|
-
navigation.navigate('Success', { paymentId });
|
|
87
|
-
}}
|
|
88
|
-
onCancel={() => {
|
|
89
|
-
navigation.goBack();
|
|
90
|
-
}}
|
|
91
|
-
onError={(err) => {
|
|
92
|
-
alert(err.message);
|
|
93
|
-
}}
|
|
94
|
-
/>
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
```
|
|
48
|
+
<!-- status:start -->
|
|
49
|
+
<!-- Generated from website/src/data/status.json. Do not edit by hand. -->
|
|
50
|
+
| Feature | Status | Evidence |
|
|
51
|
+
| --- | --- | --- |
|
|
52
|
+
| React hook and button | Beta | automated tests (React Testing Library) |
|
|
53
|
+
| Vue 3 composable | Beta | automated tests (Vue Test Utils) |
|
|
54
|
+
| Svelte store | Beta | automated tests |
|
|
55
|
+
| Angular service | Beta | automated tests |
|
|
56
|
+
| React Native WebView checkout | Experimental | automated tests (React Native Testing Library); NOT TESTED on a device |
|
|
57
|
+
<!-- status:end -->
|
|
98
58
|
|
|
99
|
-
|
|
59
|
+
> **Android back button:** `BkashCheckout` does not handle the hardware back button yet. Confirm with your navigation library before leaving a payment in progress.
|
|
100
60
|
|
|
101
61
|
## License
|
|
102
62
|
|
|
103
|
-
MIT
|
|
63
|
+
MIT
|
package/dist/angular.cjs
CHANGED
|
@@ -69,7 +69,7 @@ var BkashClient = class {
|
|
|
69
69
|
* Initiates payment flow by calling the merchant backend,
|
|
70
70
|
* obtaining the gateway URL, and redirecting the customer.
|
|
71
71
|
*/
|
|
72
|
-
async checkout(params) {
|
|
72
|
+
async checkout(params = {}) {
|
|
73
73
|
if (typeof navigator !== "undefined" && navigator.onLine === false) {
|
|
74
74
|
this.setState("offline");
|
|
75
75
|
const offlineErr = new Error("Device is offline. Please check your internet connection.");
|
package/dist/angular.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/angular.ts"],"names":[],"mappings":"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","file":"angular.cjs","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\nexport interface InitiateCheckoutParams {\n amount: number | string;\n invoiceNumber: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n","import {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\n/**\n * Plain TypeScript Service for Angular applications.\n *\n * Design Decision & Justification:\n * Modern Angular (16+) seamlessly imports standard TypeScript services directly\n * without requiring the heavy complexity of ng-packagr / Angular Package Format (APF),\n * ensuring broad compatibility across Angular 16, 17, 18, and 19 without version pinning.\n */\nexport class BkashService {\n private client: BkashClient;\n\n constructor(options?: BkashClientOptions) {\n this.client = new BkashClient(options);\n }\n\n public getState(): BkashClientState {\n return this.client.getState();\n }\n\n public getPaymentId(): string | null {\n return this.client.getPaymentId();\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n return this.client.subscribe(listener);\n }\n\n public checkout(params: InitiateCheckoutParams): Promise<void> {\n return this.client.checkout(params);\n }\n\n public reset(): void {\n this.client.reset();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/angular.ts"],"names":[],"mappings":"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","file":"angular.cjs","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\n/**\n * All fields are optional hints. bkash-server decides the amount and invoice from its own\n * data and ignores any amount or invoice sent from the browser.\n */\nexport interface InitiateCheckoutParams {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams = {}): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n","import {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\n/**\n * Plain TypeScript Service for Angular applications.\n *\n * Design Decision & Justification:\n * Modern Angular (16+) seamlessly imports standard TypeScript services directly\n * without requiring the heavy complexity of ng-packagr / Angular Package Format (APF),\n * ensuring broad compatibility across Angular 16, 17, 18, and 19 without version pinning.\n */\nexport class BkashService {\n private client: BkashClient;\n\n constructor(options?: BkashClientOptions) {\n this.client = new BkashClient(options);\n }\n\n public getState(): BkashClientState {\n return this.client.getState();\n }\n\n public getPaymentId(): string | null {\n return this.client.getPaymentId();\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n return this.client.subscribe(listener);\n }\n\n public checkout(params: InitiateCheckoutParams): Promise<void> {\n return this.client.checkout(params);\n }\n\n public reset(): void {\n this.client.reset();\n }\n}\n"]}
|
package/dist/angular.js
CHANGED
|
@@ -93,7 +93,7 @@ var BkashClient = (() => {
|
|
|
93
93
|
* Initiates payment flow by calling the merchant backend,
|
|
94
94
|
* obtaining the gateway URL, and redirecting the customer.
|
|
95
95
|
*/
|
|
96
|
-
async checkout(params) {
|
|
96
|
+
async checkout(params = {}) {
|
|
97
97
|
if (typeof navigator !== "undefined" && navigator.onLine === false) {
|
|
98
98
|
this.setState("offline");
|
|
99
99
|
const offlineErr = new Error("Device is offline. Please check your internet connection.");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\nexport interface InitiateCheckoutParams {\n amount
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\n/**\n * All fields are optional hints. bkash-server decides the amount and invoice from its own\n * data and ignores any amount or invoice sent from the browser.\n */\nexport interface InitiateCheckoutParams {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams = {}): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -67,7 +67,7 @@ var BkashClient = class {
|
|
|
67
67
|
* Initiates payment flow by calling the merchant backend,
|
|
68
68
|
* obtaining the gateway URL, and redirecting the customer.
|
|
69
69
|
*/
|
|
70
|
-
async checkout(params) {
|
|
70
|
+
async checkout(params = {}) {
|
|
71
71
|
if (typeof navigator !== "undefined" && navigator.onLine === false) {
|
|
72
72
|
this.setState("offline");
|
|
73
73
|
const offlineErr = new Error("Device is offline. Please check your internet connection.");
|
|
@@ -120,5 +120,5 @@ var BkashClient = class {
|
|
|
120
120
|
};
|
|
121
121
|
|
|
122
122
|
export { BkashClient };
|
|
123
|
-
//# sourceMappingURL=chunk-
|
|
124
|
-
//# sourceMappingURL=chunk-
|
|
123
|
+
//# sourceMappingURL=chunk-FXLW32P4.js.map
|
|
124
|
+
//# sourceMappingURL=chunk-FXLW32P4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAyDO,IAAM,cAAN,MAAkB;AAAA,EACf,KAAA,GAA0B,MAAA;AAAA,EAC1B,OAAA;AAAA,EACA,gBAAA,GAAkC,IAAA;AAAA,EAClC,SAAA,uBAAgB,GAAA,EAAuC;AAAA,EAE/D,YAAY,OAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,SAAA,EAAW,mBAAA;AAAA,MACX,GAAG;AAAA,KACL;AAAA,EACF;AAAA,EAEO,QAAA,GAA6B;AAClC,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEO,YAAA,GAA8B;AACnC,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,eAAA,GAA0B;AAC/B,IAAA,QAAQ,KAAK,KAAA;AAAO,MAClB,KAAK,MAAA;AACH,QAAA,OAAO,6BAAA;AAAA,MACT,KAAK,UAAA;AACH,QAAA,OAAO,4CAAA;AAAA,MACT,KAAK,eAAA;AACH,QAAA,OAAO,6CAAA;AAAA,MACT,KAAK,WAAA;AACH,QAAA,OAAO,iCAAA;AAAA,MACT,KAAK,SAAA;AACH,QAAA,OAAO,iCAAA;AAAA,MACT,KAAK,SAAA;AAAA,MACL,KAAK,SAAA;AACH,QAAA,OAAO,iGAAA;AAAA,MACT,KAAK,WAAA;AACH,QAAA,OAAO,wBAAA;AAAA,MACT,KAAK,SAAA;AACH,QAAA,OAAO,2EAAA;AAAA,MACT,KAAK,OAAA;AACH,QAAA,OAAO,oCAAA;AAAA,MACT;AACE,QAAA,OAAO,EAAA;AAAA;AACX,EACF;AAAA,EAEO,UAAU,QAAA,EAAyD;AACxE,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,IAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC7C;AAAA,EAEO,MAAA,GAAe;AACpB,IAAA,IAAA,CAAK,SAAS,WAAW,CAAA;AACzB,IAAA,IAAA,CAAK,QAAQ,QAAA,IAAW;AAAA,EAC1B;AAAA,EAEO,WAAW,SAAA,EAA0B;AAC1C,IAAA,IAAI,SAAA,OAAgB,gBAAA,GAAmB,SAAA;AACvC,IAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,EACzB;AAAA,EAEQ,SAAS,QAAA,EAAkC;AACjD,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,OAAA,CAAQ,gBAAgB,QAAQ,CAAA;AACrC,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAC,EAAA,KAAO,EAAA,CAAG,QAAQ,CAAC,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,QAAA,CAAS,MAAA,GAAiC,EAAC,EAAkB;AAExE,IAAA,IAAI,OAAO,SAAA,KAAc,WAAA,IAAe,SAAA,CAAU,WAAW,KAAA,EAAO;AAClE,MAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AACvB,MAAA,MAAM,UAAA,GAAa,IAAI,KAAA,CAAM,2DAA2D,CAAA;AACxF,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,UAAU,CAAA;AACjC,MAAA,MAAM,UAAA;AAAA,IACR;AAEA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,SAAS,UAAU,CAAA;AAExB,MAAA,MAAM,kBAAkB,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,UAAU,IAAA,GAAO,EAAA;AAChF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,IAAA,CAAK,QAAQ,SAAA,EAAY;AAAA,QAC/C,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,QAAQ,MAAA,CAAO,MAAA;AAAA,UACf,eAAe,MAAA,CAAO,aAAA;AAAA,UACtB,SAAS,MAAA,CAAO,OAAA;AAAA,UAChB,WAAA,EAAa,IAAA,CAAK,OAAA,CAAQ,WAAA,IAAe,eAAA;AAAA,UACzC,gBAAgB,MAAA,CAAO,cAAA;AAAA,UACvB,UAAU,MAAA,CAAO;AAAA,SAClB;AAAA,OACF,CAAA;AAED,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uCAAA,EAA0C,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,MACxE;AAEA,MAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAK7B,MAAA,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,KAAK,SAAA,EAAW;AACxC,QAAA,MAAM,IAAI,KAAA,CAAM,IAAA,CAAK,KAAA,IAAS,+CAA+C,CAAA;AAAA,MAC/E;AAEA,MAAA,IAAA,CAAK,mBAAmB,IAAA,CAAK,SAAA;AAC7B,MAAA,IAAA,CAAK,SAAS,eAAe,CAAA;AAG7B,MAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,QAAA,EAAU;AACpD,QAAA,MAAA,CAAO,QAAA,CAAS,OAAO,IAAA,CAAK,WAAA;AAAA,MAC9B;AAAA,IACF,SAAS,GAAA,EAAc;AACrB,MAAA,MAAM,KAAA,GAAQ,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAChE,MAAA,MAAM,SAAA,GACJ,KAAA,CAAM,IAAA,KAAS,YAAA,IACf,KAAA,CAAM,SAAS,cAAA,IACf,gBAAA,CAAiB,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAErC,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,MACzB,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,MACvB;AAEA,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,KAAK,CAAA;AAC5B,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEO,KAAA,GAAc;AACnB,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EACtB;AACF","file":"chunk-FXLW32P4.js","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\n/**\n * All fields are optional hints. bkash-server decides the amount and invoice from its own\n * data and ignores any amount or invoice sent from the browser.\n */\nexport interface InitiateCheckoutParams {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams = {}): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -69,7 +69,7 @@ var BkashClient = class {
|
|
|
69
69
|
* Initiates payment flow by calling the merchant backend,
|
|
70
70
|
* obtaining the gateway URL, and redirecting the customer.
|
|
71
71
|
*/
|
|
72
|
-
async checkout(params) {
|
|
72
|
+
async checkout(params = {}) {
|
|
73
73
|
if (typeof navigator !== "undefined" && navigator.onLine === false) {
|
|
74
74
|
this.setState("offline");
|
|
75
75
|
const offlineErr = new Error("Device is offline. Please check your internet connection.");
|
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":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\n/**\n * All fields are optional hints. bkash-server decides the amount and invoice from its own\n * data and ignores any amount or invoice sent from the browser.\n */\nexport interface InitiateCheckoutParams {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams = {}): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -30,9 +30,13 @@ interface BkashClientOptions {
|
|
|
30
30
|
*/
|
|
31
31
|
onCancel?: () => void;
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* All fields are optional hints. bkash-server decides the amount and invoice from its own
|
|
35
|
+
* data and ignores any amount or invoice sent from the browser.
|
|
36
|
+
*/
|
|
33
37
|
interface InitiateCheckoutParams {
|
|
34
|
-
amount
|
|
35
|
-
invoiceNumber
|
|
38
|
+
amount?: number | string;
|
|
39
|
+
invoiceNumber?: string;
|
|
36
40
|
orderId?: string;
|
|
37
41
|
payerReference?: string;
|
|
38
42
|
metadata?: Record<string, string>;
|
|
@@ -59,7 +63,7 @@ declare class BkashClient {
|
|
|
59
63
|
* Initiates payment flow by calling the merchant backend,
|
|
60
64
|
* obtaining the gateway URL, and redirecting the customer.
|
|
61
65
|
*/
|
|
62
|
-
checkout(params
|
|
66
|
+
checkout(params?: InitiateCheckoutParams): Promise<void>;
|
|
63
67
|
reset(): void;
|
|
64
68
|
}
|
|
65
69
|
|
package/dist/index.d.ts
CHANGED
|
@@ -30,9 +30,13 @@ interface BkashClientOptions {
|
|
|
30
30
|
*/
|
|
31
31
|
onCancel?: () => void;
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* All fields are optional hints. bkash-server decides the amount and invoice from its own
|
|
35
|
+
* data and ignores any amount or invoice sent from the browser.
|
|
36
|
+
*/
|
|
33
37
|
interface InitiateCheckoutParams {
|
|
34
|
-
amount
|
|
35
|
-
invoiceNumber
|
|
38
|
+
amount?: number | string;
|
|
39
|
+
invoiceNumber?: string;
|
|
36
40
|
orderId?: string;
|
|
37
41
|
payerReference?: string;
|
|
38
42
|
metadata?: Record<string, string>;
|
|
@@ -59,7 +63,7 @@ declare class BkashClient {
|
|
|
59
63
|
* Initiates payment flow by calling the merchant backend,
|
|
60
64
|
* obtaining the gateway URL, and redirecting the customer.
|
|
61
65
|
*/
|
|
62
|
-
checkout(params
|
|
66
|
+
checkout(params?: InitiateCheckoutParams): Promise<void>;
|
|
63
67
|
reset(): void;
|
|
64
68
|
}
|
|
65
69
|
|
package/dist/index.js
CHANGED
package/dist/react.cjs
CHANGED
|
@@ -73,7 +73,7 @@ var BkashClient = class {
|
|
|
73
73
|
* Initiates payment flow by calling the merchant backend,
|
|
74
74
|
* obtaining the gateway URL, and redirecting the customer.
|
|
75
75
|
*/
|
|
76
|
-
async checkout(params) {
|
|
76
|
+
async checkout(params = {}) {
|
|
77
77
|
if (typeof navigator !== "undefined" && navigator.onLine === false) {
|
|
78
78
|
this.setState("offline");
|
|
79
79
|
const offlineErr = new Error("Device is offline. Please check your internet connection.");
|
package/dist/react.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/react.ts"],"names":["useState","useEffect","useCallback","createElement"],"mappings":"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","file":"react.cjs","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\nexport interface InitiateCheckoutParams {\n amount: number | string;\n invoiceNumber: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n","import { useState, useEffect, useCallback, createElement } from 'react';\nimport {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\nexport function useBkash(options?: BkashClientOptions) {\n const [client] = useState(() => new BkashClient(options));\n const [state, setState] = useState<BkashClientState>(client.getState());\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n return client.subscribe((newState) => setState(newState));\n }, [client]);\n\n const checkout = useCallback(\n async (params: InitiateCheckoutParams) => {\n setError(null);\n try {\n await client.checkout(params);\n } catch (err: unknown) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n }\n },\n [client]\n );\n\n const reset = useCallback(() => {\n setError(null);\n client.reset();\n }, [client]);\n\n return {\n state,\n error,\n paymentId: client.getPaymentId(),\n checkout,\n reset,\n client,\n };\n}\n\nexport interface BkashButtonProps {\n amount: number | string;\n invoiceNumber: string;\n orderId?: string;\n options?: BkashClientOptions;\n className?: string;\n children?: any;\n}\n\nexport function BkashButton({\n amount,\n invoiceNumber,\n orderId,\n options,\n className,\n children,\n}: BkashButtonProps) {\n const { state, checkout } = useBkash(options);\n\n const handleClick = async () => {\n if (state === 'creating') return;\n await checkout({ amount, invoiceNumber, orderId });\n };\n\n return createElement(\n 'button',\n {\n type: 'button',\n onClick: handleClick,\n disabled: state === 'creating',\n className: className || 'bkash-pay-btn',\n },\n children || (state === 'creating' ? 'Connecting to bKash...' : 'Pay with bKash')\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/react.ts"],"names":["useState","useEffect","useCallback","createElement"],"mappings":"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","file":"react.cjs","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\n/**\n * All fields are optional hints. bkash-server decides the amount and invoice from its own\n * data and ignores any amount or invoice sent from the browser.\n */\nexport interface InitiateCheckoutParams {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams = {}): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n","import { useState, useEffect, useCallback, createElement } from 'react';\nimport {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\nexport function useBkash(options?: BkashClientOptions) {\n const [client] = useState(() => new BkashClient(options));\n const [state, setState] = useState<BkashClientState>(client.getState());\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n return client.subscribe((newState) => setState(newState));\n }, [client]);\n\n const checkout = useCallback(\n async (params: InitiateCheckoutParams) => {\n setError(null);\n try {\n await client.checkout(params);\n } catch (err: unknown) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n }\n },\n [client]\n );\n\n const reset = useCallback(() => {\n setError(null);\n client.reset();\n }, [client]);\n\n return {\n state,\n error,\n paymentId: client.getPaymentId(),\n checkout,\n reset,\n client,\n };\n}\n\nexport interface BkashButtonProps {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n options?: BkashClientOptions;\n className?: string;\n children?: any;\n}\n\nexport function BkashButton({\n amount,\n invoiceNumber,\n orderId,\n options,\n className,\n children,\n}: BkashButtonProps) {\n const { state, checkout } = useBkash(options);\n\n const handleClick = async () => {\n if (state === 'creating') return;\n await checkout({ amount, invoiceNumber, orderId });\n };\n\n return createElement(\n 'button',\n {\n type: 'button',\n onClick: handleClick,\n disabled: state === 'creating',\n className: className || 'bkash-pay-btn',\n },\n children || (state === 'creating' ? 'Connecting to bKash...' : 'Pay with bKash')\n );\n}\n"]}
|
package/dist/react.d.cts
CHANGED
|
@@ -10,8 +10,8 @@ declare function useBkash(options?: BkashClientOptions): {
|
|
|
10
10
|
client: BkashClient;
|
|
11
11
|
};
|
|
12
12
|
interface BkashButtonProps {
|
|
13
|
-
amount
|
|
14
|
-
invoiceNumber
|
|
13
|
+
amount?: number | string;
|
|
14
|
+
invoiceNumber?: string;
|
|
15
15
|
orderId?: string;
|
|
16
16
|
options?: BkashClientOptions;
|
|
17
17
|
className?: string;
|
package/dist/react.d.ts
CHANGED
|
@@ -10,8 +10,8 @@ declare function useBkash(options?: BkashClientOptions): {
|
|
|
10
10
|
client: BkashClient;
|
|
11
11
|
};
|
|
12
12
|
interface BkashButtonProps {
|
|
13
|
-
amount
|
|
14
|
-
invoiceNumber
|
|
13
|
+
amount?: number | string;
|
|
14
|
+
invoiceNumber?: string;
|
|
15
15
|
orderId?: string;
|
|
16
16
|
options?: BkashClientOptions;
|
|
17
17
|
className?: string;
|
package/dist/react.js
CHANGED
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react.ts"],"names":[],"mappings":";;;;AAQO,SAAS,SAAS,OAAA,EAA8B;AACrD,EAAA,MAAM,CAAC,MAAM,CAAA,GAAI,QAAA,CAAS,MAAM,IAAI,WAAA,CAAY,OAAO,CAAC,CAAA;AACxD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,IAAI,QAAA,CAA2B,MAAA,CAAO,UAAU,CAAA;AACtE,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAO,OAAO,SAAA,CAAU,CAAC,QAAA,KAAa,QAAA,CAAS,QAAQ,CAAC,CAAA;AAAA,EAC1D,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,OAAO,MAAA,KAAmC;AACxC,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,CAAO,SAAS,MAAM,CAAA;AAAA,MAC9B,SAAS,GAAA,EAAc;AACrB,QAAA,MAAM,QAAA,GAAW,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AACnE,QAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,QAAA,MAAM,QAAA;AAAA,MACR;AAAA,IACF,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAY,MAAM;AAC9B,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,MAAA,CAAO,KAAA,EAAM;AAAA,EACf,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA,EAAW,OAAO,YAAA,EAAa;AAAA,IAC/B,QAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;AAWO,SAAS,WAAA,CAAY;AAAA,EAC1B,MAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAS,GAAI,SAAS,OAAO,CAAA;AAE5C,EAAA,MAAM,cAAc,YAAY;AAC9B,IAAA,IAAI,UAAU,UAAA,EAAY;AAC1B,IAAA,MAAM,QAAA,CAAS,EAAE,MAAA,EAAQ,aAAA,EAAe,SAAS,CAAA;AAAA,EACnD,CAAA;AAEA,EAAA,OAAO,aAAA;AAAA,IACL,QAAA;AAAA,IACA;AAAA,MACE,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS,WAAA;AAAA,MACT,UAAU,KAAA,KAAU,UAAA;AAAA,MACpB,WAAW,SAAA,IAAa;AAAA,KAC1B;AAAA,IACA,QAAA,KAAa,KAAA,KAAU,UAAA,GAAa,wBAAA,GAA2B,gBAAA;AAAA,GACjE;AACF","file":"react.js","sourcesContent":["import { useState, useEffect, useCallback, createElement } from 'react';\nimport {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\nexport function useBkash(options?: BkashClientOptions) {\n const [client] = useState(() => new BkashClient(options));\n const [state, setState] = useState<BkashClientState>(client.getState());\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n return client.subscribe((newState) => setState(newState));\n }, [client]);\n\n const checkout = useCallback(\n async (params: InitiateCheckoutParams) => {\n setError(null);\n try {\n await client.checkout(params);\n } catch (err: unknown) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n }\n },\n [client]\n );\n\n const reset = useCallback(() => {\n setError(null);\n client.reset();\n }, [client]);\n\n return {\n state,\n error,\n paymentId: client.getPaymentId(),\n checkout,\n reset,\n client,\n };\n}\n\nexport interface BkashButtonProps {\n amount
|
|
1
|
+
{"version":3,"sources":["../src/react.ts"],"names":[],"mappings":";;;;AAQO,SAAS,SAAS,OAAA,EAA8B;AACrD,EAAA,MAAM,CAAC,MAAM,CAAA,GAAI,QAAA,CAAS,MAAM,IAAI,WAAA,CAAY,OAAO,CAAC,CAAA;AACxD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,IAAI,QAAA,CAA2B,MAAA,CAAO,UAAU,CAAA;AACtE,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAuB,IAAI,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAO,OAAO,SAAA,CAAU,CAAC,QAAA,KAAa,QAAA,CAAS,QAAQ,CAAC,CAAA;AAAA,EAC1D,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,QAAA,GAAW,WAAA;AAAA,IACf,OAAO,MAAA,KAAmC;AACxC,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,IAAI;AACF,QAAA,MAAM,MAAA,CAAO,SAAS,MAAM,CAAA;AAAA,MAC9B,SAAS,GAAA,EAAc;AACrB,QAAA,MAAM,QAAA,GAAW,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AACnE,QAAA,QAAA,CAAS,QAAQ,CAAA;AACjB,QAAA,MAAM,QAAA;AAAA,MACR;AAAA,IACF,CAAA;AAAA,IACA,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAY,MAAM;AAC9B,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,MAAA,CAAO,KAAA,EAAM;AAAA,EACf,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,OAAO;AAAA,IACL,KAAA;AAAA,IACA,KAAA;AAAA,IACA,SAAA,EAAW,OAAO,YAAA,EAAa;AAAA,IAC/B,QAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;AAWO,SAAS,WAAA,CAAY;AAAA,EAC1B,MAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA,EAAqB;AACnB,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,EAAS,GAAI,SAAS,OAAO,CAAA;AAE5C,EAAA,MAAM,cAAc,YAAY;AAC9B,IAAA,IAAI,UAAU,UAAA,EAAY;AAC1B,IAAA,MAAM,QAAA,CAAS,EAAE,MAAA,EAAQ,aAAA,EAAe,SAAS,CAAA;AAAA,EACnD,CAAA;AAEA,EAAA,OAAO,aAAA;AAAA,IACL,QAAA;AAAA,IACA;AAAA,MACE,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS,WAAA;AAAA,MACT,UAAU,KAAA,KAAU,UAAA;AAAA,MACpB,WAAW,SAAA,IAAa;AAAA,KAC1B;AAAA,IACA,QAAA,KAAa,KAAA,KAAU,UAAA,GAAa,wBAAA,GAA2B,gBAAA;AAAA,GACjE;AACF","file":"react.js","sourcesContent":["import { useState, useEffect, useCallback, createElement } from 'react';\nimport {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\nexport function useBkash(options?: BkashClientOptions) {\n const [client] = useState(() => new BkashClient(options));\n const [state, setState] = useState<BkashClientState>(client.getState());\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n return client.subscribe((newState) => setState(newState));\n }, [client]);\n\n const checkout = useCallback(\n async (params: InitiateCheckoutParams) => {\n setError(null);\n try {\n await client.checkout(params);\n } catch (err: unknown) {\n const errorObj = err instanceof Error ? err : new Error(String(err));\n setError(errorObj);\n throw errorObj;\n }\n },\n [client]\n );\n\n const reset = useCallback(() => {\n setError(null);\n client.reset();\n }, [client]);\n\n return {\n state,\n error,\n paymentId: client.getPaymentId(),\n checkout,\n reset,\n client,\n };\n}\n\nexport interface BkashButtonProps {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n options?: BkashClientOptions;\n className?: string;\n children?: any;\n}\n\nexport function BkashButton({\n amount,\n invoiceNumber,\n orderId,\n options,\n className,\n children,\n}: BkashButtonProps) {\n const { state, checkout } = useBkash(options);\n\n const handleClick = async () => {\n if (state === 'creating') return;\n await checkout({ amount, invoiceNumber, orderId });\n };\n\n return createElement(\n 'button',\n {\n type: 'button',\n onClick: handleClick,\n disabled: state === 'creating',\n className: className || 'bkash-pay-btn',\n },\n children || (state === 'creating' ? 'Connecting to bKash...' : 'Pay with bKash')\n );\n}\n"]}
|
package/dist/svelte.cjs
CHANGED
|
@@ -69,7 +69,7 @@ var BkashClient = class {
|
|
|
69
69
|
* Initiates payment flow by calling the merchant backend,
|
|
70
70
|
* obtaining the gateway URL, and redirecting the customer.
|
|
71
71
|
*/
|
|
72
|
-
async checkout(params) {
|
|
72
|
+
async checkout(params = {}) {
|
|
73
73
|
if (typeof navigator !== "undefined" && navigator.onLine === false) {
|
|
74
74
|
this.setState("offline");
|
|
75
75
|
const offlineErr = new Error("Device is offline. Please check your internet connection.");
|
package/dist/svelte.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/svelte.ts"],"names":[],"mappings":"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","file":"svelte.cjs","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\nexport interface InitiateCheckoutParams {\n amount: number | string;\n invoiceNumber: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n","import {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\nexport interface BkashSvelteStore {\n subscribe: (run: (value: { state: BkashClientState; paymentId: string | null }) => void) => () => void;\n checkout: (params: InitiateCheckoutParams) => Promise<void>;\n reset: () => void;\n}\n\n/**\n * Svelte readable store wrapper for bKash Client.\n */\nexport function createBkashStore(options?: BkashClientOptions): BkashSvelteStore {\n const client = new BkashClient(options);\n\n return {\n subscribe: (run) => {\n run({ state: client.getState(), paymentId: client.getPaymentId() });\n return client.subscribe((state) => {\n run({ state, paymentId: client.getPaymentId() });\n });\n },\n checkout: (params) => client.checkout(params),\n reset: () => client.reset(),\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/svelte.ts"],"names":[],"mappings":"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","file":"svelte.cjs","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\n/**\n * All fields are optional hints. bkash-server decides the amount and invoice from its own\n * data and ignores any amount or invoice sent from the browser.\n */\nexport interface InitiateCheckoutParams {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams = {}): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n","import {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\nexport interface BkashSvelteStore {\n subscribe: (run: (value: { state: BkashClientState; paymentId: string | null }) => void) => () => void;\n checkout: (params: InitiateCheckoutParams) => Promise<void>;\n reset: () => void;\n}\n\n/**\n * Svelte readable store wrapper for bKash Client.\n */\nexport function createBkashStore(options?: BkashClientOptions): BkashSvelteStore {\n const client = new BkashClient(options);\n\n return {\n subscribe: (run) => {\n run({ state: client.getState(), paymentId: client.getPaymentId() });\n return client.subscribe((state) => {\n run({ state, paymentId: client.getPaymentId() });\n });\n },\n checkout: (params) => client.checkout(params),\n reset: () => client.reset(),\n };\n}\n"]}
|
package/dist/svelte.js
CHANGED
package/dist/vue.cjs
CHANGED
|
@@ -73,7 +73,7 @@ var BkashClient = class {
|
|
|
73
73
|
* Initiates payment flow by calling the merchant backend,
|
|
74
74
|
* obtaining the gateway URL, and redirecting the customer.
|
|
75
75
|
*/
|
|
76
|
-
async checkout(params) {
|
|
76
|
+
async checkout(params = {}) {
|
|
77
77
|
if (typeof navigator !== "undefined" && navigator.onLine === false) {
|
|
78
78
|
this.setState("offline");
|
|
79
79
|
const offlineErr = new Error("Device is offline. Please check your internet connection.");
|
package/dist/vue.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/vue.ts"],"names":["ref","readonly"],"mappings":"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","file":"vue.cjs","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\nexport interface InitiateCheckoutParams {\n amount: number | string;\n invoiceNumber: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n","import { ref, readonly, type Ref, type DeepReadonly } from 'vue';\nimport {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\nexport interface UseBkashReturn {\n state: DeepReadonly<Ref<BkashClientState>>;\n error: DeepReadonly<Ref<Error | null>>;\n paymentId: DeepReadonly<Ref<string | null>>;\n getState: () => BkashClientState;\n getError: () => Error | null;\n getPaymentId: () => string | null;\n checkout: (params: InitiateCheckoutParams) => Promise<void>;\n reset: () => void;\n client: BkashClient;\n}\n\n/**\n * Vue 3 Composable for bKash Checkout.\n * Provides deep reactivity via Vue 3 Refs, compatible with <script setup> and JSX templates.\n */\nexport function useBkash(options?: BkashClientOptions): UseBkashReturn {\n const client = new BkashClient(options);\n const state = ref<BkashClientState>(client.getState());\n const error = ref<Error | null>(null);\n const paymentId = ref<string | null>(client.getPaymentId());\n\n client.subscribe((newState) => {\n state.value = newState;\n paymentId.value = client.getPaymentId();\n });\n\n const checkout = async (params: InitiateCheckoutParams) => {\n error.value = null;\n try {\n await client.checkout(params);\n paymentId.value = client.getPaymentId();\n } catch (err: unknown) {\n const errObj = err instanceof Error ? err : new Error(String(err));\n error.value = errObj;\n throw errObj;\n }\n };\n\n const reset = () => {\n error.value = null;\n client.reset();\n paymentId.value = null;\n };\n\n return {\n state: readonly(state),\n error: readonly(error),\n paymentId: readonly(paymentId),\n getState: () => state.value,\n getError: () => error.value,\n getPaymentId: () => paymentId.value,\n checkout,\n reset,\n client,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/vue.ts"],"names":["ref","readonly"],"mappings":";;;;;;;AAyDO,IAAM,cAAN,MAAkB;AAAA,EACf,KAAA,GAA0B,MAAA;AAAA,EAC1B,OAAA;AAAA,EACA,gBAAA,GAAkC,IAAA;AAAA,EAClC,SAAA,uBAAgB,GAAA,EAAuC;AAAA,EAE/D,YAAY,OAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,SAAA,EAAW,mBAAA;AAAA,MACX,GAAG;AAAA,KACL;AAAA,EACF;AAAA,EAEO,QAAA,GAA6B;AAClC,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEO,YAAA,GAA8B;AACnC,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,eAAA,GAA0B;AAC/B,IAAA,QAAQ,KAAK,KAAA;AAAO,MAClB,KAAK,MAAA;AACH,QAAA,OAAO,6BAAA;AAAA,MACT,KAAK,UAAA;AACH,QAAA,OAAO,4CAAA;AAAA,MACT,KAAK,eAAA;AACH,QAAA,OAAO,6CAAA;AAAA,MACT,KAAK,WAAA;AACH,QAAA,OAAO,iCAAA;AAAA,MACT,KAAK,SAAA;AACH,QAAA,OAAO,iCAAA;AAAA,MACT,KAAK,SAAA;AAAA,MACL,KAAK,SAAA;AACH,QAAA,OAAO,iGAAA;AAAA,MACT,KAAK,WAAA;AACH,QAAA,OAAO,wBAAA;AAAA,MACT,KAAK,SAAA;AACH,QAAA,OAAO,2EAAA;AAAA,MACT,KAAK,OAAA;AACH,QAAA,OAAO,oCAAA;AAAA,MACT;AACE,QAAA,OAAO,EAAA;AAAA;AACX,EACF;AAAA,EAEO,UAAU,QAAA,EAAyD;AACxE,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,IAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC7C;AAAA,EAEO,MAAA,GAAe;AACpB,IAAA,IAAA,CAAK,SAAS,WAAW,CAAA;AACzB,IAAA,IAAA,CAAK,QAAQ,QAAA,IAAW;AAAA,EAC1B;AAAA,EAEO,WAAW,SAAA,EAA0B;AAC1C,IAAA,IAAI,SAAA,OAAgB,gBAAA,GAAmB,SAAA;AACvC,IAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,EACzB;AAAA,EAEQ,SAAS,QAAA,EAAkC;AACjD,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,OAAA,CAAQ,gBAAgB,QAAQ,CAAA;AACrC,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAC,EAAA,KAAO,EAAA,CAAG,QAAQ,CAAC,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,QAAA,CAAS,MAAA,GAAiC,EAAC,EAAkB;AAExE,IAAA,IAAI,OAAO,SAAA,KAAc,WAAA,IAAe,SAAA,CAAU,WAAW,KAAA,EAAO;AAClE,MAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AACvB,MAAA,MAAM,UAAA,GAAa,IAAI,KAAA,CAAM,2DAA2D,CAAA;AACxF,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,UAAU,CAAA;AACjC,MAAA,MAAM,UAAA;AAAA,IACR;AAEA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,SAAS,UAAU,CAAA;AAExB,MAAA,MAAM,kBAAkB,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,UAAU,IAAA,GAAO,EAAA;AAChF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,IAAA,CAAK,QAAQ,SAAA,EAAY;AAAA,QAC/C,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,QAAQ,MAAA,CAAO,MAAA;AAAA,UACf,eAAe,MAAA,CAAO,aAAA;AAAA,UACtB,SAAS,MAAA,CAAO,OAAA;AAAA,UAChB,WAAA,EAAa,IAAA,CAAK,OAAA,CAAQ,WAAA,IAAe,eAAA;AAAA,UACzC,gBAAgB,MAAA,CAAO,cAAA;AAAA,UACvB,UAAU,MAAA,CAAO;AAAA,SAClB;AAAA,OACF,CAAA;AAED,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uCAAA,EAA0C,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,MACxE;AAEA,MAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAK7B,MAAA,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,KAAK,SAAA,EAAW;AACxC,QAAA,MAAM,IAAI,KAAA,CAAM,IAAA,CAAK,KAAA,IAAS,+CAA+C,CAAA;AAAA,MAC/E;AAEA,MAAA,IAAA,CAAK,mBAAmB,IAAA,CAAK,SAAA;AAC7B,MAAA,IAAA,CAAK,SAAS,eAAe,CAAA;AAG7B,MAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,QAAA,EAAU;AACpD,QAAA,MAAA,CAAO,QAAA,CAAS,OAAO,IAAA,CAAK,WAAA;AAAA,MAC9B;AAAA,IACF,SAAS,GAAA,EAAc;AACrB,MAAA,MAAM,KAAA,GAAQ,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAChE,MAAA,MAAM,SAAA,GACJ,KAAA,CAAM,IAAA,KAAS,YAAA,IACf,KAAA,CAAM,SAAS,cAAA,IACf,gBAAA,CAAiB,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAErC,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,MACzB,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,MACvB;AAEA,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,KAAK,CAAA;AAC5B,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEO,KAAA,GAAc;AACnB,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EACtB;AACF,CAAA;;;ACnLO,SAAS,SAAS,OAAA,EAA8C;AACrE,EAAA,MAAM,MAAA,GAAS,IAAI,WAAA,CAAY,OAAO,CAAA;AACtC,EAAA,MAAM,KAAA,GAAQA,OAAA,CAAsB,MAAA,CAAO,QAAA,EAAU,CAAA;AACrD,EAAA,MAAM,KAAA,GAAQA,QAAkB,IAAI,CAAA;AACpC,EAAA,MAAM,SAAA,GAAYA,OAAA,CAAmB,MAAA,CAAO,YAAA,EAAc,CAAA;AAE1D,EAAA,MAAA,CAAO,SAAA,CAAU,CAAC,QAAA,KAAa;AAC7B,IAAA,KAAA,CAAM,KAAA,GAAQ,QAAA;AACd,IAAA,SAAA,CAAU,KAAA,GAAQ,OAAO,YAAA,EAAa;AAAA,EACxC,CAAC,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,OAAO,MAAA,KAAmC;AACzD,IAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AACd,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,CAAO,SAAS,MAAM,CAAA;AAC5B,MAAA,SAAA,CAAU,KAAA,GAAQ,OAAO,YAAA,EAAa;AAAA,IACxC,SAAS,GAAA,EAAc;AACrB,MAAA,MAAM,MAAA,GAAS,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AACjE,MAAA,KAAA,CAAM,KAAA,GAAQ,MAAA;AACd,MAAA,MAAM,MAAA;AAAA,IACR;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,QAAQ,MAAM;AAClB,IAAA,KAAA,CAAM,KAAA,GAAQ,IAAA;AACd,IAAA,MAAA,CAAO,KAAA,EAAM;AACb,IAAA,SAAA,CAAU,KAAA,GAAQ,IAAA;AAAA,EACpB,CAAA;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAOC,aAAS,KAAK,CAAA;AAAA,IACrB,KAAA,EAAOA,aAAS,KAAK,CAAA;AAAA,IACrB,SAAA,EAAWA,aAAS,SAAS,CAAA;AAAA,IAC7B,QAAA,EAAU,MAAM,KAAA,CAAM,KAAA;AAAA,IACtB,QAAA,EAAU,MAAM,KAAA,CAAM,KAAA;AAAA,IACtB,YAAA,EAAc,MAAM,SAAA,CAAU,KAAA;AAAA,IAC9B,QAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF","file":"vue.cjs","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\n/**\n * All fields are optional hints. bkash-server decides the amount and invoice from its own\n * data and ignores any amount or invoice sent from the browser.\n */\nexport interface InitiateCheckoutParams {\n amount?: number | string;\n invoiceNumber?: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams = {}): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n","import { ref, readonly, type Ref, type DeepReadonly } from 'vue';\nimport {\n BkashClient,\n type BkashClientOptions,\n type BkashClientState,\n type InitiateCheckoutParams,\n} from './index.js';\n\nexport interface UseBkashReturn {\n state: DeepReadonly<Ref<BkashClientState>>;\n error: DeepReadonly<Ref<Error | null>>;\n paymentId: DeepReadonly<Ref<string | null>>;\n getState: () => BkashClientState;\n getError: () => Error | null;\n getPaymentId: () => string | null;\n checkout: (params: InitiateCheckoutParams) => Promise<void>;\n reset: () => void;\n client: BkashClient;\n}\n\n/**\n * Vue 3 Composable for bKash Checkout.\n * Provides deep reactivity via Vue 3 Refs, compatible with <script setup> and JSX templates.\n */\nexport function useBkash(options?: BkashClientOptions): UseBkashReturn {\n const client = new BkashClient(options);\n const state = ref<BkashClientState>(client.getState());\n const error = ref<Error | null>(null);\n const paymentId = ref<string | null>(client.getPaymentId());\n\n client.subscribe((newState) => {\n state.value = newState;\n paymentId.value = client.getPaymentId();\n });\n\n const checkout = async (params: InitiateCheckoutParams) => {\n error.value = null;\n try {\n await client.checkout(params);\n paymentId.value = client.getPaymentId();\n } catch (err: unknown) {\n const errObj = err instanceof Error ? err : new Error(String(err));\n error.value = errObj;\n throw errObj;\n }\n };\n\n const reset = () => {\n error.value = null;\n client.reset();\n paymentId.value = null;\n };\n\n return {\n state: readonly(state),\n error: readonly(error),\n paymentId: readonly(paymentId),\n getState: () => state.value,\n getError: () => error.value,\n getPaymentId: () => paymentId.value,\n checkout,\n reset,\n client,\n };\n}\n"]}
|
package/dist/vue.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bkash-client",
|
|
3
|
-
"version": "0.1.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Headless, multi-framework client SDK for bKash payment flows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
7
|
"module": "./dist/index.js",
|
|
@@ -111,15 +111,9 @@
|
|
|
111
111
|
"optional": true
|
|
112
112
|
}
|
|
113
113
|
},
|
|
114
|
-
"scripts": {
|
|
115
|
-
"build": "tsup",
|
|
116
|
-
"test": "vitest run",
|
|
117
|
-
"test:watch": "vitest",
|
|
118
|
-
"typecheck": "tsc --noEmit",
|
|
119
|
-
"dev": "tsup --watch"
|
|
120
|
-
},
|
|
121
114
|
"keywords": [
|
|
122
115
|
"bkash",
|
|
116
|
+
"bangladesh",
|
|
123
117
|
"payment",
|
|
124
118
|
"checkout",
|
|
125
119
|
"react",
|
|
@@ -129,7 +123,7 @@
|
|
|
129
123
|
"angular",
|
|
130
124
|
"headless"
|
|
131
125
|
],
|
|
132
|
-
"author": "
|
|
126
|
+
"author": "Md Tanvir Ahamed Shanto (https://github.com/iamtashanto)",
|
|
133
127
|
"license": "MIT",
|
|
134
128
|
"devDependencies": {
|
|
135
129
|
"@testing-library/react": "^16.3.3",
|
|
@@ -137,7 +131,7 @@
|
|
|
137
131
|
"@types/react": "^18.3.3",
|
|
138
132
|
"@types/react-dom": "^18.3.7",
|
|
139
133
|
"@vue/test-utils": "^2.5.1",
|
|
140
|
-
"jsdom": "^
|
|
134
|
+
"jsdom": "^24.1.3",
|
|
141
135
|
"react": "^18.3.1",
|
|
142
136
|
"react-dom": "^18.3.1",
|
|
143
137
|
"svelte": "^5.57.2",
|
|
@@ -145,5 +139,24 @@
|
|
|
145
139
|
"typescript": "^5.5.4",
|
|
146
140
|
"vitest": "^2.1.3",
|
|
147
141
|
"vue": "^3.5.44"
|
|
142
|
+
},
|
|
143
|
+
"repository": {
|
|
144
|
+
"type": "git",
|
|
145
|
+
"url": "git+https://github.com/iamtashanto/Bkash.git",
|
|
146
|
+
"directory": "packages/bkash-client"
|
|
147
|
+
},
|
|
148
|
+
"homepage": "https://bkash-sdk.tashanto.com/docs/",
|
|
149
|
+
"bugs": {
|
|
150
|
+
"url": "https://github.com/iamtashanto/Bkash/issues"
|
|
151
|
+
},
|
|
152
|
+
"publishConfig": {
|
|
153
|
+
"access": "public"
|
|
154
|
+
},
|
|
155
|
+
"scripts": {
|
|
156
|
+
"build": "tsup",
|
|
157
|
+
"test": "vitest run",
|
|
158
|
+
"test:watch": "vitest",
|
|
159
|
+
"typecheck": "tsc --noEmit",
|
|
160
|
+
"dev": "tsup --watch"
|
|
148
161
|
}
|
|
149
|
-
}
|
|
162
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";AAqDO,IAAM,cAAN,MAAkB;AAAA,EACf,KAAA,GAA0B,MAAA;AAAA,EAC1B,OAAA;AAAA,EACA,gBAAA,GAAkC,IAAA;AAAA,EAClC,SAAA,uBAAgB,GAAA,EAAuC;AAAA,EAE/D,YAAY,OAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,SAAA,EAAW,mBAAA;AAAA,MACX,GAAG;AAAA,KACL;AAAA,EACF;AAAA,EAEO,QAAA,GAA6B;AAClC,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA,EAEO,YAAA,GAA8B;AACnC,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,eAAA,GAA0B;AAC/B,IAAA,QAAQ,KAAK,KAAA;AAAO,MAClB,KAAK,MAAA;AACH,QAAA,OAAO,6BAAA;AAAA,MACT,KAAK,UAAA;AACH,QAAA,OAAO,4CAAA;AAAA,MACT,KAAK,eAAA;AACH,QAAA,OAAO,6CAAA;AAAA,MACT,KAAK,WAAA;AACH,QAAA,OAAO,iCAAA;AAAA,MACT,KAAK,SAAA;AACH,QAAA,OAAO,iCAAA;AAAA,MACT,KAAK,SAAA;AAAA,MACL,KAAK,SAAA;AACH,QAAA,OAAO,iGAAA;AAAA,MACT,KAAK,WAAA;AACH,QAAA,OAAO,wBAAA;AAAA,MACT,KAAK,SAAA;AACH,QAAA,OAAO,2EAAA;AAAA,MACT,KAAK,OAAA;AACH,QAAA,OAAO,oCAAA;AAAA,MACT;AACE,QAAA,OAAO,EAAA;AAAA;AACX,EACF;AAAA,EAEO,UAAU,QAAA,EAAyD;AACxE,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,IAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC7C;AAAA,EAEO,MAAA,GAAe;AACpB,IAAA,IAAA,CAAK,SAAS,WAAW,CAAA;AACzB,IAAA,IAAA,CAAK,QAAQ,QAAA,IAAW;AAAA,EAC1B;AAAA,EAEO,WAAW,SAAA,EAA0B;AAC1C,IAAA,IAAI,SAAA,OAAgB,gBAAA,GAAmB,SAAA;AACvC,IAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,EACzB;AAAA,EAEQ,SAAS,QAAA,EAAkC;AACjD,IAAA,IAAA,CAAK,KAAA,GAAQ,QAAA;AACb,IAAA,IAAA,CAAK,OAAA,CAAQ,gBAAgB,QAAQ,CAAA;AACrC,IAAA,IAAA,CAAK,UAAU,OAAA,CAAQ,CAAC,EAAA,KAAO,EAAA,CAAG,QAAQ,CAAC,CAAA;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAa,SAAS,MAAA,EAA+C;AAEnE,IAAA,IAAI,OAAO,SAAA,KAAc,WAAA,IAAe,SAAA,CAAU,WAAW,KAAA,EAAO;AAClE,MAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AACvB,MAAA,MAAM,UAAA,GAAa,IAAI,KAAA,CAAM,2DAA2D,CAAA;AACxF,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,UAAU,CAAA;AACjC,MAAA,MAAM,UAAA;AAAA,IACR;AAEA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,SAAS,UAAU,CAAA;AAExB,MAAA,MAAM,kBAAkB,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,UAAU,IAAA,GAAO,EAAA;AAChF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,IAAA,CAAK,QAAQ,SAAA,EAAY;AAAA,QAC/C,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,QAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,UACnB,QAAQ,MAAA,CAAO,MAAA;AAAA,UACf,eAAe,MAAA,CAAO,aAAA;AAAA,UACtB,SAAS,MAAA,CAAO,OAAA;AAAA,UAChB,WAAA,EAAa,IAAA,CAAK,OAAA,CAAQ,WAAA,IAAe,eAAA;AAAA,UACzC,gBAAgB,MAAA,CAAO,cAAA;AAAA,UACvB,UAAU,MAAA,CAAO;AAAA,SAClB;AAAA,OACF,CAAA;AAED,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uCAAA,EAA0C,GAAA,CAAI,MAAM,CAAA,CAAE,CAAA;AAAA,MACxE;AAEA,MAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAK7B,MAAA,IAAI,CAAC,IAAA,CAAK,WAAA,IAAe,CAAC,KAAK,SAAA,EAAW;AACxC,QAAA,MAAM,IAAI,KAAA,CAAM,IAAA,CAAK,KAAA,IAAS,+CAA+C,CAAA;AAAA,MAC/E;AAEA,MAAA,IAAA,CAAK,mBAAmB,IAAA,CAAK,SAAA;AAC7B,MAAA,IAAA,CAAK,SAAS,eAAe,CAAA;AAG7B,MAAA,IAAI,OAAO,MAAA,KAAW,WAAA,IAAe,MAAA,CAAO,QAAA,EAAU;AACpD,QAAA,MAAA,CAAO,QAAA,CAAS,OAAO,IAAA,CAAK,WAAA;AAAA,MAC9B;AAAA,IACF,SAAS,GAAA,EAAc;AACrB,MAAA,MAAM,KAAA,GAAQ,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAChE,MAAA,MAAM,SAAA,GACJ,KAAA,CAAM,IAAA,KAAS,YAAA,IACf,KAAA,CAAM,SAAS,cAAA,IACf,gBAAA,CAAiB,IAAA,CAAK,KAAA,CAAM,OAAO,CAAA;AAErC,MAAA,IAAI,SAAA,EAAW;AAEb,QAAA,IAAA,CAAK,SAAS,SAAS,CAAA;AAAA,MACzB,CAAA,MAAO;AACL,QAAA,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,MACvB;AAEA,MAAA,IAAA,CAAK,OAAA,CAAQ,UAAU,KAAK,CAAA;AAC5B,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA,EAEO,KAAA,GAAc;AACnB,IAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,IAAA,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EACtB;AACF","file":"chunk-L3C2S2EZ.js","sourcesContent":["/**\n * @bkash/client\n * Universal, headless client SDK for bKash payment integrations.\n */\n\nexport type BkashClientState =\n | 'idle'\n | 'creating'\n | 'awaiting_user'\n | 'verifying'\n | 'success'\n | 'pending'\n | 'cancelled'\n | 'timeout'\n | 'offline'\n | 'error';\n\nexport interface BkashClientOptions {\n /**\n * Endpoint on merchant backend to create payment session.\n * Defaults to \"/api/bkash/create\".\n */\n createUrl?: string;\n /**\n * Callback URL registered with merchant backend.\n */\n callbackUrl?: string;\n /**\n * Hook triggered on state transition.\n */\n onStateChange?: (state: BkashClientState) => void;\n /**\n * Hook triggered when payment completes successfully.\n */\n onSuccess?: (paymentId: string) => void;\n /**\n * Hook triggered on payment error.\n */\n onError?: (error: Error) => void;\n /**\n * Hook triggered if user cancels payment.\n */\n onCancel?: () => void;\n}\n\nexport interface InitiateCheckoutParams {\n amount: number | string;\n invoiceNumber: string;\n orderId?: string;\n payerReference?: string;\n metadata?: Record<string, string>;\n}\n\nexport class BkashClient {\n private state: BkashClientState = 'idle';\n private options: BkashClientOptions;\n private currentPaymentId: string | null = null;\n private listeners = new Set<(state: BkashClientState) => void>();\n\n constructor(options?: BkashClientOptions) {\n this.options = {\n createUrl: '/api/bkash/create',\n ...options,\n };\n }\n\n public getState(): BkashClientState {\n return this.state;\n }\n\n public getPaymentId(): string | null {\n return this.currentPaymentId;\n }\n\n /**\n * Returns human-readable UI guidance for the current client state.\n * Specifically guarantees that unknown or timed-out outcomes are presented as\n * \"payment pending, do not pay again\" rather than a false failure.\n */\n public getStateMessage(): string {\n switch (this.state) {\n case 'idle':\n return 'Ready to initiate checkout.';\n case 'creating':\n return 'Initializing payment session with bKash...';\n case 'awaiting_user':\n return 'Redirecting to bKash secure payment page...';\n case 'verifying':\n return 'Verifying payment with bKash...';\n case 'success':\n return 'Payment completed successfully!';\n case 'pending':\n case 'timeout':\n return 'Payment pending, do not pay again. Please wait while your transaction is reconciled with bKash.';\n case 'cancelled':\n return 'Payment was cancelled.';\n case 'offline':\n return 'Device is offline. Please check your internet connection before retrying.';\n case 'error':\n return 'An error occurred during checkout.';\n default:\n return '';\n }\n }\n\n public subscribe(listener: (state: BkashClientState) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n public cancel(): void {\n this.setState('cancelled');\n this.options.onCancel?.();\n }\n\n public setPending(paymentId?: string): void {\n if (paymentId) this.currentPaymentId = paymentId;\n this.setState('pending');\n }\n\n private setState(newState: BkashClientState): void {\n this.state = newState;\n this.options.onStateChange?.(newState);\n this.listeners.forEach((fn) => fn(newState));\n }\n\n /**\n * Initiates payment flow by calling the merchant backend,\n * obtaining the gateway URL, and redirecting the customer.\n */\n public async checkout(params: InitiateCheckoutParams): Promise<void> {\n // Offline pre-check\n if (typeof navigator !== 'undefined' && navigator.onLine === false) {\n this.setState('offline');\n const offlineErr = new Error('Device is offline. Please check your internet connection.');\n this.options.onError?.(offlineErr);\n throw offlineErr;\n }\n\n try {\n this.setState('creating');\n\n const defaultCallback = typeof window !== 'undefined' ? window.location?.href : '';\n const res = await fetch(this.options.createUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n amount: params.amount,\n invoiceNumber: params.invoiceNumber,\n orderId: params.orderId,\n callbackUrl: this.options.callbackUrl || defaultCallback,\n payerReference: params.payerReference,\n metadata: params.metadata,\n }),\n });\n\n if (!res.ok) {\n throw new Error(`Failed to create payment session: HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as {\n redirectUrl?: string;\n paymentId?: string;\n error?: string;\n };\n if (!data.redirectUrl || !data.paymentId) {\n throw new Error(data.error || 'Invalid session response from payment server.');\n }\n\n this.currentPaymentId = data.paymentId;\n this.setState('awaiting_user');\n\n // Launch bKash Hosted Checkout\n if (typeof window !== 'undefined' && window.location) {\n window.location.href = data.redirectUrl;\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n const isTimeout =\n error.name === 'AbortError' ||\n error.name === 'TimeoutError' ||\n /timeout|abort/i.test(error.message);\n\n if (isTimeout) {\n // Under AUD-08: timeout / unknown outcome MUST display pending (\"do not pay again\")\n this.setState('pending');\n } else {\n this.setState('error');\n }\n\n this.options.onError?.(error);\n throw error;\n }\n }\n\n public reset(): void {\n this.currentPaymentId = null;\n this.setState('idle');\n }\n}\n"]}
|