בנה לוח בקרה של מינויים ב-Stripe עם Claude Code
בנה לוח בקרה של מינויים ב-Stripe עם Claude Code
מה תבנה
כרטיס ניהול מנויים עם פרטי התכנית, אזהרות כשל תשלום, ספירה לאחור של תקופת ניסיון, והחלפת תכנית בלחיצה אחת
הבעיה
השקת את ה-SaaS שלך. אנשים משלמים. אבל כשמנוי נכנס ללוח הבקרה שלו, הוא לא רואה כלום על המנוי שלו. אין שם התוכנית. אין תאריך חידוש. אין סכום חיוב. כשכרטיס אשראי מתפוג ותשלום נכשל — שקט מוחלט. המשתמש פשוט מאבד גישה ללא הסבר כלשהו. ומשתמשי ניסיון? הם מתעוררים ביום 4 להתעמתות עם דיוקן תשלום ללא אזהרה. מערכת התשלום שלך עובדת, אבל חוויית התשלום שלך לא קיימת.
מה אתה בונה
כרטיס מידע מנוי שחי בלוח הבקרה. הוא מציג את התוכנית שלך, מה שאתה משלם, מתי הוא מתחדש, והסטטוס שלך — עם אזהרות חכמות שמשתנות על סמך מה שקורה. תשלום נכשל? באנר אדום בחלק העליון של כל עמוד עם כפתור תיקון. ניסיון מסתיים מחר? ספירה לאחור בצבע ענבר. מבטלים? הודעה המציגה מתי הגישה מסתיימת. בתוספת כפתור חד-לחיצה להחלפה בין חודשי ושנתי.
שלב 1: כרטיס מידע המנוי
המנויים שלך משלמים אבל הם עיוורים. בואו נתן להם כרטיס המציג הכל במבט אחד.
הנושא:
Create a new component at components/subscription-info.tsx. It's a server component that receives a Subscription object as a prop (with fields: status, plan, current_period_end, cancel_at_period_end). Display it as a shadcn Card with a 4-column grid showing: Plan name (Pro Monthly or Pro Annual with a crown icon), Billing amount ($39/mo or $299/yr), Renewal date (formatted as "Feb 21, 2026"), and Status badge. Color-code the badge: green for active, blue for trialing, red for past_due, amber for cancel_at_period_end, gray for canceled. Use lucide-react icons (Crown, CreditCard, Calendar, ArrowUpRight).
מה Claude Code עושה: הוא יוצר קומפוננטה שרת עם פונקציות עוזר לעיצוב תאריכים, חישוב תגי סטטוס, ומיפוי שמות תוכניות למחירים. קומפוננטות שרת משתמשות בשרת עם אפס JavaScript בצד הלקוח — מושלם להצגת נתוני מנוי שלא צריכים אינטראקטיביות.
נסה: ייבא את SubscriptionInfo לכל עמוד והעבור לו אובייקט מנוי דמה עם status: "active" ו-plan: "monthly". אתה אמור לראות כרטיס נקי עם ארבע עמודות ותגית "Active" ירוקה.
שלב 2: חבר אותו ללוח הבקרה
הקומפוננטה קיימת אבל לוח הבקרה לא משתמש בה. זה הזמן להנעים אותה נתוני מנוי אמתיים מ-Supabase.
הנושא:
Update the dashboard page to fetch the full subscription row from Supabase for the current user. Query for active or trialing subscriptions first. If none found, also check for past_due subscriptions so we can still show the card when payment fails. Pass the subscription object to the SubscriptionInfo component and render it between the stats grid and the tutorial list. Only render the card when a subscription exists.
מה Claude Code עושה: הוא מוסיף דפוס שאילתה עם חלופה — קודם כל נסה את השביל הטוב (פעיל/בנסיון), אחר כך בדוק מצבים בעייתיים (past_due). כך הכרטיס תמיד מופיע כשמנוי קיים, אפילו אחד שבור. אין מנוי בכלל? הכרטיס פשוט לא יש.
נסה: התחבר ללוח הבקרה שלך. אם יש לך מנוי, כרטיס המידע מופיע מתחת לסטטיסטיקה שלך. התוכנית, החיוב, תאריך החידוש והסטטוס צריכים להתאים את מנוי ה-Stripe שלך.
שלב 3: באנר כשל תשלום
כרטיס לא מספיק כשכסף בתמונה. אם תשלום נכשל, משתמשים צריכים באנר אדום שהם לא יכולים להחמיץ — בכל עמוד בלוח בקרה, לא רק בעמוד הבית.
הנושא:
Create components/payment-failure-banner.tsx as a client component. Red background, white text, full-width banner with an AlertTriangle icon, the message "Your last payment failed. Update your payment method to keep Pro access", an "Update payment" button that calls POST /api/stripe/portal and redirects to the returned Stripe billing portal URL, and a dismiss X button with useState. Then update the dashboard layout (not the page — the layout) to check if the user has a past_due subscription and conditionally render this banner above the children.
מה Claude Code עושה: שני דברים קורים כאן. הבאנר הוא קומפוננטה לקוח (צריך useState להסתרה, צריך fetch להפניית הפורטל). אבל בדיקת הפריסה היא קומפוננטת שרת שעושה שאילתה ל-Supabase. זה דפוס פריסה-רמה עבור UX קריטי — על ידי הצבת הבדיקה בפריסה במקום בעמוד, הבאנר מופיע באופן אוטומטי בכל מסלול בלוח בקרה.
נסה: ב-Supabase, עדכן את סטטוס המנוי של משתמש ל-past_due. רענן כל עמוד בלוח בקרה — באנר אדום אמור להופיע בחלק העליון. לחץ על "Update payment" — זה פותח את פורטל החיוב של Stripe. לחץ על X — זה מסתיר עד לטעינה מחדש של הדף.
שלב 4: אזהרת פקיעת ניסיון
משתמשי ניסיון הם המנויים בסיכון הגבוה ביותר שלך. הם צריכים לדעת שזה מסתיים לפני שזה מסתיים.
הנושא:
Add a trial expiration warning to the SubscriptionInfo component. When status is "trialing", show a banner inside the card that says "Trial ends in X days" with the billing amount that kicks in after. Calculate days remaining from current_period_end. If more than 1 day remaining, use blue styling (bg-blue-50, border-blue-200). If 1 day or less, switch to amber urgent styling (bg-amber-100, border-amber-300) with "Trial ends today" and a warning about upcoming billing. Also add a similar amber warning when cancel_at_period_end is true showing the access end date.
מה Claude Code עושה: זה מוסיף הדרגת דחיפות — אותה אזהרה משנה מראה על סמך כמה קרוב הקו הזמן. כחול אומר "שימו לב". ענבר אומר "פעל עכשיו". הדפוס המפתח הוא עיצוב מותנה מונהג על ידי חישובי זמן — קומפוננטה אחת, מספר מצבים חזותיים, הכל שולט על ידי פונקציית getDaysUntil() פשוטה.
נסה: הגדר מנוי ל-trialing עם current_period_end מוגדר למחר. אתה אמור לראות אזהרה בצבע ענבר שאומרת "Trial ends today." שנה את תאריך הסיום ל-3 ימים קדימה — זה משתנה לכחול שליו עם "Trial ends in 3 days."
שלב 5: החלפת תוכנית
משתמשים חודשיים צריכים להיות מסוגלים לשדרג לשנתי ולחסוך כסף. לחיצה אחת, ללא צורך בפורטל Stripe.
הנושא:
Create two things: 1) An API route at app/api/stripe/change-plan/route.ts that accepts { newPlan: "monthly" | "annual" }, validates with zod, checks the user has an active subscription in Supabase, retrieves the Stripe subscription, swaps the price item using stripe.subscriptions.update with proration_behavior "create_prorations", and updates the local Supabase record immediately. 2) A client component at components/switch-plan-button.tsx that shows "Switch to Annual — Save 36%" for monthly users or "Switch to Monthly" for annual users, calls the API on click, shows a loading state, handles errors, and reloads the page on success. Add this button to SubscriptionInfo below the plan details grid, only visible when status is active and not canceling.
מה Claude Code עושה: מסלול ה-API משתמש ב-proration של Stripe — כשאתה משנה את פריט המחיר של מנוי באמצע המחזור, Stripe בעצם מחשבת את הקרדיט עבור הזמן שלא בשימוש בתוכנית הישנה ומחילה אותו על החדשה. אתה לא כותב כל ביצוע חישוב. הדגל proration_behavior: "create_prorations" אומר ל-Stripe להטפל בהכל.
נסה: כרטיס הלוח שלך אמור להציג "Switch to Annual — Save 36%" מתחת לפרטי התוכנית. לחץ עליו. בדוק את לוח הבקרה של Stripe שלך — המנוי אמור להציג את המחיר השנתי עם קרדיט prorated מיושם. הדף שלך טוען מחדש עם מידע התוכנית המעודכן.
מה בנית
זוכר את לוח הבקרה הריק שבו מנויים היו משלמים אבל עיוורים? זה עתה החלפת אותו בחוויית ניהול מנוי מלאה. משתמשים רואים את התוכנית שלהם, יודעים מתי היא מתחדשת, מקבלים אזהרה כשמשהו יהלך לא בסדר, ויכולים להחליף תוכניות בלחיצה אחת. חמש קומפוננטות, מסלול API אחד, אפס בלבול.
מה קטפת בדרך: גבולות קומפוננטה שרת מול לקוח, דפוס פריסה-רמה לאזהרות גלובליות, הדרגת דחיפות עם עיצוב מבוסס זמן, ומערכת proration של Stripe שמטפלת בביצוע חישובים כך שאתה לא צריך.
קח את זה הלאה
- הוסף שיעורי מס — צור שיעור מס של Stripe לשיעור ה-VAT של הארץ שלך והצמד אותו לפריטי שורת checkout עם
lineItem.tax_rates = [taxRateId] - ביטול בתוך האפליקציה — בנה דף ביטול עם טופס משוב והצעת winback במקום לשלוח משתמשים לפורטל של Stripe
- כללים על כשלי תשלום — תזריק דוא"ל מה-webhook שלך כשה-
invoice.payment_failedמגיע, עם קישור ישיר לעדכון הכרטיס שלהם