{"_id":"@bucksbox/capacitor-payment-sdk","_rev":"4-61d142572381f7a5be3a5223e9b9cf4b","name":"@bucksbox/capacitor-payment-sdk","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@bucksbox/capacitor-payment-sdk","version":"0.1.0","keywords":["capacitor","plugin","native","bucksbox","aeps","dmt"],"author":{"name":"BucksBox"},"license":"UNLICENSED","_id":"@bucksbox/capacitor-payment-sdk@0.1.0","maintainers":[{"name":"bucksbox","email":"bucksboxteam@gmail.com"}],"dist":{"shasum":"4368d5d89feab359df11c30d84684d89d3bfefc2","tarball":"https://registry.npmjs.org/@bucksbox/capacitor-payment-sdk/-/capacitor-payment-sdk-0.1.0.tgz","fileCount":19,"integrity":"sha512-utrV7INQVay86lxzA+lMyEohrOhTYZ5ACYjNDbBF6xya4UAXC2c2CrPNJITArion0+pp0maR6US2mbiAIDH0tg==","signatures":[{"sig":"MEQCIAWbBVJU2KZ3COBgM3IIzYXmSVbshLwQca4banHlT94zAiBlOYklXgB1vCJrdNqG7pNI+JcDLy/oUPMFIRiQJeFOwA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57678},"main":"dist/plugin.cjs.js","types":"dist/esm/index.d.ts","unpkg":"dist/plugin.js","module":"dist/esm/index.js","gitHead":"fba6eea4365db02cd74f21d7ac8226c00422733d","scripts":{"build":"npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs","clean":"rimraf ./dist","watch":"tsc --watch","docgen":"docgen --api BucksBoxPaymentSdkPlugin --output-readme README.md --output-json dist/docs.json","verify":"npm run verify:android && npm run verify:web","verify:web":"npm run build","verify:android":"cd android && ./gradlew clean build test && cd .."},"_npmUser":{"name":"bucksbox","email":"bucksboxteam@gmail.com"},"capacitor":{"android":{"src":"android"}},"_npmVersion":"10.8.2","description":"Capacitor wrapper around the native BucksBoxSDK (AEPS, DMT, Dynamic QR) Android AAR","directories":{},"_nodeVersion":"20.19.2","_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.1.2","rollup":"^4.30.1","typescript":"^5.9.3","@capacitor/core":"^7.0.0","@capacitor/docgen":"^0.3.0","@capacitor/android":"^7.0.0"},"peerDependencies":{"@capacitor/core":">=7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/capacitor-payment-sdk_0.1.0_1786438805302_0.7188977022041996","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bucksbox/capacitor-payment-sdk","version":"0.1.1","keywords":["capacitor","plugin","native","bucksbox","aeps","dmt"],"author":{"name":"BucksBox"},"license":"UNLICENSED","_id":"@bucksbox/capacitor-payment-sdk@0.1.1","maintainers":[{"name":"bucksbox","email":"bucksboxteam@gmail.com"}],"dist":{"shasum":"32c16773aad6def79ad2f084c30d4cdc750915bc","tarball":"https://registry.npmjs.org/@bucksbox/capacitor-payment-sdk/-/capacitor-payment-sdk-0.1.1.tgz","fileCount":19,"integrity":"sha512-Kcv8Ody+B2b/3DjGLj55NmDuNTLb5Wnr0b5sH9oaH+YSGMBdUPLvIANykbIMPRirlX5/r0WqI65mG3fdR3dmfw==","signatures":[{"sig":"MEUCIQCAlGjhGZWrHW+S5ZFtrI4GR0aMIOKvBIWi3C3Oz6Y7nAIgeIWeryMGYjZ6vbsZ6+tf6+n3RJkyZxwYkRtA6JlKiPM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58521},"main":"dist/plugin.cjs.js","types":"dist/esm/index.d.ts","unpkg":"dist/plugin.js","module":"dist/esm/index.js","gitHead":"fba6eea4365db02cd74f21d7ac8226c00422733d","scripts":{"build":"npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs","clean":"rimraf ./dist","watch":"tsc --watch","docgen":"docgen --api BucksBoxPaymentSdkPlugin --output-readme README.md --output-json dist/docs.json","verify":"npm run verify:android && npm run verify:web","verify:web":"npm run build","verify:android":"cd android && ./gradlew clean build test && cd .."},"_npmUser":{"name":"bucksbox","email":"bucksboxteam@gmail.com"},"capacitor":{"android":{"src":"android"}},"_npmVersion":"10.8.2","description":"Capacitor wrapper around the native BucksBoxSDK (AEPS, DMT, Dynamic QR) Android AAR","directories":{},"_nodeVersion":"20.19.2","_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.1.2","rollup":"^4.30.1","typescript":"^5.9.3","@capacitor/core":"^7.0.0","@capacitor/docgen":"^0.3.0","@capacitor/android":"^7.0.0"},"peerDependencies":{"@capacitor/core":">=7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/capacitor-payment-sdk_0.1.1_1786454512603_0.7333966414726867","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bucksbox/capacitor-payment-sdk","version":"0.1.2","keywords":["capacitor","plugin","native","bucksbox","aeps","dmt"],"author":{"name":"BucksBox"},"license":"MTI","_id":"@bucksbox/capacitor-payment-sdk@0.1.2","maintainers":[{"name":"bucksbox","email":"bucksboxteam@gmail.com"}],"dist":{"shasum":"f81a1d46f978802633ec6109e75f68d84cb44803","tarball":"https://registry.npmjs.org/@bucksbox/capacitor-payment-sdk/-/capacitor-payment-sdk-0.1.2.tgz","fileCount":19,"integrity":"sha512-WyOcvtQrNNkqkGgFZd2AKvrabO8FIaFQW9kcSjoBaj/GPo/2yIoMjwwoT07YLQEW0WLoVogK19KTMt0wMqXS3w==","signatures":[{"sig":"MEYCIQCHZ6tG57KC95KirTXmB7V5OE0uOFw55LqnusWBbySUwQIhAJVhgwQQx5eCUAuxt+0Cc+E78LS7wrISV72bqwFLw2BU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":71387},"main":"dist/plugin.cjs.js","types":"dist/esm/index.d.ts","unpkg":"dist/plugin.js","module":"dist/esm/index.js","gitHead":"fba6eea4365db02cd74f21d7ac8226c00422733d","scripts":{"build":"npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs","clean":"rimraf ./dist","watch":"tsc --watch","docgen":"docgen --api BucksBoxPaymentSdkPlugin --output-readme README.md --output-json dist/docs.json","verify":"npm run verify:android && npm run verify:web","verify:web":"npm run build","verify:android":"cd android && ./gradlew clean build test && cd .."},"_npmUser":{"name":"bucksbox","email":"bucksboxteam@gmail.com"},"capacitor":{"android":{"src":"android"}},"_npmVersion":"10.8.2","description":"Capacitor wrapper around the native BucksBoxSDK (AEPS, DMT, Dynamic QR) Android AAR","directories":{},"_nodeVersion":"20.19.2","_hasShrinkwrap":false,"devDependencies":{"rimraf":"^6.1.2","rollup":"^4.30.1","typescript":"^5.9.3","@capacitor/core":"^7.0.0","@capacitor/docgen":"^0.3.0","@capacitor/android":"^7.0.0"},"peerDependencies":{"@capacitor/core":">=7.0.0"},"_npmOperationalInternal":{"tmp":"tmp/capacitor-payment-sdk_0.1.2_1786456575211_0.8781365393991998","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@bucksbox/capacitor-payment-sdk","version":"0.1.3","description":"Capacitor wrapper around the native BucksBoxSDK (AEPS, DMT, Dynamic QR) Android AAR","main":"dist/plugin.cjs.js","module":"dist/esm/index.js","types":"dist/esm/index.d.ts","unpkg":"dist/plugin.js","author":{"name":"BucksBox"},"license":"MTI","keywords":["capacitor","plugin","native","bucksbox","aeps","dmt"],"scripts":{"verify":"npm run verify:android && npm run verify:web","verify:android":"cd android && ./gradlew clean build test && cd ..","verify:web":"npm run build","docgen":"docgen --api BucksBoxPaymentSdkPlugin --output-readme README.md --output-json dist/docs.json","build":"npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs","clean":"rimraf ./dist","watch":"tsc --watch"},"devDependencies":{"@capacitor/android":"^7.0.0","@capacitor/core":"^7.0.0","@capacitor/docgen":"^0.3.0","rimraf":"^6.1.2","rollup":"^4.30.1","typescript":"^5.9.3"},"peerDependencies":{"@capacitor/core":">=7.0.0"},"capacitor":{"android":{"src":"android"}},"_id":"@bucksbox/capacitor-payment-sdk@0.1.3","gitHead":"fba6eea4365db02cd74f21d7ac8226c00422733d","_nodeVersion":"20.19.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-PWRtSciFj2L+Qeiu2PRDno90h0prkdYje/iVFLUjtxOA2/A1/xJEZ7OAbMd6XHpftYYRwrOOfz9ECREBZbzEtQ==","shasum":"b466a55d665e63233a58e38d049ffda21e11d8e6","tarball":"https://registry.npmjs.org/@bucksbox/capacitor-payment-sdk/-/capacitor-payment-sdk-0.1.3.tgz","fileCount":19,"unpackedSize":81256,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFlAPgRunIuGEe1yPgiwTzt+rVtIL3aPPeJIMUAT0TL2AiEA+T5rlSEpFlUZOtxYFNXfeOEwm+z7MR+LFYmfYLotSEI="}]},"_npmUser":{"name":"bucksbox","email":"bucksboxteam@gmail.com"},"directories":{},"maintainers":[{"name":"bucksbox","email":"bucksboxteam@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/capacitor-payment-sdk_0.1.3_1787158646014_0.6813157910280885"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-11T09:00:04.991Z","modified":"2026-08-19T16:57:26.348Z","0.1.0":"2026-08-11T09:00:05.454Z","0.1.1":"2026-08-11T13:21:52.777Z","0.1.2":"2026-08-11T13:56:15.453Z","0.1.3":"2026-08-19T16:57:26.155Z"},"author":{"name":"BucksBox"},"license":"MTI","keywords":["capacitor","plugin","native","bucksbox","aeps","dmt"],"description":"Capacitor wrapper around the native BucksBoxSDK (AEPS, DMT, Dynamic QR) Android AAR","maintainers":[{"name":"bucksbox","email":"bucksboxteam@gmail.com"}],"readme":"# @bucksbox/capacitor-payment-sdk\n\nA Capacitor plugin wrapping the native **BucksBox Payment SDK** (`android-sdk/dashboard`)\nfor Android applications built with Capacitor. Every method here launches the SDK's own\nnative, full-screen UI — this plugin does not accept transaction parameters directly or\nreturn transaction results from its calls; it starts the native flow and reports outcomes\nthrough a single event stream.\n\nThe SDK provides:\n\n- AEPS (Aadhaar Enabled Payment System) — Cash Withdrawal, Balance Enquiry, Mini\n  Statement, Aadhaar Pay\n- DMT (Domestic Money Transfer) — customer search, new-customer onboarding\n  (register → OTP → Aadhaar → biometric), beneficiaries, transfer\n- Dynamic UPI QR generation\n- A built-in dashboard screen host apps don't need to build themselves\n\nAndroid-only today — see `src/web.ts`, which rejects every call rather than silently\nno-oping (there is no browser equivalent to native RD-service biometric capture).\n\n## Recent fixes (now in `dashboard:0.1.3`)\n\nThis bridge has no code of its own affected by these — both were native-SDK bugs inside\nthe screens `openAEPS()`/`openDMT()` launch, fixed at the source and picked up automatically\nonce this plugin is built against the AAR version below:\n\n- **AEPS — Agent Authentication screen was unreachable.** A Compose navigation bug nested\n  the one-time 24h terminal-auth screen inside a branch it could never actually render\n  from, so tapping \"Authenticate Now\" appeared to do nothing. Fixed; `openAEPS()`'s full\n  flow (auth gate → agent auth → transaction) now completes correctly.\n- **DMT — three flow transitions could silently stall.** A `ViewModel` reentrancy guard\n  dropped chained calls fired from success callbacks: customer search → remitter load,\n  biometric onboarding → remitter load, and add-beneficiary → remitter load. Each looked\n  like the screen just stopped responding after the first step. Fixed; `openDMT()`'s full\n  flow (search/onboarding/add-beneficiary/transfer) no longer gets stuck mid-way.\n\nBoth fixes were verified via `./gradlew :aeps:testDebugUnitTest :dmt:testDebugUnitTest`\nagainst the real `paymentSystem` backend contract, then this plugin's own\n`npm run verify:android` was re-run against the republished `dashboard:0.1.3` AAR —\n`BUILD SUCCESSFUL`.\n\n## Package\n\n```bash\nnpm install @bucksbox/capacitor-payment-sdk\n```\n\nAfter installation:\n\n```bash\nnpx cap sync android\n```\n\n---\n\n# Requirements\n\n| Requirement | Version |\n|---|---|\n| Node.js | 18+ recommended |\n| npm | 9+ recommended |\n| Capacitor | 7.x (`@capacitor/core` peer dependency: `>=7.0.0`) |\n| Android Studio | Hedgehog or newer |\n| Android compileSdk | 34 (matches `android-sdk`'s own modules — AGP 8.5.2 warns if pushed to 35 without an AGP upgrade) |\n| Java | 17 |\n| Kotlin | 2.0.20 (matching `android-sdk`'s pinned version — see the AAR compatibility note below) |\n\n---\n\n# Installation\n\nInstall the package using npm:\n\n```bash\nnpm install @bucksbox/capacitor-payment-sdk\n```\n\nSync the native Android project:\n\n```bash\nnpx cap sync android\n```\n\nOpen the Android project:\n\n```bash\nnpx cap open android\n```\n\n---\n\n# Capacitor Configuration\n\nThe plugin registers its Android implementation via the `capacitor` field in its own\n`package.json` — no configuration needed in the host app beyond a normal `npx cap sync`:\n\n```json\n{\n  \"capacitor\": {\n    \"android\": {\n      \"src\": \"android\"\n    }\n  }\n}\n```\n\n---\n\n# Import the Plugin\n\nThe registered plugin name is `BucksBoxPaymentSdk` (not the Kotlin class name):\n\n```typescript\nimport { BucksBoxPaymentSdk } from '@bucksbox/capacitor-payment-sdk';\n```\n\n---\n\n# Initialize BucksBox SDK\n\nCall `initialize()` once before any other method. It wraps `BucksBoxSDK.initialize` on the\nnative side — `environment` and `jwtToken` are required; everything else is optional\nwhite-labeling/behavior config.\n\n`environment` is `\"production\"` or `\"staging\"` — **not** a URL. The SDK resolves the name to\na fixed, native-side host (`SdkEnvironment.forName`, see `SdkConfig.kt`) and rejects anything\nelse; there is deliberately no way to pass an arbitrary base URL from JS. This bridge's JS\nlayer is materially less trusted than the native host app around it — a compromised CDN\nasset or a tampered bundle must never be able to redirect real AEPS/DMT/QR transaction\ntraffic to an attacker-controlled server.\n\n```typescript\nconst profile = await BucksBoxPaymentSdk.initialize({\n  environment: 'staging',                    // required — 'production' | 'staging'\n  jwtToken: hostAppOwnJwt,                   // required — from your own backend login\n  brandName: 'My Merchant App',\n  toolbarTitle: 'My Merchant App',\n  primaryColor: '#1142D4',                   // hex string\n  secondaryColor: '#4169E1',\n  successColor: '#059669',\n  warningColor: '#D97706',\n  errorColor: '#DC2626',\n  darkModeDefault: 'system',                 // 'light' | 'dark' | 'system'\n  locale: 'en-IN',\n  currencySymbol: '₹',\n  showWelcomeScreen: true,\n  enableRootDetection: true,\n  enableEmulatorDetection: true,              // set false only for emulator testing\n  sessionTimeoutMinutes: 15,\n  requestTimeoutSeconds: 30,\n});\n\nconsole.log(profile.legalName, profile.services);\n```\n\n`initialize()` resolves with the `MerchantProfile` (`id`, `legalName`, `mobileNumber?`,\n`email?`, `role`, `services: { service, status }[]`) or rejects with the native\n`ApiResult.Failure`/`NetworkError` message. **Not included**: `BrandConfig.logoRes`/\n`splashRes` — native Android drawable resource IDs with no JS-safe representation.\n\n---\n\n# Subscribe to Events First\n\nEvery outcome — AEPS/DMT/QR success or failure, session expiry, logout — arrives on one\nevent stream, not as a return value from the method that triggered it. Subscribe **before**\ncalling `initialize()` or any `open*` method so nothing is missed:\n\n```typescript\nBucksBoxPaymentSdk.addListener('sdkEvent', (event) => {\n  switch (event.type) {\n    case 'AepsSuccess':\n      console.log('AEPS success', event.transactionId, event.amount);\n      break;\n    case 'AepsFailed':\n      console.log('AEPS failed', event.reason);\n      break;\n    case 'DmtSuccess':\n      console.log('DMT success', event.transactionId, event.amount);\n      break;\n    case 'DmtFailed':\n      console.log('DMT failed', event.reason);\n      break;\n    case 'QrPaid':\n      console.log('QR paid', event.orderId, event.utr);\n      break;\n    case 'SessionExpired':\n      // re-run your own login, then call initialize() again\n      break;\n    default:\n      // SdkReady, AuthenticationSuccess/Failed, QrGenerated/Expired/Cancelled,\n      // TransactionPending/Success/Failed, Logout, SdkClosed — see the type table below\n      break;\n  }\n});\n```\n\n## Event type reference\n\nEvery `BucksBoxSdkEvent.type` value and its extra payload fields (all optional beyond\n`type`):\n\n| `type` | Extra fields |\n|---|---|\n| `SdkReady`, `AuthenticationSuccess`, `Logout`, `SdkClosed`, `SessionExpired` | — |\n| `AuthenticationFailed`, `AepsFailed`, `DmtFailed` | `reason` |\n| `AepsSuccess`, `DmtSuccess` | `transactionId`, `amount` |\n| `QrGenerated`, `QrExpired`, `QrCancelled` | `orderId` |\n| `QrPaid` | `orderId`, `utr?` |\n| `QrFailed` | `orderId`, `reason` |\n| `TransactionPending`, `TransactionSuccess` | `transactionId` |\n| `TransactionFailed` | `transactionId`, `reason` |\n\n---\n\n# AEPS\n\n`openAEPS()` launches the SDK's own native AEPS screen (transaction type selection →\nAadhaar/customer-name form → RD-service biometric capture → result) — the host app\nsupplies no transaction parameters and gets no direct return value. **Requires a\nUIDAI-certified RD-service app installed on the device** (Mantra/Morpho/Startek/SecuGen);\ndoes not work on an emulator.\n\n```typescript\nawait BucksBoxPaymentSdk.openAEPS();\n// outcome arrives via 'sdkEvent': AepsSuccess { transactionId, amount } or\n// AepsFailed { reason }\n```\n\n---\n\n# DMT\n\n`openDMT()` launches the SDK's own native DMT screen: mobile-number search, automatically\nbranching into either the existing-customer beneficiary/transfer flow or, for a new\nmobile number, the full onboarding flow (register → OTP → Aadhaar → biometric).\n\n```typescript\nawait BucksBoxPaymentSdk.openDMT();\n// outcome arrives via 'sdkEvent': DmtSuccess { transactionId, amount } or\n// DmtFailed { reason }\n```\n\n---\n\n# Dynamic QR\n\n`openDynamicQR(options?)` launches the SDK's native Dynamic QR screen (amount/order ID\nentry, QR render, real-time payment status via Socket.IO — no polling). Passing\n`amount`+`orderId` skips the on-screen form entirely and generates the QR immediately.\n\n```typescript\nawait BucksBoxPaymentSdk.openDynamicQR({ amount: 100, orderId: 'ORDER123456' });\n// outcome arrives via 'sdkEvent': QrGenerated, then QrPaid { orderId, utr } / QrFailed\n// { orderId, reason } / QrExpired / QrCancelled\n```\n\n**Vendor sessions must also pass `merchantId`.** Check `(await BucksBoxPaymentSdk.getMerchantProfile())?.role`\n— `'vendor'` means this session's apiKey/JWT belongs to a vendor managing many merchants, not\none, so paymentSystem needs to be told which merchant this QR is for:\n\n```typescript\nconst profile = await BucksBoxPaymentSdk.getMerchantProfile();\nawait BucksBoxPaymentSdk.openDynamicQR({\n  amount: 100,\n  orderId: 'ORDER123456',\n  merchantId: profile?.role === 'vendor' ? 'MERCHANT123' : undefined,\n});\n```\n\nA merchant session resolves its own `merchantId` automatically — omit it there.\n\n`amount`/`orderId` are accepted for forward compatibility but **not yet threaded through**\nto prefill the native screen — `QrActivity` still collects them on-screen today. This is a\ndocumented native-SDK limitation, not a bug in this bridge.\n\n---\n\n# Dashboard, Wallet, Reports, Transaction History\n\n```typescript\nawait BucksBoxPaymentSdk.launchDashboard();   // the SDK's built-in dashboard screen\n\n// These three currently REJECT — BucksBoxSDK.kt throws NotImplementedError for them\n// natively (see android-sdk's own roadmap), and this bridge forwards that message\n// rather than hiding it:\nawait BucksBoxPaymentSdk.openTransactionHistory();\nawait BucksBoxPaymentSdk.openWallet();\nawait BucksBoxPaymentSdk.openReports();\n```\n\n---\n\n# Session & Merchant Info\n\n```typescript\nconst { ready } = await BucksBoxPaymentSdk.isReady();\nconst { verified } = await BucksBoxPaymentSdk.hasVerifiedService({ service: 'DMT' });\nconst profile = await BucksBoxPaymentSdk.getMerchantProfile(); // null if not initialized\nawait BucksBoxPaymentSdk.logout();\n```\n\n---\n\n# Error Handling\n\nAlways handle SDK errors using `try/catch`:\n\n```typescript\ntry {\n  await BucksBoxPaymentSdk.openAEPS();\n} catch (error) {\n  console.error('BucksBox SDK Error:', error);\n}\n```\n\n`initialize()` rejections carry the native `ApiResult.Failure`'s `statusCode`/`message` or\nthe `NetworkError`'s underlying message — not a generic error.\n\n---\n\n# Android Permissions\n\nThe host app's `AndroidManifest.xml` needs:\n\n```xml\n<uses-permission android:name=\"android.permission.INTERNET\" />\n<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />\n```\n\n`INTERNET` for all API calls; `ACCESS_FINE_LOCATION` because every AEPS/DMT transaction\nrequires latitude/longitude in the request (see `LocationProvider.kt`) — the native SDK\nrequests this at runtime, but the manifest declaration must be present. AEPS/DMT biometric\ncapture itself needs no special Android permission — it depends on a UIDAI-certified\nRD-service app being installed on the device, not an app permission.\n\n---\n\n# Android Configuration\n\nAfter installing the package:\n\n```bash\nnpx cap sync android\n```\n\nThen open Android Studio:\n\n```bash\nnpx cap open android\n```\n\nBuild the application from Android Studio or using Gradle.\n\n## How `:dashboard` resolves\n\nThis plugin depends on `com.bucksbox.sdk:dashboard:0.1.3`, resolved from a local Maven\nrepo at `android-sdk/maven-repo/` (`repositories { maven { url = uri('../../../maven-repo') } }`\nin `android/build.gradle`). That repo is real Maven output — `.aar` + `.pom` + Gradle\nmodule metadata for all 6 `android-sdk` library modules — generated by running\n`./gradlew publish` from `android-sdk/`. **Regenerate it whenever `android-sdk`'s source\nchanges** and you need this plugin to pick up the new build; otherwise it silently keeps\nbuilding against the last-published AAR.\n\nThis only works with `maven-repo/` reachable at that relative path (inside this monorepo,\nor wherever `maven-repo/` gets copied to the same relative position). For a host app\nentirely outside this checkout: copy `android-sdk/maven-repo/` alongside this plugin and\nadjust the `url` above, or push the same published artifacts to a real remote Maven repo\n(GitHub Packages, a private Nexus/Artifactory, or Maven Central) and point `url` there —\nthe standard way real-world Android SDKs get distributed, and a one-line change once ready.\n\n---\n\n# Production Configuration\n\nFor production, pass `environment: 'production'` and use the JWT your own backend's\nproduction login issues.\n\nDo not hard-code production JWTs or backend credentials directly into application source\ncode — fetch them from your own authenticated backend at runtime.\n\n```typescript\nconst config = {\n  environment: 'production',\n  jwtToken: await fetchJwtFromMyOwnBackend(),\n};\n```\n\n---\n\n# Development Environment\n\nFor development/testing, pass `environment: 'staging'`:\n\n```typescript\nconst config = {\n  environment: 'staging',\n  jwtToken: await fetchJwtFromMyOwnBackend(),\n  enableEmulatorDetection: false, // only if testing on an emulator\n};\n```\n\n`enableEmulatorDetection: false` is the only way `initialize()` succeeds on an emulator —\nby design, it rejects with `SECURITY_EMULATOR` otherwise. AEPS and DMT's biometric step\nstill require a real device with an RD-service app installed regardless.\n\n---\n\n# Supported Platform\n\nCurrently supported:\n\n```text\nAndroid\n```\n\nThe plugin is designed for applications using:\n\n```text\nCapacitor 7+\n```\n\niOS is not built — `BucksBoxSDK` itself is Android-only today. `Plugins/rd-service`\nelsewhere in this repo shows the expected shape (`Package.swift`, `.podspec`) for a future\niOS bridge.\n\n---\n\n# Project Structure\n\n```text\ncapacitor/\n│\n├── android/\n│   ├── build.gradle\n│   ├── settings.gradle\n│   ├── gradle.properties\n│   ├── local.properties        (machine-specific, gitignored)\n│   └── src/\n│       └── main/\n│           ├── AndroidManifest.xml\n│           └── java/com/bucksbox/paymentsdk/capacitor/\n│               └── BucksBoxCapacitorPlugin.kt\n│\n├── src/\n│   ├── definitions.ts\n│   ├── index.ts\n│   └── web.ts\n│\n├── dist/\n│\n├── package.json\n├── rollup.config.mjs\n├── tsconfig.json\n└── README.md\n```\n\n---\n\n# Build From Source\n\nClone this repository (adjust the URL/path to wherever your team hosts it), then:\n\n```bash\ncd android-sdk/bridges/capacitor\nnpm install\nnpm run build\n```\n\n`npm run build` runs `clean` → `docgen` → `tsc` → `rollup`, producing `dist/plugin.js` and\n`dist/plugin.cjs.js`.\n\n---\n\n# Verify Package\n\nRun the Android verification (compiles the native module against the published AAR —\nrequires `android-sdk/maven-repo/` to already exist; run `./gradlew publish` from\n`android-sdk/` first if it doesn't):\n\n```bash\nnpm run verify:android\n```\n\nRun the web/TypeScript build:\n\n```bash\nnpm run verify:web\n```\n\nRun the complete verification:\n\n```bash\nnpm run verify\n```\n\n---\n\n# Create npm Package\n\nBefore publishing, verify the files that will be included:\n\n```bash\nnpm pack --dry-run\n```\n\nCreate the package locally:\n\n```bash\nnpm pack\n```\n\nThis will generate:\n\n```text\nbucksbox-capacitor-payment-sdk-0.1.0.tgz\n```\n\nYou can install this local package into another project for testing:\n\n```bash\nnpm install ./bucksbox-capacitor-payment-sdk-0.1.0.tgz\n```\n\nNote: the packaged `android/build.gradle` still points at `../../../maven-repo` relative\nto its position inside `node_modules` after install — that path will not resolve outside\nthis monorepo checkout until the `:dashboard` distribution question above is settled.\n\n---\n\n# Publish to npm\n\nLogin to npm:\n\n```bash\nnpm login\n```\n\nVerify the logged-in account:\n\n```bash\nnpm whoami\n```\n\nPublish the package:\n\n```bash\nnpm publish --access public\n```\n\nAfter publishing, install it using:\n\n```bash\nnpm install @bucksbox/capacitor-payment-sdk\n```\n\n---\n\n# Version Management\n\nFor a patch release:\n\n```bash\nnpm version patch\n```\n\nExample:\n\n```text\n0.1.0 → 0.1.1\n```\n\nFor a minor release:\n\n```bash\nnpm version minor\n```\n\nExample:\n\n```text\n0.1.1 → 0.2.0\n```\n\nFor a major release:\n\n```bash\nnpm version major\n```\n\nExample:\n\n```text\n0.2.0 → 1.0.0\n```\n\nThen publish:\n\n```bash\nnpm publish\n```\n\n---\n\n# Example Application\n\n```typescript\nimport { BucksBoxPaymentSdk } from '@bucksbox/capacitor-payment-sdk';\n\nasync function startPayment() {\n  BucksBoxPaymentSdk.addListener('sdkEvent', (event) => {\n    if (event.type === 'DmtSuccess') {\n      console.log('DMT success', event.transactionId, event.amount);\n    }\n  });\n\n  try {\n    const profile = await BucksBoxPaymentSdk.initialize({\n      environment: 'staging',\n      jwtToken: await fetchJwtFromMyOwnBackend(),\n      brandName: 'My Merchant App',\n    });\n    console.log('SDK Initialized:', profile.legalName);\n\n    await BucksBoxPaymentSdk.openDMT();\n  } catch (error) {\n    console.error('SDK Initialization Failed:', error);\n  }\n}\n```\n\n---\n\n# Security\n\nNever expose the following information in source control:\n\n- JWTs or backend credentials used to obtain them\n- API keys\n- Encryption keys\n- Private certificates\n- Merchant credentials\n\nFetch the JWT passed to `initialize()` from your own authenticated backend at runtime, not\nfrom a hard-coded value.\n\n---\n\n# Troubleshooting\n\n## Package installation fails\n\nRun:\n\n```bash\nnpm cache verify\nnpm install\n```\n\nIf required:\n\n```bash\nrm -rf node_modules\nnpm install\n```\n\nOn Windows:\n\n```cmd\nrmdir /s /q node_modules\nnpm install\n```\n\n---\n\n## Capacitor plugin not detected\n\nRun:\n\n```bash\nnpx cap sync android\n```\n\nThen:\n\n```bash\nnpx cap open android\n```\n\nClean and rebuild the Android project.\n\n---\n\n## Android build failure: `Could not resolve com.bucksbox.sdk:dashboard`\n\n`android-sdk/maven-repo/` doesn't exist yet or is stale. From `android-sdk/`:\n\n```bash\n./gradlew publish\n```\n\nThen retry the plugin build.\n\n## Android build failure: `SDK location not found`\n\nAdd a `local.properties` file next to `android/build.gradle` with `sdk.dir` pointing at\nyour Android SDK install (this file is gitignored and machine-specific — not shipped).\n\n## Android build failure (other)\n\nRun:\n\n```bash\ncd android\n./gradlew clean\n./gradlew build\n```\n\nOn Windows:\n\n```cmd\ncd android\ngradlew.bat clean\ngradlew.bat build\n\nadb install -r \"c:\\project\\payments\\sdk\\android-sdk\\sample-app\\build\\outputs\\apk\\debug\\sample-app-debug.apk\"\n```\n\n---\n\n# Support\n\nFor SDK integration and technical support, contact your BucksBox integration team.\n\n---\n\n# License\n\nProprietary — internal use within this project only, unless your organization's licensing\nterms state otherwise.\n","readmeFilename":"README.md"}