@durrapay/sdk 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.
Files changed (3) hide show
  1. package/README.md +47 -0
  2. package/index.mjs +101 -0
  3. package/package.json +19 -0
package/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @durrapay/sdk (Node)
2
+
3
+ Thin, dependency-free client for the [DurraPay Platform API](https://developer.durrapay.com).
4
+ Requires Node 18+.
5
+
6
+ ```bash
7
+ npm install @durrapay/sdk
8
+ ```
9
+
10
+ ```js
11
+ import { DurraPay } from '@durrapay/sdk'
12
+
13
+ const dp = new DurraPay({
14
+ apiKey: process.env.DURRAPAY_KEY, // dpk_test_... or dpk_live_...
15
+ // baseUrl: 'https://api.durrapay.com/v1', // default
16
+ })
17
+
18
+ // Who am I?
19
+ console.log(await dp.me())
20
+
21
+ // Collect in Kenya (M-Pesa STK)
22
+ const c = await dp.collections.stk({
23
+ phone: '254712345678',
24
+ amount_minor: 150000, // KES 1,500.00 (minor units)
25
+ currency: 'KES',
26
+ reference: 'ORDER-1001',
27
+ })
28
+
29
+ // Poll status (or use webhooks)
30
+ await dp.collections.get(c.payment_id)
31
+
32
+ // Send cross-border (FX + payout)
33
+ const quote = await dp.transfers.quote({ from_currency: 'KES', destination_country: 'TZ', from_amount_minor: 1000000 })
34
+ await dp.transfers.create({
35
+ quote_id: quote.quote_id,
36
+ dest_type: 'PHONE',
37
+ dest_phone: '255712345678',
38
+ dest_name: 'Jane Doe',
39
+ })
40
+
41
+ // Customers, recipients, payment links, balances, usage…
42
+ await dp.customers.create({ name: 'Jane Doe', email: 'jane@example.com' })
43
+ await dp.balances()
44
+ ```
45
+
46
+ Idempotency keys are auto-generated for POSTs (override with `{ idempotencyKey }`).
47
+ Errors throw `DurraPayError` with `.status`, `.code`, and `.body`.
package/index.mjs ADDED
@@ -0,0 +1,101 @@
1
+ // DurraPay Node SDK — a thin, dependency-free client for the /v1 Platform API.
2
+ // Requires Node 18+ (global fetch).
3
+ //
4
+ // import { DurraPay } from '@durrapay/sdk'
5
+ // const dp = new DurraPay({ apiKey: process.env.DURRAPAY_KEY })
6
+ // const me = await dp.me()
7
+
8
+ import { randomUUID } from 'node:crypto'
9
+
10
+ export class DurraPayError extends Error {
11
+ constructor(message, { status, code, body } = {}) {
12
+ super(message)
13
+ this.name = 'DurraPayError'
14
+ this.status = status
15
+ this.code = code
16
+ this.body = body
17
+ }
18
+ }
19
+
20
+ export class DurraPay {
21
+ constructor({ apiKey, baseUrl = 'https://api.durrapay.com/v1', fetch: fetchImpl } = {}) {
22
+ if (!apiKey) throw new Error('DurraPay: apiKey is required')
23
+ this._apiKey = apiKey
24
+ this._baseUrl = baseUrl.replace(/\/$/, '')
25
+ this._fetch = fetchImpl || globalThis.fetch
26
+ }
27
+
28
+ async _request(method, path, { body, idempotencyKey, query } = {}) {
29
+ let url = this._baseUrl + path
30
+ if (query) {
31
+ const qs = new URLSearchParams(
32
+ Object.entries(query).filter(([, v]) => v !== undefined && v !== null)
33
+ ).toString()
34
+ if (qs) url += '?' + qs
35
+ }
36
+ const headers = { 'X-DurraPay-API-Key': this._apiKey }
37
+ if (body) headers['Content-Type'] = 'application/json'
38
+ if (method === 'POST') headers['Idempotency-Key'] = idempotencyKey || randomUUID()
39
+
40
+ const res = await this._fetch(url, {
41
+ method,
42
+ headers,
43
+ body: body ? JSON.stringify(body) : undefined,
44
+ })
45
+ const json = await res.json().catch(() => ({}))
46
+ if (!res.ok || json.success === false) {
47
+ const err = json.error || {}
48
+ throw new DurraPayError(err.message || `HTTP ${res.status}`, {
49
+ status: res.status,
50
+ code: err.code,
51
+ body: json,
52
+ })
53
+ }
54
+ return json.data
55
+ }
56
+
57
+ // --- identity / account ---
58
+ me() { return this._request('GET', '/me') }
59
+ balances() { return this._request('GET', '/balances') }
60
+ usage(days = 30) { return this._request('GET', '/usage', { query: { days } }) }
61
+ corridors(from = 'KES') { return this._request('GET', '/corridors', { query: { from } }) }
62
+
63
+ // --- collections ---
64
+ collections = {
65
+ stk: (input, opts = {}) => this._request('POST', '/collections/stk', { body: input, idempotencyKey: opts.idempotencyKey }),
66
+ list: (query = {}) => this._request('GET', '/collections', { query }),
67
+ get: (id) => this._request('GET', `/collections/${id}`),
68
+ }
69
+
70
+ // --- payment links ---
71
+ paymentLinks = {
72
+ create: (input, opts = {}) => this._request('POST', '/payment-links', { body: input, idempotencyKey: opts.idempotencyKey }),
73
+ list: (query = {}) => this._request('GET', '/payment-links', { query }),
74
+ delete: (id) => this._request('DELETE', `/payment-links/${id}`),
75
+ }
76
+
77
+ // --- customers ---
78
+ customers = {
79
+ create: (input) => this._request('POST', '/customers', { body: input }),
80
+ list: (query = {}) => this._request('GET', '/customers', { query }),
81
+ get: (id) => this._request('GET', `/customers/${id}`),
82
+ delete: (id) => this._request('DELETE', `/customers/${id}`),
83
+ }
84
+
85
+ // --- recipients ---
86
+ recipients = {
87
+ create: (input) => this._request('POST', '/recipients', { body: input }),
88
+ list: () => this._request('GET', '/recipients'),
89
+ delete: (id) => this._request('DELETE', `/recipients/${id}`),
90
+ }
91
+
92
+ // --- transfers (cross-border send) ---
93
+ transfers = {
94
+ quote: (input) => this._request('POST', '/transfers/quote', { body: input }),
95
+ create: (input, opts = {}) => this._request('POST', '/transfers', { body: input, idempotencyKey: opts.idempotencyKey }),
96
+ list: (query = {}) => this._request('GET', '/transfers', { query }),
97
+ get: (id) => this._request('GET', `/transfers/${id}`),
98
+ }
99
+ }
100
+
101
+ export default DurraPay
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@durrapay/sdk",
3
+ "version": "0.1.0",
4
+ "description": "DurraPay Platform API client for Node.js",
5
+ "type": "module",
6
+ "main": "index.mjs",
7
+ "exports": { ".": "./index.mjs" },
8
+ "engines": { "node": ">=18" },
9
+ "files": ["index.mjs", "README.md"],
10
+ "keywords": ["durrapay", "payments", "mpesa", "africa", "fintech"],
11
+ "license": "MIT",
12
+ "homepage": "https://developer.durrapay.com",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/Durrafx-repos/durrapy-sdks.git",
16
+ "directory": "node"
17
+ },
18
+ "bugs": { "url": "https://github.com/Durrafx-repos/durrapy-sdks/issues" }
19
+ }