新增Google内购相关代码
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'com.tencent.vasdolly'
|
||||
@@ -228,6 +229,9 @@ dependencies {
|
||||
implementation "io.github.tencent:vap:2.0.24"
|
||||
|
||||
implementation 'com.github.mmin18:realtimeblurview:1.2.1'
|
||||
|
||||
implementation 'com.appsflyer:af-android-sdk:6.2.3'
|
||||
implementation 'com.android.installreferrer:installreferrer:2.2'
|
||||
}
|
||||
|
||||
channel {
|
||||
|
47
app/google-services.json
Normal file
47
app/google-services.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "766987211654",
|
||||
"project_id": "fluid-keyword-363108",
|
||||
"storage_bucket": "fluid-keyword-363108.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:766987211654:android:e22efc16d8ba608189d207",
|
||||
"android_client_info": {
|
||||
"package_name": "com.vele.peko"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "766987211654-2b4de5kbhe7tpgtfto4bjll3dj7ih26u.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "com.vele.peko",
|
||||
"certificate_hash": "a8ac3327a1144cf1b566ca7702338e471f143469"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "766987211654-oe8kjt7rserq31d1rdulqj2aao5b96a7.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyBLTgRb9tTIGjUvIaGl0WoLJjVFSQlEEOA"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "766987211654-oe8kjt7rserq31d1rdulqj2aao5b96a7.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
@@ -51,7 +51,7 @@ class SelectPayTypeDialog : BaseDialog<DialogSelectPayTypeBinding>() {
|
||||
PayModel.get().walletInfo
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe({
|
||||
setWalletData(it)
|
||||
//setWalletData(it)
|
||||
}, {
|
||||
SingleToastUtil.showToast(it.message)
|
||||
it.printStackTrace()
|
||||
@@ -77,37 +77,4 @@ class SelectPayTypeDialog : BaseDialog<DialogSelectPayTypeBinding>() {
|
||||
dismissAllowingStateLoss()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* defaultPay 1:默认支付宝,2:默认微信
|
||||
*/
|
||||
private fun setWalletData(walletInfo: WalletInfo) {
|
||||
binding.rg.visibility = View.VISIBLE
|
||||
when (walletInfo.defaultPay) {
|
||||
ChargeActivity.ALI_PAY_CLOSE -> {
|
||||
payChannel = Constants.CHARGE_ALIPAY
|
||||
removeView = binding.rbAlipay
|
||||
binding.rg.removeView(binding.rbAlipay)
|
||||
binding.rbWechat.isChecked = true
|
||||
binding.tvMore.visibility = View.VISIBLE
|
||||
}
|
||||
ChargeActivity.WX_PAY_CLOSE -> {
|
||||
payChannel = Constants.CHARGE_WX
|
||||
removeView = binding.rbWechat
|
||||
binding.rg.removeView(binding.rbWechat)
|
||||
binding.rbAlipay.isChecked = true
|
||||
binding.tvMore.visibility = View.VISIBLE
|
||||
}
|
||||
ChargeActivity.WX_PAY_OPEN -> {
|
||||
payChannel = Constants.CHARGE_WX
|
||||
binding.rbWechat.isChecked = true
|
||||
binding.rg.removeView(binding.rbAlipay)
|
||||
binding.rg.addView(binding.rbAlipay)
|
||||
}
|
||||
else -> {
|
||||
payChannel = Constants.CHARGE_ALIPAY
|
||||
binding.rbAlipay.isChecked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,15 +1,7 @@
|
||||
package com.yizhuan.erban.pay.presenter;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
|
||||
import com.yizhuan.erban.pay.view.IChargeView;
|
||||
import com.yizhuan.xchat_android_core.pay.PayModel;
|
||||
import com.yizhuan.xchat_android_core.user.UserModel;
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
/**
|
||||
* Created by MadisonRong on 05/01/2018.
|
||||
@@ -26,56 +18,10 @@ public class ChargePresenter extends PayPresenter<IChargeView> {
|
||||
* 加载用户信息(显示用户账号和钱包余额)
|
||||
*/
|
||||
public void loadUserInfo() {
|
||||
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
|
||||
if (userInfo != null) {
|
||||
getMvpView().setupUserInfo(userInfo);
|
||||
}
|
||||
refreshWalletInfo(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取充值产品列表
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
public void getChargeList() {
|
||||
payModel.getChargeList(1,0L)
|
||||
.compose(bindToLifecycle())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(chargeBeans -> {
|
||||
if (chargeBeans != null) {
|
||||
getMvpView().buildChargeList(chargeBeans.getList());
|
||||
} else {
|
||||
getMvpView().getChargeListFail("请求数据为空");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示充值选项(支付宝或者微信)
|
||||
*/
|
||||
public void showChargeOptionsDialog() {
|
||||
getMvpView().displayChargeOptionsDialog();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起充值
|
||||
* @param context context
|
||||
* @param chargeProdId 充值产品 ID
|
||||
* @param payChannel 充值渠道,目前只支持
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
public void requestCharge(Context context, String chargeProdId, String payChannel) {
|
||||
payModel.requestCharge(context, chargeProdId, payChannel)
|
||||
.compose(bindToLifecycle())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(jsonObject -> {
|
||||
if (jsonObject != null) {
|
||||
getMvpView().getChargeOrOrderInfo(jsonObject.toString());
|
||||
} else {
|
||||
getMvpView().getChargeOrOrderInfoFail("请求错误");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,26 +1,11 @@
|
||||
package com.yizhuan.erban.pay.view;
|
||||
|
||||
|
||||
import com.yizhuan.xchat_android_core.pay.bean.ChargeBean;
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by MadisonRong on 05/01/2018.
|
||||
*/
|
||||
|
||||
public interface IChargeView extends IPayView {
|
||||
|
||||
public void setupUserInfo(UserInfo userInfo);
|
||||
|
||||
public void buildChargeList(List<ChargeBean> chargeBeanList);
|
||||
|
||||
public void getChargeListFail(String error);
|
||||
|
||||
public void displayChargeOptionsDialog();
|
||||
|
||||
public void getChargeOrOrderInfo(String data);
|
||||
|
||||
public void getChargeOrOrderInfoFail(String error);
|
||||
}
|
||||
|
242
app/src/main/java/com/yizhuan/erban/ui/pay/BillingManager.java
Normal file
242
app/src/main/java/com/yizhuan/erban/ui/pay/BillingManager.java
Normal file
@@ -0,0 +1,242 @@
|
||||
package com.yizhuan.erban.ui.pay;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.android.billingclient.api.AcknowledgePurchaseParams;
|
||||
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
|
||||
import com.android.billingclient.api.BillingClient;
|
||||
import com.android.billingclient.api.BillingClient.BillingResponseCode;
|
||||
import com.android.billingclient.api.BillingClient.SkuType;
|
||||
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.Purchase.PurchasesResult;
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class BillingManager implements PurchasesUpdatedListener {
|
||||
|
||||
private static final String TAG = "BillingManager";
|
||||
|
||||
/*购买key*/
|
||||
private static final String BASE_64_ENCODED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnagnKdJFBKmp3zb8lmnZfnRcVc7hRf39Zes2YaBQrhNIcesrbtSvV8uCHQrFLan1ekYVPT52mX+AylEvdQ3n5isotS2nfp0jf7l05bJ9bxVKGU7fe2jnT0B+rW2LJpacNzBj/pRDgp1TSN/kl/FI+SXP+jL6f8vhRMwY7GmSvOSHUl/pm8Imi0Se+Y7hBpUtTQioHF0oMiUuNH6vrB/eyx73//thS4D2YylPSN4Q8P4UTLpq4YMCGj8IbY6ZBjDRqGdUfLcb2eU6IRFoyHaBGZWfG/KdrCj1PfnEwh4hIBTBrnZXY1OhPPvztTLVx/sd8iIUX371GJ8GfWfuqvpTXQIDAQAB";
|
||||
|
||||
/*客户端*/
|
||||
private BillingClient billingClient;
|
||||
|
||||
/*活动*/
|
||||
private final Activity mActivity;
|
||||
|
||||
/*监听*/
|
||||
private final BillingUpdatesListener mBillingUpdatesListener;
|
||||
|
||||
/*是否连接成功*/
|
||||
private boolean mIsServiceConnected;
|
||||
|
||||
/*商品列表*/
|
||||
private final List<Purchase> purchaseList = new ArrayList<>();
|
||||
|
||||
/*消耗令牌*/
|
||||
private Set<String> mTokensToBeConsumed;
|
||||
|
||||
/*监听接口*/
|
||||
public interface BillingUpdatesListener {
|
||||
void onBillingClientSetupFinished();
|
||||
|
||||
void onPurchasesUpdated(List<Purchase> purchases);
|
||||
|
||||
void onConsumeFinished(String token, @BillingResponseCode int result);
|
||||
|
||||
void onFailedHandle(@BillingResponseCode int result);
|
||||
}
|
||||
|
||||
public boolean isServiceConnected() {
|
||||
return mIsServiceConnected;
|
||||
}
|
||||
|
||||
public BillingManager(Activity activity, final BillingUpdatesListener updatesListener) {
|
||||
mActivity = activity;
|
||||
mBillingUpdatesListener = updatesListener;
|
||||
billingClient = BillingClient.newBuilder(mActivity).enablePendingPurchases().setListener(this).build();
|
||||
startServiceConnection(() -> {
|
||||
mBillingUpdatesListener.onBillingClientSetupFinished();
|
||||
onQueryPurchases();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/*开始连接Play*/
|
||||
public void startServiceConnection(final Runnable executeOnSuccess) {
|
||||
billingClient.startConnection(new BillingClientStateListener() {
|
||||
@Override
|
||||
public void onBillingSetupFinished(@NotNull BillingResult billingResult) {
|
||||
Log.d(TAG, "Setup finished. Response code: " + billingResult.getDebugMessage() + " code = " + billingResult.getResponseCode());
|
||||
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
|
||||
mIsServiceConnected = true;
|
||||
if (executeOnSuccess != null) {
|
||||
executeOnSuccess.run();
|
||||
}
|
||||
} else {
|
||||
mIsServiceConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBillingServiceDisconnected() {
|
||||
mIsServiceConnected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*请求商品库存*/
|
||||
public void onQueryPurchases() {
|
||||
Runnable queryToExecute = () -> {
|
||||
//系统当前时间
|
||||
long time = System.currentTimeMillis();
|
||||
//请求内购商品
|
||||
PurchasesResult purchasesResult = billingClient.queryPurchases(SkuType.INAPP);
|
||||
onQueryPurchasesFinished(purchasesResult);
|
||||
};
|
||||
executeServiceRequest(queryToExecute);
|
||||
}
|
||||
|
||||
/*请求商品信息完成*/
|
||||
private void onQueryPurchasesFinished(PurchasesResult result) {
|
||||
if (billingClient == null || result.getResponseCode() != BillingResponseCode.OK) {
|
||||
Log.w(TAG, "billingClient is null or result code (" + result.getResponseCode()
|
||||
+ ") was bad - quitting");
|
||||
return;
|
||||
}
|
||||
purchaseList.clear();
|
||||
onPurchasesUpdated(result.getBillingResult(), result.getPurchasesList());
|
||||
}
|
||||
|
||||
/*更新商品*/
|
||||
@Override
|
||||
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
|
||||
//Log.i(TAG, "billingResult.getResponseCode()==" + billingResult.getResponseCode() + ",purchases.size()==" + purchases.size());
|
||||
|
||||
if (billingResult.getResponseCode() == BillingResponseCode.OK) {
|
||||
for (Purchase purchase : purchases) {
|
||||
handlePurchase(purchase);
|
||||
}
|
||||
mBillingUpdatesListener.onPurchasesUpdated(purchaseList);
|
||||
} else {
|
||||
if (billingResult.getResponseCode() == BillingResponseCode.USER_CANCELED) {
|
||||
} else {
|
||||
}
|
||||
mBillingUpdatesListener.onFailedHandle(billingResult.getResponseCode());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*商品处理*/
|
||||
private void handlePurchase(Purchase purchase) {
|
||||
//验证签名数据
|
||||
if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
|
||||
return;
|
||||
}
|
||||
purchaseList.add(purchase);
|
||||
}
|
||||
|
||||
/*验证签名*/
|
||||
private boolean verifyValidSignature(String signedData, String signature) {
|
||||
try {
|
||||
return Security.verifyPurchase(BASE_64_ENCODED_PUBLIC_KEY, signedData, signature);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Got an exception trying to validate a purchase: " + e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*执行服务请求*/
|
||||
private void executeServiceRequest(Runnable runnable) {
|
||||
if (mIsServiceConnected) {
|
||||
runnable.run();
|
||||
} else {
|
||||
startServiceConnection(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
/*查询内购商品详情*/
|
||||
public void querySkuDetailsAsync(@SkuType final String itemType, final List<String> skuList,
|
||||
final SkuDetailsResponseListener listener) {
|
||||
Runnable queryRequest = () -> {
|
||||
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
|
||||
params.setSkusList(skuList)
|
||||
.setType(itemType);
|
||||
billingClient.querySkuDetailsAsync(params.build(), listener);
|
||||
};
|
||||
executeServiceRequest(queryRequest);
|
||||
}
|
||||
|
||||
/*启动购买,订购流程*/
|
||||
public void initiatePurchaseFlow(final SkuDetails skuDetails, String recordId) {
|
||||
Runnable purchaseFlowRequest = () -> {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("p", skuDetails.getPrice());
|
||||
jsonObject.put("a", skuDetails.getPriceAmountMicros() / 10000);
|
||||
jsonObject.put("c", skuDetails.getPriceCurrencyCode());
|
||||
BillingFlowParams purchaseParams = BillingFlowParams.newBuilder()
|
||||
.setObfuscatedAccountId(recordId)
|
||||
.setObfuscatedProfileId(jsonObject.toJSONString())
|
||||
.setSkuDetails(skuDetails)
|
||||
.build();
|
||||
BillingResult billingResult = billingClient.launchBillingFlow(mActivity, purchaseParams);
|
||||
Log.i(TAG, " initiatePurchaseFlow billingResult=" + billingResult.getResponseCode() + " " + billingResult.getDebugMessage());
|
||||
};
|
||||
executeServiceRequest(purchaseFlowRequest);
|
||||
}
|
||||
|
||||
public void consumeAsync(final String purchaseToken) {
|
||||
if (mTokensToBeConsumed == null) {
|
||||
mTokensToBeConsumed = new HashSet<>();
|
||||
} else if (mTokensToBeConsumed.contains(purchaseToken)) {
|
||||
Log.i(TAG, "Token was already scheduled to be consumed - skipping...");
|
||||
return;
|
||||
}
|
||||
mTokensToBeConsumed.add(purchaseToken);
|
||||
|
||||
final ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchaseToken).build();
|
||||
|
||||
final ConsumeResponseListener consumeResponseListener = new ConsumeResponseListener() {
|
||||
@Override
|
||||
public void onConsumeResponse(@NonNull @NotNull BillingResult billingResult, @NonNull @NotNull String s) {
|
||||
mBillingUpdatesListener.onConsumeFinished(purchaseToken, billingResult.getResponseCode());
|
||||
}
|
||||
};
|
||||
executeServiceRequest(() -> billingClient.consumeAsync(consumeParams, consumeResponseListener));
|
||||
}
|
||||
|
||||
|
||||
public void acknowledgePurchase(AcknowledgePurchaseParams acknowledgePurchaseParams, AcknowledgePurchaseResponseListener Listener) {
|
||||
billingClient.acknowledgePurchase(acknowledgePurchaseParams, Listener);
|
||||
}
|
||||
|
||||
/* 释放连接*/
|
||||
public void destroy() {
|
||||
Log.d(TAG, "Destroying the manager.");
|
||||
if (billingClient != null && billingClient.isReady()) {
|
||||
billingClient.endConnection();
|
||||
billingClient = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,504 +1,256 @@
|
||||
package com.yizhuan.erban.ui.pay;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.netease.nim.uikit.StatusBarUtil;
|
||||
import com.android.billingclient.api.BillingClient;
|
||||
import com.android.billingclient.api.Purchase;
|
||||
import com.android.billingclient.api.SkuDetails;
|
||||
import com.appsflyer.AFInAppEventParameterName;
|
||||
import com.appsflyer.AFInAppEventType;
|
||||
import com.appsflyer.AppsFlyerLib;
|
||||
import com.yizhuan.erban.R;
|
||||
import com.yizhuan.erban.base.BaseActivity;
|
||||
import com.yizhuan.erban.base.TitleBar;
|
||||
import com.yizhuan.erban.base.BaseMvpActivity;
|
||||
import com.yizhuan.erban.pay.presenter.ChargePresenter;
|
||||
import com.yizhuan.erban.pay.view.IChargeView;
|
||||
import com.yizhuan.erban.ui.setting.ModifyPwdActivity;
|
||||
import com.yizhuan.erban.ui.webview.CommonWebViewActivity;
|
||||
import com.yizhuan.erban.ui.widget.password.PasswordEvent;
|
||||
import com.yizhuan.xchat_android_core.Constants;
|
||||
import com.yizhuan.xchat_android_core.UriProvider;
|
||||
import com.yizhuan.xchat_android_core.auth.AuthModel;
|
||||
import com.yizhuan.xchat_android_core.bean.response.result.ChargeListResult;
|
||||
import com.yizhuan.xchat_android_core.pay.PayModel;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.ChargeBean;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.WalletInfo;
|
||||
import com.yizhuan.xchat_android_core.pay.event.GetWalletInfoEvent;
|
||||
import com.yizhuan.xchat_android_core.pay.event.UpdateWalletInfoEvent;
|
||||
import com.yizhuan.xchat_android_core.user.UserModel;
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
|
||||
import com.yizhuan.xchat_android_core.utils.CheckUtils;
|
||||
import com.yizhuan.xchat_android_core.utils.net.BeanObserver;
|
||||
import com.yizhuan.xchat_android_core.web.event.WebViewRefreshEvent;
|
||||
import com.yizhuan.xchat_android_library.utils.ListUtils;
|
||||
import com.yizhuan.xchat_android_core.utils.net.IgnoreException;
|
||||
import com.yizhuan.xchat_android_library.base.factory.CreatePresenter;
|
||||
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Map;
|
||||
|
||||
import io.reactivex.SingleObserver;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
/**
|
||||
* 充值界面
|
||||
*
|
||||
* @author zhouxiangfeng
|
||||
* @date 2017/6/19
|
||||
* Created by MadisonRong on 05/01/2018.
|
||||
* 充值页面
|
||||
*/
|
||||
public class ChargeActivity extends BaseActivity {
|
||||
|
||||
public static final int ALI_PAY_CLOSE = 1;
|
||||
public static final int WX_PAY_CLOSE = 2;
|
||||
public static final int ALI_PAY_OPEN = 3;
|
||||
public static final int WX_PAY_OPEN = 4;
|
||||
@CreatePresenter(ChargePresenter.class)
|
||||
public class ChargeActivity extends BaseMvpActivity<IChargeView, ChargePresenter>
|
||||
implements IChargeView, BillingManager.BillingUpdatesListener {
|
||||
private static final String TAG = "ChargeActivity";
|
||||
private final int BINDCODE_GOLD = 200;
|
||||
List<ChargeBean> mBigList;
|
||||
List<ChargeBean> mList;
|
||||
private TextView mTv_gold;
|
||||
private LinearLayout ll_type_first;
|
||||
private ImageView iv_sel_first;
|
||||
private ImageView iv_type_first;
|
||||
private TextView tv_type_first;
|
||||
private LinearLayout ll_type_second;
|
||||
private ImageView iv_sel_second;
|
||||
private ImageView iv_type_second;
|
||||
private TextView tv_type_second;
|
||||
private TextView tvCharge;
|
||||
private RecyclerView mRecyclerView;
|
||||
@BindView(R.id.tv_gold)
|
||||
TextView mTv_gold;
|
||||
@BindView(R.id.iv_back)
|
||||
ImageView ivBack;
|
||||
@BindView(R.id.recyclerView)
|
||||
RecyclerView mRecyclerView;
|
||||
private ChargeAdapter mChargeAdapter;
|
||||
private TextView tvAgreement;
|
||||
private LinearLayout ll_more;
|
||||
private ChargeBean mSelectChargeBean;
|
||||
private int mListSize;
|
||||
private volatile String payChannel = Constants.CHARGE_WX;
|
||||
private boolean mIsFromH5;
|
||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
private final int BINDCODE_GOLD = 200;
|
||||
|
||||
private BillingManager billingManager;
|
||||
|
||||
public static void start(Context context) {
|
||||
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
|
||||
if (context == null || userInfo == null) return;
|
||||
Intent intent = new Intent(context, ChargeActivity.class);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void start(Context context, boolean isFromH5) {
|
||||
UserInfo userInfo = UserModel.get().getCacheLoginUserInfo();
|
||||
if (context == null || userInfo == null) return;
|
||||
Intent intent = new Intent(context, ChargeActivity.class);
|
||||
intent.putExtra("isFromH5", isFromH5);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatMatches")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_charge);
|
||||
initWhiteTitleBar(getString(R.string.label_charge_gold));
|
||||
mTitleBar.setLeftClickListener(v -> finishPage());
|
||||
mTitleBar.addAction(new TitleBar.TextAction("我的收益", getResources().getColor(R.color.color_333333)) {
|
||||
@Override
|
||||
public void performAction(View view) {
|
||||
CommonWebViewActivity.start(ChargeActivity.this,
|
||||
UriProvider.getMyIncomeUrl());
|
||||
}
|
||||
});
|
||||
bindViews();
|
||||
setListener();
|
||||
initiate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initWhiteTitleBar(String title) {
|
||||
mTitleBar = findViewById(R.id.title_bar);
|
||||
if (mTitleBar != null) {
|
||||
mTitleBar.setTitle(title);
|
||||
mTitleBar.setImmersive(false);
|
||||
mTitleBar.setTitleColor(getResources().getColor(R.color.color_333333));
|
||||
mTitleBar.setLeftImageResource(R.drawable.arrow_left);
|
||||
mTitleBar.setCommonBackgroundColor(getResources().getColor(R.color.transparent));
|
||||
mTitleBar.setLeftClickListener(v -> onLeftClickListener());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setListener() {
|
||||
ll_more.setOnClickListener(v -> hideMoreButton());
|
||||
tvCharge.setOnClickListener(v -> {
|
||||
if (mSelectChargeBean == null) return;
|
||||
getDialogManager().showProgressDialog(this, false);
|
||||
});
|
||||
tvAgreement.setOnClickListener(v -> {
|
||||
CommonWebViewActivity.start(this, UriProvider.getRechargeAgreementUrl());
|
||||
});
|
||||
}
|
||||
|
||||
private void hideMoreButton() {
|
||||
ll_more.setVisibility(View.GONE);
|
||||
ll_type_second.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void showMoreButton() {
|
||||
ll_more.setVisibility(View.VISIBLE);
|
||||
ll_type_second.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
private void bindViews() {
|
||||
mTv_gold = findViewById(R.id.tv_gold);
|
||||
ll_type_first = findViewById(R.id.ll_type_first);
|
||||
iv_sel_first = findViewById(R.id.iv_sel_first);
|
||||
iv_type_first = findViewById(R.id.iv_type_first);
|
||||
ll_type_second = findViewById(R.id.ll_type_second);
|
||||
ll_more = findViewById(R.id.ll_more);
|
||||
iv_sel_second = findViewById(R.id.iv_sel_second);
|
||||
tvCharge = findViewById(R.id.tv_charge);
|
||||
tvAgreement = findViewById(R.id.tv_agreement);
|
||||
iv_type_second = findViewById(R.id.iv_type_second);
|
||||
tv_type_first = findViewById(R.id.tv_type_first);
|
||||
tv_type_second = findViewById(R.id.tv_type_second);
|
||||
}
|
||||
|
||||
public void selectPayChannelDisplay(String payChannel, int defaultPay) {
|
||||
this.payChannel = payChannel;
|
||||
boolean selectWeChatPay = (Objects.equals(this.payChannel, Constants.CHARGE_WX));
|
||||
boolean selectAliPay = (Objects.equals(this.payChannel, Constants.CHARGE_ALIPAY));
|
||||
if (!ListUtils.isListEmpty(mBigList)) {
|
||||
if (selectAliPay) {
|
||||
if (mList.size() == mListSize) {
|
||||
for (ChargeBean bigList : mBigList) {
|
||||
mList.add(bigList);
|
||||
}
|
||||
mChargeAdapter.setNewData(mList);
|
||||
mChargeAdapter.notifyDataSetChanged();
|
||||
}
|
||||
} else {
|
||||
if (mList.size() > mListSize) {
|
||||
setItemSelect(0);
|
||||
}
|
||||
for (ChargeBean bigList : mBigList) {
|
||||
mList.remove(bigList);
|
||||
}
|
||||
mChargeAdapter.setNewData(mList);
|
||||
mChargeAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
switch (defaultPay) {
|
||||
case ALI_PAY_CLOSE:
|
||||
case ALI_PAY_OPEN:
|
||||
iv_sel_first.setSelected(selectAliPay);
|
||||
iv_sel_second.setSelected(selectWeChatPay);
|
||||
break;
|
||||
|
||||
case WX_PAY_CLOSE:
|
||||
case WX_PAY_OPEN:
|
||||
iv_sel_first.setSelected(selectWeChatPay);
|
||||
iv_sel_second.setSelected(selectAliPay);
|
||||
break;
|
||||
default:
|
||||
defaultSetPay(selectWeChatPay, selectAliPay);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认选择的支付方式
|
||||
*
|
||||
* @param selectWeChatPay
|
||||
* @param selectAliPay
|
||||
*/
|
||||
private void defaultSetPay(boolean selectWeChatPay, boolean selectAliPay) {
|
||||
iv_sel_first.setSelected(selectWeChatPay);
|
||||
iv_sel_second.setSelected(selectAliPay);
|
||||
}
|
||||
|
||||
private void initiate() {
|
||||
mIsFromH5 = getIntent().getBooleanExtra("isFromH5", false);
|
||||
mRecyclerView = findViewById(R.id.recyclerView);
|
||||
mRecyclerView.setNestedScrollingEnabled(false);
|
||||
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
|
||||
mChargeAdapter = new ChargeAdapter(false);
|
||||
mRecyclerView.setAdapter(mChargeAdapter);
|
||||
mChargeAdapter.setOnItemClickListener((baseQuickAdapter, view, position) -> {
|
||||
setItemSelect(position);
|
||||
// int money = mSelectChargeBean.getMoney();
|
||||
// if (money >= 30000) {
|
||||
// // 大于 3w 的时候,隐藏微信支付的选项
|
||||
// ll_type_first.setVisibility(View.GONE);
|
||||
// // 默认选中支付宝支付的选项
|
||||
// selectPayChannelDisplay(Constants.CHARGE_ALIPAY);
|
||||
// } else {
|
||||
// ll_type_first.setVisibility(View.VISIBLE);
|
||||
// }
|
||||
});
|
||||
onRefreshing();
|
||||
onLoadingData();
|
||||
}
|
||||
|
||||
private void setItemSelect(int position) {
|
||||
List<ChargeBean> list = mChargeAdapter.getData();
|
||||
if (ListUtils.isListEmpty(list)) return;
|
||||
|
||||
// 空对象,不让蒙板遮挡最后一个item;
|
||||
ChargeBean temp = list.get(position);
|
||||
if (TextUtils.isEmpty(temp.getProdName()))
|
||||
return;
|
||||
|
||||
mSelectChargeBean = list.get(position);
|
||||
int size = list.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
list.get(i).isSelected = position == i;
|
||||
}
|
||||
mChargeAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void onLoadingData() {
|
||||
UserInfo userInfos = UserModel.get().getCacheLoginUserInfo();
|
||||
if (userInfos != null) {
|
||||
PayModel.get().getWalletInfo(userInfos.getUid()).subscribe(new SingleObserver<WalletInfo>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {
|
||||
mCompositeDisposable.add(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(WalletInfo walletInfo) {
|
||||
setWalletData(walletInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void onRefreshing() {
|
||||
PayModel.get().getChargeList(1, AuthModel.get().getCurrentUid()).subscribe(new BeanObserver<ChargeListResult>() {
|
||||
@Override
|
||||
public void onSuccess(ChargeListResult chargeBeans) {
|
||||
if (chargeBeans == null) return;
|
||||
mBigList = chargeBeans.getBigList();
|
||||
mList = chargeBeans.getList();
|
||||
mListSize = chargeBeans.getList().size();
|
||||
onGetChargeList(chargeBeans.getList());
|
||||
//默认选中
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onErrorMsg(String error) {
|
||||
onGetChargeListFail(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
ButterKnife.bind(this);
|
||||
EventBus.getDefault().register(this);
|
||||
if (PayModel.get().isFirstChargeSuccess()) {
|
||||
PayModel.get().setFirstChargeSuccess(false);
|
||||
onRefreshing();
|
||||
initViews();
|
||||
initBilling();
|
||||
}
|
||||
|
||||
|
||||
/*初始化*/
|
||||
public void initBilling() {
|
||||
billingManager = new BillingManager(this, this);
|
||||
}
|
||||
|
||||
/*客户端设置成功回调*/
|
||||
@SuppressLint("CheckResult")
|
||||
@Override
|
||||
public void onBillingClientSetupFinished() {
|
||||
Log.i(TAG, "onBillingClientSetupFinished");
|
||||
PayModel.get().getChargeList(4, AuthModel.get().getCurrentUid())
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe(chargeListResult -> initProduceList(chargeListResult.getList()));
|
||||
}
|
||||
|
||||
|
||||
public void initProduceList(List<ChargeBean> chargeBeanList) {
|
||||
|
||||
final List<String> productKeys = new ArrayList<>();
|
||||
for (ChargeBean chargeBean : chargeBeanList) {
|
||||
productKeys.add(chargeBean.getChargeProdId());
|
||||
}
|
||||
|
||||
billingManager.querySkuDetailsAsync(BillingClient.SkuType.INAPP, productKeys, (billingResult, skuDetailsList) -> {
|
||||
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
||||
Log.w(TAG, "Unsuccessful query for type: " + BillingClient.SkuType.INAPP
|
||||
+ ". Error code: " + billingResult.getResponseCode());
|
||||
} else if (skuDetailsList != null && skuDetailsList.size() > 0) {
|
||||
List<ChargeBean> showChargeList = new ArrayList<>();
|
||||
for (ChargeBean chargeBean : chargeBeanList) {
|
||||
for (SkuDetails skuDetails : skuDetailsList) {
|
||||
if (skuDetails.getSku().equals(chargeBean.getChargeProdId())) {
|
||||
chargeBean.setSkuDetails(skuDetails);
|
||||
showChargeList.add(chargeBean);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
mChargeAdapter.setNewData(showChargeList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*商品更新回调*/
|
||||
@SuppressLint("CheckResult")
|
||||
@Override
|
||||
public void onPurchasesUpdated(List<Purchase> purchases) {
|
||||
for (Purchase purchase : purchases) {
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED &&
|
||||
purchase.getAccountIdentifiers() != null) {
|
||||
PayModel.get().verifyOrder(
|
||||
purchase.getAccountIdentifiers().getObfuscatedAccountId(),
|
||||
purchase.getSkus().get(0),
|
||||
purchase.getPackageName(),
|
||||
purchase.getPurchaseToken())
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe(
|
||||
token -> {
|
||||
//L.i("token=" + token);
|
||||
billingManager.consumeAsync(token);
|
||||
|
||||
SkuDetails skuDetails = null;
|
||||
for (ChargeBean datum : mChargeAdapter.getData()) {
|
||||
if (datum.getChargeProdId().equals(purchase.getSkus().get(0))) {
|
||||
skuDetails = datum.getSkuDetails();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skuDetails != null) {
|
||||
Map<String, Object> eventValue = new HashMap<>();
|
||||
eventValue.put(AFInAppEventParameterName.CONTENT_TYPE, "Gold");
|
||||
eventValue.put(AFInAppEventParameterName.QUANTITY, 1);
|
||||
eventValue.put(AFInAppEventParameterName.CONTENT_ID, purchase.getOrderId());
|
||||
eventValue.put(AFInAppEventParameterName.REVENUE, skuDetails.getPriceAmountMicros() / 1000000f);
|
||||
eventValue.put("Price", skuDetails.getPrice());
|
||||
eventValue.put(AFInAppEventParameterName.CURRENCY, skuDetails.getPriceCurrencyCode());
|
||||
AppsFlyerLib.getInstance().logEvent(getApplicationContext(), AFInAppEventType.PURCHASE, eventValue);
|
||||
}
|
||||
|
||||
},
|
||||
throwable -> {
|
||||
if (!(throwable instanceof IgnoreException)) {
|
||||
SingleToastUtil.showToast(throwable.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Log.i(TAG, "onPurchasesUpdated");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
EventBus.getDefault().unregister(this);
|
||||
public void onConsumeFinished(String token, int result) {
|
||||
}
|
||||
|
||||
public void onGetChargeList(List<ChargeBean> chargeBeanList) {
|
||||
if (chargeBeanList != null && chargeBeanList.size() > 0) {
|
||||
//先判断存不存在1元档位
|
||||
boolean isExistOneYuan = false;
|
||||
for (int i = 0; i < chargeBeanList.size(); i++) {
|
||||
ChargeBean chargeBean = chargeBeanList.get(i);
|
||||
if (chargeBean.getMoney() == 1) {
|
||||
isExistOneYuan = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int selectedMoney = isExistOneYuan ? 1 : 6;
|
||||
for (int i = 0; i < chargeBeanList.size(); i++) {
|
||||
ChargeBean chargeBean = chargeBeanList.get(i);
|
||||
chargeBean.isSelected = chargeBean.getMoney() == selectedMoney;
|
||||
if (selectedMoney == chargeBean.getMoney()) {
|
||||
mSelectChargeBean = chargeBean;
|
||||
}
|
||||
}
|
||||
|
||||
// ChargeBean chargeBean = new ChargeBean(0);
|
||||
// chargeBean.setChannel(0);
|
||||
// chargeBean.setChargeProdId(0);
|
||||
// chargeBean.setGiftGoldNum(0);
|
||||
// chargeBean.setProdName("");
|
||||
// chargeBeanList.add(chargeBean);
|
||||
|
||||
mChargeAdapter.setNewData(chargeBeanList);
|
||||
}
|
||||
/*失败处理*/
|
||||
public void onFailedHandle(@BillingClient.BillingResponseCode int result) {
|
||||
}
|
||||
|
||||
public void onGetChargeListFail(String error) {
|
||||
toast(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
getDialogManager().dismissDialog();
|
||||
if (resultCode != RESULT_OK) {
|
||||
return;
|
||||
}
|
||||
if (requestCode == BINDCODE_GOLD) {
|
||||
ModifyPwdActivity.start(this, ModifyPwdActivity.FOGERT_PAY_PWD);
|
||||
}
|
||||
}
|
||||
|
||||
private void disposeCompositeDisposable() {
|
||||
if (compositeDisposable != null && !compositeDisposable.isDisposed()) {
|
||||
compositeDisposable.dispose();
|
||||
/*购买商品*/
|
||||
@SuppressLint("CheckResult")
|
||||
public void buyProduct(SkuDetails skuDetails) {
|
||||
if (skuDetails != null) {
|
||||
Log.d(TAG, "BuyProduct:" + skuDetails.getSku());
|
||||
PayModel.get().placeOrder(skuDetails.getSku())
|
||||
.compose(bindToLifecycle())
|
||||
.subscribe(recordId -> billingManager.initiatePurchaseFlow(skuDetails, recordId.getRecordId()),
|
||||
throwable -> SingleToastUtil.showToast(throwable.getMessage()));
|
||||
} else {
|
||||
Log.w(TAG, "skuDetails ==null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
disposeCompositeDisposable();
|
||||
EventBus.getDefault().unregister(this);
|
||||
if (billingManager != null) {
|
||||
billingManager.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (billingManager != null && billingManager.isServiceConnected()) {
|
||||
billingManager.onQueryPurchases();
|
||||
}
|
||||
getMvpPresenter().loadUserInfo();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
ivBack.setOnClickListener(v -> finish());
|
||||
mRecyclerView.setLayoutManager(new LinearLayoutManager(context));
|
||||
mChargeAdapter = new ChargeAdapter();
|
||||
mRecyclerView.setAdapter(mChargeAdapter);
|
||||
mChargeAdapter.setOnItemClickListener((baseQuickAdapter, view, position) -> {
|
||||
buyProduct(mChargeAdapter.getItem(position).getSkuDetails());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onReloadDate() {
|
||||
getMvpPresenter().loadUserInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupUserWalletBalance(WalletInfo walletInfo) {
|
||||
mTv_gold.setText(Double.toString(walletInfo.getGoldNum()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getUserWalletInfoFail(String error) {
|
||||
toast(error);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
//支付页面返回处理
|
||||
if (requestCode == BINDCODE_GOLD && resultCode == Activity.RESULT_OK) {
|
||||
ModifyPwdActivity.start(this, ModifyPwdActivity.FOGERT_PAY_PWD);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onWalletInfoUpdate(UpdateWalletInfoEvent event) {
|
||||
WalletInfo walletInfo = PayModel.get().getCurrentWalletInfo();
|
||||
if (walletInfo != null) {
|
||||
setWalletData(walletInfo);
|
||||
mTv_gold.setText(String.valueOf(walletInfo.getGoldNum()));
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onGetWalletInfo(GetWalletInfoEvent event) {
|
||||
WalletInfo walletInfo = PayModel.get().getCurrentWalletInfo();
|
||||
if (walletInfo != null) {
|
||||
setWalletData(walletInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* defaultPay 1:默认支付宝,2:默认微信
|
||||
*/
|
||||
private void setWalletData(WalletInfo walletInfo) {
|
||||
if (walletInfo == null) return;
|
||||
mTv_gold.setText(getString(R.string.charge_gold, walletInfo.getDiamondNum()));
|
||||
int defaultPay = walletInfo.getDefaultPay();
|
||||
switch (defaultPay) {
|
||||
case ALI_PAY_CLOSE:
|
||||
payChannel = Constants.CHARGE_ALIPAY;
|
||||
showMoreButton();
|
||||
setAliPayFirst(defaultPay);
|
||||
break;
|
||||
|
||||
case WX_PAY_CLOSE:
|
||||
payChannel = Constants.CHARGE_WX;
|
||||
showMoreButton();
|
||||
setWxPayFirst(defaultPay);
|
||||
break;
|
||||
|
||||
case ALI_PAY_OPEN:
|
||||
payChannel = Constants.CHARGE_ALIPAY;
|
||||
hideMoreButton();
|
||||
setAliPayFirst(defaultPay);
|
||||
break;
|
||||
|
||||
case WX_PAY_OPEN:
|
||||
payChannel = Constants.CHARGE_WX;
|
||||
hideMoreButton();
|
||||
setWxPayFirst(defaultPay);
|
||||
break;
|
||||
default:
|
||||
defaultPay(defaultPay);
|
||||
break;
|
||||
}
|
||||
if (CheckUtils.isCheckUser()) {
|
||||
selectPayChannelDisplay(Constants.CHARGE_ALIPAY, defaultPay);
|
||||
} else {
|
||||
selectPayChannelDisplay(payChannel, defaultPay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认支付方式
|
||||
*
|
||||
* @param defaultPay
|
||||
*/
|
||||
private void defaultPay(int defaultPay) {
|
||||
payChannel = Constants.CHARGE_WX;
|
||||
hideMoreButton();
|
||||
setWxPayFirst(defaultPay);
|
||||
}
|
||||
|
||||
private void setAliPayFirst(int defaultType) {
|
||||
iv_type_first.setImageDrawable(getResources().getDrawable(R.drawable.ic_ali_charge));
|
||||
iv_type_second.setImageDrawable(getResources().getDrawable(R.drawable.ic_wechat_charge));
|
||||
tv_type_first.setText("支付宝");
|
||||
tv_type_second.setText("微信");
|
||||
ll_type_first.setOnClickListener(v -> selectPayChannelDisplay(Constants.CHARGE_ALIPAY, defaultType));
|
||||
ll_type_second.setOnClickListener(v -> selectPayChannelDisplay(Constants.CHARGE_WX, defaultType));
|
||||
if (CheckUtils.isCheckUser()) {
|
||||
ll_type_first.setVisibility(View.VISIBLE);
|
||||
ll_type_second.setVisibility(View.GONE);
|
||||
ll_more.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setWxPayFirst(int defaultType) {
|
||||
iv_type_first.setImageDrawable(getResources().getDrawable(R.drawable.ic_wechat_charge));
|
||||
iv_type_second.setImageDrawable(getResources().getDrawable(R.drawable.ic_ali_charge));
|
||||
tv_type_first.setText("微信");
|
||||
tv_type_second.setText("支付宝");
|
||||
ll_type_first.setOnClickListener(v -> selectPayChannelDisplay(Constants.CHARGE_WX, defaultType));
|
||||
ll_type_second.setOnClickListener(v -> selectPayChannelDisplay(Constants.CHARGE_ALIPAY, defaultType));
|
||||
if (CheckUtils.isCheckUser()) {
|
||||
ll_type_first.setVisibility(View.GONE);
|
||||
ll_type_second.setVisibility(View.VISIBLE);
|
||||
ll_more.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void onGetPassword(PasswordEvent event) {
|
||||
getDialogManager().showProgressDialog(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean needSteepStateBar() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setStatusBar() {
|
||||
super.setStatusBar();
|
||||
StatusBarUtil.transparencyBar(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
finishPage();
|
||||
}
|
||||
|
||||
private void finishPage() {
|
||||
finish();
|
||||
if (!mIsFromH5) return;
|
||||
EventBus.getDefault().post(new WebViewRefreshEvent());
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,9 @@
|
||||
package com.yizhuan.erban.ui.pay;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.netease.nim.uikit.common.util.sys.ScreenUtil;
|
||||
import com.yizhuan.erban.R;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.ChargeBean;
|
||||
|
||||
@@ -18,32 +14,17 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Created by Administrator on 2017/11/20.
|
||||
*/
|
||||
public class ChargeAdapter extends BaseQuickAdapter<ChargeBean, BaseViewHolder> {
|
||||
|
||||
private final boolean isDialogCharge;
|
||||
|
||||
ChargeAdapter(boolean isDialogCharge) {
|
||||
public ChargeAdapter() {
|
||||
super(R.layout.list_item_charge);
|
||||
this.isDialogCharge = isDialogCharge;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(@NotNull BaseViewHolder baseViewHolder, ChargeBean chargeBean) {
|
||||
if (chargeBean == null) return;
|
||||
|
||||
if (isDialogCharge) {
|
||||
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) baseViewHolder.itemView.getLayoutParams();
|
||||
layoutParams.height = ScreenUtil.dip2px(54);
|
||||
baseViewHolder.itemView.setLayoutParams(layoutParams);
|
||||
}
|
||||
|
||||
baseViewHolder.setVisible(R.id.ll_gold_charge, !TextUtils.isEmpty(chargeBean.getProdName()))
|
||||
.setText(R.id.tv_money_gold, chargeBean.prodName.replace("钻石", ""))
|
||||
.setText(R.id.cb_money, mContext.getString(R.string.charge_number, chargeBean.money));
|
||||
|
||||
LinearLayout rl_gold_charge = baseViewHolder.getView(R.id.ll_gold_charge);
|
||||
rl_gold_charge.setSelected(chargeBean.isSelected);
|
||||
|
||||
|
||||
baseViewHolder.setText(R.id.tv_title, chargeBean.getProdName())
|
||||
.setText(R.id.tv_desc, chargeBean.getProdDesc())
|
||||
.setText(R.id.item_charge_money, chargeBean.getSkuDetails().getPrice())
|
||||
.setGone(R.id.tv_desc, !TextUtils.isEmpty(chargeBean.getProdDesc()));
|
||||
}
|
||||
|
||||
}
|
||||
|
69
app/src/main/java/com/yizhuan/erban/ui/pay/Security.java
Normal file
69
app/src/main/java/com/yizhuan/erban/ui/pay/Security.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package com.yizhuan.erban.ui.pay;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.SignatureException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
public class Security {
|
||||
private static final String TAG = "GoogleIap/Security";
|
||||
private static final String KEY_FACTORY_ALGORITHM = "RSA";
|
||||
private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
|
||||
public static boolean verifyPurchase(String base64PublicKey, String signedData,
|
||||
String signature) throws IOException {
|
||||
if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey)
|
||||
|| TextUtils.isEmpty(signature)) {
|
||||
return false;
|
||||
}
|
||||
PublicKey key = generatePublicKey(base64PublicKey);
|
||||
return verify(key, signedData, signature);
|
||||
}
|
||||
|
||||
public static PublicKey generatePublicKey(String encodedPublicKey) throws IOException {
|
||||
try {
|
||||
byte[] decodedKey = Base64.decode(encodedPublicKey, Base64.DEFAULT);
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_FACTORY_ALGORITHM);
|
||||
return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// "RSA" is guaranteed to be available.
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
String msg = "Invalid key specification: " + e;
|
||||
throw new IOException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean verify(PublicKey publicKey, String signedData, String signature) {
|
||||
byte[] signatureBytes;
|
||||
try {
|
||||
signatureBytes = Base64.decode(signature, Base64.DEFAULT);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Signature signatureAlgorithm = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||
signatureAlgorithm.initVerify(publicKey);
|
||||
signatureAlgorithm.update(signedData.getBytes());
|
||||
if (!signatureAlgorithm.verify(signatureBytes)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// "RSA" is guaranteed to be available.
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvalidKeyException e) {
|
||||
} catch (SignatureException e) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@@ -109,7 +109,7 @@ public class JSInterface {
|
||||
@JavascriptInterface
|
||||
public void openChargePage() {
|
||||
if (context != null) {
|
||||
ChargeActivity.start(context, true);
|
||||
ChargeActivity.start(context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,53 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ll_gold_charge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:layout_margin="@dimen/dp_4"
|
||||
android:background="@drawable/selector_gold_price"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginEnd="15dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
android:background="@drawable/bg_secondary_radius_15"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
<ImageView
|
||||
android:layout_width="@dimen/dp_30"
|
||||
android:layout_height="@dimen/dp_30"
|
||||
android:layout_marginStart="@dimen/dp_16"
|
||||
android:src="@drawable/icon_gold" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_charge_diamond" />
|
||||
android:layout_marginStart="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_money_gold"
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="@color/color_333333"
|
||||
android:textSize="14dp"
|
||||
tools:text="8" />
|
||||
android:textSize="20sp"
|
||||
tools:text="400" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_desc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="@dimen/dp_5"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/diamond"
|
||||
android:textColor="@color/text_normal_c6c6e9"
|
||||
android:textSize="@dimen/dp_11"
|
||||
android:visibility="gone" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/tv_title"
|
||||
android:gravity="center"
|
||||
android:maxWidth="120dp"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/color_999999"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone"
|
||||
tools:text="哈哈哈"
|
||||
tools:visibility="visible" />
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cb_money"
|
||||
android:id="@+id/item_charge_money"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/color_999999"
|
||||
android:textSize="12dp"
|
||||
tools:text="¥8元" />
|
||||
android:layout_marginEnd="@dimen/dp_15"
|
||||
android:drawablePadding="2dp"
|
||||
android:gravity="end"
|
||||
android:includeFontPadding="false"
|
||||
android:textColor="#42425B"
|
||||
android:textSize="20sp"
|
||||
tools:text="6" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_buy"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:background="@drawable/common_btn_bg"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:text="购买"
|
||||
android:textColor="#000B22"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@@ -25,6 +25,7 @@ buildscript {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'com.tencent.vasdolly:plugin:3.0.3'
|
||||
classpath "com.mob.sdk:MobSDK:2018.0319.1724"
|
||||
classpath 'com.google.gms:google-services:4.3.8'
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -91,6 +91,15 @@ dependencies {
|
||||
|
||||
api 'com.tencent.bugly:crashreport:4.1.9'
|
||||
|
||||
//firebase推送、统计
|
||||
implementation 'com.google.firebase:firebase-messaging:22.0.0'
|
||||
implementation 'com.google.android.gms:play-services-base:17.6.0'
|
||||
implementation 'com.google.firebase:firebase-core:19.0.0'
|
||||
|
||||
//googleplay内购
|
||||
api 'com.google.android.gms:play-services-wallet:18.1.3'
|
||||
api 'com.android.billingclient:billing:4.0.0'
|
||||
|
||||
api project(':nim_uikit')
|
||||
api project(':library')
|
||||
api project(':trtc_release')
|
||||
|
@@ -265,4 +265,6 @@ public class XChatConstants {
|
||||
(byte) 0x33, (byte) 0x3f, (byte) 0x33, (byte) 0x90, (byte) 0x07, (byte) 0x53, (byte) 0xeb, (byte) 0xd2, (byte) 0xd2,
|
||||
(byte) 0x4e, (byte) 0xc5, (byte) 0xed, (byte) 0xfd, (byte) 0x43
|
||||
};
|
||||
|
||||
public static final int CODE_IGNORE_TOAST = 5263;
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import com.yizhuan.xchat_android_core.bean.response.ServiceResult;
|
||||
import com.yizhuan.xchat_android_core.bean.response.result.ChargeListResult;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.FirstChargeGoods;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.NewUserChargeInfo;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.PayRecordId;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.WalletInfo;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.WxPayType;
|
||||
|
||||
@@ -101,4 +102,12 @@ public interface IPayModel extends IModel {
|
||||
Single<List<FirstChargeGoods>> getFirstChargeList();
|
||||
|
||||
Single<NewUserChargeInfo> getNewUserChargeInfo();
|
||||
|
||||
Single<String> verifyOrder(String chargeRecordId,
|
||||
String googlePlayProdId,
|
||||
String packageName,
|
||||
String purchaseToken);
|
||||
|
||||
Single<PayRecordId> placeOrder(String googlePlayProdId);
|
||||
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ import android.content.Context;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.yizhuan.xchat_android_constants.XChatConstants;
|
||||
import com.yizhuan.xchat_android_core.auth.AuthModel;
|
||||
import com.yizhuan.xchat_android_core.base.BaseModel;
|
||||
import com.yizhuan.xchat_android_core.bean.response.ServiceResult;
|
||||
@@ -15,6 +16,7 @@ import com.yizhuan.xchat_android_core.manager.IMNetEaseManager;
|
||||
import com.yizhuan.xchat_android_core.manager.RoomEvent;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.FirstChargeGoods;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.NewUserChargeInfo;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.PayRecordId;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.WalletInfo;
|
||||
import com.yizhuan.xchat_android_core.pay.bean.WxPayType;
|
||||
import com.yizhuan.xchat_android_core.pay.event.ChargeCustomNotificationEvent;
|
||||
@@ -22,6 +24,7 @@ import com.yizhuan.xchat_android_core.pay.event.FirstRechargeEvent;
|
||||
import com.yizhuan.xchat_android_core.pay.event.GetWalletInfoEvent;
|
||||
import com.yizhuan.xchat_android_core.pay.event.UpdateWalletInfoEvent;
|
||||
import com.yizhuan.xchat_android_core.user.event.LoginUserInfoUpdateEvent;
|
||||
import com.yizhuan.xchat_android_core.utils.net.IgnoreException;
|
||||
import com.yizhuan.xchat_android_core.utils.net.RxHelper;
|
||||
import com.yizhuan.xchat_android_library.net.rxnet.RxNet;
|
||||
import com.yizhuan.xchat_android_library.utils.NetworkUtils;
|
||||
@@ -447,6 +450,32 @@ public class PayModel extends BaseModel implements IPayModel {
|
||||
.compose(RxHelper.handleSchAndExce());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<String> verifyOrder(String chargeRecordId,
|
||||
String googlePlayProdId,
|
||||
String packageName,
|
||||
String purchaseToken) {
|
||||
return api.verifyOrder(chargeRecordId, googlePlayProdId, packageName, purchaseToken)
|
||||
.compose(RxHelper.handleException())
|
||||
.flatMap(result -> {
|
||||
if (result.isSuccess()) {
|
||||
return Single.just(result.getData() == null ? "" : result.getData());
|
||||
}
|
||||
if (result.getCode() == XChatConstants.CODE_IGNORE_TOAST) {
|
||||
return Single.error(new IgnoreException("不需要toast提示的错误"));
|
||||
}
|
||||
return Single.error(new Throwable(result.getMessage()));
|
||||
})
|
||||
.compose(RxHelper.handleSchedulers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Single<PayRecordId> placeOrder(String googlePlayProdId) {
|
||||
return api.placeOrder(googlePlayProdId)
|
||||
.compose(RxHelper.handleBeanData())
|
||||
.compose(RxHelper.handleSchedulers());
|
||||
}
|
||||
|
||||
|
||||
public interface Api {
|
||||
|
||||
@@ -616,6 +645,27 @@ public class PayModel extends BaseModel implements IPayModel {
|
||||
*/
|
||||
@GET("/first/charge/limit/list")
|
||||
Single<ServiceResult<NewUserChargeInfo>> getNewUserChargeInfo();
|
||||
|
||||
/**
|
||||
* 验证googlePlay订单
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@FormUrlEncoded
|
||||
@POST("/googlePlayBilling/verifyOrder")
|
||||
Single<ServiceResult<String>> verifyOrder(@Field("chargeRecordId") String chargeRecordId,
|
||||
@Field("googlePlayProdId") String googlePlayProdId,
|
||||
@Field("packageName") String packageName,
|
||||
@Field("purchaseToken") String purchaseToken);
|
||||
|
||||
/**
|
||||
* googlePlay预下单
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@FormUrlEncoded
|
||||
@POST("/googlePlayBilling/placeOrder")
|
||||
Single<ServiceResult<PayRecordId>> placeOrder(@Field("chargeProdId") String chargeProdId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,5 +1,7 @@
|
||||
package com.yizhuan.xchat_android_core.pay.bean;
|
||||
|
||||
import com.android.billingclient.api.SkuDetails;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
@@ -23,6 +25,7 @@ public class ChargeBean implements Serializable{
|
||||
public int giftGoldNum;
|
||||
public int channel;
|
||||
public String prodDesc;
|
||||
private SkuDetails skuDetails;
|
||||
|
||||
public boolean isSelected;
|
||||
|
||||
@@ -30,17 +33,6 @@ public class ChargeBean implements Serializable{
|
||||
public ChargeBean(int money) {
|
||||
this.money = money;
|
||||
}
|
||||
// public int seqNo;
|
||||
//
|
||||
//
|
||||
// public int getSeqNo() {
|
||||
// return seqNo;
|
||||
// }
|
||||
//
|
||||
// public void setSeqNo(int seqNo) {
|
||||
// this.seqNo = seqNo;
|
||||
// }
|
||||
|
||||
|
||||
public String getChargeProdId() {
|
||||
return chargeProdId;
|
||||
@@ -82,15 +74,40 @@ public class ChargeBean implements Serializable{
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public String getProdDesc() {
|
||||
return prodDesc;
|
||||
}
|
||||
|
||||
public void setProdDesc(String prodDesc) {
|
||||
this.prodDesc = prodDesc;
|
||||
}
|
||||
|
||||
public SkuDetails getSkuDetails() {
|
||||
return skuDetails;
|
||||
}
|
||||
|
||||
public void setSkuDetails(SkuDetails skuDetails) {
|
||||
this.skuDetails = skuDetails;
|
||||
}
|
||||
|
||||
public boolean isSelected() {
|
||||
return isSelected;
|
||||
}
|
||||
|
||||
public void setSelected(boolean selected) {
|
||||
isSelected = selected;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChargeBean{" +
|
||||
"chargeProdId=" + chargeProdId +
|
||||
"chargeProdId='" + chargeProdId + '\'' +
|
||||
", prodName='" + prodName + '\'' +
|
||||
", money=" + money +
|
||||
", giftGoldNum=" + giftGoldNum +
|
||||
", channel=" + channel +
|
||||
", prodDesc='" + prodDesc + '\'' +
|
||||
", skuDetails=" + skuDetails +
|
||||
", isSelected=" + isSelected +
|
||||
'}';
|
||||
}
|
||||
|
@@ -0,0 +1,14 @@
|
||||
package com.yizhuan.xchat_android_core.pay.bean;
|
||||
|
||||
public class PayRecordId {
|
||||
|
||||
private String recordId;
|
||||
|
||||
public String getRecordId() {
|
||||
return recordId;
|
||||
}
|
||||
|
||||
public void setRecordId(String recordId) {
|
||||
this.recordId = recordId;
|
||||
}
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
package com.yizhuan.xchat_android_core.utils.net;
|
||||
|
||||
/**
|
||||
* 可以忽略的异常,比如不弹toast
|
||||
*/
|
||||
|
||||
public class IgnoreException extends Exception {
|
||||
public IgnoreException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user