Skip to content

feat(ui): generalize billing provider descriptors and payment method display - #48

Merged
yyyyaaa merged 1 commit into
mainfrom
phat/component-polish
Oct 1, 2026
Merged

yyyyaaa merged 1 commit into
mainfrom
phat/component-polish

Conversation

@yyyyaaa

@yyyyaaa yyyyaaa commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Makes the billing templates provider-neutral in shape, not just in name, and stops showing provider internals to customers.

  • Descriptor fields on BillingProviderDescriptor (all optional, so existing descriptors keep working):
    • logo: an image drawn on the provider tile instead of the monogram
    • merchantOfRecord: the payment panel says the provider charges, handles tax, and issues invoices
    • immutablePrices: the catalog copy about immutable prices only appears for providers that work that way
    • modeLabels: e.g. Sandbox instead of Test, used by the console badge, sidebar, provider card, and feature chip
    • detectMode: replaces running Stripe's key-prefix parsing on every provider's credentials
  • Customer invoices view: drops the raw sub_… id and the merchant-dashboard link, which customers couldn't open, and shows the method on file through a new provider-neutral paymentMethod field rendered by PaymentMethodRow (card brand, last four, expiry with "Expires soon" / expired states; wallets, bank accounts, invoicing).
  • Demo data: payment methods on the account fixtures (an expired card in the overdue scenario), and the example Paddle and Lemon Squeezy descriptors marked as merchant of record.
const PADDLE: BillingProviderDescriptor = {
  ...base,
  merchantOfRecord: true,
  modeLabels: { test: 'Sandbox', live: 'Live' },
  detectMode: (values) => (values.PADDLE_API_KEY?.includes('_sdbx_') ? 'test' : 'live'),
};
Before After
"Manage in Stripe" panel with the raw subscription id and a dashboard link Method on file (brand, last four, expiry) and provider-specific copy; see Storybook Templates/Billing Account → Merchant of record provider and Billing Kit/History → PaymentMethodRow

🤖 Generated with Claude Code

https://claude.ai/code/session_01GPTLDuvMBGBawVLKL42yYV

…display

- Add logo, merchantOfRecord, immutablePrices, modeLabels, and detectMode to
  BillingProviderDescriptor so non-Stripe providers describe their own
  behaviour instead of inheriting Stripe assumptions
- Show the payment method on file through a provider-neutral
  PaymentMethodSummary and PaymentMethodRow, with expiry warnings
- Keep provider object ids and dashboard links out of customer views
- Name modes and the test-mode feature the provider's way in the console
@tenki-reviewer

tenki-reviewer Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

Review complete. No blocking issues — approved ✅; 1 nitpick below.

🧹 Nitpicks (1) — 🟢 1 low
  • 🟢 Broken logo URL leaves no monogram fallback (provider.tsx:41) — ProviderMark renders <img src={provider.logo}> whenever logo is set, with no load-error fallback to the monogram (packages/ui/src/components/billing-kit/provider.tsx:41).

The change reworks how billing providers describe themselves and how payment methods render to customers. Provider descriptors gain explicit mode-detection and label fallbacks, and the console's connect flow now calls detectMode on submitted values instead of guessing from a secret-prefix heuristic. Customer-facing invoice views drop provider object ids and dashboard links in favor of display-grade payment fields (icon, brand, last4, expiry state via a new UTC-safe monthsToExpiry helper).

Files Change
packages/ui/src/components/billing-kit/{providers,provider,types,demo,index} Provider descriptor contract: detectMode, mode/feature labels, merchant-of-record and immutable-price flags, logo handling
packages/ui/src/components/billing-kit/invoices.tsx Payment-method summary rendering with expiry month math and tone mapping
packages/ui/src/components/billing-console/* Connect flow and catalog/provider views updated to the new descriptor contract
packages/ui/src/components/billing-account/* Customer-facing invoice view: privacy-safe provider copy and fixtures
packages/ui/src/stories/billing/*, packages/ui/test/billing-templates.test.tsx Story variants and tests covering expiry boundaries and privacy assertions

Reviewed commit: c0d2387

@yyyyaaa
yyyyaaa merged commit 22c50f0 into main Oct 1, 2026
5 checks passed
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