{"locator":"npm:@dainamite/cpq-billing-connector","path":"@dainamite/cpq-billing-connector","npm":"@dainamite/cpq-billing-connector","github":"dainamite-technologies/dainamite-core","repoPath":"dainamite-technologies/dainamite-core#main/packages/cpq-billing-connector","kind":"module","type":"3rd-party","enterprise":false,"title":"CPQ → Billing Connector","summary":"Turns CPQ subscription events (activated, amended, renewed, cancelled, merged) into billing accounts and items.","whenToUse":"Use when you run both Dainamite CPQ and Billing and subscriptions sold in CPQ must be billed automatically.","whenNotToUse":"It has no UI or tables of its own: without cpq and billing it does nothing.","category":"payments-finance","tags":["cpq","billing","subscriptions"],"providers":[],"moduleIds":["cpq_billing_connector"],"requires":[{"raw":"cpq","resolvesTo":null},{"raw":"billing","resolvesTo":null},{"raw":"auth","resolvesTo":"core:auth"},{"raw":"directory","resolvesTo":"core:directory"},{"raw":"@dainamite/billing","resolvesTo":"npm:@dainamite/billing"},{"raw":"@dainamite/cpq","resolvesTo":"npm:@dainamite/cpq"},{"raw":"@open-mercato/events","resolvesTo":"npm:@open-mercato/events"}],"replaces":[],"slotConflicts":[],"renamedFrom":[],"supersededBy":null,"alternatives":[],"status":"active","listed":true,"featured":false,"license":{"spdx":"MIT","kind":"osi","mismatch":false},"version":{"latest":"1.0.0","preview":null,"publishedAt":"2026-08-25","integrity":"sha512-NtrNXs4IfPrYYBThH6my8q1Tlz4AIsJGG39Pqj6lAjwrAZ2i68f0jbE6Kvyki3PaNcmRIKD8a0m/PwsWCZtMwA==","installableFrom":"2026-08-30","gitRef":"bf641f89e1493ae88a88234140f0cf43daaa0849","recommended":{"0.9":null,"0.8":null,"next":null}},"identity":{"builtFrom":"none","claimed":false,"source":"npm"},"compat":{"builtFor":{"range":"^0.6.7","kind":"caret-0x","lines":[]},"lines":{"0.9":{"status":"broken","step":"typecheck","omVersion":"0.9.0","moduleVersion":"1.0.0","at":"2026-10-29T09:03:43Z","receipt":"r_20261029_824d4c522ba4","since":"2026-10-29","precheck":null,"patches":[],"finding":"Typecheck failed: TS2707 Generic type 'ColumnDef' requires between 2 and 3 type arguments."}},"verifiedOn":[],"isolation":{"0.9":{"status":"broken","step":"typecheck","moduleVersion":"1.0.0","at":"2026-10-29T09:03:43Z","receipt":"r_20261029_7b9e9a88f335","finding":"Typecheck failed: TS2707 Generic type 'ColumnDef' requires between 2 and 3 type arguments."}}},"anatomy":{"version":"1.0.0","coverage":"partial","counts":{"entities":0,"tables":0,"migrations":0,"routes":0,"publicRoutes":0,"aclFeatures":0,"eventsEmitted":0,"eventsConsumed":6,"backendPages":0,"frontendPages":0,"widgets":0,"workers":0,"cli":0,"aiTools":0,"aiAgents":0,"extends":6},"lists":{"aclFeatures":[],"eventsEmitted":[],"eventsConsumed":["cpq.subscription.activated","cpq.subscription.amended","cpq.subscription.cancelled","cpq.subscription.merged","cpq.subscription.renewed","cpq.subscription.superseded"],"env":[],"hosts":[],"tables":[],"publicRoutes":[],"credentials":[]},"callout":"FEW CONTRACTS","diff":{"from":"0.1.1","added":{"tables":0,"routes":0,"publicRoutes":0,"aclFeatures":0,"env":[],"hosts":[]},"removed":{"tables":0,"routes":0,"aclFeatures":0}}},"signals":{"receipt":{"0.9":"broken","0.8":"untested","next":"untested"},"fit":{"0.9":"ok","0.8":"drift","next":"ok"},"anatomy":"partial","supplyChain":{"status":"ok","reasons":[]},"hygiene":{"status":"ok","failing":[]},"maintenance":{"status":"current","lastRelease":"2026-08-25","catchUpDays":null},"declaredVsObserved":{"status":"match","notes":[]}},"tier":"listed","quality":null,"agentPolicy":{"0.9":{"decision":"refuse","reasons":[{"code":"BROKEN","text":"Broken at typecheck on 0.9 since 29 Oct."},{"code":"THIRD_PARTY","text":"Third-party code runs with access to all tenants' data."}]},"0.8":{"decision":"ask","reasons":[{"code":"THIRD_PARTY","text":"Third-party code runs with access to all tenants' data."},{"code":"NOT_VERIFIED","text":"Not yet tested in a new app on 0.8."}],"consentText":"Install @dainamite/cpq-billing-connector@1.0.0"},"next":{"decision":"ask","reasons":[{"code":"THIRD_PARTY","text":"Third-party code runs with access to all tenants' data."},{"code":"NOT_VERIFIED","text":"Not yet tested in a new app on next."}],"consentText":"Install @dainamite/cpq-billing-connector@1.0.0"}},"install":{"cli":"yarn mercato module add @dainamite/cpq-billing-connector@1.0.0 --allow-third-party","cmm":"npx create-mercato-module install @dainamite/cpq-billing-connector@1.0.0","needsAllowThirdParty":true,"moduleFlag":null},"stats":{"downloads30d":26,"stars":1},"sigil":{"glyph":"0002002","phase":93,"publicRoutes":false},"links":{"page":"https://modules.openmercato.com/m/@dainamite/cpq-billing-connector","md":"https://modules.openmercato.com/m/@dainamite/cpq-billing-connector.md","json":"https://modules.openmercato.com/m/@dainamite/cpq-billing-connector.json","facts":"https://modules.openmercato.com/m/@dainamite/cpq-billing-connector/v/1.0.0/facts.json","npm":"https://www.npmjs.com/package/@dainamite/cpq-billing-connector","repo":"https://github.com/dainamite-technologies/dainamite-core","docs":null},"addedAt":"2026-10-23","updatedAt":"2026-10-29T09:22:28Z","_meta":{"com.openmercato.modules/installable":{"0.9":"1.0.0","0.8":"1.0.0","next":"1.0.0"}},"facts":{"factsVersion":1,"extractor":{"engine":"@open-mercato/cli@0.9.0 extractModuleFacts","factsContractVersion":2,"catalog":"om-modules rentgen 1","durationMs":36},"package":{"locator":"npm:@dainamite/cpq-billing-connector","name":"@dainamite/cpq-billing-connector","version":"1.0.0","integrity":"sha512-NtrNXs4IfPrYYBThH6my8q1Tlz4AIsJGG39Pqj6lAjwrAZ2i68f0jbE6Kvyki3PaNcmRIKD8a0m/PwsWCZtMwA==","source":"npm-tarball","gitRef":"bf641f89e1493ae88a88234140f0cf43daaa0849"},"gate":{"installable":true,"needsModuleFlag":false,"reason":null,"modules":[{"id":"cpq_billing_connector","src":true,"dist":true}]},"kind":"module","license":{"value":"MIT","kind":"osi","mismatch":false,"sources":{"packageJson":"MIT","licenseFile":"MIT","moduleInfo":"MIT","integrationTs":null}},"omPeers":{"@open-mercato/core":"^0.6.7","@open-mercato/events":"^0.6.7","@open-mercato/shared":"^0.6.7"},"dependencies":{},"agentsMd":false,"readmeExcerpt":"# @dainamite/cpq-billing-connector\n\nPre-built integration that wires `@dainamite/cpq` subscription lifecycle\nevents to `@dainamite/billing` API calls.\n\nIt depends on both `@dainamite/cpq` and `@dainamite/billing` (as peers) and\n**must be registered after both** so their services are resolvable when its\nsubscribers fire:\n\n```typescript\n// src/modules.ts — order matters\n{ id: 'cpq', from: '@dainamite/cpq' }\n{ id: 'billing', from: '@dainamite/billing' }\n{ id: 'cpq_billing_connector', from: '@dainamite/cpq-billing-connector' }\n```\n\n```bash\nyarn generate\nyarn mercato db migrate\n```\n\nThere is no UI or schema of its own to configure — it is pure event glue.\nEngines: **Node ≥ 24**.\n\nThe connector subscribes to six CPQ lifecycle events and translates each\nto the billing API contract:\n\n| CPQ event | Connector action |\n|---|---|\n| `cpq.subscription.activated` | Create Billing Account if missing; create Billing Items per charge (one-time + recurring split) |\n| `cpq.subscription.amended` | Create new Billing Items for added subscription items; compute proration value for the partial cycle and post as `one_time` Billing Item; set `bill_end_date` on removed items |\n| `cpq.subscription.renewed` | Extend `bill_end_date` on existing Billing Items; create new Items for any added subscription items |\n| `cpq.subscription.cancelled` | Set `bill_end_date` on all Billing Items for the subscription |\n| `cpq.subscription.merged` | Move Billing Items from source subscriptions to the merged subscription (update `subscription_id`) |\n| `cpq.subscription.superseded` | Set `bill_end_date` on all Billing Items for the superseded subscription |\n\n## Status\n\n**Built — publishing soon** (alongside `@dainamite/billing`; not yet on npm).\nAll six subscribers are wired end-to-end — `@dainamite/cpq` emits the\nmatching events (`cpq.subscription.activated` on new-sale activation,\nthe ARC events on amend / renew / cancel / merge). Proration math lives\nin this package: the `amended` subscriber derives the bill cycle from\nthe billing account via billing's `cycleContaining` (CPQ stays neutral\non billing-calendar semantics).\n\nSee [`specs/implementation/xd-249-billing-spec.md`](../../specs/implementation/xd-249-billing-spec.md)\n§ CPQ Integration for the full design.\n\n## License\n\nMIT\n","modules":[{"id":"cpq_billing_connector","title":"CPQ → Billing Connector","description":null,"requires":[{"raw":"cpq","resolvesTo":null},{"raw":"billing","resolvesTo":null},{"raw":"auth","resolvesTo":"core:auth"},{"raw":"directory","resolvesTo":"core:directory"}],"ejectable":false,"data":{"entities":[],"migrations":{"count":0,"first":null,"last":null},"customEntities":0},"http":{"routes":[],"legacyRouteFiles":0,"authResolved":1},"security":{"aclFeatures":[],"setupDefaultRoleFeatures":false},"events":{"emits":[],"subscribes":[{"event":"cpq.subscription.activated","src":{"file":"src/modules/cpq_billing_connector/subscribers/cpq-subscription-activated.ts","line":7}},{"event":"cpq.subscription.amended","src":{"file":"src/modules/cpq_billing_connector/subscribers/cpq-subscription-amended.ts","line":5}},{"event":"cpq.subscription.cancelled","src":{"file":"src/modules/cpq_billing_connector/subscribers/cpq-subscription-cancelled.ts","line":5}},{"event":"cpq.subscription.merged","src":{"file":"src/modules/cpq_billing_connector/subscribers/cpq-subscription-merged.ts","line":5}},{"event":"cpq.subscription.renewed","src":{"file":"src/modules/cpq_billing_connector/subscribers/cpq-subscription-renewed.ts","line":9}},{"event":"cpq.subscription.superseded","src":{"file":"src/modules/cpq_billing_connector/subscribers/cpq-subscription-superseded.ts","line":5}}]},"ui":{"backendPages":[],"frontendPages":[],"widgets":0,"extensionHosts":0},"background":{"workers":[],"cli":[]},"ai":{"tools":[],"agents":[]},"config":{"credentials":[],"env":[]},"network":{"hosts":[],"undeclared":[]},"extends":[{"kind":"subscriber","target":"cpq.subscription.activated"},{"kind":"subscriber","target":"cpq.subscription.amended"},{"kind":"subscriber","target":"cpq.subscription.cancelled"},{"kind":"subscriber","target":"cpq.subscription.merged"},{"kind":"subscriber","target":"cpq.subscription.renewed"},{"kind":"subscriber","target":"cpq.subscription.superseded"}],"omImports":{"@open-mercato/shared":{"lib/commands/command-bus":["CommandBus"],"lib/di/container":["AppContainer","createRequestContainer"],"modules/entities":["CustomEntitySpec"],"modules/registry":["ModuleInfo"],"modules/setup":["ModuleSetupConfig"]}},"collisionKeys":{"moduleId":"cpq_billing_connector","tables":[],"aclFeatures":[],"eventIds":[],"backendRoutes":[]},"publicRoutes":0,"glyph":"0002002","lint":[{"code":"likely-example","severity":"info","message":"Module has no api/ and no data/ folder. Consider the example tag if this is an exercise.","anchor":"spec 4.3","src":null},{"code":"no-agents-md","severity":"info","message":"No AGENTS.md in the package.","anchor":"g3 §3","src":null},{"code":"peer-range-behind","severity":"info","message":"Built for ^0.6.7 does not include Open Mercato 0.9.0.","anchor":"w4 §4.2","src":null},{"code":"ships-tests","severity":"info","message":"The tarball ships test files.","anchor":null,"src":null},{"code":"version-drift","severity":"info","message":"ModuleInfo says 0.1.0, package.json says 1.0.0.","anchor":null,"src":{"file":"src/modules/cpq_billing_connector/index.ts","line":3}}]}],"coverage":{"routesAuthResolved":1,"integrationTs":"absent"},"diagnostics":[]},"receipts":[{"schema":1,"id":"r_20261029_7b9e9a88f335","cellKey":"7b9e9a88f335ee9e6a3d1123952f1ec0441cfba379b20b09db9b53e3aa8472c0","module":{"locator":"npm:@dainamite/cpq-billing-connector","version":"1.0.0","integrity":"sha512-NtrNXs4IfPrYYBThH6my8q1Tlz4AIsJGG39Pqj6lAjwrAZ2i68f0jbE6Kvyki3PaNcmRIKD8a0m/PwsWCZtMwA=="},"om":{"line":"0.9","version":"0.9.0","createApp":"create-mercato-app@0.9.0","preset":"empty"},"harness":{"version":"c349007c2b5b","node":"24.21.0","yarn":"4.17.1","runner":"ubuntu-latest","mode":"realistic","patches":[{"id":"api-keys","why":"OM 0.9.0 empty preset omits api_keys (fixed on main in #7473, not in release/v0.9.x)","ref":"https://github.com/open-mercato/open-mercato/pull/7473"}]},"baseline":{"status":"verified","receipt":"r_20261029_971197f20239"},"requiresInstalled":["core:catalog","core:sales","core:customers","core:dictionaries","@dainamite/cpq@0.4.0","core:payment_gateways","@dainamite/billing@0.19.0"],"steps":[{"name":"scaffold","status":"pass","sec":3,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"install","status":"pass","sec":69,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"add","status":"pass","sec":106,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"generate","status":"pass","sec":10,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"typecheck","status":"fail","sec":69,"signature":"3685a147f34b2b921f29c9053f72d8a937f6de5b","excerpt":"node_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(223,33): error TS2707: Generic type 'ColumnDef' requires between 2 and 3 type arguments.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(228,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(237,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(242,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(247,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(311,33): error TS2707: Generic type 'ColumnDef' requires between 2 and 3 type arguments.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(316,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modul","file":"node_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx","line":223},{"name":"initialize","status":"fail","sec":11,"signature":"df68c8f70cd0105e07db3fe36f90d40678bf9004","excerpt":"❌ Initialization failed: relation \"message_channel_links\" does not exist","file":null,"line":null},{"name":"build","status":"skipped","sec":null,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"start","status":"skipped","sec":null,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"smoke","status":"skipped","sec":null,"signature":null,"excerpt":null,"file":null,"line":null}],"result":{"status":"broken","failedStep":"typecheck","alsoFailed":["initialize"],"classification":"module-fail","quarantineUntil":null},"transition":{"from":null,"to":"broken","confirmed":true},"run":{"id":40842502780,"attempt":2,"url":"https://github.com/open-mercato/modules/actions/runs/40846683223/job/123356065770","at":"2026-10-29T09:03:43Z","durationSec":354},"attestation":null},{"schema":1,"id":"r_20261029_824d4c522ba4","cellKey":"824d4c522ba4254fb77e110c7b08678fb59d312813b16528e6eca9d378ae172a","module":{"locator":"npm:@dainamite/cpq-billing-connector","version":"1.0.0","integrity":"sha512-NtrNXs4IfPrYYBThH6my8q1Tlz4AIsJGG39Pqj6lAjwrAZ2i68f0jbE6Kvyki3PaNcmRIKD8a0m/PwsWCZtMwA=="},"om":{"line":"0.9","version":"0.9.0","createApp":"create-mercato-app@0.9.0","preset":"classic"},"harness":{"version":"c349007c2b5b","node":"24.21.0","yarn":"4.17.1","runner":"ubuntu-latest","mode":"realistic","patches":[]},"baseline":{"status":"verified","receipt":"r_20261029_e5f612bd10e0"},"requiresInstalled":["@dainamite/cpq@0.4.0","@dainamite/billing@0.19.0"],"steps":[{"name":"scaffold","status":"pass","sec":3,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"install","status":"pass","sec":68,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"add","status":"pass","sec":121,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"generate","status":"pass","sec":29,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"typecheck","status":"fail","sec":127,"signature":"3685a147f34b2b921f29c9053f72d8a937f6de5b","excerpt":"node_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(223,33): error TS2707: Generic type 'ColumnDef' requires between 2 and 3 type arguments.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(228,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(237,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(242,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(247,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(311,33): error TS2707: Generic type 'ColumnDef' requires between 2 and 3 type arguments.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(316,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modul","file":"node_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx","line":223},{"name":"initialize","status":"pass","sec":50,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"build","status":"fail","sec":233,"signature":"ee212b5a7b33e2a2a986a9a7ad81f052728cadc3","excerpt":"node_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(223,33): error TS2707: Generic type 'ColumnDef' requires between 2 and 3 type arguments.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(228,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(237,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(242,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(247,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(311,33): error TS2707: Generic type 'ColumnDef' requires between 2 and 3 type arguments.\nnode_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx(316,18): error TS7031: Binding element 'row' implicitly has an 'any' type.\nnode_modul","file":"node_modules/@dainamite/billing/src/modules/billing/backend/billing/accounts/[id]/page.tsx","line":223},{"name":"start","status":"skipped","sec":null,"signature":null,"excerpt":null,"file":null,"line":null},{"name":"smoke","status":"skipped","sec":null,"signature":null,"excerpt":null,"file":null,"line":null}],"result":{"status":"broken","failedStep":"typecheck","alsoFailed":["build"],"classification":"module-fail","quarantineUntil":null},"transition":{"from":null,"to":"broken","confirmed":true},"run":{"id":40842502780,"attempt":2,"url":"https://github.com/open-mercato/modules/actions/runs/40846683223/job/123356065701","at":"2026-10-29T09:03:43Z","durationSec":764},"attestation":null}],"rules":[{"id":"LST-1","pass":true,"detail":"Descriptor is valid."},{"id":"LST-2","pass":true,"detail":"Stable version exists and is not deprecated."},{"id":"LST-3","pass":true,"detail":"src/modules and dist/modules pair found."},{"id":"LST-4","pass":true,"detail":"License: MIT."},{"id":"LST-5","pass":true,"detail":"No known malware or open critical advisory."},{"id":"LST-6","pass":true,"detail":"Name reviewed at merge."},{"id":"VER-1","pass":false,"detail":"Broken at typecheck on 0.9 since 29 Oct."},{"id":"VER-2","pass":true,"detail":"Fits statically on 0.9: ok."},{"id":"VER-3","pass":true,"detail":"Supply chain: ok."},{"id":"VER-4","pass":true,"detail":"No lint errors."},{"id":"VER-5","pass":true,"detail":"Tarball repository.url matches the descriptor."}],"maintainers":["dainamite-acc","kamyyylo"]}
