חמישה מצבים של מנוי, המעברים ביניהם, מה מפעיל כל מעבר, איך מחשבים פרורציה בשינוי תוכנית באמצע מחזור עם מספרים אמיתיים, ומה קורה לחשבונית פתוחה בשדרוג.
עיקרי הדברים
- חמישה מצבים מספיקים לרוב העסקים, אבל שניים מהם נבדלים רק בשאלה מי פועל: `past_due` הוא זמן שבו המערכת מנסה שוב לבד, ו`grace` הוא זמן שבו אדם מנסה. אם אין הבחנה, אף אחד לא מנסה.
- השירות נכבה במעבר ל`suspended`, לא במעבר ל`past_due`. חסימה ברגע הכישלון הראשון מבטלת מנויים בגלל תקלת סליקה זמנית.
- Stripe מתעדת מדיניות ניסיונות חוזרים שמוגבלת בטווח של שבוע, שבועיים, שלושה שבועות, חודש או חודשיים, ובסוף הטווח המנוי עובר ל`canceled` או ל`unpaid` לפי הגדרה. הבחירה הזאת היא החלטה עסקית, לא ברירת מחדל.
- שינוי תוכנית באמצע מחזור הוא שתי שורות ולא אחת: זיכוי על התקופה שלא נוצלה בתוכנית הישנה, וחיוב על אותה תקופה בתוכנית החדשה. ההפרש הוא מה שהלקוח משלם.
- שדרוג אינו מנקה חשבונית פתוחה. אם זיכוי הפרורציה מקזז חוב קודם, איבדתם את היכולת לגבות אותו וגם את התיעוד שהוא היה קיים.
מנוי הוא מכונת מצבים, לא שדה "פעיל/לא פעיל". חמישה מצבים - פעיל, בפיגור, ארכה, מושהה ומבוטל - וכל מעבר ביניהם מופעל באירוע אחד מוגדר: כישלון חיוב, ניסיון חוזר שהצליח, סוף חלון ארכה או שינוי תוכנית. בלי המפה הזאת כל כרטיס שנפסל מייצר החלטה אנושית מחדש.
חמישה מצבים ומה כל אחד מהם מתיר
המצב של מנוי קובע שלושה דברים בו זמנית: האם השירות פועל, האם המערכת תנסה לחייב שוב, והאם מותר לשנות תוכנית. ערבוב בין השלושה הוא מקור הבלבול.
active- השירות פועל, קיים אמצעי תשלום תקף, החיוב הבא מתוזמן. זה המצב היחיד שבו שינוי תוכנית פשוט.past_due- חיוב חידוש נכשל והמערכת מריצה לוח ניסיונות חוזרים. השירות ממשיך לפעול. הלקוח לרוב עדיין לא יודע.grace- הניסיונות האוטומטיים מוצו והכסף לא נגבה. השירות עדיין פועל, אבל מכאן זו משימה של אדם עם תאריך יעד: פנייה ללקוח, עדכון כרטיס, קישור תשלום.suspended- השירות כבוי, הנתונים נשמרים, החוב עדיין קיים ועדיין ניתן לגבייה. זהו מצב הפיך.cancelled- מצב סופי. המנוי לא יחזור לחיים; לקוח שחוזר מקבל מנוי חדש עם מזהה חדש.
ההבדל שנשמט הכי הרבה הוא בין past_due לבין grace. שניהם נראים ללקוח זהים - השירות עובד והכסף לא שולם - אבל בראשון האחריות היא של המערכת ובשני של אדם. עסק שמחזיק רק "פיגור" אחד מגלה שהמערכת הפסיקה לנסות לפני שבועיים ואף אחד לא ידע.
למה "חיוב נכשל" אינו מצב?
מפני שכישלון חיוב הוא אירוע בזמן, והמצב הוא מה שנכון עכשיו. אירוע קורה פעם אחת ונרשם ביומן; מצב נמשך עד שאירוע אחר מחליף אותו. כשמערכת שומרת payment_failed בשדה הסטטוס, היא לא יכולה לענות על שאלה בסיסית: כמה זמן הלקוח כבר בפיגור, וכמה ניסיונות נותרו.
ההפרדה הפרקטית: יומן אירועים אחד שמכיל charge_attempted, charge_failed, charge_succeeded, plan_changed, card_updated וstate_changed, לצד שדה מצב יחיד ברשומת המנוי. המצב תמיד נגזר מהאירוע האחרון שהצדיק אותו, והשדה state_reason שומר את הקוד שהחזיר הסולק. הבחנה בין סירוב זמני לסירוב קשה מכתיבה התנהגות שונה לגמרי - Stripe מציינת במפורש שהיא אינה מנסה שוב כאשר אין אמצעי תשלום זמין או כאשר המנפיק החזיר סירוב קשה. פירוט של קודי סירוב נפוצים בשוק הישראלי נמצא בטיפול בסירוב עסקה קוד 12.
טבלת המעברים
| ממצב | אירוע מפעיל | למצב | מה קורה לשירות |
|---|---|---|---|
active | חיוב חידוש נכשל | past_due | ממשיך לפעול |
past_due | ניסיון חוזר הצליח | active | ללא שינוי |
past_due | לוח הניסיונות מוצה | grace | ממשיך לפעול, נפתחת משימה לאדם |
grace | תשלום התקבל ידנית | active | ללא שינוי |
grace | חלון הארכה הסתיים | suspended | נכבה |
suspended | החוב נפרע | active | נדלק, מונפקת חשבונית הפעלה מחדש |
suspended | חלון השימור הסתיים | cancelled | סופי |
active | הלקוח ביקש ביטול | cancelled בסוף התקופה | פועל עד current_period_end |
שתי שורות בטבלה הזאת הן ההחלטות היקרות. אורך חלון הארכה קובע כמה הכנסה תאבד לעומת כמה לקוחות תאבדו, ואורך חלון השימור קובע כמה זמן הנתונים נשמרים אחרי הכיבוי. שתיהן צריכות להיכתב כמספר בקובץ הגדרות, לא להיקבע בכל פעם מחדש בשיחה.
כמה באמת עולה שינוי תוכנית באמצע מחזור?
חישוב הפרורציה הוא שתי שורות: זיכוי על מה שלא נוצל בתוכנית הישנה, וחיוב על אותה תקופה בתוכנית החדשה. דוגמה מלאה במספרים, מחזור של 30 יום מ-1 בספטמבר עד 30 בו:
- תוכנית Basic ב-240 ש"ח לחודש חויבה ב-1 בספטמבר.
- ב-11 בספטמבר הלקוח עובר ל-Pro ב-600 ש"ח לחודש. נותרו 20 ימים במחזור.
- זיכוי על Basic שלא נוצל: 240 × 20/30 = 160 ש"ח.
- חיוב על Pro לתקופה שנותרה: 600 × 20/30 = 400 ש"ח.
- ההפרש לחיוב מיידי: 400 פחות 160 = 240 ש"ח.
- החשבונית הבאה, ב-1 באוקטובר, היא 600 ש"ח מלאים.
בדיקת שפיות: הלקוח שילם על ספטמבר 240 בתחילת החודש ועוד 240 באמצעו, סך 480 ש"ח. עשרה ימי Basic הם 80 ש"ח ועשרים ימי Pro הם 400 ש"ח, ובסך הכול 480. אם הבדיקה הזאת לא נסגרת, הבסיס לחישוב שגוי.
שדרוג מייצר חיוב, אבל שנמוך מייצר זיכוי, וכאן צריכה החלטה. אותו לקוח יורד מ-Pro ל-Basic ב-21 בספטמבר, עשרה ימים לפני הסוף: זיכוי של 600 × 10/30 = 200 ש"ח מול חיוב של 240 × 10/30 = 80 ש"ח, כלומר יתרת זכות של 120 ש"ח. שתי מדיניות סבירות: לצבור את הזיכוי לחשבונית הבאה, שתצא על 240 פחות 120 = 120 ש"ח, או להנפיק מסמך מיד. Stripe מכנה את שתי ההתנהגויות create_prorations ו-always_invoice, לצד none שמבטל פרורציה לגמרי. בחרו אחת וכתבו אותה בתנאי השימוש, כי לקוח שרואה חשבונית של 120 ש"ח בלי הסבר פותח פנייה.
נקודה שקל לפספס: בסיס החישוב. מערכת שמחשבת לפי ימים ומערכת שמחשבת לפי שניות יגיעו למספרים שונים באותו שינוי. אין כאן נכון ולא נכון, אבל חייבת להיות תשובה אחת בקוד ואותה תשובה בתיעוד. הצד השני של אותו תהליך, הנפקת המסמך על כל חיוב, מתואר באוטומציה של חיוב מחזורי בישראל.
החשבונית הפתוחה ששורדת שדרוג
שדרוג אינו אירוע גבייה. אם ללקוח יש חשבונית פתוחה מהחודש שעבר והוא משדרג היום, החשבונית הזאת נשארת בדיוק כפי שהייתה. שלוש טעויות נפוצות שמוחקות אותה בשקט:
- קיזוז זיכוי הפרורציה מול החוב הישן. שתי השורות שייכות לתקופות שונות ולמסמכים שונים, והקיזוז מוחק את העקבות של החוב.
- יצירת מנוי חדש במקום שינוי תוכנית. המנוי הישן נסגר, ואיתו נסגרת גם עמדת הגבייה שלו.
- איפוס
dunning_attemptבעקבות חיוב מוצלח של הפרורציה. הכרטיס עבד עכשיו, אבל החשבונית הישנה עדיין לא שולמה.
הכלל שמונע את שלושתן: חשבונית היא מסמך עצמאי עם מחזור חיים משלה, ושינוי תוכנית משנה את המנוי בלבד. מכאן נובעת גם ההחלטה האם לחסום שדרוג בזמן past_due. חסימה נקייה יותר לוגיסטית; אישור שדרוג מגדיל הכנסה אבל דורש שהחוב הישן יישאר גלוי בדוח הגבייה. כשהגבייה עצמה עוברת בהוראת קבע ולא בכרטיס, לוח הזמנים של הכישלון שונה לגמרי - ההשוואה מפורטת בהוראות קבע במס"ב מול חיוב בכרטיס.
רשומת המנוי: השדות שמאפשרים לשחזר את המצב
| שדה | ערך לדוגמה | למה הוא נחוץ |
|---|---|---|
subscription_id | SUB-2026-004812 | מזהה יציב שלא משתנה בשינוי תוכנית |
state | past_due | המצב הנוכחי, ערך אחד מתוך חמישה |
state_reason | card_expired | הסיבה למעבר האחרון, מקוד הסולק |
plan_code | pro-monthly | התוכנית הפעילה עכשיו |
current_period_start | 2026-09-01 | תחילת המחזור, בסיס לפרורציה |
current_period_end | 2026-09-30 | סוף המחזור |
next_payment_attempt | 2026-09-05T09:00:00+03:00 | מתי המערכת תנסה שוב |
dunning_attempt | 2 | כמה ניסיונות כבר בוצעו |
grace_until | 2026-09-14 | מתי המצב עובר להשהיה |
open_invoice_ids | ["INV-2026-11907"] | חשבוניות שטרם שולמו |
השדה next_payment_attempt הוא זה שהופך את הגבייה לניתנת לניטור. Stripe חושפת אותו על החשבונית בדיוק למטרה הזאת. בלעדיו אי אפשר לענות על השאלה "אילו מנויים יעברו להשהיה השבוע", וזו השאלה היחידה שמעניינת מישהו בבוקר יום ראשון.
איפה הכסף דולף בלי שאיש שם לב
- מנוי ב-
graceבלי משימה משויכת. אף אחד לא מתקשר, החלון נסגר, הלקוח נעלם בלי שדיבר עם איש. - ניסיון חוזר שנופל שוב ושוב על אותו קוד סירוב קבוע. חמישה ניסיונות על כרטיס שפג תוקפו הם חמישה כישלונות ודאיים.
- שדרוג שנרשם כתוכנית חדשה, כך שדוח ההכנסה החוזרת סופר לקוח קיים כלקוח חדש ומנוי שנסגר כנטישה.
- ביטול שנרשם מיד במקום בסוף התקופה, כשהלקוח כבר שילם על החודש. זה החזר שלא ביקשתם לתת.
- שינוי תוכנית שמתבצע ידנית במסך ניהול בלי לרשום אירוע. חודש אחר כך אין דרך להסביר את הסכום בחשבונית.
- מנוי שחזר מ-
suspendedל-activeבלי לחדש את תאריך המחזור, כך שהחיוב הבא יוצא במועד לא נכון.
מקורות
שאלות נפוצות
כמה ניסיונות חוזרים כדאי להגדיר?
המספר פחות חשוב מהטווח ומהסיבה. Stripe מאפשרת להגדיר מספר ניסיונות בתוך טווח של שבוע עד חודשיים, ומדלגת על ניסיון כשאין אמצעי תשלום או כשהתקבל סירוב קשה. ניסיונות על סירוב קבוע לא יצליחו לעולם, ולכן ההפרדה בין סוגי הסירוב שווה יותר מהוספת ניסיון.
האם לכבות את השירות ברגע שהחיוב נכשל?
לא, כי חלק ניכר מהכישלונות זמניים: כרטיס שהוחלף, מסגרת שנוצלה, תקלת סליקה. הכיבוי שייך למעבר ל`suspended`, אחרי שהניסיונות האוטומטיים מוצו וגם חלון הארכה נסגר. הרווח מהמתנה של שבועיים כמעט תמיד גדול מהנזק, למעט שירותים שעלות השימוש בהם משתנה.
מה ההבדל בין ביטול מיידי לביטול בסוף התקופה?
ביטול בסוף התקופה משאיר את המנוי פעיל עד `current_period_end` ומונע חיוב נוסף, וזו ברירת המחדל כשהלקוח כבר שילם. ביטול מיידי מפסיק את השירות עכשיו ומעלה שאלת החזר יחסי. שתי ההתנהגויות לגיטימיות, אבל הן חייבות להיות שני מצבים נפרדים ברשומה ולא אותו כפתור.
איך מוודאים שהחשבונית תואמת לחיוב בפועל?
בהתאמה יומית שמשווה שלושה מקורות: אירועי החיוב מהסולק, המסמכים שהונפקו, והשורות ברשומת המנוי. פער מוצג עם מזהה החיוב ומזהה המסמך, לא כמספר מסכם. חיוב שהצליח בלי מסמך וחשבונית בלי חיוב הן שתי תקלות שונות עם טיפול שונה.
להמשך קריאה
שירות רלוונטי
אוטומציה לעסקים
אני בונה אוטומציות מותאמות שמורידות עבודה חוזרת מקצה לקצה.
על הכותב
יהונתן סעדיה
מפתח פרילנסר לאוטומציה, אתרים ו-MVP
אני יהונתן סעדיה, מפתח בכיר שבונה אוטומציה עסקית, אתרים מותאמים ומוצרי MVP לעסקים קטנים ובינוניים בארה"ב, אירופה וישראל. המדריכים האלה נכתבים מתוך עבודה אמיתית עם לקוחות, לא מתיאוריה.
בוא נעבוד יחדיש לך פרויקט דומה?
ספר לי מה אתה רוצה לבנות או איזה תהליך להפוך לאוטומטי. אני חוזר תוך 24 שעות עסקים עם כמה שאלות ממוקדות, ואז עוברים על זה יחד בשיחת היכרות חינמית של 30 דקות, בלי התחייבות. בסוף יש לך היקף עבודה, לוח זמנים ומחיר קבוע - או תשובה כנה שלא שווה לבנות את זה.
