קל לארגן דפים בעזרת אוספים
אפשר לשמור ולסווג תוכן על סמך ההעדפות שלך.
אחרי שיוצרים כרטיס ומקודדים אותו ב-JWT, אפשר להנפיק אותו באפליקציה ל-Android. כדי לעשות זאת, צריך לבדוק אם Google Wallet API זמין במכשיר של המשתמש, להציג לו את הלחצן 'הוספה ל-Google Wallet' ולאחר מכן לשמור את הכרטיס ב-Google Wallet אחרי שהוא מקייש על הלחצן.
דרישות מוקדמות
לפני שמנסים להנפיק כרטיס, חשוב לוודא שהתנאים הבאים מתקיימים:
אם אתם משתמשים בתבניות עיצוב אחרות, כדאי להציב את הלוגיקה העסקית הספציפית לדומיין באופן מתאים. לדוגמה, אם אתם משתמשים בתבנית MVVM, תוכלו למקם את הלוגיקה העסקית שקשורה לממשק המשתמש ב-Activity או ב-Fragment (למשל: רכיבי ממשק משתמש, תוצאת הפעילות) ולוגיקה תפעולית במודל התצוגה (למשל: יצירת מכונה של לקוח, טריגרים של קריאות לרשת).
לאחר מכן, משתמשים ב-PayClient כדי לבדוק אם ה-API זמין:
לבסוף, כשצריך לקבוע את הזמינות של ה-API, קוראים לשיטה שהגדרתם באפליקציה.
טיפול במקרים שבהם ה-API לא זמין
בין הסיבות האפשריות לכך שה-API לא זמין: הגרסאות של Android או של Google Play Services לא עדכניות, או ש-Google Wallet לא זמין במדינה של המשתמש.
אם ה-API לא זמין, מומלץ להסתיר את הלחצן ולעבור לשילוב אחר (למשל, באמצעות קישור JWT). חשוב לדעת שהמשתמש עשוי לעמוד בדרישות לשימוש ב-API בעתיד.
3. הוספת הלחצן 'הוספה ל-Google Wallet'
ב-Google Wallet יש כפתור מוכר שאפשר להשתמש בו כדי להפעיל את התהליך של ההוספה ל-Google Wallet באפליקציה. נכסי וקטורים של הלחצן זמינים בהנחיות ללחצנים.
אפשר לייבא נכסי וקטורים ב-Android Studio בקטע File > New > Vector Asset. בוחרים באפשרות 'קובץ מקומי' באשף, מוסיפים שם (למשל:
add_to_google_wallet_button.xml) ומאתרים את הקובץ בכונן המקומי כדי לייבא אותו.
עכשיו אפשר להשתמש ב-drawable שיובאת כדי להוסיף את הלחצן לממשק המשתמש:
[[["התוכן קל להבנה","easyToUnderstand","thumb-up"],["התוכן עזר לי לפתור בעיה","solvedMyProblem","thumb-up"],["סיבה אחרת","otherUp","thumb-up"]],[["חסרים לי מידע או פרטים","missingTheInformationINeed","thumb-down"],["התוכן מורכב מדי או עם יותר מדי שלבים","tooComplicatedTooManySteps","thumb-down"],["התוכן לא עדכני","outOfDate","thumb-down"],["בעיה בתרגום","translationIssue","thumb-down"],["בעיה בדוגמאות/בקוד","samplesCodeIssue","thumb-down"],["סיבה אחרת","otherDown","thumb-down"]],["עדכון אחרון: 2025-08-17 (שעון UTC)."],[[["\u003cp\u003eBefore issuing passes, complete onboarding, create a Passes Class and Object, and encode them in a JWT.\u003c/p\u003e\n"],["\u003cp\u003eIntegrate the Google Wallet Android SDK to add a Google Pay button that enables users to save passes to their Google Wallet.\u003c/p\u003e\n"],["\u003cp\u003eEnsure the Google Wallet API is available on the user's device before displaying the 'Add to Google Wallet' button.\u003c/p\u003e\n"],["\u003cp\u003eHandle potential API unavailability by considering alternative integration methods and providing appropriate user feedback.\u003c/p\u003e\n"],["\u003cp\u003eUpon successful pass addition, leverage the \u003ccode\u003eonActivityResult\u003c/code\u003e method to confirm the save operation and manage potential errors.\u003c/p\u003e\n"]]],["To issue a pass in an Android app, first, verify Google Wallet API availability using `PayClient.getPayApiAvailabilityStatus`. If available, display the 'Add to Google Wallet' button; otherwise, hide it. When the user taps the button, use `walletClient.savePasses` (or `savePassesJwt` for web integration) with the encoded JWT to add the pass. Finally, handle the result in `onActivityResult`, checking for success, cancellation, or errors using `resultCode`. Remember to first install the Google Wallet SDK.\n"],null,["Once you've created a pass and encoded it in a JWT, you are ready to issue it in your Android app. To do this, you will need to check that the Google Wallet API is available on the user's device, present them with an 'Add to Google Wallet' button, then save the pass to their Google Wallet once they tap the button.\n\nPrerequisites\n\nBefore you try to issue a pass, be sure you have completed the following:\n\n- Completed all of the steps in the [Onboarding guide](../getting-started/onboarding-guide).\n- Create at least one [Passes Class](../use-cases/create#creating_a_passes_class).\n- Create at least one [Passes Object](../use-cases/create#creating_a_passes_object).\n- [Encoded](../use-cases/jwt) your Passes Class and Passes Object in a JWT.\n\n| **Demo Mode / \\[TEST ONLY\\] passes**\n|\n| When you are still in [Demo Mode](../resources/terminology#demo-mode), all the passes that you create will have an additional text \"\\[TEST ONLY\\]\" in the title. This is to differentiate demo passes from live passes. Once you are granted [publishing access](../test-and-go-live/request-publishing-access), these demo mode passes will no longer have the additional text when the user reopens the wallet app on a connected device.\n\n1. Install the Google Wallet Android SDK \nTo use the Google Wallet Android SDK, add `com.google.android.gms:play-services-pay` to the `dependencies` section of your app-level `build.gradle` file: \n\n```\n implementation \"com.google.android.gms:play-services-pay:16.5.0\"\n```\n\n2. Check for Google Wallet API availability \nBefore saving the new object, ensure that the Google Wallet API is\navailable on the target device by calling the`getPayApiAvailabilityStatus` method in the `PayClient` class.\n\nStart by adding a member variable to the\nactivity where you will show the button and instantiate it when the activity is\ncreated: \n\nKotlin \n\n import com.google.android.gms.pay.PayClient\n\n private lateinit var walletClient: PayClient\n\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n\n walletClient = Pay.getClient(this)\n\n // Additional logic in your onCreate method\n }\n\nJava \n\n import com.google.android.gms.pay.PayClient;\n\n private final PayClient walletClient;\n\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n\n walletClient = Pay.getClient(application);\n\n // Additional logic in your onCreate method\n }\n\nIf you are using other design patterns consider placing domain specific business logic appropriately. For example, if you are using the MVVM pattern,\nplace UI related business logic in your Activity or Fragment (eg.: UI elements,\nactivity result), and operational logic in your view model (eg.: client\ninstantiation, network call triggers).\n\nNext, use the `PayClient` to check whether the API is available: \n\nKotlin \n\n import com.google.android.gms.pay.PayApiAvailabilityStatus\n\n private fun fetchCanUseGoogleWalletApi() {\n walletClient\n .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)\n .addOnSuccessListener { status -\u003e\n if (status == PayApiAvailabilityStatus.AVAILABLE) {\n // The API is available, show the button in your UI\n } else {\n // The user or device is not eligible for using the Pay API\n }\n }\n .addOnFailureListener {\n // Hide the button and optionally show an error message\n }\n }\n\nJava \n\n import com.google.android.gms.pay.PayApiAvailabilityStatus;\n\n private void fetchCanAddPassesToGoogleWallet() {\n walletClient\n .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)\n .addOnSuccessListener(status -\u003e {\n if (status == PayApiAvailabilityStatus.AVAILABLE) {\n // The API is available, show the button in your UI\n } else {\n // The user or device is not eligible for using the Pay API\n };\n })\n .addOnFailureListener(exception -\u003e {\n // Google Play Services is too old, or API availability not verified\n // Hide the button and optionally show an error message\n });\n }\n\nFinally, call the method you just defined in your application when you need to determine the availability of the API.\n\nHandle when the API is unavailable\n\nSome reasons why the API may be unavailable include the Android or Google\nPlay services versions being out of date, or that Google Wallet is\nunavailable in the user's country.\n\nIf the API is not available\nconsider hiding the button and falling back to a different integration (e.g.\n[using a JWT link](/wallet/generic/web)). Note that the user may become eligible to use the API in the future.\n\n3. Add the 'Add to Google Wallet' button \nGoogle Wallet provides a familiar button that you can use to trigger the\nAdd to Google Wallet flow in your application. Vector assets for the button are\navailable in the\n[Button guidelines](/wallet/generic/resources/brand-guidelines).\n| **Tip:** Make sure to only include graphics for the configurations supported.\n\nYou can import vector assets in Android Studio under `File \u003e New \u003e Vector Asset`. Select \"Local file\" in the wizard, add a name (eg.:\n`add_to_google_wallet_button.xml`) and locate the file in your local drive to import it.\n- \n- \n\nNow, you can use the imported drawable to add the button to your user interface: \n\n```xml\n \u003cImageButton\n android:id=\"@+id/addToGoogleWalletButton\"\n android:layout_width=\"match_parent\"\n android:layout_height=\"48dp\"\n android:minWidth=\"200dp\"\n android:clickable=\"true\"\n android:src=\"@drawable/add_to_google_wallet_button\" /\u003e\n```\n\nThe button has a `layout_height` of 48 dp and must be at least 200 dp wide.\n\n4. Add a pass to a user's Google Wallet \nThe `GenericObject` can be added by passing an unsigned JWT to the `savePasses` method.\nYou can start the add operation as a result of clicking the Google Wallet\nbutton.\n**Note:** If you are integrating for both Android and web, you can reuse the signed JWT that is required for the web integration, calling `savePassesJwt` instead of ` savePasses`. \n\nKotlin \n\n import android.os.Bundle\n import android.view.View\n import com.google.android.gms.samples.wallet.databinding.ActivityCheckoutBinding\n\n private val addToGoogleWalletRequestCode = 1000\n\n private lateinit var layout: ActivityCheckoutBinding\n private lateinit var addToGoogleWalletButton: View\n\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n\n // Use view binding to access the UI elements\n layout = ActivityCheckoutBinding.inflate(layoutInflater)\n setContentView(layout.root)\n\n addToGoogleWalletButton = layout.addToGoogleWalletButton\n addToGoogleWalletButton.setOnClickListener {\n walletClient.savePasses(newObjectJson, this, addToGoogleWalletRequestCode)\n }\n\n // Additional logic in your onCreate method\n }\n\nJava \n\n import android.os.Bundle;\n import android.view.View;\n import com.google.android.gms.samples.wallet.databinding.ActivityCheckoutBinding;\n\n private static final int ADD_TO_GOOGLE_WALLET_REQUEST_CODE = 999;\n\n private ActivityCheckoutBinding layout:\n private View addToGoogleWalletButton;\n\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n\n // Use view binding to access the UI elements\n layout = ActivityCheckoutBinding.inflate(getLayoutInflater());\n setContentView(layout.getRoot());\n\n addToGoogleWalletButton = layout.addToGoogleWalletButton;\n addToGoogleWalletButton.setOnClickListener(v -\u003e {\n walletClient.savePasses(newObjectJson, this, ADD_TO_GOOGLE_WALLET_REQUEST_CODE);\n });\n\n // Additional logic in your onCreate method\n }\n\nResult handling\n\nThe `savePasses` method triggers the save flow and invokes the\n` onActivityResult` method after the save flow has completed. The implementation of `onActivityResult` should be similar to the following: \n\nKotlin \n\n import android.content.Intent\n\n override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {\n super.onActivityResult(requestCode, resultCode, data)\n\n if (requestCode == addToGoogleWalletRequestCode) {\n when (resultCode) {\n RESULT_OK -\u003e {\n // Pass saved successfully\n }\n\n RESULT_CANCELED -\u003e {\n // Save operation canceled\n }\n\n PayClient.SavePassesResult.SAVE_ERROR -\u003e data?.let { intentData -\u003e\n val errorMessage = intentData.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE)\n // Handle error\n }\n\n else -\u003e {\n // Handle unexpected (non-API) exception\n }\n }\n }\n }\n\nJava \n\n import android.content.Intent;\n\n @Override\n protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {\n super.onActivityResult(requestCode, resultCode, data);\n\n if (requestCode == ADD_TO_GOOGLE_WALLET_REQUEST_CODE) {\n switch (resultCode) {\n case RESULT_OK: {\n // Pass saved successfully\n break;\n }\n\n case RESULT_CANCELED: {\n // Save operation canceled\n break;\n }\n\n case PayClient.SavePassesResult.SAVE_ERROR: {\n if (data != null) {\n String apiErrorMessage = data.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE);\n // Handle error\n }\n break;\n }\n\n default: {\n // Handle unexpected (non-API) exception\n }\n }\n }\n }\n\nWhen the pass is successfully added, the `resultCode` contains the value of ` Activity.RESULT_OK`."]]