{"_id":"@emergente-labs/elements-sdk","name":"@emergente-labs/elements-sdk","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@emergente-labs/elements-sdk","version":"0.1.0","description":"Embeddable payment Elements SDK for moneymotion.","type":"module","sideEffects":false,"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./effect":{"types":"./dist/effect.d.ts","import":"./dist/effect.js"},"./errors":{"types":"./dist/errors.d.ts","import":"./dist/errors.js"},"./package.json":"./package.json"},"engines":{"node":">=18"},"author":{"name":"Emergente Labs"},"license":"MIT","homepage":"https://github.com/emergente-labs/elements-sdk#readme","bugs":{"url":"https://github.com/emergente-labs/elements-sdk/issues"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/emergente-labs/elements-sdk.git"},"peerDependencies":{"effect":"^3.19.0"},"devDependencies":{"effect":"^3.19.0","happy-dom":"^15.11.0","typescript":"^5.9.3","vite":"^7.1.9","vitest":"^3.0.0"},"scripts":{"build":"vite build && tsc -p tsconfig.build.json","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest"},"_id":"@emergente-labs/elements-sdk@0.1.0","_integrity":"sha512-ZTRsrhxJh/aZflKcotthgh3K438e2BcUxM6brxaj566Qp6qCP/c3r2OJaQVAulcJkly87LsF8fXWcERWU1zY9g==","_resolved":"/tmp/2999e6caadf465022026dc73b4443785/emergente-labs-elements-sdk-0.1.0.tgz","_from":"file:emergente-labs-elements-sdk-0.1.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-ZTRsrhxJh/aZflKcotthgh3K438e2BcUxM6brxaj566Qp6qCP/c3r2OJaQVAulcJkly87LsF8fXWcERWU1zY9g==","shasum":"9e4930a2cbe4a916e813a5a7998b32501040e8af","tarball":"https://registry.npmjs.org/@emergente-labs/elements-sdk/-/elements-sdk-0.1.0.tgz","fileCount":22,"unpackedSize":140230,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICjj3GJAlQYbBmtUsz/0cZLawRVgFQb/spZm8WbBfiQAAiEAmHUv2+EDbMeT/K2679ta5/k75r1w4RdQ9ItCkLak03I="}]},"_npmUser":{"name":"francisco-m001","email":"francisco@sellhub.cx"},"directories":{},"maintainers":[{"name":"francisco-m001","email":"francisco@sellhub.cx"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/elements-sdk_0.1.0_1778089599285_0.9119071809075143"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-06T17:46:39.114Z","0.1.0":"2026-05-06T17:46:39.429Z","modified":"2026-05-06T17:46:39.719Z"},"maintainers":[{"name":"francisco-m001","email":"francisco@sellhub.cx"}],"description":"Embeddable payment Elements SDK for moneymotion.","homepage":"https://github.com/emergente-labs/elements-sdk#readme","repository":{"type":"git","url":"git+https://github.com/emergente-labs/elements-sdk.git"},"author":{"name":"Emergente Labs"},"bugs":{"url":"https://github.com/emergente-labs/elements-sdk/issues"},"license":"MIT","readme":"# @emergente-labs/elements-sdk\n\nEmbeddable, processor-agnostic payment Elements for the browser. Mount Card,\nExpress Checkout, or Address iframes on your page, collect a buyer's payment\ndetails, and run a full PaymentIntent confirmation — including 3-D Secure —\nwithout ever touching the card data yourself.\n\nThe SDK ships two interchangeable surfaces:\n\n- **Promise API** (`@emergente-labs/elements-sdk`) — a class-based facade for\n  vanilla JS, React, Vue, etc.\n- **Effect API** (`@emergente-labs/elements-sdk/effect`) — Effect-native\n  primitives for codebases already running an Effect runtime.\n\nBoth surfaces share the same internals; the Promise wrapper is a thin layer.\n\n## Installation\n\n```sh\nnpm install @emergente-labs/elements-sdk effect\n# or\npnpm add @emergente-labs/elements-sdk effect\n# or\nyarn add @emergente-labs/elements-sdk effect\n```\n\n`effect` is a peer requirement — the SDK is built on top of it.\n\n## Quickstart\n\n```ts\nimport { loadElements } from \"@emergente-labs/elements-sdk\";\n\n// 1. Mint a PaymentIntent server-side, return its client_secret to the page.\n//    The SDK never sees your secret API key.\nconst elements = await loadElements({\n    publishableKey: \"pk_test_...\",\n    clientSecret: \"cs_...\",\n    iframeOrigin: \"https://elements.example.com\",\n});\n\n// 2. Mount the card element into your DOM.\nconst card = elements.create(\"payment\");\ncard.mount(\"#card-container\");\n\n// 3. Listen for input state changes (validity, brand, etc.).\ncard.on(\"change\", (event) => {\n    console.log(event.complete, event.brand);\n});\n\n// 4. Confirm when the buyer submits.\nconst result = await elements.confirm({\n    element: card,\n    billingAddress: {\n        firstName: \"Ada\",\n        lastName: \"Lovelace\",\n        lineOne: \"1 Analytical Engine Way\",\n        city: \"London\",\n        postalCode: \"SW1A 1AA\",\n        country: \"GB\",\n    },\n    returnUrl: window.location.href,\n});\n\nif (result.status === \"succeeded\") {\n    // Payment captured — redirect to confirmation page.\n}\n```\n\n3-D Secure (fingerprint + challenge) is handled automatically. The promise\nonly resolves once the intent has reached a terminal status — your code does\nnot need to manage redirects, hidden iframes, or ACS postMessages.\n\n## Effect API\n\n```ts\nimport * as Elements from \"@emergente-labs/elements-sdk/effect\";\nimport { Effect, Stream } from \"effect\";\n\nconst program = Effect.gen(function* () {\n    const elements = yield* Elements.make({\n        publishableKey: \"pk_test_...\",\n        clientSecret: \"cs_...\",\n        iframeOrigin: \"https://elements.example.com\",\n    });\n\n    const card = yield* elements.create(\"payment\");\n    yield* card.mount(\"#card-container\");\n\n    yield* card.changes.pipe(\n        Stream.tap((event) => Effect.log(event)),\n        Stream.runDrain,\n        Effect.fork,\n    );\n\n    return yield* elements.confirm({\n        element: card,\n        billingAddress: { /* ... */ },\n        returnUrl: location.href,\n    });\n});\n\nEffect.runPromise(program.pipe(Effect.scoped));\n```\n\nWhen the surrounding `Scope` closes, every iframe, listener, and fiber is torn\ndown automatically — no manual `dispose()` call is required.\n\n## Configuration\n\n`loadElements` / `Elements.make` accept the following options:\n\n| Option           | Required | Description                                                     |\n| ---------------- | -------- | --------------------------------------------------------------- |\n| `publishableKey` | yes      | Your `pk_*` publishable key.                                    |\n| `clientSecret`   | yes      | Client secret returned when you created the PaymentIntent.     |\n| `iframeOrigin`   | yes      | Origin serving the Elements iframe pages.                       |\n| `appearance`     | no       | Theme + variables + rules forwarded to the iframe.              |\n| `apiBase`        | no       | Override the iframe's RPC base URL (defaults to `iframeOrigin`). |\n\n## Element types\n\n| Type              | Path                | Purpose                                  |\n| ----------------- | ------------------- | ---------------------------------------- |\n| `payment`         | `/v1/card.html`     | Card number / expiry / CVC.              |\n| `expressCheckout` | `/v1/express.html`  | Apple Pay / Google Pay / wallet buttons. |\n| `address`         | `/v1/address.html`  | Billing or shipping address.             |\n\nThe iframe pages must be served by your backend at `iframeOrigin`. This SDK\nhandles the merchant-side glue only — see your provider's docs for hosting the\niframe pages themselves.\n\n## Errors\n\nEvery error raised by the Effect surface is a tagged class re-exported from\n`@emergente-labs/elements-sdk/errors`. The Promise API re-throws them\nverbatim, so `instanceof` checks work either way:\n\n```ts\nimport { ElementsConfigError, ElementMountError } from \"@emergente-labs/elements-sdk/errors\";\n\ntry {\n    await loadElements({ /* ... */ });\n} catch (err) {\n    if (err instanceof ElementsConfigError) {\n        // bad publishable key, missing window, etc.\n    }\n}\n```\n\nThe full set: `ElementsConfigError`, `ElementMountError`,\n`ElementNotMountedError`, `ElementLoadError`, `UnsupportedActionError`,\n`UnexpectedActionError`. The `ElementsError` union is exported for exhaustive\n`Effect.catchTag` checks.\n\n## Lifecycle\n\n`loadElements` opens a single root scope. Calling `Elements.dispose()` closes\nit, which:\n\n- unmounts every element created from this instance,\n- detaches the parent-window `message` listener,\n- interrupts the per-element listener fibers,\n- shuts down the internal PubSub instances.\n\nThe Effect API uses the surrounding `Scope` instead of an explicit\n`dispose()` — closing the scope tears everything down.\n\n## Browser support\n\nModern evergreen browsers (Chrome, Firefox, Safari, Edge). The SDK uses\n`postMessage`, `URLSearchParams`, and standard DOM APIs — no polyfills\nrequired for supported targets.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md). Issues and pull requests welcome.\n\n## Security\n\nTo report a security vulnerability, see [SECURITY.md](./SECURITY.md). Please\ndo not open a public issue.\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n","readmeFilename":"README.md","_rev":"1-9bf3af06f30cc16000864b6c7a52f983"}