Android集成Google Pay:API及示例导入类缺失,无法完成支付初始化
问题说明
我正在给Android应用集成Google Pay结账功能,已经成功在XML布局里添加了Google Pay按钮:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:wallet="http://schemas.android.com/apk/res-auto" android:background="#303030" > <LinearLayout> <com.google.android.gms.wallet.button.PayButton android:id="@+id/google_pay_buttonLL" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>
但按照官方文档写CheckoutActivity时,发现文档里的几个导入类根本不存在:com.google.android.gms.samples.pay.R、ActivityCheckoutBinding、PaymentsUtil、CheckoutViewModel,这些类又是实现结账的关键。之前已经把PaymentsUtil里的CONSTANTS替换成了WalletConstants,但这几个缺失的类还是不知道怎么处理。我已经在Gradle里开了viewBinding和dataBinding,也加了依赖:
buildFeatures { viewBinding true dataBinding true } viewBinding { enabled true } ... dependencies { implementation 'com.google.android.gms:play-services-wallet:19.4.0' implementation "com.google.android.gms:play-services-pay:16.5.0" }
逐个解决缺失类问题
1. com.google.android.gms.samples.pay.R
这是Google官方示例项目的资源类,直接换成你自己项目的R类就行——比如你的应用包名是com.yourcompany.yourapp,就改成com.yourcompany.yourapp.R。
2. ActivityCheckoutBinding
这是View Binding自动生成的类,要满足两个条件:
- 你的Activity布局文件名必须是
activity_checkout.xml(View Binding的类名是布局文件名转驼峰后加Binding,比如布局叫activity_pay.xml,生成的就是ActivityPayBinding)。 - 确认Gradle配置正确,不要重复写配置,模块级build.gradle里保留这一段就行:
android { ... buildFeatures { viewBinding true } }
写完后点Android Studio顶部的Sync Project with Gradle Files,等构建完成,这个类就会自动生成。
3. PaymentsUtil
这是官方示例封装的工具类,用来处理Google Pay的配置、支付参数构建等逻辑,你得自己创建这个类。核心功能包括判断设备是否支持Google Pay、构建支付请求、设置环境(测试/生产),参考核心代码:
import com.google.android.gms.wallet.WalletConstants; import com.google.android.gms.wallet.PaymentDataRequest; import com.google.android.gms.wallet.PaymentMethodTokenizationParameters; import com.google.android.gms.wallet.PaymentMethodTokenizationType; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; public class PaymentsUtil { // 替换成你的支付网关信息 private static final String PAYMENT_GATEWAY_NAME = "your_payment_gateway"; private static final String MERCHANT_ID = "your_merchant_id"; // 判断设备是否支持Google Pay public static boolean isReadyToPay(Context context) { JSONObject isReadyToPayJson = new JSONObject(); try { isReadyToPayJson.put("apiVersion", 2); isReadyToPayJson.put("apiVersionMinor", 0); JSONObject allowedPaymentMethods = new JSONObject(); allowedPaymentMethods.put("type", "CARD"); JSONObject parameters = new JSONObject(); parameters.put("allowedAuthMethods", new JSONArray().put("PAN_ONLY").put("CRYPTOGRAM_3DS")); parameters.put("allowedCardNetworks", new JSONArray().put("AMEX").put("DISCOVER").put("MASTERCARD").put("VISA")); allowedPaymentMethods.put("parameters", parameters); isReadyToPayJson.put("allowedPaymentMethods", new JSONArray().put(allowedPaymentMethods)); IsReadyToPayRequest request = IsReadyToPayRequest.fromJson(isReadyToPayJson.toString()); Task<Boolean> task = Wallet.getPaymentsClient(context, new Wallet.WalletOptions.Builder() .setEnvironment(getEnvironment()) .build()).isReadyToPay(request); return task.get(); } catch (JSONException | ExecutionException | InterruptedException e) { e.printStackTrace(); return false; } } // 构建支付请求 public static PaymentDataRequest createPaymentDataRequest(long totalPriceCents) throws JSONException { JSONObject paymentDataRequestJson = new JSONObject(); paymentDataRequestJson.put("apiVersion", 2); paymentDataRequestJson.put("apiVersionMinor", 0); JSONObject allowedPaymentMethods = new JSONObject(); allowedPaymentMethods.put("type", "CARD"); JSONObject parameters = new JSONObject(); parameters.put("allowedAuthMethods", new JSONArray().put("PAN_ONLY").put("CRYPTOGRAM_3DS")); parameters.put("allowedCardNetworks", new JSONArray().put("AMEX").put("DISCOVER").put("MASTERCARD").put("VISA")); allowedPaymentMethods.put("parameters", parameters); JSONObject tokenizationSpecification = new JSONObject(); tokenizationSpecification.put("type", PaymentMethodTokenizationType.PAYMENT_GATEWAY); JSONObject tokenizationParams = new JSONObject(); tokenizationParams.put("gateway", PAYMENT_GATEWAY_NAME); tokenizationParams.put("gatewayMerchantId", MERCHANT_ID); tokenizationSpecification.put("parameters", tokenizationParams); allowedPaymentMethods.put("tokenizationSpecification", tokenizationSpecification); paymentDataRequestJson.put("allowedPaymentMethods", new JSONArray().put(allowedPaymentMethods)); JSONObject transactionInfo = new JSONObject(); transactionInfo.put("totalPrice", String.valueOf(totalPriceCents / 100.0)); transactionInfo.put("totalPriceStatus", "FINAL"); transactionInfo.put("currencyCode", "USD"); // 替换成你的货币代码 paymentDataRequestJson.put("transactionInfo", transactionInfo); JSONObject merchantInfo = new JSONObject(); merchantInfo.put("merchantName", "你的商家名称"); paymentDataRequestJson.put("merchantInfo", merchantInfo); return PaymentDataRequest.fromJson(paymentDataRequestJson.toString()); } // 设置环境:测试用TEST,上线用PRODUCTION public static int getEnvironment() { return WalletConstants.ENVIRONMENT_TEST; } }
4. CheckoutViewModel
这是示例里用的ViewModel,用来分离UI和业务逻辑。如果不想用MVVM,可以直接把逻辑写到Activity里;如果要用,自己创建这个类就行,核心是初始化PaymentsClient、处理支付结果,参考代码:
import androidx.lifecycle.ViewModel; import com.google.android.gms.wallet.PaymentData; import com.google.android.gms.wallet.PaymentsClient; import com.google.android.gms.wallet.Wallet; public class CheckoutViewModel extends ViewModel { private PaymentsClient paymentsClient; public void initPaymentsClient(Context context) { Wallet.WalletOptions options = new Wallet.WalletOptions.Builder() .setEnvironment(PaymentsUtil.getEnvironment()) .build(); paymentsClient = Wallet.getPaymentsClient(context, options); } // 解析支付结果,获取令牌传给后端 public void handlePaymentResult(PaymentData paymentData) { String paymentToken = paymentData.getPaymentMethodToken().getToken(); // 这里调用你的后端接口完成支付 } public PaymentsClient getPaymentsClient() { return paymentsClient; } }
额外注意事项
- 确保
play-services-wallet和play-services-pay的版本兼容,建议用最新稳定版。 - 如果View Binding没生成类,检查布局文件有没有语法错误。
- 测试时要用支持Google Pay的设备,并且添加官方文档里的测试银行卡。
内容的提问来源于stack exchange,提问作者Alon Belkin

