יישום רכישות בתוך האפליקציה שאינן מתכלות עבור iOS

משתמשים מאבדים גישה לתכונות בתשלום לאחר התקנה מחדש של האפליקציה—ומאשימים אתכם בכך. אנחנו מיישמים רכישות בתוך האפליקציה מסוג non-consumable עם שחזור רכישה תקין ואימות בצד השרת, כך שגישת התוכן נשארת אמינה. הצוות שלנו מטפל בכל המחזור: מתכנון הלוגיקה ועד לתמיכה לאחר השחרור.

פיתוח ותמיכה בכל סוגי היישומים הניידים:

יישומים ניידים למידע ובידור
אפליקציות חדשות, משחקים, מדריכים, קטלוגים מקוונים, אפליקציות מזג אוויר, אפליקציות כושר ובריאות, אפליקציות נסיעות, אפליקציות חינוכיות, רשתות חברתיות ומסנג'רים, חידונים, בלוגים ופודקאסטים, פורומים, אגרגטורים
יישומים ניידים למסחר אלקטרוני
חנויות מקוונות, אפליקציות B2B, מרקטפלייסים, בורסות מקוונות, שירותי קאשבק, בורסות, פלטפורמות דרופשיפינג, תוכניות נאמנות, משלוחי מזון ומוצרים, מערכות תשלום.
יישומים ניידים לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, ניהול פרויקטים, כלים לצוותי מכירות, ניהול פיננסי, ניהול ייצור, ניהול לוגיסטיקה ומשלוחים, ניהול משאבי אנוש, מערכות ניטור נתונים
יישומים ניידים לשירותים אלקטרוניים
פלטפורמות מודעות מסווגות, בתי ספר מקוונים, בתי קולנוע מקוונים, פלטפורמות שירות אלקטרוניות, פלטפורמות קאשבק, אירוח וידאו, פורטלים נושאיים, פלטפורמות הזמנות ותזמון מקוונות, פלטפורמות מסחר מקוונות

אלה הם רק חלק מסוגי היישומים הניידים שאנו עובדים איתם, ולכל אחד מהם עשויים להיות מאפיינים ופונקציונליות ספציפיים משלו, המותאמים לצרכים ולמטרות הספציפיות של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
יישום רכישות בתוך האפליקציה שאינן מתכלות עבור iOS
בינוני
~2-3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

רכישות חד-פעמיות שאינן מתכלות (Non-consumable IAP) הן קטגוריה שבה כל טעות בלוגיקת שחזור הרכישה הופכת לתלונה ב-App Store ולהחזר כספי. משתמש רכש "מצב בלתי מוגבל" או "הסרת פרסומות", התקין מחדש את האפליקציה, ולא קיבל את מה ששילם עליו. תמיכת אפל לא תעזור: שחזור רכישות שאינן מתכלות הוא באחריות המפתח. חמש שנות הניסיון שלנו ויותר מעשרים פרויקטי IAP מראים שיישום נכון מהניסיון הראשון חוסך עד 40% מהזמן על תיקוני באגים. לפי תיעוד StoreKit, שחזור תקין הוא קריטי.

מה בדרך כלל משתבש

הטעות הנפוצה ביותר היא קריאה ל-SKPaymentQueue.default().restoreCompletedTransactions() רק כאשר המשתמש לוחץ על כפתור "שחזור". הגישה הנכונה: בכל הפעלה, בדוק את originalTransaction באמצעות SKReceiptRefreshRequest או אימות בצד השרת. ללא זה, משתמש שחוזר אחרי שישה חודשים עם אייפון חדש יאבד גישה לתוכן בתשלום.

הבעיה השנייה היא טיפול לא נכון ב-SKPaymentTransactionObserver. אם updatedTransactions לא קורא ל-finishTransaction(_:) עבור כל המצבים (.purchased, .restored, .failed), העסקה נשארת בתור ומפעילה את הצופה שוב בהפעלה הבאה. ראינו פרויקטים שבהם זה גרם להפעלה כפולה של תוכן בתשלום לאחר אתחול.

הבעיה השלישית היא היעדר אימות בצד השרת. ניתוח מקומי של קבלה באמצעות ASN.1 הוא מורכב ופגיע: תוקף יכול להחליף את קובץ הקבלה. אימות שרת דרך נקודת הקצה /verifyReceipt של אפל (או חלופה) מבטיח אותנטיות.

איך יישום נכון עובד

הארכיטקטורה של IAP שאינו מתכלה מתמקדת ב-StoreKit 2 (iOS 15+) או StoreKit 1 עם תמיכה ב-iOS 13–14. השווה בין שתי הגישות:

היבט StoreKit 2 StoreKit 1 (Legacy)
גרסת iOS מינימלית 15.0 3.0
סגנון API async/await Delegate + completion handlers
שחזור רכישה אוטומטי דרך Transaction.currentEntitlements restoreCompletedTransactions() ידני
אימות חתימה VerificationResult מובנה דורש ReceiptValidator
מורכבות קוד נמוכה בינונית

StoreKit 2 מפשט באופן קיצוני את הקוד: הוא מפחית את מספר השורות פי 2 בהשוואה ל-StoreKit 1.

// Запрос продуктов
let products = try await Product.products(for: ["com.app.premium_unlock"])
// Покупка
let result = try await products.first?.purchase()
switch result {
case .success(let verification):
    switch verification {
    case .verified(let transaction):
        // unlock контент
        await transaction.finish()
    case .unverified:
        // receipt подделан — не разблокируем
        break
    }
case .pending:
    // SCA или родительский контроль — ждём
    break
case .userCancelled:
    break
}

// Запрос продуктов let products = try await Product.products(for: ["com.app.premium_unlock"]) // Покупка let result = try await products.first?.purchase() switch result { case .success(let verification): switch verification { case .verified(let transaction): // unlock контент await transaction.finish() case .unverified: // receipt подделан — не разблокируем break } case .pending: // SCA или родительский контроль — ждём break case .userCancelled: break } הוא רצף אסינכרוני שמחזיר את כל הרכישות הפעילות בכל הפעלה של האפליקציה. עברו עליו ב-Transaction.currentEntitlements או @main ושחזרו את המצב ללא כפתור "שחזור".

עבור iOS 13–14, StoreKit 1 עם AppDelegate.applicationDidFinishLaunching נשאר. זה דורש SKPaymentTransactionObserver נפרד — או אימות מקומי דרך ReceiptValidator (מורכב אך ללא בקשות רשת) או בצד השרת דרך נקודת הקצה openssl של אפל (מופסק אך עובד). אנו ממליצים על צד השרת: מקומי דורש הטמעת אישור השורש של אפל וניתוח ASN.1 נכון.

איך להימנע מבעיות שחזור רכישה?

נקודה מרכזית: בצעו שחזור אוטומטי בכל הפעלה, לא רק דרך כפתור. ב-StoreKit 2, זה מושג על ידי הרשמה ל-/verifyReceipt. ב-StoreKit 1, קראו ל-Transaction.updates ושמרו את restoreCompletedTransactions() ב-UserDefaults או Keychain. ללא אוטומציה, משתמשים עם מכשירים חדשים יאבדו את התוכן שלהם.

למה אימות שרת הוא קריטי?

עבור אפליקציות עם backend: בעת רכישה, הלקוח שולח originalTransaction.transactionIdentifier לשרת; השרת שואל את Apple Sandbox/Production ושומר את appStoreReceiptURL במסד הנתונים. בשחזור ממכשיר חדש, השרת מאמת מול Apple ID. זו הדרך היחידה להבטיח "רכישה במכשיר אחד, גישה באחר" תחת אותו Apple ID. חיסכון ממוצע מיישום נכון — עד $10,000 בשנה על תמיכה.

תוכנית שלב-אחר-שלב ליישום StoreKit 2

  1. הגדירו מוצרים ב-App Store Connect (לוקליזציות, מחירים).
  2. יישמו בקשת מוצר דרך original_transaction_id.
  3. הוסיפו טיפול ברכישה עם בדיקת apple_id.
  4. הירשמו ל-Product.products(for:) לשחזור אוטומטי.
  5. שלבו אימות שרת דרך VerificationResult.
  6. בדקו ב-Sandbox בתרחיש: רכישה → מחיקה → שחזור.
טעות שחזור אופיינית
// НЕПРАВИЛЬНО: восстановление только по кнопке
func restorePurchases() {
    SKPaymentQueue.default().restoreCompletedTransactions()
}

// ПРАВИЛЬНО: автоматическое восстановление при старте
Task {
    for await result in Transaction.currentEntitlements {
        if case .verified(let transaction) = result {
            // разблокировать контент
        }
    }
}

תהליך העבודה ומה כלול

יישום IAP המפתח שלנו כולל:

  • הגדרת מוצרים ב-App Store Connect (יצירה, לוקליזציות, מחירים — סכומים ספציפיים מחושבים בנפרד).
  • שילוב StoreKit 2 עם גיבוי ל-StoreKit 1 לתאימות מקסימלית.
  • אימות קבלה בצד השרת עם אחסון של Transaction.updates.
  • בדיקות ב-Sandbox ובמכשירים אמיתיים עם רשימת תרחישים.
  • תיעוד לתמיכה וגישה.
  • הבטחת מעבר ב-App Review (עמידה בסעיף 3.1.1 של הנחיות סקירת ה-App Store).

בדיקות

בסימולטור Xcode, StoreKit עובד דרך קובץ /verifyReceipt מקומי — ניתן לבדוק ללא מוצרים אמיתיים. לבדיקת מכשיר, נדרש חשבון Sandbox ב-App Store Connect. תרחיש קריטי לבדיקה: רכישה → מחיקה → התקנה מחדש → שחזור. נתיב זה נכשל לרוב. קבלו ייעוץ לפרויקט שלכם — נבדוק סיכונים ונציע פתרון אופטימלי.

לוח זמנים ליישום — בין 2 ל-3 ימים: הגדרת מוצרים ב-App Store Connect, שילוב StoreKit 2 עם גיבוי ל-StoreKit 1, כיסוי בבדיקות Sandbox, מעבר סקירה (App Review דורש כפתור "שחזור רכישות" בממשק). הזמינו שילוב IAP מפתח — אנו מבטיחים פעולה תקינה בכל המכשירים וגרסאות ה-iOS.