如何解决即使我确认购买,Google仍会在3天内退还所有已购买的订阅
我开发了一个项目,该项目集成了应用内订阅方法。 它是非消耗性产品,每月有3.99美元的订阅项目。 我已使用计费客户端方法2.1.0并在Google上配置了订阅项。 当我通过内部测试测试应用程序订阅时,它表明该商品已成功购买。 但是,发行版具有很大的风险。 所有用户的订阅将在3天内自动退款。 Google支持小组表示,确认所有购买必须在三天内完成。 如果未正确确认购买,则会导致这些购买被退款。
我集成了确认侦听器,但结果仍然相同。 我将附上几张截图,显示如何退款。
这是我正在处理的代码。 是否有任何原因由于我的代码问题而将所有物品自动退款? 感谢您的阅读和观看。
//build.gradle
implementation 'com.android.billingclient:billing:2.1.0'
implementation 'com.android.billingclient:billing-ktx:2.1.0'
//Androidmanifest.xml
<uses-permission android:name="com.android.vending.BILLING" />
//Subscription Purchase and AckNowledge code
class SubscriptionActivity : AppCompatActivity(),PurchasesUpdatedListener {
lateinit var billingClient: BillingClient
lateinit var skuList: MutableList<SkuDetails>
val ackNowledgePurchaseResponseListener =
AckNowledgePurchaseResponseListener {
Toast.makeText(this@SubscriptionActivity,"Purchase ackNowledged",Toast.LENGTH_SHORT).show() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_subscription)
setupBillingClient()
setupInitEvents()
}
private fun getAvailableProducts() {
if (billingClient.isReady)
{
val params = SkuDetailsParams.newBuilder()
.setSkusList(Arrays.asList(SubscriptionID))
.setType(BillingClient.SkuType.SUBS)
.build()
billingClient.querySkuDetailsAsync(params)
{
p0,skuDetailsList ->
if (p0.responseCode == BillingClient.BillingResponseCode.OK)
skuList = skuDetailsList as MutableList<SkuDetails>
//displayProduct(skuDetailsList)
else {
//Toast.makeText(this@SubscriptionActivity,"Cannot find product",Toast.LENGTH_SHORT).show()
}
}
}
else
{
//Toast.makeText(this@SubscriptionActivity,"Billing Client not ready",Toast.LENGTH_SHORT).show()
}
}
private fun setupBillingClient() {
//billingClient = BillingClient.newBuilder(this).setListener(this).build()
billingClient = BillingClient.newBuilder(this)
.enablePendingPurchases()
.setListener(this)
.build();
billingClient.startConnection(object:BillingClientStateListener{
override fun onBillingServicedisconnected() {
//Toast.makeText(this@SubscriptionActivity,"disconnected",Toast.LENGTH_SHORT).show()
}
override fun onBillingSetupFinished(p0: BillingResult) {
if (p0.responseCode == BillingClient.BillingResponseCode.OK) {
getAvailableProducts();
} else {
/*
Toast.makeText(
this@SubscriptionActivity,"BillingClient connecting err : " + p0.responseCode,Toast.LENGTH_SHORT
).show()
}
}
})
}
private fun setupInitEvents() {
buttonClose.setonClickListener {
closeActivity()
}
buttonContainer.setonClickListener {
purchase()
}
buttonRestorePurchase.setonClickListener {
restorePurchase()
}
}
private fun closeActivity() {
setResult(Activity.RESULT_CANCELED,null);
finish()
}
private fun purchase() {
if (!SpLaunch.getPurchasetoken().isNullOrEmpty())
{
val builder = AlertDialog.Builder(this)
.setTitle(getString(R.string.restore_title))
.setMessage("Already Purchased")
.setPositiveButton(R.string.ok) { dialog,id ->
}
.create().show()
return
}
if (this::skuList.isInitialized && skuList.size > 0) {
var billingFlowParams = BillingFlowParams.newBuilder()
.setSkuDetails(skuList[0])
.build()
val responseCode = billingClient.launchBillingFlow(this,billingFlowParams).responseCode
} else {
//Toast.makeText(this@SubscriptionActivity,"No Subscription List",Toast.LENGTH_SHORT).show()
}
}
private fun restorePurchase() {
//Toast.makeText(this@SubscriptionActivity,"restorePurchase",Toast.LENGTH_SHORT).show()
if (SpLaunch.getPurchasetoken().isNullOrEmpty())
{
val builder = AlertDialog.Builder(this)
.setTitle(getString(R.string.restore_title))
.setMessage(getString(R.string.restore_message))
.setPositiveButton(R.string.ok) { dialog,id ->
}
.create().show()
} else {
val url = "https://www.googleapis.com/androidpublisher/v3/applications/" + packageName + "/purchases/subscriptions/" + SubscriptionID + "/tokens/" + SpLaunch.getPurchasetoken() + ":refund"
HttpTask({
if (it == null) {
//Toast.makeText(this@SubscriptionActivity,"Connection error",Toast.LENGTH_SHORT).show()
return@HttpTask
}
//Toast.makeText(this@SubscriptionActivity,"refund Success",Toast.LENGTH_SHORT).show()
SpLaunch.setPurchasetoken("")
}).execute("POST",url,"")
}
}
override fun onPurchasesUpdated(p0: BillingResult,p1: MutableList<Purchase>?) {
if (p0.responseCode == BillingClient.BillingResponseCode.OK && p1 != null) {
//Toast.makeText(this@SubscriptionActivity,"Purchase Success",Toast.LENGTH_SHORT).show()
for (_pur in p1) {
var packageName: String = _pur.packageName
var purchasetoken: String = _pur.purchasetoken
var purchaseTime: Long = _pur.purchaseTime
var purchaseState: Int = _pur.purchaseState
SpLaunch.setPurchasePackage(packageName)
SpLaunch.setPurchasetoken(purchasetoken)
SpLaunch.setPurchaseTime(purchaseTime)
SpLaunch.setPurchaseState(purchaseState)
handlePurchase(_pur)
}
setResult(Activity.RESULT_OK,null)
finish()
} else if (p0.responseCode == BillingClient.BillingResponseCode.USER_CANCELED) {
//Toast.makeText(this@SubscriptionActivity,"Purchase canceled by User",Toast.LENGTH_SHORT).show()
setResult(Activity.RESULT_CANCELED,null)
finish()
} else {
//Toast.makeText(this@SubscriptionActivity,"Purchase canceled by Error: " + p0.responseCode,null)
finish()
}
}
private fun handlePurchase(purchase : Purchase)
{
//in handlePurchase()
if (purchase.purchaseState === Purchase.PurchaseState.PURCHASED) {
/*
val ackNowledgePurchaseParams: AckNowledgePurchaseParams =
AckNowledgePurchaseParams.newBuilder()
.setPurchasetoken(purchase.purchasetoken)
.build()
billingClient.ackNowledgePurchase(
ackNowledgePurchaseParams,ackNowledgePurchaseResponseListener
)*/
val params = AckNowledgePurchaseParams.newBuilder()
.setPurchasetoken(purchase.purchasetoken)
.build()
billingClient.ackNowledgePurchase(params) { billingResult ->
val responseCode = billingResult.responseCode
val debugMessage = billingResult.debugMessage
}
}
}
override fun onDestroy() {
super.onDestroy()
billingClient.endConnection()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。