למה זה חשוב
לקוח לוחץ על תשלום, התשובה מתעכבת והוא מנסה שוב. מבחינתו זו אותה רכישה. בלי הגנה מתאימה, שני ניסיונות יכולים להיתפס כשתי פעולות, כלומר שתי הזמנות ושני חיובים.
כיבוי הכפתור משפר את המסך, אבל לא מגן מפני ניסיון חוזר ברשת או מפני שתי בקשות שכבר יצאו לשרת.
מה זה אידמפוטנטיות
אידמפוטנטיות היא התכנון שבו ניסיון חוזר של אותה פעולה אינו יוצר שוב את אותה תוצאה עסקית. אותה רכישה שנשלחה פעמיים מקבלת את אותה תשובה, ולא חיוב שני.
חשוב לדעת: זו לא הבטחה כללית של “בדיוק פעם אחת” בכל המערכת. זה מנגנון לפעולה מסוימת, עם גבולות ברורים.
שלושה דברים שצריך לתכנן
1. זהות לפעולה, לא לכל לחיצה
מזהה יציב לכוונת רכישה אחת, שממשיך איתה בכל ניסיון חוזר. רכישה חדשה באמת מקבלת זהות חדשה. לא משתמשים באימייל או במידע רגיש כמפתח.
2. אכיפה בצד שמבצע
השרת שומר ומאמת את המזהה, את הבעלים ואת הפרמטרים, ומטפל גם בשתי בקשות שמגיעות במקביל. “בדוק אם קיים ואז כתוב” בלי הגנה מתחרות עלול לתת לשתי בקשות לעבור יחד.
3. גם שירות ההמשך צריך לזהות את הפעולה
ספק התשלום מקבל מפתח שמתאים לאותה רכישה. אם התשובה מהספק אבדה, מבררים את המצב במקום להתחיל חיוב חדש. יש הבדלים בין ספקים, גרסאות, זמני שמירה וסוגי כשל, ולכן בודקים את התיעוד של הספק שלכם.
פרומפט מלא לסוכן
העתיקו את הפרומפט הבא לסוכן הקוד שלכם (Claude Code, Cursor או כל סוכן אחר), בתוך הפרויקט:
בדוק את מסלול הרכישה בפרויקט לפני שתשנה קוד. הסבר היכן נוצרת כוונת רכישה ואיך אותה זהות נשמרת בניסיון חוזר. תכנן אכיפה בשרת, בקשות מקבילות, בעלות משתמש והתאמת פרמטרים. בדוק בתיעוד העדכני של ספק התשלומים את מנגנון האידמפוטנטיות שלו ואת משך השמירה. השתמש במפתח יציב לאותה רכישה גם מול הספק. טפל במצב שבו החיוב אולי הצליח אבל התשובה לא הגיעה. אל תניח שכישלון רשת פירושו שאין חיוב. הוסף בדיקות עם ספק דמה או מצב בדיקה בלבד, בלי כסף אמיתי ובלי נתוני לקוחות. הצג תוכנית ומבחנים לפני פעולות שיכולות להשפיע על production. בסיום החזר: קוד ששונה, בדיקות שעברו, בדיקות שנכשלו ומה לא נבדק.
שש בדיקות קבלה
אחרי שהסוכן סיים, אלה הבדיקות שמוכיחות שההגנה עובדת. מריצים אותן רק בסביבה מבודדת.
| בדיקה | מה עושים בסביבה מבודדת | תוצאה צפויה |
|---|---|---|
| ניסיון חוזר | שתי בקשות רצופות לאותה רכישה | אין הזמנה או חיוב נוסף. מוחזר מצב מוסכם של אותה פעולה |
| בקשות מקבילות | שתי בקשות לאותה פעולה באותו זמן | האכיפה מונעת שתי תופעות לוואי, ולא מסתמכת רק על בדיקה מוקדמת |
| תשובה שאבדה | ספק דמה מבצע את החיוב ואז החיבור נכשל | בירור או ניסיון חוזר בטוח, לא חיוב חדש אוטומטי |
| פרמטרים השתנו | אותו מפתח עם מוצר או סכום שונים | טיפול מפורש לפי החוזה, לא מיחזור שקט של הצלחה לרכישה אחרת |
| רכישה חדשה | כוונת רכישה חדשה עם מזהה חדש | רכישה לגיטימית נוספת עדיין אפשרית |
| זהות ושמירה | משתמש אחר מנסה מזהה קיים, ובדיקת מגבלת זמן | אין חשיפה של רכישה זרה. תקופת השמירה מוגדרת ונבדקת |
הבדיקות האלה הן התאמה לימודית שלנו, לא תוצאה של ניסוי שהורץ על האפליקציה שלכם. הריצו אותן רק בסביבת בדיקה או sandbox, עם ספק דמה ונתונים מזויפים, בלי כסף אמיתי ובלי נתוני לקוחות.
מה נשאר מחוץ להבטחה
מפתח אידמפוטנטיות אינו פתרון שלם לתשלומים. עדיין צריך לטפל ב:
- התאמות מול הספק (reconciliation)
- הודעות webhook מהספק
- ביטולים והחזרים
- עסקאות שנשארו במצב לא ידוע
טרנזקציה במסד הנתונים המקומי לא הופכת קריאה לספק חיצוני לאטומית. התאימו את התכנון לתיעוד הספק ולאופן החיוב שלכם.
לינקים
- Stripe: Idempotent requests, מנגנון המפתח, ניסיונות חוזרים, מגבלות והשוואת פרמטרים.
- Stripe: Low-level error handling, קריאה משלימה לפני התאמה לספק ולסוג השגיאה. לא מעתיקים מדיניות retry בלי לבדוק.