Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计提醒

stripe-subscription-uxStripe subscription UX 浏览器

Agent Skill

用于辅助界面设计、视觉规范、排版、配色、布局和交互体验优化。它适合让 Agent 根据产品场景整理页面结构、生成 UI 方案、检查视觉一致性或改进组件层级。使用时需要结合现有品牌、设计系统和用户任务,不应只堆装饰元素;涉及真实页面改动时,应通过截图或浏览器预览检查文本溢出、对齐和响应式表现。

总安装

535

周安装

23

GitHub Stars

8

下载量

188
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:stripe-subscription-ux(Stripe subscription UX 浏览器)
来源仓库:https://github.com/phrazzld/claude-config
仓库路径:skills/stripe-subscription-ux
安装命令:
npx skills add https://github.com/phrazzld/claude-config --skill stripe-subscription-ux
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/phrazzld/claude-config --skill stripe-subscription-ux

简介

用于辅助界面设计、视觉规范、排版、配色、布局和交互体验优化。

  • 适合整理页面结构、生成 UI 方案或检查视觉一致性。
  • 可在 Codex、Claude、Cursor、Gemini CLI 中调用,结合品牌和设计系统使用。
  • 涉及真实页面改动时,应通过截图或浏览器预览检查文本溢出和对齐。
  • 不应只堆装饰元素,需结合用户任务和现有组件层级。

SKILL.md

Subscription Management UX

Every Stripe integration must include a world-class subscription management experience. Users should never wonder about their billing status.

Non-Negotiable Requirements

A complete Stripe integration MUST include UI for users to:

1. View Current Plan

  • Plan name (e.g., "Pro", "Monthly", "Annual")
  • Subscription status (active, trialing, canceled, past_due)
  • Clear visual indicator of status
  • Trial remaining (if applicable)

2. See Billing Cycle

  • Next billing date
  • Amount to be charged
  • Billing frequency (monthly/annual)
  • Current period start/end dates

3. View Payment Method

  • Card brand and last 4 digits (e.g., "Visa ending in 4242")
  • Expiration date
  • Update payment method button

4. Manage Subscription

  • Cancel subscription
  • Resume canceled subscription (if before period end)
  • Upgrade/downgrade (if multiple tiers)
  • Switch billing frequency (monthly ↔ annual)

5. View Billing History

  • Past invoices with dates and amounts
  • Download invoice PDFs
  • Payment status (paid, failed, refunded)

Implementation Approaches

Option A: Stripe Customer Portal (Recommended)

Use Stripe's built-in Customer Portal for most functionality:

// Create portal session
const portalSession = await stripe.billingPortal.sessions.create({
  customer: stripeCustomerId,
  return_url: `${APP_URL}/settings`,
});

// Redirect user to portal
redirect(portalSession.url);

Pros:

  • Minimal code
  • Stripe handles PCI compliance
  • Always up-to-date with Stripe features
  • Mobile-responsive

Cons:

  • Less control over styling
  • Branding limited to Stripe's options
  • User leaves your site briefly

Option B: Custom UI + Stripe API

Build custom UI that calls Stripe API:

// Fetch subscription details
const subscription = await stripe.subscriptions.retrieve(subscriptionId, {
  expand: ['default_payment_method', 'latest_invoice'],
});

// Display in your UI
const planName = subscription.items.data[0].price.nickname;
const status = subscription.status;
const currentPeriodEnd = new Date(subscription.current_period_end * 1000);
const paymentMethod = subscription.default_payment_method as Stripe.PaymentMethod;
const cardBrand = paymentMethod?.card?.brand;
const cardLast4 = paymentMethod?.card?.last4;

Pros:

  • Full control over UX
  • Stays within your app
  • Custom branding

Cons:

  • More code to maintain
  • Must handle payment method updates carefully (PCI)
  • Must implement all edge cases

Option C: Hybrid (Best of Both)

Custom settings page for display, Stripe Portal for mutations:

// Custom display UI
<SettingsCard>
  <h2>Subscription</h2>
  <p>Plan: {planName}</p>
  <p>Status: <StatusBadge status={status} /></p>
  <p>Next billing: {formatDate(currentPeriodEnd)}</p>
  <p>Card: {cardBrand} ending in {cardLast4}</p>

  {/* Mutations go to Stripe Portal */}
  <Button onClick={openStripePortal}>
    Manage Subscription
  </Button>
</SettingsCard>

This is the recommended approach.

Component Structure

Typical implementation needs:

components/
├── billing/
│   ├── SubscriptionCard.tsx      # Current plan overview
│   ├── BillingCycleInfo.tsx      # Next billing date, amount
│   ├── PaymentMethodDisplay.tsx  # Card on file
│   ├── BillingHistory.tsx        # Past invoices
│   ├── ManageSubscriptionButton.tsx  # Opens portal
│   └── TrialBanner.tsx           # Trial status/countdown

Settings page:

// app/(dashboard)/settings/page.tsx
export default function SettingsPage() {
  return (
    <div>
      <h1>Settings</h1>

      <section>
        <h2>Subscription</h2>
        <SubscriptionCard />
        <BillingCycleInfo />
        <PaymentMethodDisplay />
        <ManageSubscriptionButton />
      </section>

      <section>
        <h2>Billing History</h2>
        <BillingHistory />
      </section>
    </div>
  );
}

API Requirements

Backend needs to expose:

// convex/billing.ts (or API route)

// Get subscription details for display
export const getSubscriptionDetails = query({
  handler: async (ctx) => {
    const userId = await requireAuth(ctx);
    const user = await ctx.db.get(userId);

    return {
      status: user.subscriptionStatus,
      planName: user.planName ?? 'Pro',
      currentPeriodEnd: user.currentPeriodEnd,
      cancelAtPeriodEnd: user.cancelAtPeriodEnd,
      trialEndsAt: user.trialEndsAt,
      // Payment method from Stripe (cached or fetched)
      paymentMethod: user.paymentMethodSummary,
    };
  },
});

// Create Stripe Portal session
export const createPortalSession = action({
  handler: async (ctx) => {
    const userId = await requireAuth(ctx);
    const user = await ctx.runQuery(internal.users.get, { userId });

    if (!user.stripeCustomerId) {
      throw new ConvexError("No billing account");
    }

    const session = await stripe.billingPortal.sessions.create({
      customer: user.stripeCustomerId,
      return_url: `${process.env.NEXT_PUBLIC_APP_URL}/settings`,
    });

    return { url: session.url };
  },
});

// Get billing history (invoices)
export const getBillingHistory = action({
  handler: async (ctx) => {
    const userId = await requireAuth(ctx);
    const user = await ctx.runQuery(internal.users.get, { userId });

    if (!user.stripeCustomerId) {
      return { invoices: [] };
    }

    const invoices = await stripe.invoices.list({
      customer: user.stripeCustomerId,
      limit: 10,
    });

    return {
      invoices: invoices.data.map(inv => ({
        id: inv.id,
        date: inv.created,
        amount: inv.amount_paid,
        status: inv.status,
        invoicePdf: inv.invoice_pdf,
      })),
    };
  },
});

Schema Requirements

User model needs:

// convex/schema.ts
users: defineTable({
  // ... existing fields

  // Subscription state
  subscriptionStatus: v.optional(v.string()),
  stripeCustomerId: v.optional(v.string()),
  stripeSubscriptionId: v.optional(v.string()),

  // Billing cycle
  currentPeriodEnd: v.optional(v.number()),
  cancelAtPeriodEnd: v.optional(v.boolean()),

  // Trial
  trialEndsAt: v.optional(v.number()),

  // Payment method cache (update from webhooks)
  paymentMethodSummary: v.optional(v.object({
    brand: v.string(),
    last4: v.string(),
    expMonth: v.number(),
    expYear: v.number(),
  })),

  // Plan info
  planName: v.optional(v.string()),
  planInterval: v.optional(v.string()), // 'month' or 'year'
})

Webhook Updates

To keep payment method cached, handle:

case 'customer.subscription.updated':
case 'payment_method.attached':
case 'payment_method.updated':
  // Extract payment method details
  const pm = event.data.object.default_payment_method;
  if (pm?.card) {
    await ctx.runMutation(internal.users.updatePaymentMethod, {
      userId,
      paymentMethod: {
        brand: pm.card.brand,
        last4: pm.card.last4,
        expMonth: pm.card.exp_month,
        expYear: pm.card.exp_year,
      },
    });
  }

UX Best Practices

Status Messaging

StatusMessageColor
active"Your subscription is active"Green
trialing"Trial ends in X days"Blue
canceled"Cancels on [date]"Yellow
past_due"Payment failed - update card"Red
incomplete"Complete payment setup"Red

Trial Banner (Credit Card Upfront Model)

With credit card collected upfront, the trial banner focuses on when billing starts:

{user.subscriptionStatus === 'trialing' && (
  <Banner variant="info">
    Your free trial ends on {formatDate(trialEndsAt)}.
    You'll be charged ${amount} unless you cancel.
    <Link href="/settings">Manage subscription</Link>
  </Banner>
)}

Key messaging for credit card upfront:

  • "Free trial ends on [date]" (not "X days left")
  • "You won't be charged until [date]"
  • "Cancel anytime before [date] to avoid charges"
  • Link to manage/cancel, not to "subscribe"
### Canceled State

When subscription is canceled but still in period:

<Card className="border-yellow-500"> <p>Your subscription has been canceled.</p> <p>You have access until {formatDate(currentPeriodEnd)}.</p> <Button onClick={resubscribe}>Resume Subscription</Button> </Card>


### Payment Failed State

Urgent but not alarmist:

<Card className="border-red-500"> <p>Your last payment failed.</p> <p>Please update your payment method to avoid losing access.</p> <Button onClick={openStripePortal}>Update Payment</Button> </Card>


## Verification Checklist

A complete subscription management UX should pass:

- User can see current plan name
- User can see subscription status with clear indicator
- User can see next billing date and amount
- User can see payment method on file
- User can access billing history
- User can cancel subscription
- User can resume canceled subscription (if in period)
- User can update payment method
- Trial users see trial status and remaining time
- Failed payment shows clear call-to-action
- All states have appropriate messaging

## Integration with Stripe Workflow

This skill is invoked by:

- `stripe-scaffold` — generates UX components
- `stripe-audit` — checks for UX completeness
- `stripe-verify` — tests UX functionality

## Related Skills

- `subscription-patterns` — State management and access control
- `billing-security` — Security considerations
- `stripe-configure` — Portal configuration in Stripe Dashboard

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

36.05%
按下载量换算68

Claude

31.79%
按下载量换算60

Cursor

17.56%
按下载量换算33

Gemini CLI

9.62%
按下载量换算18

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills