Google play pay 消耗商品 demo

package cn.nenly.android.clanshelper.activity;

import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.ConsumeParams;
import com.android.billingclient.api.ConsumeResponseListener;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchaseHistoryRecord;
import com.android.billingclient.api.PurchaseHistoryResponseListener;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.callback.StringCallback;
import com.lzy.okgo.model.Response;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import androidx.annotation.Nullable;
import cn.nenly.android.clanshelper.R;
import cn.nenly.android.clanshelper.bean.Order;
import cn.nenly.android.clanshelper.bean.RespBase;
import cn.nenly.android.clanshelper.constant.Config;
import cn.nenly.android.clanshelper.constant.Consts;
import cn.nenly.android.clanshelper.ui.MyDialog;
import cn.nenly.android.clanshelper.utils.CommonUtil;
import cn.nenly.android.clanshelper.utils.MyLog;

public class BuyActivity extends BaseActivity implements View.OnClickListener, PurchasesUpdatedListener {

    private RelativeLayout layoutPay1;
    private TextView tvTime1;
    private TextView tvAmount1;
    private RelativeLayout layoutPay2;
    private TextView tvTime2;
    private TextView tvAmount2;
    private RelativeLayout layoutPay3;
    private TextView tvTime3;
    private TextView tvAmount3;
    private TextView tvPayAmount;
    private TextView tvGoPay;
    private TextView tvEmail;

    private BillingClient billingClient;

    private Map<String, SkuDetails> mapSkuPrice = new HashMap<>();

    private final String PRODUCT_ID_1 = "id_test_001";
    private final String PRODUCT_ID_7 = "id_test_001";
    private final String PRODUCT_ID_30 = "id_test_001";
    private final String PRODUCT_ID_90 = "id_test_001";

