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();
}
}
}
Google play pay 消耗商品 demo
最新推荐文章于 2024-06-05 09:29:05 发布