@kuvarpay/sdk 1.2.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/README.md +96 -129
  2. package/index.js +13 -4
  3. package/index.mjs +12 -3
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -1,162 +1,129 @@
1
1
  # KuvarPay Server SDK
2
2
 
3
- Backend-focused SDK for creating and verifying checkout sessions, subscription sessions, invoices, and transactions using your Business SECRET API key.
3
+ Official Node.js SDK for integrating **KuvarPay**, the ultimate fiat gateway for the crypto economy. This SDK allows you to handle checkout sessions, direct crypto-to-fiat transactions, recurring subscriptions, and split payments with ease.
4
4
 
5
- Works with Node 18+ (global `fetch`) or any environment where you can supply a `fetch` implementation. Also includes quick PHP cURL examples.
5
+ [![npm version](https://badge.fury.io/js/@kuvarpay%2Fsdk.svg)](https://badge.fury.io/js/@kuvarpay%2Fsdk)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
7
 
7
- ## Installation
8
+ ## 🚀 Installation
8
9
 
9
- This repository includes the SDK source files. You can copy `server-sdk/index.js` (CommonJS) or `server-sdk/index.mjs` (ESM) into your backend project, or import them via your build tooling.
10
+ ```bash
11
+ npm install @kuvarpay/sdk
12
+ ```
10
13
 
11
- > Requirements:
12
- > - Business ID
13
- > - SECRET API Key (server-only)
14
- > - Payment API Base URL (e.g., `https://pay.kuvarpay.com` or your payment host)
14
+ ## 🛠️ Quick Start (Speed Mode)
15
15
 
16
- ## Node (CommonJS) Usage
16
+ Initiate a payment and get a crypto deposit address in one line of code:
17
17
 
18
- ```js
19
- // index.js (Node 18+)
20
- const { KuvarPayServer } = require('./server-sdk/index.js');
18
+ ```javascript
19
+ const { KuvarPayServer } = require('@kuvarpay/sdk');
21
20
 
22
21
  const kv = new KuvarPayServer({
23
- baseUrl: process.env.PAYMENT_API_BASE_URL, // e.g., https://pay.kuvarpay.com
24
- businessId: process.env.KUVARPAY_BUSINESS_ID,
25
- secretApiKey: process.env.KUVARPAY_SECRET_API_KEY,
22
+ businessId: 'your_business_id',
23
+ secretApiKey: 'rsp_secret_...' // Starts with rsp_secret_
26
24
  });
27
25
 
28
- async function verify(sessionId) {
29
- const result = await kv.verifyPayment(sessionId);
30
- console.log('Verified?', result.verified, 'status:', result.status);
26
+ async function startPayment() {
27
+ const payment = await kv.createDirectPayment({
28
+ amount: 5000,
29
+ currency: 'NGN',
30
+ fromCurrency: 'USDT',
31
+ fromNetwork: 'BSC',
32
+ customerEmail: 'customer@example.com'
33
+ });
34
+
35
+ console.log('Send USDT to:', payment.depositAddress);
36
+ console.log('Exact amount:', payment.fromAmount); // e.g. 3.76 USDT
31
37
  }
38
+ ```
32
39
 
33
- async function session(sessionId) {
34
- const s = await kv.getSessionStatus(sessionId);
35
- console.log('Session:', s);
36
- }
40
+ ---
37
41
 
38
- async function txn(transactionId) {
39
- const t = await kv.getTransactionStatus(transactionId);
40
- console.log('Transaction:', t);
41
- }
42
- ```
42
+ ## ⚙️ Configuration
43
43
 
44
- ## Node (ESM) Usage
44
+ The SDK defaults to the KuvarPay Production API (`https://payment.kuvarpay.com`).
45
45
 
46
- ```js
47
- // index.mjs (Node 18+)
48
- import { KuvarPayServer } from './server-sdk/index.mjs';
46
+ | Option | Description | Env Fallback |
47
+ | :--- | :--- | :--- |
48
+ | `businessId` | Your KuvarPay Business ID | - |
49
+ | `secretApiKey` | Your Production Secret Key | - |
50
+ | `baseUrl` | Overrides the API endpoint | `KUVARPAY_API_BASE_URL` |
51
+ | `timeoutMs` | Request timeout (default 60s) | - |
49
52
 
50
- const kv = new KuvarPayServer({
51
- baseUrl: process.env.PAYMENT_API_BASE_URL,
52
- businessId: process.env.KUVARPAY_BUSINESS_ID,
53
- secretApiKey: process.env.KUVARPAY_SECRET_API_KEY,
54
- });
53
+ ---
55
54
 
56
- const result = await kv.verifyPayment('sess_123');
57
- console.log(result);
58
- ```
55
+ ## 📖 API Reference
59
56
 
60
- ### Node < 18
57
+ ### 💳 Payments & Transactions
61
58
 
62
- Provide your own `fetchImpl` (e.g., from `node-fetch`) when constructing:
59
+ | Method | Description |
60
+ | :--- | :--- |
61
+ | `createDirectPayment(data)` | **Recommended**. Creates a session & transaction in one call. |
62
+ | `createCheckoutSession(data)` | Creates a checkout session (returns `approvalUrl`). |
63
+ | `createTransaction(data)` | Manually initiates a crypto transaction for an existing session. |
64
+ | `verifyPayment(sessionId)` | Convenience method to check if a payment is confirmed. |
65
+ | `getSessionStatus(sessionId)`| Fetches full session/transaction status. |
63
66
 
64
- ```js
65
- const fetch = (...args) => import('node-fetch').then(mod => mod.default(...args));
66
- const kv = new KuvarPayServer({ baseUrl, businessId, secretApiKey, fetchImpl: fetch });
67
- ```
67
+ ### 📈 Subaccounts & Split Payments
68
68
 
69
- ## PHP cURL Examples
70
-
71
- Replace `PAYMENT_API_BASE_URL`, `BUSINESS_ID`, and `SECRET_API_KEY` with your values.
72
-
73
- ### Verify Payment (Checkout Session)
74
-
75
- ```php
76
- $base = getenv('PAYMENT_API_BASE_URL');
77
- $businessId = getenv('KUVARPAY_BUSINESS_ID');
78
- $secret = getenv('KUVARPAY_SECRET_API_KEY');
79
- $sessionId = 'sess_123';
80
-
81
- $ch = curl_init("$base/api/v1/checkout-sessions/" . urlencode($sessionId));
82
- curl_setopt($ch, CURLOPT_HTTPHEADER, [
83
- "Accept: application/json",
84
- "X-API-Key: $secret",
85
- "X-Business-ID: $businessId"
86
- ]);
87
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
88
- $resp = curl_exec($ch);
89
- $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
90
- curl_close($ch);
91
-
92
- if ($statusCode >= 200 && $statusCode < 300) {
93
- $data = json_decode($resp, true);
94
- $status = $data['status'] ?? ($data['data']['status'] ?? null);
95
- $verified = ($status === 'COMPLETED');
96
- // handle $verified
97
- } else {
98
- // handle error
99
- }
100
- ```
69
+ | Method | Description |
70
+ | :--- | :--- |
71
+ | `createSubaccount(data)` | Create a vendor subaccount for split settlements. |
72
+ | `listSubaccounts()` | Fetch all subaccounts for your business. |
73
+ | `createSplitGroup(data)` | Define percentage-based distribution between subaccounts. |
101
74
 
102
- ### Transaction Status
103
-
104
- ```php
105
- $transactionId = 'tx_123';
106
- $ch = curl_init("$base/api/v1/transactions/" . urlencode($transactionId));
107
- curl_setopt($ch, CURLOPT_HTTPHEADER, [
108
- "Accept: application/json",
109
- "X-API-Key: $secret",
110
- "X-Business-ID: $businessId"
111
- ]);
112
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
113
- $resp = curl_exec($ch);
114
- $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
115
- curl_close($ch);
116
-
117
- if ($statusCode >= 200 && $statusCode < 300) {
118
- $data = json_decode($resp, true);
119
- $status = $data['status'] ?? null;
120
- // handle $status
121
- } else {
122
- // handle error
123
- }
124
- ```
75
+ ### 🔄 Subscriptions
76
+
77
+ | Method | Description |
78
+ | :--- | :--- |
79
+ | `createDirectSubscription(data)` | Initiates a subscription setup and returns an approval URL. |
80
+ | `renewSubscription(subId)` | Manually trigger a renewal for an active allowance. |
81
+ | `cancelSubscription(subId)` | Hard-cancel a customer subscription. |
82
+ | `createMeteredInvoice(subId, data)`| Charge a customer based on usage (Metered billing). |
83
+
84
+ ### 🏦 Banks & Verification
85
+
86
+ | Method | Description |
87
+ | :--- | :--- |
88
+ | `getBanks(currency)` | List supported settlement banks for a specific currency. |
89
+ | `resolveBankAccount(data)` | Verify bank account names before creating subaccounts. |
90
+
91
+ ---
92
+
93
+ ## 🔒 Security: Webhook Verification
125
94
 
126
- ## API Reference
95
+ Verify that incoming webhooks are genuinely from KuvarPay using HMAC-SHA256:
127
96
 
128
- Payments:
129
- - `createCheckoutSession(data)` `{ sessionId, authToken?, approvalUrl?, raw }`
130
- - `getSessionStatus(sessionId)` `{ sessionId, status, transactionId?, raw }`
131
- - `getTransactionStatus(transactionId)` `{ transactionId, status, raw }`
132
- - `verifyPayment(sessionId)` → `{ verified: boolean, status, sessionId, transactionId?, raw }`
97
+ ```javascript
98
+ app.post('/webhooks/kuvarpay', (req, res) => {
99
+ const signature = req.headers['x-kuvarpay-signature'];
100
+ const payload = req.body; // Raw body object
133
101
 
134
- Subscriptions:
135
- - `createSubscriptionCheckoutSession(data)` → `{ sessionId, approvalUrl?, raw }`
136
- - `getSubscriptionCheckoutSession(id)` → full session details
137
- - `confirmSubscriptionCheckoutSession(id, body?)` → confirmation response
138
- - `getSubscription(subscriptionId)` → full subscription details
139
- - `cancelSubscription(subscriptionId, body?)` → cancellation response
140
- - `createMeteredInvoice(subscriptionId, invoiceData)` → invoice response
141
- - `createSubscriptionInvoice(subscriptionId, invoiceData)` → alias to metered invoice
142
- - `scheduleSubscriptionInvoice(subscriptionId, invoiceData)` → enforces `chargeSchedule: 'SCHEDULED'`
143
- - `createRenewalCheckoutSession(body)` → renewal checkout creation
144
- - `renewSubscription(subscriptionId, body?)` → direct renew trigger
102
+ const isValid = kv.verifyWebhookSignature(payload, signature);
145
103
 
146
- Relay Authorization (metered):
147
- - `createRelayAuthorization(body)`
148
- - `getRelayAuthorizationStatus(body)`
149
- - `revokeRelayAuthorization(body)` (supports legacy path via `{ useLegacyPath: true }`)
104
+ if (isValid) {
105
+ // Process payment (e.g. status === 'completed')
106
+ res.status(200).send();
107
+ } else {
108
+ res.status(401).send('Invalid signature');
109
+ }
110
+ });
111
+ ```
112
+
113
+ ---
150
114
 
151
- Notes:
152
- - Status values commonly include `PENDING`, `ARMED`, `PROCESSING`, `COMPLETED`, `FAILED`, `EXPIRED`, `CANCELLED`, etc.
153
- - `verifyPayment` returns `verified = true` when `status === 'COMPLETED'`.
115
+ ## 🧩 TypeScript Support
154
116
 
155
- ## Security
117
+ This SDK includes a full `index.d.ts` definition file. You get auto-completion and type checking out of the box.
118
+
119
+ ```typescript
120
+ import { KuvarPayServer } from '@kuvarpay/sdk';
121
+
122
+ const kv = new KuvarPayServer({ ... });
123
+ ```
156
124
 
157
- - Always keep your SECRET API key in server-side environment variables. Never expose it to the browser.
158
- - Use HTTPS for all API calls.
125
+ ---
159
126
 
160
- ## Parity with Client SDK
127
+ ## 📄 License
161
128
 
162
- The Server SDK provides server-side equivalents of the Client SDK’s network operations (creating sessions, fetching statuses, managing subscriptions, and invoices). It does not implement browser UI features like `openPayment(...)` / `openSubscription(...)` modals, postMessage callbacks, or iframe overlays. Use the Client SDK in the browser for UI, and the Server SDK on your backend for secure API operations.
129
+ MIT © KuvarPay Development Team
package/index.js CHANGED
@@ -389,9 +389,19 @@ class KuvarPayServer {
389
389
  businessId: subscriptionData?.businessId || this.businessId,
390
390
  }, subscriptionData);
391
391
  const data = await this._post('/api/v1/subscriptions/checkout-sessions', payload);
392
+ const body = data.data || data.checkoutSession || data;
393
+ const approvalUrl = body.approvalUrl || body.approval_url || body.approvalUrl;
394
+
395
+ // Fallback: Extract ID from approval URL if missing (e.g., .../subscriptions/ID)
396
+ let sessionId = body.sessionId || body.id || body.uid;
397
+ if (!sessionId && approvalUrl) {
398
+ const parts = approvalUrl.split('/');
399
+ sessionId = parts[parts.length - 1];
400
+ }
401
+
392
402
  return {
393
- sessionId: data?.sessionId || data?.id || data?.checkoutSession?.id || data?.checkoutSession?.uid,
394
- approvalUrl: data?.approvalUrl || data?.approval_url || data?.checkoutSession?.approval_url,
403
+ sessionId,
404
+ approvalUrl,
395
405
  raw: data,
396
406
  };
397
407
  }
@@ -472,10 +482,9 @@ class KuvarPayServer {
472
482
  */
473
483
  async createDirectSubscription(data) {
474
484
  const payload = Object.assign({
475
- billingMode: data.billingMode || 'FIXED',
485
+ billingMode: data.amount ? 'METERED' : (data.billingMode || 'FIXED'),
476
486
  }, data);
477
487
 
478
- // If amount/currency is provided but expectedUsage is not, map it
479
488
  if (data.amount && data.currency && !data.expectedUsage) {
480
489
  payload.expectedUsage = {
481
490
  amount: data.amount,
package/index.mjs CHANGED
@@ -274,9 +274,18 @@ export class KuvarPayServer {
274
274
  businessId: subscriptionData?.businessId || this.businessId,
275
275
  }, subscriptionData);
276
276
  const data = await this._post('/api/v1/subscriptions/checkout-sessions', payload);
277
+ const body = data.data || data.checkoutSession || data;
278
+ const approvalUrl = body.approvalUrl || body.approval_url || body.approvalUrl;
279
+
280
+ let sessionId = body.sessionId || body.id || body.uid;
281
+ if (!sessionId && approvalUrl) {
282
+ const parts = approvalUrl.split('/');
283
+ sessionId = parts[parts.length - 1];
284
+ }
285
+
277
286
  return {
278
- sessionId: data?.sessionId || data?.id || data?.checkoutSession?.id || data?.checkoutSession?.uid,
279
- approvalUrl: data?.approvalUrl || data?.approval_url || data?.checkoutSession?.approval_url,
287
+ sessionId,
288
+ approvalUrl,
280
289
  raw: data,
281
290
  };
282
291
  }
@@ -328,7 +337,7 @@ export class KuvarPayServer {
328
337
 
329
338
  async createDirectSubscription(data) {
330
339
  const payload = Object.assign({
331
- billingMode: data.billingMode || 'FIXED',
340
+ billingMode: data.amount ? 'METERED' : (data.billingMode || 'FIXED'),
332
341
  }, data);
333
342
 
334
343
  if (data.amount && data.currency && !data.expectedUsage) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kuvarpay/sdk",
3
- "version": "1.2.2",
3
+ "version": "1.3.1",
4
4
  "description": "Official KuvarPay Server SDK for Node.js",
5
5
  "main": "index.js",
6
6
  "module": "index.mjs",