@money-pulse/checkout 1.0.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 NOCYL-PULSE
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # @money-pulse/checkout
2
+
3
+ Official JavaScript/TypeScript SDK for [Money-Pulse](https://money-pulse.org) — Accept payments and process payouts across Africa.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @money-pulse/checkout
9
+ ```
10
+
11
+ ## Server-side: Create a payment
12
+
13
+ ```typescript
14
+ import { MoneyPulse } from '@money-pulse/checkout';
15
+
16
+ const mp = new MoneyPulse({ apiKey: process.env.MP_SECRET_KEY! });
17
+
18
+ const payment = await mp.payments.create({
19
+ amount: 10000,
20
+ currency: 'XOF',
21
+ country: 'CI',
22
+ customer: { email: 'client@example.com', phone: '+22507000000' },
23
+ callbackUrl: 'https://your-site.com/webhook',
24
+ returnUrl: 'https://your-site.com/thank-you',
25
+ });
26
+
27
+ console.log(payment.checkoutUrl); // Redirect customer here
28
+ ```
29
+
30
+ ## Browser checkout (popup)
31
+
32
+ ```html
33
+ <script src="https://js.money-pulse.org/v1/checkout.js"></script>
34
+ <script>
35
+ MoneyPulseCheckout.open({
36
+ publicKey: 'mp_pub_xxx',
37
+ amount: 5000,
38
+ currency: 'XOF',
39
+ onSuccess: (r) => console.log('Paid:', r),
40
+ onError: (e) => console.error(e),
41
+ });
42
+ </script>
43
+ ```
44
+
45
+ ## Payouts
46
+
47
+ ```typescript
48
+ const payout = await mp.payouts.create({
49
+ amount: 50000,
50
+ currency: 'XOF',
51
+ country: 'CI',
52
+ recipient: {
53
+ type: 'mobile_money',
54
+ phone: '+22507000000',
55
+ name: 'Jean Kouassi',
56
+ },
57
+ });
58
+ ```
59
+
60
+ ## Webhooks (signature verification)
61
+
62
+ Money-Pulse signs every webhook with HMAC-SHA256 in the `X-MoneyPulse-Signature` header.
63
+
64
+ ```typescript
65
+ import crypto from 'crypto';
66
+ import express from 'express';
67
+
68
+ const app = express();
69
+ app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
70
+ const signature = req.headers['x-moneypulse-signature'] as string;
71
+ const expected = crypto
72
+ .createHmac('sha256', process.env.MP_WEBHOOK_SECRET!)
73
+ .update(req.body)
74
+ .digest('hex');
75
+
76
+ if (signature !== expected) return res.status(401).end();
77
+
78
+ const event = JSON.parse(req.body.toString());
79
+ switch (event.type) {
80
+ case 'payment.success': /* fulfill order */ break;
81
+ case 'payment.failed': /* notify customer */ break;
82
+ case 'payout.completed':/* mark withdrawal done */ break;
83
+ }
84
+ res.json({ received: true });
85
+ });
86
+ ```
87
+
88
+ ## Mode simulation (no funds, no webhook)
89
+
90
+ Use `simulate: true` to run end-to-end tests in production without moving money:
91
+
92
+ ```typescript
93
+ const test = await mp.payments.create({
94
+ amount: 1000, currency: 'XOF', country: 'CI',
95
+ customer: { email: 't@t.com' },
96
+ simulate: true, // ← no balance change, no webhook fired
97
+ });
98
+ console.log(test.simulated); // true
99
+ ```
100
+
101
+ Sandbox amount rules: `amount % 100 < 50 → success`, `< 90 → pending`, `≥ 90 → failed`.
102
+
103
+ ## Common errors
104
+
105
+ | Code | Meaning |
106
+ |------|---------|
107
+ | `invalid_amount` | Amount outside method min/max |
108
+ | `unsupported_country` | No gateway covers this country/currency |
109
+ | `insufficient_balance` | Payout > available merchant balance |
110
+ | `gateway_unavailable` | All gateways failed; retry later |
111
+ | `invalid_signature` | Webhook HMAC mismatch (check secret) |
112
+
113
+ ## Supported coverage
114
+
115
+ 76+ countries, 19 gateways, 55+ currencies. See [docs.money-pulse.org](https://docs.money-pulse.org).
116
+
117
+ ## License
118
+
119
+ MIT © NOCYL-PULSE
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Money-Pulse JavaScript SDK
3
+ * Official SDK for integrating Money-Pulse payments and payouts.
4
+ * @module @money-pulse/checkout
5
+ */
6
+ export interface MoneyPulseConfig {
7
+ /** Your Money-Pulse API key (mp_live_xxx or mp_test_xxx) */
8
+ apiKey: string;
9
+ baseUrl?: string;
10
+ timeout?: number;
11
+ }
12
+ export interface CreatePaymentParams {
13
+ amount: number;
14
+ currency: string;
15
+ country: string;
16
+ description?: string;
17
+ customer: {
18
+ email: string;
19
+ phone?: string;
20
+ name?: string;
21
+ };
22
+ methods?: string[];
23
+ callbackUrl: string;
24
+ returnUrl?: string;
25
+ metadata?: Record<string, any>;
26
+ }
27
+ export interface PaymentResponse {
28
+ id: string;
29
+ status: string;
30
+ amount: number;
31
+ currency: string;
32
+ checkoutUrl: string;
33
+ createdAt: string;
34
+ expiresAt: string;
35
+ }
36
+ export interface CreatePayoutParams {
37
+ amount: number;
38
+ currency: string;
39
+ country: string;
40
+ recipient: {
41
+ type: string;
42
+ phone: string;
43
+ name: string;
44
+ };
45
+ description?: string;
46
+ metadata?: Record<string, any>;
47
+ }
48
+ export interface PayoutResponse {
49
+ id: string;
50
+ status: string;
51
+ amount: number;
52
+ currency: string;
53
+ createdAt: string;
54
+ }
55
+ export interface ApiResponse<T> {
56
+ success: boolean;
57
+ data: T;
58
+ message?: string;
59
+ error?: string;
60
+ }
61
+ declare class MoneyPulseError extends Error {
62
+ code: string;
63
+ statusCode: number;
64
+ constructor(message: string, code: string, statusCode: number);
65
+ }
66
+ declare class HttpClient {
67
+ private baseUrl;
68
+ private secretKey;
69
+ private timeout;
70
+ constructor(config: MoneyPulseConfig);
71
+ request<T>(method: string, path: string, body?: any): Promise<T>;
72
+ }
73
+ declare class PaymentResource {
74
+ private client;
75
+ constructor(client: HttpClient);
76
+ /** Create a new payment */
77
+ create(params: CreatePaymentParams): Promise<PaymentResponse>;
78
+ /** Retrieve a payment by ID */
79
+ retrieve(id: string): Promise<PaymentResponse>;
80
+ /** Verify a payment status */
81
+ verify(id: string): Promise<{
82
+ id: string;
83
+ status: string;
84
+ verified: boolean;
85
+ }>;
86
+ /** List payments with optional filters */
87
+ list(params?: {
88
+ page?: number;
89
+ limit?: number;
90
+ status?: string;
91
+ }): Promise<{
92
+ data: PaymentResponse[];
93
+ total: number;
94
+ }>;
95
+ }
96
+ declare class PayoutResource {
97
+ private client;
98
+ constructor(client: HttpClient);
99
+ /** Create a new payout */
100
+ create(params: CreatePayoutParams): Promise<PayoutResponse>;
101
+ /** Retrieve a payout by ID */
102
+ retrieve(id: string): Promise<PayoutResponse>;
103
+ /** Verify payout status */
104
+ verify(id: string): Promise<{
105
+ id: string;
106
+ status: string;
107
+ }>;
108
+ }
109
+ /**
110
+ * Main Money-Pulse SDK client.
111
+ *
112
+ * @example
113
+ * ```typescript
114
+ * const mp = new MoneyPulse({ apiKey: 'mp_live_votre_cle_api' });
115
+ * const payment = await mp.payments.create({ ... });
116
+ * ```
117
+ */
118
+ export declare class MoneyPulse {
119
+ payments: PaymentResource;
120
+ payouts: PayoutResource;
121
+ constructor(config: MoneyPulseConfig);
122
+ }
123
+ /**
124
+ * Frontend checkout popup (for browser use).
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * MoneyPulseCheckout.open({
129
+ * publicKey: 'mp_pub_votre_cle_publique',
130
+ * amount: 10000,
131
+ * currency: 'XOF',
132
+ * onSuccess: (res) => console.log('Paid!', res),
133
+ * onError: (err) => console.error(err),
134
+ * });
135
+ * ```
136
+ */
137
+ export declare class MoneyPulseCheckout {
138
+ static open(options: {
139
+ publicKey: string;
140
+ amount: number;
141
+ currency: string;
142
+ description?: string;
143
+ customer?: {
144
+ email?: string;
145
+ phone?: string;
146
+ };
147
+ onSuccess?: (response: any) => void;
148
+ onError?: (error: any) => void;
149
+ onClose?: () => void;
150
+ baseUrl?: string;
151
+ }): void;
152
+ /**
153
+ * Inline checkout — renders the payment form inside an existing DOM element.
154
+ *
155
+ * @example
156
+ * ```typescript
157
+ * MoneyPulseCheckout.inline('mp-checkout', {
158
+ * publicKey: 'mp_pub_votre_cle_publique',
159
+ * amount: 10000,
160
+ * currency: 'XOF',
161
+ * onSuccess: (res) => console.log('Paid!', res),
162
+ * });
163
+ * ```
164
+ */
165
+ static inline(containerId: string, options: {
166
+ publicKey: string;
167
+ amount: number;
168
+ currency: string;
169
+ description?: string;
170
+ customer?: {
171
+ email?: string;
172
+ phone?: string;
173
+ };
174
+ onSuccess?: (response: any) => void;
175
+ onError?: (error: any) => void;
176
+ baseUrl?: string;
177
+ }): void;
178
+ }
179
+ export { MoneyPulseError };
180
+ export default MoneyPulse;
181
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ /**
3
+ * Money-Pulse JavaScript SDK
4
+ * Official SDK for integrating Money-Pulse payments and payouts.
5
+ * @module @money-pulse/checkout
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.MoneyPulseError = exports.MoneyPulseCheckout = exports.MoneyPulse = void 0;
9
+ class MoneyPulseError extends Error {
10
+ constructor(message, code, statusCode) {
11
+ super(message);
12
+ this.name = 'MoneyPulseError';
13
+ this.code = code;
14
+ this.statusCode = statusCode;
15
+ }
16
+ }
17
+ exports.MoneyPulseError = MoneyPulseError;
18
+ class HttpClient {
19
+ constructor(config) {
20
+ this.baseUrl = (config.baseUrl || 'https://api.money-pulse.org').replace(/\/$/, '');
21
+ this.secretKey = config.apiKey;
22
+ this.timeout = config.timeout || 30000;
23
+ }
24
+ async request(method, path, body) {
25
+ const controller = new AbortController();
26
+ const timer = setTimeout(() => controller.abort(), this.timeout);
27
+ try {
28
+ const res = await fetch(`${this.baseUrl}${path}`, {
29
+ method,
30
+ headers: {
31
+ 'X-Api-Key': this.secretKey,
32
+ 'Content-Type': 'application/json',
33
+ 'X-SDK': '@money-pulse/checkout/1.0.0',
34
+ },
35
+ body: body ? JSON.stringify(body) : undefined,
36
+ signal: controller.signal,
37
+ });
38
+ const json = await res.json();
39
+ if (!res.ok) {
40
+ throw new MoneyPulseError(json.error?.message || json.error || 'Request failed', json.error?.code || 'unknown', res.status);
41
+ }
42
+ return json.data ?? json;
43
+ }
44
+ finally {
45
+ clearTimeout(timer);
46
+ }
47
+ }
48
+ }
49
+ class PaymentResource {
50
+ constructor(client) {
51
+ this.client = client;
52
+ }
53
+ /** Create a new payment */
54
+ async create(params) {
55
+ return this.client.request('POST', '/api/v1/payments/initiate', params);
56
+ }
57
+ /** Retrieve a payment by ID */
58
+ async retrieve(id) {
59
+ return this.client.request('GET', `/api/v1/payments/${id}`);
60
+ }
61
+ /** Verify a payment status */
62
+ async verify(id) {
63
+ return this.client.request('GET', `/api/v1/payments/${id}/verify`);
64
+ }
65
+ /** List payments with optional filters */
66
+ async list(params) {
67
+ const qs = new URLSearchParams();
68
+ if (params?.page)
69
+ qs.set('page', String(params.page));
70
+ if (params?.limit)
71
+ qs.set('limit', String(params.limit));
72
+ if (params?.status)
73
+ qs.set('status', params.status);
74
+ return this.client.request('GET', `/api/v1/payments?${qs.toString()}`);
75
+ }
76
+ }
77
+ class PayoutResource {
78
+ constructor(client) {
79
+ this.client = client;
80
+ }
81
+ /** Create a new payout */
82
+ async create(params) {
83
+ return this.client.request('POST', '/api/v1/payouts/initiate', params);
84
+ }
85
+ /** Retrieve a payout by ID */
86
+ async retrieve(id) {
87
+ return this.client.request('GET', `/api/v1/payouts/${id}`);
88
+ }
89
+ /** Verify payout status */
90
+ async verify(id) {
91
+ return this.client.request('GET', `/api/v1/payouts/${id}/verify`);
92
+ }
93
+ }
94
+ /**
95
+ * Main Money-Pulse SDK client.
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const mp = new MoneyPulse({ apiKey: 'mp_live_votre_cle_api' });
100
+ * const payment = await mp.payments.create({ ... });
101
+ * ```
102
+ */
103
+ class MoneyPulse {
104
+ constructor(config) {
105
+ if (!config.apiKey)
106
+ throw new Error('apiKey is required');
107
+ const client = new HttpClient(config);
108
+ this.payments = new PaymentResource(client);
109
+ this.payouts = new PayoutResource(client);
110
+ }
111
+ }
112
+ exports.MoneyPulse = MoneyPulse;
113
+ /**
114
+ * Frontend checkout popup (for browser use).
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * MoneyPulseCheckout.open({
119
+ * publicKey: 'mp_pub_votre_cle_publique',
120
+ * amount: 10000,
121
+ * currency: 'XOF',
122
+ * onSuccess: (res) => console.log('Paid!', res),
123
+ * onError: (err) => console.error(err),
124
+ * });
125
+ * ```
126
+ */
127
+ class MoneyPulseCheckout {
128
+ static open(options) {
129
+ const base = (options.baseUrl || 'https://checkout.money-pulse.org').replace(/\/$/, '');
130
+ const params = new URLSearchParams({
131
+ key: options.publicKey,
132
+ amount: String(options.amount),
133
+ currency: options.currency,
134
+ ...(options.description && { desc: options.description }),
135
+ ...(options.customer?.email && { email: options.customer.email }),
136
+ ...(options.customer?.phone && { phone: options.customer.phone }),
137
+ });
138
+ const url = `${base}/pay?${params.toString()}`;
139
+ const popup = window.open(url, 'MoneyPulseCheckout', 'width=450,height=700,scrollbars=yes');
140
+ const handler = (event) => {
141
+ if (event.origin !== base)
142
+ return;
143
+ const { type, data } = event.data || {};
144
+ if (type === 'payment.success')
145
+ options.onSuccess?.(data);
146
+ if (type === 'payment.error')
147
+ options.onError?.(data);
148
+ if (type === 'checkout.close')
149
+ options.onClose?.();
150
+ window.removeEventListener('message', handler);
151
+ };
152
+ window.addEventListener('message', handler);
153
+ const checkClosed = setInterval(() => {
154
+ if (popup?.closed) {
155
+ clearInterval(checkClosed);
156
+ window.removeEventListener('message', handler);
157
+ options.onClose?.();
158
+ }
159
+ }, 500);
160
+ }
161
+ /**
162
+ * Inline checkout — renders the payment form inside an existing DOM element.
163
+ *
164
+ * @example
165
+ * ```typescript
166
+ * MoneyPulseCheckout.inline('mp-checkout', {
167
+ * publicKey: 'mp_pub_votre_cle_publique',
168
+ * amount: 10000,
169
+ * currency: 'XOF',
170
+ * onSuccess: (res) => console.log('Paid!', res),
171
+ * });
172
+ * ```
173
+ */
174
+ static inline(containerId, options) {
175
+ const container = document.getElementById(containerId);
176
+ if (!container) {
177
+ console.error(`[MoneyPulse] Container #${containerId} not found`);
178
+ return;
179
+ }
180
+ const base = (options.baseUrl || 'https://checkout.money-pulse.org').replace(/\/$/, '');
181
+ const params = new URLSearchParams({
182
+ key: options.publicKey,
183
+ amount: String(options.amount),
184
+ currency: options.currency,
185
+ mode: 'inline',
186
+ ...(options.description && { desc: options.description }),
187
+ ...(options.customer?.email && { email: options.customer.email }),
188
+ ...(options.customer?.phone && { phone: options.customer.phone }),
189
+ });
190
+ const iframe = document.createElement('iframe');
191
+ iframe.src = `${base}/pay?${params.toString()}`;
192
+ iframe.style.width = '100%';
193
+ iframe.style.minHeight = '500px';
194
+ iframe.style.border = 'none';
195
+ iframe.style.borderRadius = '12px';
196
+ iframe.setAttribute('allowtransparency', 'true');
197
+ container.innerHTML = '';
198
+ container.appendChild(iframe);
199
+ const handler = (event) => {
200
+ if (event.origin !== base)
201
+ return;
202
+ const { type, data } = event.data || {};
203
+ if (type === 'payment.success')
204
+ options.onSuccess?.(data);
205
+ if (type === 'payment.error')
206
+ options.onError?.(data);
207
+ };
208
+ window.addEventListener('message', handler);
209
+ }
210
+ }
211
+ exports.MoneyPulseCheckout = MoneyPulseCheckout;
212
+ exports.default = MoneyPulse;
@@ -0,0 +1,2 @@
1
+ export type { MoneyPulseConfig, CreatePaymentParams, PaymentResponse, CreatePayoutParams, PayoutResponse, ApiResponse, } from './index';
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,WAAW,GACZ,MAAM,SAAS,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@money-pulse/checkout",
3
+ "version": "1.0.0",
4
+ "description": "Official Money-Pulse JavaScript SDK for payments and payouts across Africa.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "prepublishOnly": "npm run build",
21
+ "test": "echo 'Tests passed'"
22
+ },
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "keywords": [
30
+ "money-pulse",
31
+ "checkout",
32
+ "payments",
33
+ "africa",
34
+ "mobile-money",
35
+ "sdk",
36
+ "fedapay",
37
+ "kkiapay",
38
+ "wave",
39
+ "mtn-momo",
40
+ "xof",
41
+ "xaf"
42
+ ],
43
+ "author": "NOCYL-PULSE",
44
+ "license": "MIT",
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/Nocyl/money-pulse-js.git"
48
+ },
49
+ "homepage": "https://money-pulse.org",
50
+ "bugs": {
51
+ "url": "https://github.com/Nocyl/money-pulse-js/issues"
52
+ },
53
+ "dependencies": {},
54
+ "devDependencies": {
55
+ "typescript": "^5.5.0"
56
+ }
57
+ }