הנחיות לשילוב תשלומים חיצוניים באפליקציות

במאמר הזה מוסבר איך לשלב את ממשקי ה-API של ספריית החיובים ב-Play כדי לאפשר תשלומים חיצוניים באפליקציות שעומדות בדרישות. מידע נוסף על התוכנית זמין כאן.

הגדרה של ספריית החיובים ב-Play

עליכם להוסיף את התלות של ספריית החיובים ב-Play לאפליקציית Android. כדי להשתמש בממשקי API של אמצעי תשלום חיצוניים נדרשת גרסה 8.3 ואילך. אם אתם צריכים לבצע העברה מגרסה קודמת, עליכם לפעול לפי ההוראות במדריך ההעברה כדי לשדרג לפני שתתחילו בשילוב.

אתחול של לקוח החיוב

השלבים הראשונים בתהליך השילוב זהים לאלה שמתוארים במדריך לשילוב של מערכת החיוב של Google Play, אבל יש כמה שינויים כשמפעילים את BillingClient:

בדוגמה הבאה מוצג אתחול של BillingClient כולל השינויים האלה:

Kotlin

val purchasesUpdatedListener =
    PurchasesUpdatedListener { billingResult, purchases ->
        // Handle new Google Play purchase.
    }

val developerProvidedBillingListener =
    DeveloperProvidedBillingListener { details ->
        // Handle user selection for developer provided billing option.
    }

val billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableBillingProgram(
        EnableBillingProgramParams.newBuilder()
            .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
            .setDeveloperProvidedBillingListener(developerProvidedBillingListener)
            .build())
    .build()

Java

private PurchasesUpdatedListener purchasesUpdatedListener = new PurchasesUpdatedListener() {
    @Override
    public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
        // Handle new Google Play purchase.
    }
};

private DeveloperProvidedBillingListener developerProvidedBillingListener =
    new DeveloperProvidedBillingListener() {
        @Override
        public void onUserSelectedDeveloperBilling(
            DeveloperProvidedBillingDetails details) {
            // Handle user selection for developer provided billing option.
        }
    };

private BillingClient billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .enableBillingProgram(
        EnableBillingProgramParams.newBuilder()
            .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
            .setDeveloperProvidedBillingListener(developerProvidedBillingListener)
            .build())
    .build();

חיבור ל-Google Play

אחרי שמפעילים את BillingClient, מתחברים ל-Google Play כמו שמתואר במאמר חיבור ל-Google Play.

בדיקת הזכאות של המשתמשים

אחרי שמתחברים ל-Google Play, אפשר לבדוק אם המשתמש עומד בדרישות של תוכנית התשלומים החיצונית דרך הפעלת method מסוג isBillingProgramAvailableAsync(). השיטה הזו מחזירה BillingResponseCode.OK אם המשתמש עומד בדרישות. בדוגמה הבאה אפשר לראות איך בודקים את הזכאות:

Kotlin

billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_PAYMENTS,
  object : BillingProgramAvailabilityListener {
    override fun onBillingProgramAvailabilityResponse(
      billingProgram: Int, billingResult: BillingResult) {
        if (billingResult.responseCode != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external payments unavailable, etc.
            return
        }

        // External payments are available. Can proceed with generating an
        // external transaction token.
})

Java

billingClient.isBillingProgramAvailableAsync(
  BillingProgram.EXTERNAL_PAYMENTS,
  new BillingProgramAvailabilityListener() {
    @Override
    public void onBillingProgramAvailabilityResponse(
      int billingProgram, BillingResult billingResult) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors,
            // handling external payments unavailable, etc.
            return;
        }

        // External payments are available. Can proceed with generating an external transaction token.
      }

    });

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

הצגת מוצרים זמינים

אתם יכולים להציג למשתמש את המוצרים הזמינים באותו אופן כמו בשילוב של מערכת החיוב של Google Play. אחרי שהמשתמש רואה את המוצרים שזמינים לרכישה ובוחר אחד מהם, צריך להפעיל את תהליך התשלום החיצוני כמו שמתואר בקטע על התהליך הזה.

