自从计费库2和3开始,购买成功后,我们需要执行额外的确认步骤。
购买成功后,将触发以下回叫。
df <- structure(list(rating = c(0.6, NA, 0.9, NA, 0, NA), playerID = c("a1",
"b2", "a4", "b5", "a3", "b2")), row.names = c(NA, -6L), class = "data.frame")
确认成功后,将触发以下回叫。
public interface PurchasesUpdatedListener {
void onPurchasesUpdated(BillingResult billingResult, java.util.List<com.android.billingclient.api.Purchase> list);
}
在成功案例中,当购买成功或确认成功时,我们应该解锁应用内购买项目吗?
答案 0 :(得分:0)
请查看“授予权利之前验证购买”部分。
https://developer.android.com/google/play/billing/security#verify
只有在通过后端服务器确认购买合法之后,才能解锁内容。
您实施onPurchasesUpdated
,以获取有关在应用内或应用外启动的购买更新的通知。
如果您不确认购买,则该购买将自动退款。您实施onAcknowledgePurchaseResponse
,以接收有关购买操作确认已完成的通知。
但是要知道它是否合法购买,您必须在授予权利之前确认购买是否合法。
敏感数据和逻辑的特殊情况,应在 后端是购买验证。用户制作完一个 购买,您应该执行以下操作:
- 将相应的PurchaseToken发送到您的后端。这意味着您应保留所有记录的所有purchaseToken值 购买。
- 验证当前购买的purchaseToken值与任何先前的purchaseToken值都不匹配。 PurchaseToken在全球范围内 唯一,因此您可以安全地将此值用作您的主键 数据库。
- 使用Google Play开发者API中的Purchases.products:get或Purchases.subscriptions:get端点与Google进行验证 购买是合法的。
- 如果购买的商品是合法商品,并且过去从未使用过,则可以安全地授予应用内商品或订阅的权利。
- 对于订阅,在Purchases.subscriptions:get中设置linkedPurchaseToken时,还应删除 从您的数据库中链接了PurchaseToken,并撤销了 被授予linkedPurchaseToken以确保多个用户 没有资格进行相同的购买。
因此,您仅应在全部三个完成后才能解锁内容。
完成这三个步骤后,就可以安全地解锁您的购买了。如果您不选择这三个选项,则存在解锁已退还或非法购买的内容的风险。
答案 1 :(得分:0)
购买后无法购买InApp产品。我们需要在 成功购买,以便我们可以再次购买,它将可供 下次我们购买与之前购买的产品相同的产品。
您必须确认所有非消耗性的购买,即必须确认订阅。这是参考代码,或者您
/**
* If you do not acknowledge a purchase, the Google Play Store will provide a refund to the
* users within a few days of the transaction. Therefore you have to implement
* [BillingClient.acknowledgePurchaseAsync] inside your app.
*
* @param purchase list of Purchase Details returned from the queries.
*/
private fun acknowledgeNonConsumablePurchasesAsync(purchase: Purchase) {
val acknowledgePurchaseRunnable = Runnable {
val params = AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
myBillingClient.acknowledgePurchase(
params
) { billingResult: BillingResult ->
if (billingResult.responseCode == BillingResponseCode.OK) {
LogUtils.d(TAG, "onAcknowledgePurchaseResponse: " + billingResult.responseCode)
} else {
LogUtils.d(TAG, ("onAcknowledgePurchaseResponse: " + billingResult.debugMessage))
}
}
}
}
对于消耗品,应该这样做
/**
* Consumes InApp Product Purchase after successful purchase of InApp Product Purchase. InApp
* Products cannot be bought after a purchase was made. We need to consume it after a
* successful purchase, so that we can purchase again and it will become available for the
* next time we make purchase of the same product that was bought before.
*
* @param purchase the purchase result contains Purchase Details.
*/
val onConsumeListener =
ConsumeResponseListener { billingResult: BillingResult, purchaseToken: String ->
// If billing service was disconnected, we try to reconnect 1 time
// (feel free to introduce your retry policy here).
if (billingResult.responseCode == BillingResponseCode.OK) {
LogUtils.d(TAG, "onConsumeResponse, Purchase Token: $purchaseToken")
} else {
LogUtils.d(TAG, "onConsumeResponse: " + billingResult.debugMessage)
}
}
// Creating a runnable from the request to use it inside our connection retry policy below
val consumeRequest = Runnable {
// Consume the purchase async
val consumeParams = ConsumeParams.newBuilder()
.setPurchaseToken(purchase.purchaseToken)
.build()
myBillingClient!!.consumeAsync(consumeParams, onConsumeListener)
}