{"_id":"@dosymbek/qpaynet-client","_rev":"2-22381d24d3732d27a5fd583c5b356a85","name":"@dosymbek/qpaynet-client","dist-tags":{"latest":"1.0.4"},"versions":{"1.0.3":{"name":"@dosymbek/qpaynet-client","version":"1.0.3","keywords":["aevion","qpaynet","payments","wallet","kzt","tenge","merchant","webhook","hmac","idempotency","stripe-alternative"],"author":{"name":"AEVION"},"license":"Apache-2.0","_id":"@dosymbek/qpaynet-client@1.0.3","maintainers":[{"name":"dosymbek","email":"yahiin1978@gmail.com"}],"homepage":"https://aevion.app/qpaynet","bugs":{"url":"https://github.com/Dossymbek281078/AEVION/issues"},"dist":{"shasum":"55e1fcfb257d0464abe0fa0d1c5ce5435ab211aa","tarball":"https://registry.npmjs.org/@dosymbek/qpaynet-client/-/qpaynet-client-1.0.3.tgz","fileCount":6,"integrity":"sha512-qCihOBogOmllhmTjWFy+iPCeCHzQux//Jyt1N5HGV7M/u5htqj105qYswTk1vwyvMS0tw8joBVwI/qctv3M/Kg==","signatures":[{"sig":"MEQCIA7sHuN2RjnDAIzz6kqm2XBD/UdBU9ThnOd14AcohO7EAiBQPg54XYz7KjHohqfdHh0zqwkpzw8DtwTaApQ3VuXE/Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62904},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"1bf47ed39caa13d43d085f749364738ad46dcd26","scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"dosymbek","email":"yahiin1978@gmail.com"},"repository":{"url":"git+https://github.com/Dossymbek281078/AEVION.git","type":"git","directory":"packages/qpaynet-client"},"_npmVersion":"11.6.2","description":"TypeScript client for AEVION QPayNet — embedded payment infrastructure with HMAC webhooks, idempotent transfers, merchant keys, payment links.","directories":{},"_nodeVersion":"24.11.1","_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.4.0"},"_npmOperationalInternal":{"tmp":"tmp/qpaynet-client_1.0.3_1778233002709_0.07971782373262037","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@dosymbek/qpaynet-client","version":"1.0.4","description":"TypeScript client for AEVION QPayNet — embedded payment infrastructure with HMAC webhooks, idempotent transfers, merchant keys, payment links.","license":"Apache-2.0","author":{"name":"AEVION"},"homepage":"https://aevion.app/qpaynet","repository":{"type":"git","url":"git+https://github.com/Dossymbek281078/AEVION.git","directory":"packages/qpaynet-client"},"type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"build":"tsc -p tsconfig.json","typecheck":"tsc -p tsconfig.json --noEmit"},"keywords":["aevion","qpaynet","payments","wallet","kzt","tenge","merchant","webhook","hmac","idempotency","stripe-alternative"],"engines":{"node":">=18"},"devDependencies":{"typescript":"^6.0.3"},"gitHead":"dbb8f740c5d37d62e3d798c366b330ca0baa148d","_id":"@dosymbek/qpaynet-client@1.0.4","bugs":{"url":"https://github.com/Dossymbek281078/AEVION/issues"},"_nodeVersion":"24.11.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-YKXTODEVVGchqWCZgGiLFC/up14JRnMvc0PBL87gvEOzjX6PdN5nRJpvtgMA3F7GJ/MQIavP+hyr4pLiOeWb5w==","shasum":"5173b90764f0a4184756893188e4c1e0ce289b44","tarball":"https://registry.npmjs.org/@dosymbek/qpaynet-client/-/qpaynet-client-1.0.4.tgz","fileCount":6,"unpackedSize":62835,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHvxMHgjXdYCQmDjL1yf16x4nT0MghOOHldv89Qn8xHAAiBuIbQj2v1GKTEZjlreKNnZm5G5EMfthZWBMWaZGqbB4Q=="}]},"_npmUser":{"name":"dosymbek","email":"yahiin1978@gmail.com"},"directories":{},"maintainers":[{"name":"dosymbek","email":"yahiin1978@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/qpaynet-client_1.0.4_1779098455867_0.16259877324016636"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-08T09:36:42.597Z","modified":"2026-05-18T10:00:56.096Z","1.0.3":"2026-05-08T09:36:42.848Z","1.0.4":"2026-05-18T10:00:55.997Z"},"bugs":{"url":"https://github.com/Dossymbek281078/AEVION/issues"},"author":{"name":"AEVION"},"license":"Apache-2.0","homepage":"https://aevion.app/qpaynet","keywords":["aevion","qpaynet","payments","wallet","kzt","tenge","merchant","webhook","hmac","idempotency","stripe-alternative"],"repository":{"type":"git","url":"git+https://github.com/Dossymbek281078/AEVION.git","directory":"packages/qpaynet-client"},"description":"TypeScript client for AEVION QPayNet — embedded payment infrastructure with HMAC webhooks, idempotent transfers, merchant keys, payment links.","maintainers":[{"name":"dosymbek","email":"yahiin1978@gmail.com"}],"readme":"# @aevion/qpaynet-client\n\nTypeScript client for **AEVION QPayNet** — embedded payment infrastructure for the AEVION ecosystem.\n\n- 🇰🇿 KZT-native (tiin precision, daily/transfer caps, soft-KYC)\n- 🔐 HMAC-signed webhooks (`X-Aevion-Event-Id` for partner-side dedup)\n- 🔁 Idempotency-Key on every money path\n- 🤝 Merchant API keys with scopes (charge / read / refund)\n- 🛡 Built-in retry on 429/5xx, configurable timeout\n- ⚡ Zero dependencies, isomorphic (Web Crypto + global `fetch` — works in Node 18+, Bun, Deno, browsers)\n\n## Install\n\n```bash\nnpm install @aevion/qpaynet-client\n```\n\nRequires Node 18+, Bun, Deno, or any modern browser (uses global `fetch` + Web Crypto SubtleCrypto). No `@types/node` needed.\n\n## Quick start\n\n### End-user wallet management (Bearer JWT)\n\n```ts\nimport { QPayNetClient } from \"@aevion/qpaynet-client\";\n\nconst client = new QPayNetClient({\n  baseUrl: \"https://aevion-production-a70c.up.railway.app\",\n  token: process.env.AEVION_JWT,\n});\n\n// Create wallet with partner metadata\nconst wallet = await client.wallets.create({\n  name: \"Main\",\n  metadata: { merchantOrderId: \"ORD-2026-001\" },\n});\n\n// Top up + transfer with idempotency\nawait client.deposit({ walletId: wallet.id, amount: 5000 });\nawait client.transfer(\n  { fromWalletId: wallet.id, toWalletId: \"...\", amount: 1000 },\n  { idempotencyKey: \"transfer-2026-05-06-001\" },\n);\n```\n\n### Merchant flow (X-API-Key)\n\n```ts\nconst merchant = new QPayNetClient({\n  baseUrl: \"...\",\n  merchantKey: \"qpn_live_xxx\",   // get from POST /merchant/keys\n});\n\nawait merchant.merchant.charge(\n  { customerWalletId: \"...\", amount: 1500, description: \"Order #ORD-123\" },\n  { idempotencyKey: \"charge-ord-123\" },\n);\n```\n\n### Receiving webhooks\n\n```ts\nimport { verifyWebhook } from \"@aevion/qpaynet-client\";\nimport express from \"express\";\n\nconst app = express();\napp.post(\"/webhooks/aevion\",\n  express.raw({ type: \"application/json\" }),    // ⚠ raw body for HMAC\n  async (req, res) => {\n    const ok = await verifyWebhook({\n      secret: process.env.AEVION_WEBHOOK_SECRET!,\n      timestamp: req.headers[\"x-aevion-timestamp\"] as string,\n      signature: req.headers[\"x-aevion-signature\"] as string,\n      rawBody: req.body,\n    });\n    if (!ok) return res.status(401).send(\"invalid signature\");\n\n    // Dedupe — we may retry up to 5 times with the same event-id\n    const eventId = req.headers[\"x-aevion-event-id\"] as string;\n    if (await alreadyProcessed(eventId)) {\n      return res.json({ received: true });\n    }\n    await markProcessed(eventId);\n\n    const payload = JSON.parse(req.body.toString());\n    // ...handle payment_request.paid, refund_issued, etc...\n    res.json({ received: true });\n  },\n);\n```\n\n## Error handling\n\nAll API errors throw `QPayNetError` with a stable `code` matching the\nserver's [error code registry](https://aevion-production-a70c.up.railway.app/api/qpaynet/openapi.json) (see `x-error-codes`):\n\n```ts\nimport { QPayNetError } from \"@aevion/qpaynet-client\";\n\ntry {\n  await client.transfer({ fromWalletId, toWalletId, amount: 99999999 });\n} catch (err) {\n  if (err instanceof QPayNetError) {\n    if (err.code === \"transfer_amount_exceeds_max\") { /* show cap to user */ }\n    if (err.code === \"kyc_required\") { /* redirect to /kyc */ }\n    if (err.code === \"rate_limit_exceeded\") { /* backoff */ }\n  }\n}\n```\n\nCommon codes:\n- `validation_failed` — see `err.field` and `err.details.reason`\n- `wallet_inactive` — frozen or closed\n- `insufficient_balance`\n- `kyc_required` — monthly outgoing > threshold\n- `idempotency_key_body_mismatch` — same key, different body (409)\n- `scope_missing` — merchant key lacks the required scope\n- `rate_limit_exceeded` — back off (auto-retried up to `maxRetries`)\n\n## Configuration\n\n```ts\nnew QPayNetClient({\n  baseUrl: \"https://...\",\n  token: \"...\",                   // OR merchantKey, not both\n  merchantKey: \"qpn_live_...\",\n  timeoutMs: 10000,               // per-request, default 10s\n  maxRetries: 3,                  // 5xx + 429, default 3\n  fetch: customFetch,             // override (tests/proxies)\n  userAgent: \"MyApp/1.0\",\n});\n```\n\n## API reference\n\nAll methods that move money accept an optional `{ idempotencyKey }` second arg.\n\n| Method | Path | Notes |\n|---|---|---|\n| `client.deposit(body, opts?)` | POST `/deposit` | sandbox top-up |\n| `client.withdraw(body, opts?)` | POST `/withdraw` | 0.1% fee |\n| `client.transfer(body, opts?)` | POST `/transfer` | atomic, KYC-aware |\n| `client.listTransactions(walletId?)` | GET `/transactions` | |\n| `client.exportTransactionsCsv(walletId?)` | GET `/transactions.csv` | rate-limited 5/min |\n| `client.stats()` | GET `/stats` | public |\n| `client.health()` | GET `/health` | pool + stuck delivery counts |\n| `client.wallets.create(body)` | POST `/wallets` | metadata up to 4KB |\n| `client.wallets.list()` | GET `/wallets` | |\n| `client.wallets.get(id)` | GET `/wallets/:id` | |\n| `client.wallets.lookup(id)` | GET `/wallets/:id/public` | no auth, no balance |\n| `client.wallets.update(id, body)` | PATCH `/wallets/:id` | name + metadata |\n| `client.wallets.close(id)` | POST `/wallets/:id/close` | terminal, requires zero balance |\n| `client.wallets.depositCheckout(body)` | POST `/deposit/checkout` | Stripe Checkout |\n| `client.merchant.createKey(body)` | POST `/merchant/keys` | scopes: charge,read,refund |\n| `client.merchant.listKeys()` | GET `/merchant/keys` | |\n| `client.merchant.revokeKey(id)` | DELETE `/merchant/keys/:id` | |\n| `client.merchant.charge(body, opts?)` | POST `/merchant/charge` | requires `charge` scope |\n| `client.requests.create(body)` | POST `/requests` | returns `notifySecret` once |\n| `client.requests.list()` | GET `/requests` | |\n| `client.requests.getPublic(token)` | GET `/requests/:token` | no auth |\n| `client.requests.pay(token, body, opts?)` | POST `/requests/:token/pay` | fires HMAC webhook |\n| `client.requests.cancel(id)` | DELETE `/requests/:id` | |\n| `client.webhooks.subscribe(body)` | POST `/webhook-subs` | |\n| `client.webhooks.list()` | GET `/webhook-subs` | |\n| `client.webhooks.unsubscribe(id)` | DELETE `/webhook-subs/:id` | |\n| `client.webhooks.test(body)` | POST `/webhooks/test` | smoke-test before going live |\n\n## Webhook contract\n\nWe POST JSON with the following headers. Verify them in this order:\n\n1. `X-Aevion-Timestamp` — Unix seconds. Reject if drift > 5min (replay protection).\n2. `X-Aevion-Signature` — `sha256=<hex(hmac(secret, \"${timestamp}.${rawBody}\"))>`. Constant-time compare.\n3. `X-Aevion-Event-Id` — stable across all retries of a logical event. Use as your dedup key.\n4. `X-Aevion-Event` — event type (e.g. `payment_request.paid`).\n\nWe retry **5 attempts** with exp-backoff: 30s → 2m → 10m → 30m → 2h. After\nexhaustion we dead-letter (your endpoint will be visible in our `/admin/webhook-deliveries`).\n\nThe `verifyWebhook()` helper handles 1+2 above. Dedup (3) is on you — partners\ntypically do `INSERT ON CONFLICT DO NOTHING` keyed on `event-id`.\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}