הכנה של טוקן לעסקה חיצונית

כדי לדווח על עסקה חיצונית ל-Google Play, צריך ליצור טוקן בספריית החיוב של Play. אתם צריכים ליצור טוקן חדש של עסקה חיצונית בכל פעם שהמשתמש מבקר באתר או באפליקציה חיצוניים דרך ה-API של התשלומים החיצוניים. אפשר לעשות זאת באמצעות קריאה ל-API‏ createBillingProgramReportingDetailsAsync. צריך ליצור את הטוקן מיד לפני שקוראים ל-launchBillingFlow.

Kotlin

val params =
    BillingProgramReportingDetailsParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .build()

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  object : BillingProgramReportingDetailsListener {
    override fun onCreateBillingProgramReportingDetailsResponse(
      billingResult: BillingResult,
      billingProgramReportingDetails: BillingProgramReportingDetails?) {
        if (billingResult.responseCode != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return
        }
        val externalTransactionToken =
            billingProgramReportingDetails?.externalTransactionToken
        // Persist the external transaction token locally. Pass it to
        // the external website using DeveloperBillingOptionParams when
        // launchBillingFlow is called.
    }
})

Java

BillingProgramReportingDetailsParams params =
    BillingProgramReportingDetailsParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .build();

billingClient.createBillingProgramReportingDetailsAsync(
  params,
  new BillingProgramReportingDetailsListener() {
    @Override
    public void onCreateBillingProgramReportingDetailsResponse(
      BillingResult billingResult,
      @Nullable BillingProgramReportingDetails
        billingProgramReportingDetails) {
        if (billingResult.getResponseCode() != BillingResponseCode.OK) {
            // Handle failures such as retrying due to network errors.
            return;
        }

        String transactionToken =
          billingProgramReportingDetails.getExternalTransactionToken();

        // Persist the external transaction token locally. Pass it to
        // the external website using DeveloperBillingOptionParams when
        // launchBillingFlow is called.
      }
});

אם משתמשים בתוספים של Kotlin, אפשר להיעזר ב-coroutines של Kotlin. כך לא תצטרכו להגדיר listener נפרד.

הפעלת תהליך התשלומים החיצוניים

כדי להפעיל את תהליך התשלום החיצוני, עליכם לקרוא ל-launchBillingFlow() כמו כשמפעילים תהליך רכישה עם שילוב של מערכת החיוב של Google Play. עם זאת, אתם צריכים להשתמש בפרמטר DeveloperBillingOptionParams נוסף שמציין שהאפליקציה רוצה להפעיל את תהליך התשלום החיצוני לרכישה הזו.

הפרמטר DeveloperBillingOptionParams חייב לכלול את הפרטים הבאים:

  • billingProgram מוגדר לתוכנית החיוב EXTERNAL_PAYMENTS
  • linkURI מוגדר ליעד הקישור
  • launchMode מוגדר ל-LAUNCH_IN_EXTERNAL_BROWSER_OR_APP אם Google Play צריך לפתוח את הקישור, או ל-CALLER_WILL_LAUNCH_LINK אם האפליקציה שלכם תפתח את הקישור.

כשהאפליקציה שלכם קוראת ל-launchBillingFlow() עם הערך DeveloperBillingOptionParams, מערכת החיוב של Google Play מבצעת את הבדיקה הבאה:

  • המערכת בודקת אם במדינה של המשתמש שמוגדרת ב-Google Play יש תמיכה בתשלומים חיצוניים (כלומר, מדינה נתמכת). אם המדינה נתמכת, מערכת Google Play בודקת אם התשלומים החיצוניים מופעלים על סמך ההגדרה של BillingClient והאם DeveloperBillingOptionParams סופק.
    • אם הפעלתם תשלומים חיצוניים, בתהליך הרכישה יוצג למשתמש ממשק עם אפשרויות לבחירה.
    • אם התשלומים החיצוניים לא מופעלים, תהליך הרכישה יציג למשתמש את הממשק הרגיל של מערכת החיוב של Google Play, בלי אפשרויות לבחירה.
  • אם המדינה שמוגדרת למשתמש ב-Google Play לא נתמכת, בתהליך הרכישה מוצג ממשק המשתמש הרגיל של מערכת החיוב של Google Play, בלי אפשרויות לבחירה.

