Skip to content

Add SubscriptionEvent wrapping/disable/enable and Invoice updateStatus/disable [PIP-311]#129

Open
wscourge wants to merge 4 commits intomainfrom
wiktor/pip-311-node-sdk-feature-updates
Open

Add SubscriptionEvent wrapping/disable/enable and Invoice updateStatus/disable [PIP-311]#129
wscourge wants to merge 4 commits intomainfrom
wiktor/pip-311-node-sdk-feature-updates

Conversation

@wscourge
Copy link
Contributor

@wscourge wscourge commented Mar 17, 2026

Summary

Closes PIP-311

  • Add auto-wrapping of flat params into subscription_event envelope for create/update/delete, with backward compatibility for already-enveloped inputs
  • Add SubscriptionEvent.disable / SubscriptionEvent.enable endpoints
  • Fix bug where passing undefined callback to _method() blocked request body from being sent
  • Add Invoice.updateStatus and Invoice.disable endpoints
  • Expand test coverage: body-wrapping verification, callback style, error handling, and Account include query param

Test plan

  • All 220 tests pass (npm test)
  • Verified envelope wrapping via nock body capture
  • Verified backward compatibility (pre-wrapped params not double-wrapped)
  • Verified error responses return correct status codes

Manual testing instructions

Prerequisites: Install the branch locally:

cd chartmogul-node
git checkout wiktor/pip-311-node-sdk-feature-updates
npm install
node

Then in the Node REPL:

const ChartMogul = require('./lib/chartmogul');
const config = new ChartMogul.Config('YOUR_API_KEY');

Use a staging/test account with existing subscription events and invoices.


1. SubscriptionEvent — flat params auto-wrapping (create)

Previously you had to wrap params in { subscription_event: { ... } }. Now flat params work too.

// Flat params (NEW) — should auto-wrap into envelope
const res = await ChartMogul.SubscriptionEvent.create(config, {
  customer_external_id: 'cus_test_001',
  data_source_uuid: 'ds_XXXX',
  event_type: 'subscription_start_scheduled',
  event_date: '2026-03-01T00:00:00Z',
  effective_date: '2026-04-01T00:00:00Z',
  external_id: 'evt_test_flat_' + Date.now(),
  subscription_external_id: 'sub_test_001'
});
console.log(res); // Should succeed and return { subscription_event: { id: ..., ... } }
// Envelope params (BACKWARD COMPAT) — should still work, no double-wrapping
const res2 = await ChartMogul.SubscriptionEvent.create(config, {
  subscription_event: {
    customer_external_id: 'cus_test_001',
    data_source_uuid: 'ds_XXXX',
    event_type: 'subscription_start_scheduled',
    event_date: '2026-03-01T00:00:00Z',
    effective_date: '2026-04-01T00:00:00Z',
    external_id: 'evt_test_envelope_' + Date.now(),
    subscription_external_id: 'sub_test_001'
  }
});
console.log(res2); // Should succeed identically

✅ Expected: Both calls succeed and return the created subscription event.


2. SubscriptionEvent — flat params auto-wrapping (update)

// Update using flat params with id
const updated = await ChartMogul.SubscriptionEvent.updateWithParams(config, {
  id: <EVENT_ID_FROM_STEP_1>,
  plan_external_id: 'plan_gold_monthly'
});
console.log(updated); // Should show updated plan_external_id
// Update using flat params with external_id + data_source_uuid
const updated2 = await ChartMogul.SubscriptionEvent.updateWithParams(config, {
  external_id: 'evt_test_flat_XXXX',
  data_source_uuid: 'ds_XXXX',
  plan_external_id: 'plan_silver_monthly'
});
console.log(updated2);

✅ Expected: Both calls succeed and return the updated subscription event.


3. SubscriptionEvent — flat params auto-wrapping (delete)

// Delete using flat params with id
await ChartMogul.SubscriptionEvent.deleteWithParams(config, {
  id: <EVENT_ID>
});
// Should return empty object {}
// Delete using flat params with external_id + data_source_uuid
await ChartMogul.SubscriptionEvent.deleteWithParams(config, {
  external_id: 'evt_test_envelope_XXXX',
  data_source_uuid: 'ds_XXXX'
});
// Should return empty object {}

✅ Expected: Both calls succeed with empty response {}.


4. SubscriptionEvent — disable / enable

