Skip to content

feat(cli,sdk): redeem promo codes via billing top-up --code (RND-557)#135

Draft
mmurrs wants to merge 1 commit into
masterfrom
feat/cli-redeem-code
Draft

feat(cli,sdk): redeem promo codes via billing top-up --code (RND-557)#135
mmurrs wants to merge 1 commit into
masterfrom
feat/cli-redeem-code

Conversation

@mmurrs
Copy link
Copy Markdown
Contributor

@mmurrs mmurrs commented Apr 29, 2026

Summary

Adds --code to ecloud billing top-up so existing subscribers can apply a Stripe promo code. Today there's no way to do this — the Stripe Checkout "Add code" box only shows on initial subscribe.

Usage (agent-friendly, non-interactive, no prompts):

$ ecloud billing top-up --code LAUNCH50

Redeem promotion code
─────────────────────────────────────────────

  Wallet:  0x6d4f13BD87DD441B3Fc8d94349C72EeFe27684e8
  Code:    LAUNCH50

  ✓ Redeemed LAUNCH50: $50.00 in credits
  Balance: $55.00
  Credits expire: 7/28/2026

Pairs with API PR: https://github.com/Layr-Labs/ecloud-billing-api/pull/41

Scope

 packages/cli/src/commands/billing/__tests__/top-up.test.ts | 31 +++++++++++++++
 packages/cli/src/commands/billing/top-up.ts                | 47 +++++++++++++++++++++-
 packages/sdk/src/client/common/types/index.ts              | 11 ++++++
 packages/sdk/src/client/common/utils/billingapi.ts         | 10 ++++-
 packages/sdk/src/client/modules/billing/index.ts           | 23 ++++++++++-
 5 files changed, 121 insertions(+), 1 deletion(-)

No changes to subscribe, status, cancel, or the existing USDC top-up flow. --code short-circuits before any on-chain interaction, so nothing in the USDC path is touched.

How to validate

Unit tests:

pnpm --filter @layr-labs/ecloud-cli test

All 55 tests pass (including 2 new --code cases).

Manual dry-run (no Stripe needed):

ecloud billing top-up --code ANY --help    # shows flag description

End-to-end (against Stripe test mode + local billing-api from #41):

  1. Check out feat/redeem-code on ecloud-billing-api and make run with a Stripe test key.
  2. Create a Coupon ($5 off, once) and a Promotion Code (e.g., TEST5, max_redemptions=1) in the Stripe Dashboard (test mode).
  3. Build the CLI: pnpm --filter @layr-labs/ecloud-cli build
  4. Run against a subscribed wallet:
    ecloud billing top-up --code TEST5
    
    Expect: ✓ Redeemed TEST5: $5.00 in credits + new balance + expiry.
  5. Second attempt (same wallet, same code) → Stripe idempotency re-returns the same grant silently.
  6. Different wallet, same code → friendly error: Code "TEST5" is not valid, inactive, or already redeemed. (because Promotion Code got deactivated after the first burn).
  7. Percent-off code → Code "..." is not a fixed-amount credit code (percent-off codes are not supported).
  8. Confirm via ecloud billing statusRemaining Credits should reflect the new amount.

Not in this PR

  • New menu / interactive picker — deliberately kept flag-driven for CLI + agent ergonomics. Can layer an inquirer prompt later.
  • CC top-up — separate open work.

Linear

RND-557 — https://linear.app/eigenlabs/issue/RND-557/add-couponcredit-code-redemption-to-ecloud-billing-top-up

🤖 Generated with Claude Code

Adds a --code flag to `ecloud billing top-up` so existing subscribers can
apply a Stripe promotion code without going through the initial Checkout
flow. Pairs with the new POST /products/:id/redeem endpoint on
ecloud-billing-api (#41).

SDK:
- BillingApiClient.redeemCode() — thin POST wrapper
- BillingModule.redeemCode() — telemetry-wrapped, product-aware
- RedeemCodeRequest/RedeemCodeResponse types exported through common/types

CLI:
- New --code flag on the existing `billing top-up` command
- Short-circuits before USDC flow when --code is set; USDC path unchanged
- Friendly errors for 404 (bad/inactive code) and 422 (percent-off rejected)
- Prints granted amount, new balance, and expiry in a single pass — agent-friendly,
  non-interactive, no prompts

Tests: two vitest cases covering happy path and 404; all 55 existing billing
tests still green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.

1 participant