backend-manager 5.0.117 → 5.0.119

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 (30) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/package.json +1 -1
  3. package/src/manager/events/firestore/payments-webhooks/on-write.js +11 -1
  4. package/src/manager/index.js +3 -0
  5. package/src/manager/libraries/email.js +5 -1
  6. package/src/manager/libraries/payment/processors/chargebee.js +637 -0
  7. package/src/manager/routes/marketing/email-preferences/post.js +108 -0
  8. package/src/manager/routes/payments/cancel/processors/chargebee.js +43 -0
  9. package/src/manager/routes/payments/cancel/processors/paypal.js +2 -1
  10. package/src/manager/routes/payments/intent/processors/chargebee.js +120 -0
  11. package/src/manager/routes/payments/portal/processors/chargebee.js +62 -0
  12. package/src/manager/routes/payments/portal/processors/paypal.js +2 -1
  13. package/src/manager/routes/payments/refund/processors/chargebee.js +101 -0
  14. package/src/manager/routes/payments/webhook/processors/chargebee.js +170 -0
  15. package/src/manager/schemas/marketing/email-preferences/post.js +9 -0
  16. package/templates/_.env +1 -0
  17. package/templates/backend-manager-config.json +11 -0
  18. package/test/fixtures/chargebee/invoice-one-time.json +27 -0
  19. package/test/fixtures/chargebee/subscription-active.json +44 -0
  20. package/test/fixtures/chargebee/subscription-cancelled.json +42 -0
  21. package/test/fixtures/chargebee/subscription-in-trial.json +41 -0
  22. package/test/fixtures/chargebee/subscription-legacy-plan.json +41 -0
  23. package/test/fixtures/chargebee/subscription-non-renewing.json +41 -0
  24. package/test/fixtures/chargebee/subscription-paused.json +42 -0
  25. package/test/fixtures/chargebee/webhook-payment-failed.json +51 -0
  26. package/test/fixtures/chargebee/webhook-subscription-created.json +47 -0
  27. package/test/helpers/payment/chargebee/parse-webhook.js +413 -0
  28. package/test/helpers/payment/chargebee/to-unified-one-time.js +147 -0
  29. package/test/helpers/payment/chargebee/to-unified-subscription.js +648 -0
  30. package/test/routes/marketing/email-preferences.js +216 -0
package/CHANGELOG.md CHANGED
@@ -14,6 +14,34 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
14
14
  - `Fixed` for any bug fixes.
15
15
  - `Security` in case of vulnerabilities.
16
16
 
17
+ # [5.0.119] - 2026-03-07
18
+ ### Added
19
+ - `POST /marketing/email-preferences` route for unsubscribe/resubscribe via SendGrid ASM suppression groups
20
+ - HMAC signature verification (`UNSUBSCRIBE_HMAC_KEY`) on unsubscribe links to prevent forged requests
21
+ - HMAC signature generation in email library when building unsubscribe URLs
22
+ - `UNSUBSCRIBE_HMAC_KEY` environment variable in template `.env`
23
+ - Test suite for email-preferences endpoint (10 tests covering sig verification, validation, auth)
24
+
25
+ ### Changed
26
+ - Unsubscribe URL in emails no longer includes `appName` and `appUrl` params (replaced by HMAC sig)
27
+
28
+ # [5.0.118] - 2026-03-06
29
+ ### Added
30
+ - Chargebee payment processor with full pipeline support (intent, webhook, cancel, refund, portal).
31
+ - Chargebee shared library (`payment/processors/chargebee.js`) with raw HTTP API wrapper, unified subscription/one-time transformers, and both Items model (new) and Plans model (legacy) product resolution.
32
+ - Chargebee webhook processor supporting subscription lifecycle events (`subscription_created`, `subscription_cancelled`, `subscription_renewed`, `payment_failed`, `payment_refunded`, etc.) and one-time invoice events.
33
+ - Chargebee intent processor for hosted page checkout (subscriptions and one-time purchases) with deterministic item price IDs (`{itemId}-{frequency}`).
34
+ - Chargebee cancel processor with immediate cancellation during trials and end-of-term cancellation otherwise.
35
+ - Chargebee refund processor with 7-day full/prorated refund logic (matching Stripe/PayPal behavior).
36
+ - Chargebee portal processor for self-service subscription management via Chargebee Portal Sessions.
37
+ - Backwards compatibility for legacy Chargebee subscriptions: reads `cf_clientorderid`/`cf_uid` custom fields alongside new `meta_data` JSON format.
38
+ - Chargebee test suite: `to-unified-subscription`, `to-unified-one-time`, and `parse-webhook` group tests with fixtures covering all status mappings, product resolution (Items + legacy Plans), and edge cases.
39
+ - Chargebee customer name extraction from `shipping_address`/`billing_address` in webhook on-write pipeline.
40
+ - `chargebee` config keys in product templates (`itemId`, `legacyPlanIds`).
41
+
42
+ ### Changed
43
+ - `CHARGEBEE_SITE` environment variable is now set from config in Manager init (matching PayPal pattern), so the Chargebee library doesn't need a Manager reference.
44
+
17
45
  # [5.0.111] - 2026-03-05