// First create an event to work with (or use an existing event ID)
const event = await ChartMogul.SubscriptionEvent.create(config, {
  customer_external_id: 'cus_test_001',
  data_source_uuid: 'ds_XXXX',
  event_type: 'subscription_start_scheduled',
  event_date: '2026-03-01T00:00:00Z',
  effective_date: '2026-04-01T00:00:00Z',
  external_id: 'evt_disable_test_' + Date.now(),
  subscription_external_id: 'sub_test_001'
});
const eventId = event.subscription_event.id;

// Disable
const disabled = await ChartMogul.SubscriptionEvent.disable(config, eventId);
console.log(disabled); // subscription_event.disabled should be true

// Enable
const enabled = await ChartMogul.SubscriptionEvent.enable(config, eventId);
console.log(enabled); // subscription_event.disabled should be false
// Error case — nonexistent ID should return 404
try {
  await ChartMogul.SubscriptionEvent.disable(config, 999999999);
} catch (e) {
  console.log(e.status); // Should be 404
}

✅ Expected: Disable returns disabled: true, enable returns disabled: false, nonexistent ID returns 404.


5. Invoice — updateStatus

// Void an existing invoice (use a real invoice UUID from your test account)
const invoiceUuid = 'inv_XXXX';

const result = await ChartMogul.Invoice.updateStatus(config, invoiceUuid, {
  status: 'void'
});
console.log(result); // Should show status: 'void'
// Error case — invalid status transition should return 422
try {
  await ChartMogul.Invoice.updateStatus(config, invoiceUuid, {
    status: 'invalid_status'
  });
} catch (e) {
  console.log(e.status); // Should be 422
}

✅ Expected: Valid status update succeeds, invalid status returns 422.


6. Invoice — disable

const invoiceUuid = 'inv_XXXX';

const disabled = await ChartMogul.Invoice.disable(config, invoiceUuid);
console.log(disabled); // Should show disabled: true, disabled_at, disabled_by
// Error case — nonexistent invoice should return 404
try {
  await ChartMogul.Invoice.disable(config, 'inv_nonexistent');
} catch (e) {
  console.log(e.status); // Should be 404
}

✅ Expected: Disable succeeds with disabled: true + timestamps, nonexistent UUID returns 404.


🤖 Generated with Claude Code

wscourge and others added 3 commits March 17, 2026 17:05
…passing bug

- Wrap flat params in `subscription_event` envelope for create/update/delete
- Add disable/enable state toggling endpoints
- Fix bug where undefined callback arg blocked data extraction in _method()
- Add tests verifying body wrapping and error handling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Invoice.updateStatus (PATCH /v1/invoices/:uuid)
- Add Invoice.disable (PATCH /v1/invoices/:uuid/disable)
- Add tests for happy path, callback style, body params, and error cases

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@wscourge wscourge marked this pull request as ready for review March 17, 2026 16:16
@wscourge wscourge requested a review from Copilot March 17, 2026 16:17
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the ChartMogul Node SDK to support newer API behaviors for Subscription Events, Invoices, and Account retrieval by adding/adjusting client methods and expanding test coverage for these behaviors.

Changes:

  • Add support for flat (non-enveloped) SubscriptionEvent params by auto-wrapping into a subscription_event envelope, while keeping backward compatibility for already-enveloped inputs.
  • Add SubscriptionEvent.enable/disable and Invoice.updateStatus/disable SDK methods and corresponding tests.
  • Expand invoice/account test fixtures and assertions to cover new/optional response fields (e.g., error, id, and account include query param).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
lib/chartmogul/subscription_event.js Adds param-wrapping overrides for create/update/delete and adds enable/disable endpoints.
lib/chartmogul/invoice.js Adds PATCH helpers for invoice status updates and invoice disable endpoint.
test/chartmogul/subscription-event.js Updates tests to validate envelope wrapping + adds enable/disable tests and negative cases.
test/chartmogul/invoice.js Adds tests for invoice status updates/disable + extends fixtures with error fields.
test/chartmogul/account.js Adds assertions for id and supports include query param + negative case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

- Use hasOwnProperty check in wrapParams to handle falsy envelope values
- Use typeof callback === 'function' instead of truthy check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@wscourge wscourge changed the title Wiktor/pip 311 node sdk feature updates Add SubscriptionEvent wrapping/disable/enable and Invoice updateStatus/disable [PIP-311] Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants