כיצד קודי הצעה פותרים את הבעיה של מבצעי מנויים גמישים
תארו לעצמכם: אתם משיקים קמפיין שותפים, משפיען מקדם את המנוי שלכם, אבל משתמשים מסרבים להזין פרטי כרטיס אשראי לניסיון. או שלקוח ארגוני מבקש קוד קידום לתקופת ניסיון של 90 יום. הצעות קידום סטנדרטיות דורשות חתימה בצד השרת – כל קישור חייב להיווצר דרך הקצה האחורי שלכם. קודי הצעה (קודי קידום מערכתיים של Apple) מסירים את המגבלה הזו: הקוד עובד בתיבת הדו-שיח המערכתית או דרך קישור, ללא צורך בכרטיס אשראי. יישמנו למעלה מ-30 אינטגרציות מנויים – 90% מהבעיות נובעות מטיפול לא נכון ב-Transaction.updates. מאמר זה צולל לפרטים הטכניים כדי לעזור לכם להימנע ממלכודות נפוצות.
למה קודי הצעה במקום הצעות קידום?
| תכונה | קודי הצעה | הצעות קידום |
|---|---|---|
| הפעלה | דרך ממשק מערכת או קישור, ללא כרטיס | דרך ממשק מערכת, נדרש כרטיס |
| חתימת שרת | לא נדרשת | נדרשת (חתימת הצעה בקצה האחורי שלכם) |
| מגבלות | 150,000 קודים חד-פעמיים למנוי לרבעון | אין מגבלה, אבל כל קוד דורש חתימה |
| מקרה שימוש | קמפיינים המוניים, שותפויות, QR לא מקוון | ניסיונות מותאמים אישית, החזרת לקוחות |
| מורכבות אינטגרציה | קוד מינימלי, אין צורך בקצה אחורי | דורש שרת משלכם לחתימה |
בשורה התחתונה: אם המטרה שלכם היא קידום לא מקוון או קמפיינים עם משפיענים ללא פרטי תשלום מראש, קודי הצעה הם הבחירה הקלה יותר – מפחיתים עומס על הקצה האחורי וסיכון לשגיאות. לדוגמה, קודי הצעה מפשטים את האינטגרציה פי 3 בהשוואה להצעות קידום, מכיוון שחתימת השרת מתבטלת, מה שמפחית את מאמץ התחזוקה.
שלבים לאינטגרציה של קודי הצעה
- צרו את הקוד ב-App Store Connect (מנויים → קודי הצעה → '+'). ספקו מזהה הצעה, סוג הנחה, משך. הורידו את קובץ ה-CSV של הקודים.
-
הוסיפו ממשק מימוש – ב-iOS 16 ומעלה השתמשו ב-
OfferCodeRedeemSheet(SwiftUI) אוAppStore.presentOfferCodeRedeemSheet(UIKit). עבור iOS ישן יותר, פתחו את הקישורhttps://apps.apple.com/redeem?ctx=offercodes. -
טפלו בעסקה – הירשמו ל-
Transaction.updatesותמיד קראו ל-finish(), אחרת העסקה תיתקע. - בדקו – השתמשו בחשבונות Sandbox וקודים מותאמים אישית לפני שחרור קודים חד-פעמיים.
- נטרו – ודאו שהניסיון/ההנחה הוחלו כראוי דרך אנליטיקה.
איך לשלב את תיבת הדו-שיח למימוש ב-iOS?
StoreKit 2 מספק OfferCodeRedeemSheet – ממשק מערכת מוכן לשימוש. דוגמת SwiftUI:
import StoreKit
import SwiftUI
struct SettingsView: View {
@State private var showRedeemSheet = false
var body: some View {
List {
Button("Ввести промокод") {
showRedeemSheet = true
}
}
.offerCodeRedemption(isPresented: $showRedeemSheet) { result in
switch result {
case .success(let transaction):
await updateSubscriptionStatus(transaction)
case .failure(let error):
handleRedemptionError(error)
case .pending:
break
}
}
}
}ב-UIKit (iOS 16 ומעלה), השתמשו ב-import StoreKit import SwiftUI struct SettingsView: View { @State private var showRedeemSheet = false var body: some View { List { Button("Ввести промокод") { showRedeemSheet = true } } .offerCodeRedemption(isPresented: $showRedeemSheet) { result in switch result { case .success(let transaction): await updateSubscriptionStatus(transaction) case .failure(let error): handleRedemptionError(error) case .pending: break } } } } :
Task {
do {
try await AppStore.presentOfferCodeRedeemSheet(in: windowScene)
} catch {
// fallback — открываем apps.apple.com/redeem
}
}עבור iOS מתחת ל-16, פתחו את ה-URL דרך AppStore.presentOfferCodeRedeemSheet(in:). אנו מבטיחים טיפול נכון בכל הגרסאות.
טיפול בעסקאות – ניואנס קריטי
לאחר המימוש, StoreKit יוצר עסקה. תפסו אותה דרך Task { do { try await AppStore.presentOfferCodeRedeemSheet(in: windowScene) } catch { // fallback — открываем apps.apple.com/redeem } } :
for await result in Transaction.updates {
if case .verified(let transaction) = result {
if transaction.offerType == .code {
await unlockPremiumContent()
await transaction.finish()
}
}
}חיוני לקרוא ל-UIApplication.open – אחרת העסקה תישאר בתור. בדקו את Transaction.updates כדי להבחין בין רכישות רגילות.
איך להימנע מעסקאות תקועות?
ודאו שההרשמה ל-for await result in Transaction.updates { if case .verified(let transaction) = result { if transaction.offerType == .code { await unlockPremiumContent() await transaction.finish() } } } פעילה לפני שכל ממשק מופיע – למשל, ב-transaction.finish() או בתחילת offerType == .code. התחלה קרה היא הסיבה הנפוצה ביותר לכך שקוד הצעה נכשל: העסקה לא מעובדת, התוכן נשאר נעול. אנו תמיד מוסיפים Transaction.updates בתצוגת השורש ומפעילים אותו מחדש אחרי כל מעבר לרקע.
מידע נוסף על בדיקות Sandbox
Sandbox אינו מאפשר בדיקת קודים חד-פעמיים לפני השחרור. השתמשו בקודים מותאמים אישית (ניתנים לשימוש חוזר) או בחשבון sandbox עם הזנה ידנית. לקודים מותאמים אישית אין מגבלת 150,000 אבל קשה יותר לעקוב אחריהם.
אנדרואיד – קודי קידום של Google Play
באנדרואיד, המקבילה היא קודי קידום. הבדל מרכזי: Google Play אינו מפעיל תיבת דו-שיח מערכתית למימוש – הקוד מוחל דרך חנות Play או קישור עמוק. הטיפול נעשה דרך Billing Library 5+ עם AppDelegate:
override fun onPurchasesUpdated(result: BillingResult, purchases: List<Purchase>?) {
if (result.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) {
for (purchase in purchases) {
if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) {
handleNewPurchase(purchase)
}
}
}
} | פרמטר | קודי הצעה ב-iOS | קודי קידום ב-Google Play |
|---|---|---|
| יצירה | App Store Connect | Google Play Console |
| הפעלה | תיבת דו-שיח מערכתית / קישור | חנות Play / קישור עמוק |
| טיפול | עסקת StoreKit | רכישת Billing Library |
| מגבלה | 150,000/רבעון | ללא הגבלה |
בעיות נפוצות ואיך להימנע מהן
- חסר
SceneDelegateבהתחלה קרה: העסקה נשארת בתור, התוכן נעול. פתרון – תמיד האזינו לעדכונים מיד לאחר ההשקה. - Sandbox לא יכול לבדוק קודים חד-פעמיים לפני השחרור: השתמשו בקודים מותאמים אישית או בהזנה ידנית ב-sandbox.
- השמטת
updateListenerTask: העסקה תעובד מחדש בכל השקה. - מזהה הצעה לא תואם: App Store עשוי להחזיר שגיאה -1003 (InvalidOfferIdentifier). ודאו שמזהה ההצעה רשום ברמת המנוי.
לפי תיעוד המפתחים של Apple, קודי הצעה נתמכים ב-iOS 15.4 ומעלה. התיעוד זמין ב-מסגרת StoreKit.
מה העבודה שלנו כוללת
- הגדרת קוד הצעה ב-App Store Connect (סוג, משך, מגבלות)
- שילוב
View/PurchasesUpdatedListener - גיבוי ל-iOS מתחת ל-16 (קישור עמוק)
- טיפול בעסקאות דרך
override fun onPurchasesUpdated(result: BillingResult, purchases: List<Purchase>?) { if (result.responseCode == BillingClient.BillingResponseCode.OK && purchases != null) { for (purchase in purchases) { if (purchase.purchaseState == Purchase.PurchaseState.PURCHASED) { handleNewPurchase(purchase) } } } }עםTransaction.updatesמובטח - בדיקות עם קודי הצעה ב-Sandbox
- אינטגרציה מקבילה לקודי קידום ב-Google Play (אופציונלי)
- תיעוד לצוות השיווק שלכם על תהליך המימוש
לוח זמנים ועלות
מ-3 עד 5 ימים כולל אינטגרציה לתוך חומת התשלום הקיימת ותהליך המנויים שלכם. לוח הזמנים המדויק תלוי במורכבות יישום המנויים הנוכחי שלכם ובצורך בסנכרון חוצה פלטפורמות. העלות מוערכת לאחר ניתוח. צרו קשר כדי לזהות את המקרה שלכם – נדון במלכודות פוטנציאליות.







