使用Google Wallet API,如何检查凭证是否已添加至Google Wallet?
检查Google Wallet凭证是否已添加的实现方案
针对你使用play-services-pay:16.1.0版本API遇到的问题,需要明确:新版Google Wallet PayClient并未提供前端直接查询用户钱包内凭证的接口(出于用户隐私保护),官方推荐通过以下两种方式实现状态判断,从而切换按钮文本:
方案1:本地记录添加状态(轻量实现)
在用户完成凭证添加操作后,将凭证ID存储在本地(如SharedPreferences),后续通过本地记录判断按钮状态。缺点是无法同步用户跨设备或手动删除凭证的操作,但适合无后端的轻量场景。
实现代码示例
import android.content.Intent import android.content.SharedPreferences import android.os.Bundle import android.widget.Button import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.pay.Pay import com.google.android.gms.pay.PayClient import org.json.JSONObject import android.util.Base64 class WalletActivity : AppCompatActivity() { private lateinit var walletClient: PayClient private lateinit var walletButton: Button private val addToGoogleWalletRequestCode = 1001 private val passJwtToken = "你的凭证JWT令牌" private lateinit var prefs: SharedPreferences override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_wallet) walletClient = Pay.getClient(this) walletButton = findViewById(R.id.wallet_button) prefs = getSharedPreferences("WalletPasses", MODE_PRIVATE) val passId = extractPassIdFromJwt(passJwtToken) updateWalletButton(isPassAddedLocally(passId)) } // 从JWT中提取凭证ID(需根据你的JWT payload结构调整字段) private fun extractPassIdFromJwt(jwt: String): String { val jwtParts = jwt.split(".") if (jwtParts.size != 3) throw IllegalArgumentException("无效的JWT格式") val payloadBytes = Base64.decode(jwtParts[1], Base64.URL_SAFE or Base64.NO_WRAP) val payloadJson = String(payloadBytes) return JSONObject(payloadJson).getString("id") } // 检查本地是否记录凭证已添加 private fun isPassAddedLocally(passId: String): Boolean { return prefs.getBoolean("pass_$passId", false) } // 更新按钮文本与点击事件 private fun updateWalletButton(isAdded: Boolean) { walletButton.text = if (isAdded) "在Google Wallet中查看" else "添加至Google Wallet" walletButton.setOnClickListener { if (isAdded) { // 打开Google Wallet查看凭证 val viewIntent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://wallet.google.com/pay/apis/passes/${extractPassIdFromJwt(passJwtToken)}") addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } startActivity(viewIntent) } else { walletClient.savePassesJwt(passJwtToken, this, addToGoogleWalletRequestCode) } } } // 处理添加凭证的回调,更新本地记录 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == addToGoogleWalletRequestCode) { when (resultCode) { RESULT_OK -> { val passId = extractPassIdFromJwt(passJwtToken) prefs.edit().putBoolean("pass_$passId", true).apply() updateWalletButton(true) } PayClient.SavePassesResultCodes.ERROR -> { data?.getStringExtra(PayClient.EXTRA_ERROR_MESSAGE)?.let { // 处理添加错误 } } } } } }
方案2:后端关联查询(高准确性)
如果你的服务有后端,可以结合Google Sign-In获取用户的Google账号ID(sub字段),在用户添加凭证时,将用户ID与凭证ID关联存储。后续前端请求后端查询状态,这种方式可以同步用户跨设备操作,准确性更高。
核心逻辑
- 前端通过Google Sign-In获取用户的ID Token,发送到后端验证并提取用户账号ID。
- 用户添加凭证成功后,后端存储
用户ID-凭证ID的关联关系。 - 页面加载时,前端携带用户ID和凭证ID请求后端,根据返回结果切换按钮状态。
补充说明
- 若用户手动删除钱包中的凭证,本地记录会出现偏差,此时可在用户点击「查看」按钮后,通过Google Wallet的跳转结果间接更新本地状态。
- 官方不允许前端直接访问用户钱包内的凭证列表,因此上述两种方式是合规的替代方案。
内容的提问来源于stack exchange,提问作者Evstropov V
相关产品推荐
相关产品推荐