המדינה של המשתמש ב-Play היא מדינה נתמכת

המדינה של המשתמש ב-Play לא נתמכת

תשלומים חיצוניים מופעלים (הגדרה של BillingClient ושל launchBillingFlow)

המשתמש רואה ממשק בלי אפשרויות לבחירה

המשתמש רואה את הממשק הרגיל של מערכת החיוב של Google Play

תשלומים חיצוניים לא מופעלים (לא הופעלו במהלך ההגדרה של BillingClient או שלא סופקו DeveloperBillingOptionParams להפעלת launchBillingFlow)

המשתמש רואה את הממשק הרגיל של מערכת החיוב של Google Play

המשתמש רואה את הממשק הרגיל של מערכת החיוב של Google Play

בקטע הקוד הבא אפשר לראות איך יוצרים את DeveloperBillingOptionParams:

Kotlin

val developerBillingOptionParams =
    DeveloperBillingOptionParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .setLinkUri("https://www.example.com/external/purchase")
        .setLaunchMode(
            DeveloperBillingOptionParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
        .build()

Java

DeveloperBillingOptionParams developerBillingOptionParams =
    DeveloperBillingOptionParams.newBuilder()
        .setBillingProgram(BillingProgram.EXTERNAL_PAYMENTS)
        .setLinkUri("https://www.example.com/external/purchase")
        .setLaunchMode(
            DeveloperBillingOptionParams.LaunchMode.LAUNCH_IN_EXTERNAL_BROWSER_OR_APP)
        .build();

טיפול בבחירת המשתמש

האופן שבו אתם מנהלים את המשך תהליך הרכישה תלוי בבחירה של המשתמש: מערכת החיוב של Google Play או תשלום באתר שלכם.

כשהמשתמש בוחר לשלם באתר או באפליקציית תשלום

אם המשתמש בוחר לשלם באתר שלכם, ‏ Google Play קוראת ל-DeveloperProvidedBillingListener כדי להודיע לאפליקציה שהמשתמש בחר לשלם באתר שלכם או באפליקציית תשלום. באופן ספציפי, נשלחת קריאה ל-method מסוג onUserSelectedDeveloperBilling().

אם האפליקציה מגדירה את launchMode ל-LAUNCH_IN_EXTERNAL_BROWSER_OR_APP, מערכת Google Play תפעיל את הקישור. אם הערך של launchMode הוגדר ל-CALLER_WILL_LAUNCH_LINK, האפליקציה אחראית להפעלת הקישור. אם אתם מקשרים משתמשים לאפליקציית תשלומים, אתם אחראים לוודא שהם כבר התקינו את אפליקציית התשלומים במכשיר שלהם.

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

כשהמשתמש בוחר במערכת החיוב של Google Play

אם המשתמש בוחר במערכת החיוב של Google Play, הוא ממשיך ברכישה דרך Google Play.

  • המאמר עיבוד רכישות במדריך לשילוב הספרייה כולל מידע נוסף על טיפול ברכישות חדשות באפליקציות דרך מערכת החיוב של Google Play.
  • מידע נוסף על רכישת מינויים מופיע במדריך לניהול מינויים, בקטע מינויים חדשים.

טיפול בשינויים במינוי

מפתחים שמשתמשים באמצעי תשלום חיצוניים צריכים לעבד את הרכישות דרך מערכת החיוב של Google Play או לדווח עליהן באמצעות externalTransactionId, בהתאם לבחירת המשתמש. שינויים במינויים קיימים שעברו עיבוד דרך האתר של המפתח יכולים להתבצע דרך אותה מערכת חיוב עד למועד התפוגה.

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

תהליכי שדרוג ושנמוך

התהליכים של שינוי תוכנית מינוי, כולל שדרוג ושנמוך, צריכים להתבצע בצורה שונה בהתאם לאופן שבו המינוי נרכש במקור – דרך מערכת החיוב של Google Play או דרך האתר של המפתח.

תוספים למינוי קיים שמשתמשים באותו אמצעי תשלום ומחויבים בתשלומים קבועים נחשבים לשדרוגים. בתוספים אחרים, המשתמשים יכולים לבחור באיזו מערכת חיוב הם רוצים להשתמש. כדי להתחיל חוויית רכישה חדשה, משתמשים ב-launchBillingFlow(), כמו שמתואר במאמר בנושא הפעלת תהליך תשלום חיצוני.

מינויים שנרכשו דרך האתר של המפתח או דרך אפליקציית תשלומים

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

כדי לאפשר זאת, צריך להפעיל את launchBillingFlow() כשמשתמש מבקש שדרוג או שנמוך. במקום לציין פרמטרים אחרים באובייקט SubscriptionUpdateParams, צריך להשתמש ב-setOriginalExternalTransactionId() ולציין את מזהה העסקה החיצוני של הרכישה המקורית.

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

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

מינויים שנרכשו דרך מערכת החיוב של Google Play

באופן דומה, משתמשים שרכשו את המינוי הנוכחי שלהם דרך מערכת החיוב של Google Play צריכים לעבור את תהליך החיוב הרגיל של Google Play. אסור להגדיר את DeveloperBillingOptionParams ל-launchBillingFlow בקריאה.

ביטולים ושחזורים של מינויים

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

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

מינויים שנרכשו דרך האתר של המפתח

אם יש לכם מזהה עסקה חיצונית למינוי שבוטל, לא צריך לשלוח קריאה אל launchBillingFlow() כדי לשחזר את המינוי, אז לא מומלץ להשתמש בו להפעלה כזו. אם משתמש משחזר את המינוי שלו במהלך התקופה הפעילה לאחר הביטול, לא מתבצעת עסקה חדשה באותו זמן. אפשר פשוט להמשיך לדווח על חידושים כשתקופת המינוי הנוכחית מסתיימת והחידוש הבא מתבצע. זה תקף גם למקרים שבהם המשתמש מקבל קרדיט או מחיר מיוחד לחידוש המינוי כחלק מהשחזור (לדוגמה, במסגרת מבצע שמעודד את המשתמש להמשיך את המינוי).

מינויים שנרכשו דרך מערכת החיוב של Google Play

בדרך כלל, המשתמשים יכולים לשחזר מינויים במערכת החיוב של Google Play. במקרה של מינוי שבוטל ונרכש במקור דרך מערכת החיוב של Google Play, המשתמש יכול לשחזר אותו באמצעות התכונה הרשמה מחדש ב-Google Play, כל עוד המינוי עדיין פעיל. במקרה כזה, תישלח בבק-אנד התראה בזמן אמת למפתחים (RTDN) מסוג SUBSCRIPTION_RESTARTED, ולא יונפק טוקן רכישה חדש. במקום זאת, הטוקן המקורי ישמש להמשך המינוי. במדריך לניהול מינויים מוסבר איך לנהל שחזור במערכת החיוב של Google Play.

אפשר גם לשלוח קריאה ל-launchBillingFlow() מתוך האפליקציה כדי להפעיל שחזור במערכת החיוב של Google Play. במאמר לפני שתוקף המינוי יפוג – באפליקציה מוסבר איך עושים את זה. במקרה של משתמשים שעברו את תהליך בחירת האפשרויות בזמן הרכישה המקורית (שבוטלה אבל עדיין פעילה), המערכת מזהה באופן אוטומטי את הבחירה שלהם ומציגה את ממשק המשתמש לשחזור הרכישות האלה. המשתמשים יתבקשו לאשר את הרכישה מחדש של המינוי דרך Google Play, אבל לא יצטרכו לעבור שוב את תהליך הבחירה. במקרה כזה, מונפק למשתמש טוקן רכישה חדש. הבק-אנד מקבל הודעה בזמן אמת למפתחים (RTDN) מסוג SUBSCRIPTION_PURCHASED, והערך של linkedPurchaseToken לסטטוס הרכישה החדש מוגדר כמו בשדרוג או שנמוך, יחד עם טוקן הרכישה הישן של המינוי שבוטל.

הרשמה מחדש

אם תוקף המינוי פג לגמרי, בגלל ביטול או בגלל שהתשלום נדחה ולא שוחזר (השהיית חשבון שתוקפה פג), המשתמש צריך להירשם מחדש אם הוא רוצה להפעיל מחדש את ההרשאה.

אפשר גם להפעיל הרשמה מחדש דרך האפליקציה, בתהליך דומה להרשמה רגילה. המשתמשים צריכים להיות מסוגלים לבחור באיזו מערכת חיוב הם רוצים להשתמש. יכול להיות שתישלח קריאה לפונקציה launchBillingFlow() במקרה הזה, כמו שמתואר במאמר בנושא הפעלת תהליך התשלומים החיצוניים.

טיפול בתגובות

אם מתרחשת שגיאה, יכול להיות שה-methods‏ isBillingProgramAvailableAsync(),‏ createBillingProgramReportingDetailsAsync() ו-launchBillingFlow() יספקו BillingResponseCode שאינו BillingResponseCode.OK. כדאי לטפל בקודי התגובה האלה באופן הבא:

  • BillingResponseCode.ERROR: זו שגיאה פנימית. אל תמשיכו בעסקה או בפתיחת האתר החיצוני. נסו שוב על ידי קריאה חוזרת ל-API.
  • BillingResponseCode.FEATURE_NOT_SUPPORTED: חנות Play לא תומכת בממשקי ה-API לתשלומים חיצוניים במכשיר הנוכחי. אל תמשיכו בעסקה או בפתיחת האתר החיצוני.
  • BillingResponseCode.DEVELOPER_ERROR: יש שגיאה בבקשה. כדאי להשתמש בהודעת ניפוי הבאגים כדי לזהות ולתקן את השגיאה לפני שממשיכים.
  • BillingResponseCode.USER_CANCELED: אל תמשיכו בפתיחה של האתר או האפליקציה החיצוניים. שלחו קריאה חדשה ל-launchBillingFlow() כדי שהמשתמש יראה את תיבת הדו-שיח עם המידע בפעם הבאה שתנסו להפנות אותו אל מחוץ לאפליקציה.
  • BillingResponseCode.BILLING_UNAVAILABLE: העסקה לא עומדת בדרישות לשימוש בתשלומים חיצוניים, ולכן מערכת החיוב שהמפתח בחר לא תהיה זמינה במסגרת התוכנית הזו. יכול להיות שהמשתמש לא נמצא במדינה שעומדת בדרישות של התוכנית הזו, או שלא הצלחתם לרשות החשבון שלכם לתוכנית. אם מדובר במקרה השני, צריך לבדוק את סטטוס ההרשמה ב-Play Console.
  • BillingResponseCode.NETWORK_ERROR,‏ BillingResponseCode.SERVICE_DISCONNECTED,‏ BillingResponseCode.SERVICE_UNAVAILABLE: אלה שגיאות זמניות שצריך לטפל בהן באמצעות מדיניות מתאימה של ניסיון חוזר. במקרה של SERVICE_DISCONNECTED, צריך ליצור מחדש חיבור ל-Google Play לפני שמנסים שוב.

בדיקת קישורים לתשלומים חיצוניים

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

השלבים הבאים

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