    private String mCurrProductId;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_buy);
        initData();
        initView();
        setPay2(true);
        whenSwitchPayType(2);
        sendRequest();
    }

    private void sendRequest() {
        MyLog.print("sendRequest");
        billingClient = BillingClient.newBuilder(this).enablePendingPurchases().setListener(this).build();

        billingClient.startConnection(new BillingClientStateListener() {
            @Override
            public void onBillingSetupFinished(BillingResult billingResult) {
                MyLog.print("billingResult:" + billingResult.getResponseCode() + " debug:" + billingResult.getDebugMessage());
                if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                    // The BillingClient is ready. You can query purchases here.

                    {
                        billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP, new PurchaseHistoryResponseListener() {
                            @Override
                            public void onPurchaseHistoryResponse(BillingResult historyResult, List<PurchaseHistoryRecord> purchaseHistoryRecordList) {
                                MyLog.print("queryPurchase historyResult:" + historyResult.getResponseCode());
                                if (historyResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {

                                } else {
                                    MyLog.e("PurchaseHistory error:" + historyResult.getDebugMessage());
                                }
                                if (purchaseHistoryRecordList != null) {
                                    for (PurchaseHistoryRecord historyRecord : purchaseHistoryRecordList) {
                                        MyLog.print("historyRecord --- sku:" + historyRecord.getSku() + "; getOriginalJson:" + historyRecord.getOriginalJson());
                                        MyLog.print("queryPurchase historyRecord DeveloperPayloa:" + historyRecord.getDeveloperPayload() + "; token:" + historyRecord.getPurchaseToken());

                                        reqConsume(historyRecord.getSku(), historyRecord.getPurchaseToken(), historyRecord.getDeveloperPayload());

                                    }
                                }
                            }
                        });
                    }

                    {
                        List<String> skuList = new ArrayList<>();
                        skuList.add("id_test_001");
                        SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
                        params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
                        billingClient.querySkuDetailsAsync(params.build(),
                                new SkuDetailsResponseListener() {
                                    @Override
                                    public void onSkuDetailsResponse(BillingResult billingResult,
                                                                     List<SkuDetails> skuDetailsList) {
                                        // Process the result.
                                        MyLog.print("billingResult.getResponseCode():" + billingResult.getResponseCode() + "  debug:" + billingResult.getDebugMessage());
                                        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && skuDetailsList != null) {
                                            for (SkuDetails skuDetails : skuDetailsList) {
                                                String sku = skuDetails.getSku();
                                                String price = skuDetails.getPrice();
                                                MyLog.print("sku:" + sku + ", price:" + price);
                                                // id_test_001
                                                mapSkuPrice.put(sku, skuDetails);


                                            }
                                        } else {
                                            Toast.makeText(BuyActivity.this, getString(R.string.conn_server_error), Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                });
                    }
                } else {
                    MyLog.print("getDebugMessage:" + billingResult.getDebugMessage());
                    String msg = getString(R.string.request_product_info_error);
                    Toast.makeText(BuyActivity.this, msg, Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onBillingServiceDisconnected() {
                // Try to restart the connection on the next request to
                // Google Play by calling the startConnection() method.
                Toast.makeText(BuyActivity.this, getString(R.string.network_invalid), Toast.LENGTH_SHORT).show();
            }
        });


    }

    private void reqConsume(String sku, String token, String devPayload) {
        {
            ConsumeParams consumeParams =
                    ConsumeParams.newBuilder()
                            .setPurchaseToken(token)
                            .setDeveloperPayload(devPayload)
                            .build();

            ConsumeResponseListener listener = new ConsumeResponseListener() {
                @Override
                public void onConsumeResponse(BillingResult consumeResult, String outToken) {

                    if (consumeResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
                        // Handle the success of the consume operation.
                        // For example, increase the number of coins inside the user's basket.
                        MyLog.print("消耗成功:" + sku + "outToken:" + outToken);
                    } else {
                        MyLog.e("onConsumeResponse historyResult" + consumeResult.getResponseCode() + "; msg:" + consumeResult.getDebugMessage());
                    }
                }

            };

            billingClient.consumeAsync(consumeParams, listener);

        }
    }

    private void initData() {

    }

    private int mTimeDays;
    private float mPayAmount;

    private void whenSwitchPayType(int type) {
        switch (type) {
            case 1: {
                mTimeDays = 7;
                mPayAmount = 15.0f;
                mCurrProductId = PRODUCT_ID_7;
            }
            break;
            case 2: {
                mTimeDays = 30;
                mPayAmount = 48.0f;
                mCurrProductId = PRODUCT_ID_30;
            }
            break;
            case 3: {
                mTimeDays = 90;
                mPayAmount = 118.0f;
                mCurrProductId = PRODUCT_ID_90;
            }
            break;
        }
        tvPayAmount.setText(String.format(getString(R.string.todo_pay_format), CommonUtil.convertFloat(mPayAmount, 1)));
    }


    @Override
    protected void initView() {
        findViewById(R.id.ivBack).setOnClickListener(this);

        layoutPay1 = findViewById(R.id.layoutPay1);
        tvTime1 = findViewById(R.id.tvTime1);
        tvAmount1 = findViewById(R.id.tvAmount1);
        layoutPay2 = findViewById(R.id.layoutPay2);
        tvTime2 = findViewById(R.id.tvTime2);
        tvAmount2 = findViewById(R.id.tvAmount2);
        layoutPay3 = findViewById(R.id.layoutPay3);
        tvTime3 = findViewById(R.id.tvTime3);
        tvAmount3 = findViewById(R.id.tvAmount3);
        tvPayAmount = findViewById(R.id.tvPayAmount);
        tvGoPay = findViewById(R.id.tvGoPay);
        tvEmail = findViewById(R.id.tvEmail);

        layoutPay1.setOnClickListener(this);
        layoutPay2.setOnClickListener(this);
        layoutPay3.setOnClickListener(this);
        tvGoPay.setOnClickListener(this);


    }

    private void goLogin(final int loginTo) {
        Intent intent = new Intent(this, EmailLoginActivity.class);
        intent.putExtra(Consts.CODE_LOGIN_TO, loginTo);
        startActivity(intent);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tvGoPay: {
                if (Config.getUser() == null || Config.getUser().isRegistered() == false) {
                    goLogin(Consts.CODE_LOGIN_TO_PAY);
                    return;
                }
                if (mPayAmount <= 0) {
                    return;
                }
                if (Config.getUser() == null || TextUtils.isEmpty(Config.getUser().getToken())) {
                    Toast.makeText(BuyActivity.this, R.string.please_relogin, Toast.LENGTH_SHORT).show();
                    Intent intent = new Intent(this, EmailLoginActivity.class);
                    startActivity(intent);
                    return;
                }

                // Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
                SkuDetails skuDetails = mapSkuPrice.get(mCurrProductId);
                if (skuDetails == null) {
                    sendRequest();
                } else {
                    showCircleProgressDialog(false);

                    // {"orderAmount":1,"payChannel":"wx","product":"打鱼助手","time":1}
                    // 469C1B7C483629A1BCC7F9CE11CF1015
                    Order order = new Order();
                    order.setTime(mTimeDays);
                    order.setProductType("DAY");

                    order.setOrderAmount((int) (mPayAmount * 100));
                    order.setPayChannel("GOOGLE_PAY");
                    order.setProduct(getString(R.string.app_name));
                    order.setProductId(mCurrProductId);
                    order.setUserId(Config.getUser().getUid());
                    String token = Config.getUser().getToken();
                    MyLog.print("token:" + token);
                    OkGo.<String>post(Consts.URL_PAYMENT + Consts.URL_CREATE_ORDER).headers("token", token).upJson(JSON.toJSONString(order)).execute(new StringCallback() {
                        @Override
                        public void onSuccess(Response<String> response) {
                            String result = response.body();
                            MyLog.print("result:" + result);
                            dismissCircleProgressDialog();
                            JSONObject jsonObject = JSON.parseObject(result);
                            if (jsonObject.getIntValue("code") == 0) {
                                mOrderNo = jsonObject.getString("data");
                                dismissCircleProgressDialog();
                                {

                                    MyLog.print("mCurrProductId:" + mCurrProductId + "; skuDetails title:" + skuDetails.getTitle() + " desc:" + skuDetails.getDescription() + " price:" + skuDetails.getPrice());
                                    BillingFlowParams flowParams = BillingFlowParams.newBuilder()
                                            .setSkuDetails(skuDetails)
                                            .build();
                                    BillingResult billingResult = billingClient.launchBillingFlow(BuyActivity.this, flowParams);
                                    int responseCode = billingResult.getResponseCode();
                                    MyLog.print("launchBillingFlow responseCode:" + responseCode + "; debug:" + billingResult.getDebugMessage());
                                    if (responseCode != BillingClient.BillingResponseCode.OK) {
                                        if (!TextUtils.isEmpty(billingResult.getDebugMessage())) {
                                            Toast.makeText(BuyActivity.this, billingResult.getDebugMessage(), Toast.LENGTH_SHORT).show();
                                        }
                                    }

                                }
                            } else {
                                hintPayFail();
                            }
                        }

                        @Override
                        public void onError(Response<String> response) {
                            super.onError(response);
                            dismissCircleProgressDialog();
                            hintPayFail();
                        }
                    });

                }

            }
            break;
            case R.id.ivBack: {
                finish();
            }
            break;
            case R.id.layoutPay1: {
                whenSwitchPayType(1);
                setPay1(true);
                setPay2(false);
                setPay3(false);
            }
            break;
            case R.id.layoutPay2: {
                whenSwitchPayType(2);
                setPay1(false);
                setPay2(true);
                setPay3(false);
            }
            break;
            case R.id.layoutPay3: {
                whenSwitchPayType(3);
                setPay1(false);
                setPay2(false);
                setPay3(true);
            }
            break;

        }
    }


    private void hintPayFail() {
        Toast.makeText(BuyActivity.this, R.string.pay_fail_hint, Toast.LENGTH_SHORT).show();
    }

    private String mOrderNo;


    private void hintContactUs() {
        if (this.isFinishing()) {
            return;
        }
        // Toast.makeText(this, R.string.pay_exception_contact_us, Toast.LENGTH_SHORT).show();
        final String serviceEmail = getString(R.string.service_email);
        MyDialog.Builder builder = new MyDialog.Builder(this, true);
        MyDialog dialog = builder.setValue("Pay error occurred", "Sorry, please report us with your register email. We will handle it manually for you.\nOur email address:\n" + serviceEmail, getString(R.string.copy_email), getString(R.string.send_email), true).setClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switch (view.getId()) {
                    case R.id.tvBtnLeft:
                        CommonUtil.copy(getApplicationContext(), serviceEmail);
                        Toast.makeText(BuyActivity.this, getString(R.string.copied), Toast.LENGTH_LONG).show();
                        break;
                    case R.id.tvBtnRight:
                        CommonUtil.copy(getApplicationContext(), serviceEmail);
                        Intent email = new Intent(Intent.ACTION_SEND);
                        email.setType("plain/text");
                        email.putExtra(Intent.EXTRA_EMAIL, new String[]{serviceEmail});
                        email.putExtra(Intent.EXTRA_SUBJECT, "Pay error occurred");
                        email.putExtra(Intent.EXTRA_TEXT, "My register email:" + Config.getUser().getUserName());
                        startActivity(Intent.createChooser(email, "send email"));
                        break;
                }
            }
        }).create();
        dialog.show();
        tvEmail.setVisibility(View.VISIBLE);
        tvEmail.setText("Our Email: " + serviceEmail);
        tvEmail.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                CommonUtil.copy(BuyActivity.this, serviceEmail);
                Toast.makeText(BuyActivity.this, getString(R.string.copied), Toast.LENGTH_LONG).show();
                return true;
            }
        });
    }

    private void setPay1(boolean isSelected) {
        layoutPay1.setSelected(isSelected);
        tvAmount1.setSelected(isSelected);
        tvTime1.setSelected(isSelected);
    }

    private void setPay2(boolean isSelected) {
        layoutPay2.setSelected(isSelected);
        tvAmount2.setSelected(isSelected);
        tvTime2.setSelected(isSelected);
    }

    private void setPay3(boolean isSelected) {
        layoutPay3.setSelected(isSelected);
        tvAmount3.setSelected(isSelected);
        tvTime3.setSelected(isSelected);
    }

    @Override
    public void onPurchasesUpdated(BillingResult billingResult, @Nullable List<Purchase> purchases) {
        MyLog.print("onPurchasesUpdated billingResult: getResponseCode" + billingResult.getResponseCode());
        if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK
                && purchases != null) {
            for (Purchase purchase : purchases) {
                // TODO
                // handlePurchase(purchase);
                // mOrderNo = purchase.getOrderId();
                // purchase.getOriginalJson();
                // purchase.getSignature();
                MyLog.print("mOrderNo:" + mOrderNo + " getSignature:" + purchase.getSignature() + " getOriginalJson:" + purchase.getOriginalJson());

                {
                    reqConsume(purchase.getSku(), purchase.getPurchaseToken(), purchase.getDeveloperPayload());
                }

                String url = Consts.URL_PAYMENT + Consts.URL_PAY_SUCCESS;
                OkGo.<String>get(url).headers("token", Config.getUser().getToken()).params("orderNo", mOrderNo).params("channel", "google_pay").execute(new StringCallback() {
                    @Override
                    public void onSuccess(Response<String> response) {
                        String result = response.body();
                        RespBase respBase = JSON.parseObject(result, RespBase.class);
                        if (respBase.getCode() == 0) {
                            Toast.makeText(BuyActivity.this, R.string.pay_success, Toast.LENGTH_SHORT).show();
                            finish();
                        } else {
                            hintContactUs();
                        }
                    }

                    @Override
                    public void onError(Response<String> response) {
                        super.onError(response);
                        hintContactUs();
                    }
                });
            }
        } else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.USER_CANCELED) {
            // Handle an error caused by a user cancelling the purchase flow.
            Toast.makeText(this, "Pay cancelled", Toast.LENGTH_LONG).show();
        } else {
            // Handle any other error codes.
            Toast.makeText(this, "Sorry, pay error, please retry later", Toast.LENGTH_SHORT).show();
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值