18
46
  ### Changed
19
47
  - PayPal client ID is now read from `backend-manager-config.json` (`payment.processors.paypal.clientId`) instead of requiring a `PAYPAL_CLIENT_ID` environment variable.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-manager",
3
- "version": "5.0.117",
3
+ "version": "5.0.119",
4
4
  "description": "Quick tools for developing Firebase functions",
5
5
  "main": "src/manager/index.js",
6
6
  "bin": {
@@ -321,7 +321,17 @@ function extractCustomerName(resource, resourceType) {
321
321
  }
322
322
  }
323
323
 
324
- // Subscriptions only have customer ID, no name
324
+ // Chargebee subscriptions carry shipping_address / billing_address with first_name + last_name
325
+ if (resourceType === 'subscription') {
326
+ const addr = resource.shipping_address || resource.billing_address;
327
+ if (addr?.first_name) {
328
+ const { capitalize } = require('../../../libraries/infer-contact.js');
329
+ return {
330
+ first: capitalize(addr.first_name) || null,
331
+ last: capitalize(addr.last_name) || null,
332
+ };
333
+ }
334
+ }
325
335
 
326
336
  if (!fullName) {
327
337
  return null;
@@ -141,6 +141,9 @@ Manager.prototype.init = function (exporter, options) {
141
141
  // Set PAYPAL_CLIENT_ID from config (clientId is public, not a secret — lives in config, not .env)
142
142
  process.env.PAYPAL_CLIENT_ID = process.env.PAYPAL_CLIENT_ID || self.config?.payment?.processors?.paypal?.clientId || '';
143
143
 
144
+ // Set CHARGEBEE_SITE from config (site is public, not a secret — lives in config, not .env)
145
+ process.env.CHARGEBEE_SITE = process.env.CHARGEBEE_SITE || self.config?.payment?.processors?.chargebee?.site || '';
146
+
144
147
  // Resolve legacy paths
145
148
  // TODO: Remove this in future versions (after we migrate to removing app.id from config)
146
149
  self.config.app = self.config.app || {};
@@ -161,7 +161,11 @@ Email.prototype.build = async function (settings) {
161
161
  const sendAt = normalizeSendAt(settings.sendAt);
162
162
 
163
163
  // Build unsubscribe URL
164
- const unsubscribeUrl = `${Manager.project.websiteUrl}/portal/account/email-preferences?email=${encode(to[0].email)}&asmId=${encode(groupId)}&templateId=${encode(templateId)}&appName=${brandData.name}&appUrl=${brandData.url}`;
164
+ // Generate HMAC signature for unsubscribe link verification
165
+ const crypto = require('crypto');
166
+ const unsubSig = crypto.createHmac('sha256', process.env.UNSUBSCRIBE_HMAC_KEY).update(to[0].email.toLowerCase()).digest('hex');
167
+
168
+ const unsubscribeUrl = `${Manager.project.websiteUrl}/portal/email-preferences?email=${encode(to[0].email)}&asmId=${encode(groupId)}&templateId=${encode(templateId)}&sig=${unsubSig}`;
165
169
 
166
170
  // Build signoff
167
171
  const signoff = settings?.data?.signoff || {};