安卓计费 : How to handle pending purchases

标签 android android-studio android-billing

我最近一直在尝试对我的应用实现 Android 应用内结算。但是当我使用“测试卡:几分钟后拒绝”时,购买被取消需要几个小时(~24 小时)。

我已经阅读了有关 play billing library 的所有文档 https://developer.android.com/google/play/billing/billing_overview并遵循那里的实现。

public class StoreActivity extends AppCompatActivity {

@Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_store);

       ExtendedFloatingActionButton eFabNoAds = findViewById(R.id.efab_no_ads);
        eFabNoAds.setOnClickListener((v) -> {

            BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                    .setSkuDetails(MainActivity.skuDetailsList.get(0)).build();
            MainActivity.billingClient.launchBillingFlow(this, billingFlowParams);

        });

        ExtendedFloatingActionButton eFab20Hints = findViewById(R.id.efab_20hints);
        eFab20Hints.setOnClickListener((v) -> {

            BillingFlowParams billingFlowParams = BillingFlowParams.newBuilder()
                    .setSkuDetails(MainActivity.skuDetailsList.get(1)).build();
            MainActivity.billingClient.launchBillingFlow(this, billingFlowParams);

        });    


}

public class MainActivity extends AppCompatActivity implements PurchasesUpdatedListener

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ....
        setupBillingClient();
    }

...

    private void setupBillingClient() {
        billingClient = BillingClient
                .newBuilder(this)
                .enablePendingPurchases()
                .setListener(this).build();


        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                    Toast.makeText(MainActivity.this, "Success to connect Billing", Toast.LENGTH_SHORT).show();

                    SkuDetailsParams params = SkuDetailsParams.newBuilder()
                            .setSkusList(Arrays.asList("no_ads", "hints"))
                            .setType(BillingClient.SkuType.INAPP)
                            .build();

                    billingClient.querySkuDetailsAsync(params, (billingRes, skuDetailsList) -> {
                        if (billingRes.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                            MainActivity.skuDetailsList = skuDetailsList;


                        }
                    });
                }
            }

            @Override
            public void onBillingServiceDisconnected() {

                billingClient = null;
            }
        });

    }

    @Override
    public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
        //If user clicks TAP-BUY, will retrieve data here
        if (purchases != null) {

            for (Purchase p : purchases) {
                handlePurchase(p);
            }

            Toast.makeText(this, "Purchase item: " + purchases.size(), Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this, "Purchase list empty", Toast.LENGTH_SHORT).show();

        }
    }

    AcknowledgePurchaseResponseListener acknowledgePurchaseResponseListener = new AcknowledgePurchaseResponseListener() {
        @Override
        public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
            Log.i(TAG, billingResult.getDebugMessage());
        }
    };

    ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
        @Override
        public void onConsumeResponse(BillingResult billingResult, String purchaseToken) {
            Log.i(TAG, billingResult.getDebugMessage());

        }
    };


    void handlePurchase(Purchase purchase) {
        if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
            // Grant entitlement to the user.

            // Acknowledge the purchase if it hasn't already been acknowledged.
            if (!purchase.isAcknowledged()) {

                if (purchase.getSku().equals("no_ads")) {
                    AcknowledgePurchaseParams acknowledgePurchaseParams =
                            AcknowledgePurchaseParams.newBuilder()
                                    .setPurchaseToken(purchase.getPurchaseToken())
                                    .build();
                    billingClient.acknowledgePurchase(acknowledgePurchaseParams, acknowledgePurchaseResponseListener);

                } else {

                    ConsumeParams consumeParams = ConsumeParams.newBuilder()
                            .setPurchaseToken(purchase.getPurchaseToken())
                            .build();

                    billingClient.consumeAsync(consumeParams, consumeResponseListener);

                }

            }
        } else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING) {
            // Here you can confirm to the user that they've started the pending
            // purchase, and to complete it, they should follow instructions that
            // are given to them. You can also choose to remind the user in the
            // future to complete the purchase if you detect that it is still
            // pending.

            ////// DO I NEED TO DO ANYTHING HERE? ///// 

        }
    }
}

我希望我的用户能够根据需要购买多少提示。而且我不希望他们等待取消待处理的购买。

有什么方法可以取消待处理的购买吗?或者让用户在下次尝试购买时完成购买?

最佳答案

开发者无法取消挂单。只有用户可以。

如果用户有挂单,那么您可以在调用 queryPurchases() 后得知。您可以检查 purchaseState 和 purchaseState.PENDING 表示用户有待处理的购买。您可以以不同的方式呈现项目按钮以提醒用户完成订单。

关于安卓计费 : How to handle pending purchases,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58067519/

相关文章:

Android InApp Billing v3,谷歌播放对话框未显示

android - native 应用程序直接与数据库对话

安卓 java.net.UnknownHostException

android-studio - 亚马逊火棒有模拟器吗?

android - 磨损项目-attr 'android:windowSwipeToDismiss'

java - 应用内计费V3 : Syncing purchases across devices

android - CalledFromWrongThreadException : Only the original thread that created a view hierarchy can touch views

java - 如何在 Android 中并行运行线程

java - 在 Android Studio 中使用 Gradle 风格

Android 应用内计费 : Can't start launchPurchaseFlow because launchPurchaseFlow is in progress