删除不用的代码文件
This commit is contained in:
parent
f153b5f34c
commit
9ee96de9fe
@ -1,30 +0,0 @@
|
||||
package com.juzu.dz.message;
|
||||
|
||||
/**
|
||||
* 管理和前端的通信消息以及json字段
|
||||
* */
|
||||
public class BFMessage {
|
||||
// Google登录
|
||||
public static final int GOOGLE_LOGIN_SUCCESS = 1;
|
||||
public static final int GOOGLE_LOGIN_FAILED = 2;
|
||||
// Google登出成功
|
||||
public static final int GOOGLE_LOGOUT_SUCCESS = 3;
|
||||
// Google支付
|
||||
public static final int GOOGLE_PAY_SUCCESS = 4;
|
||||
public static final int GOOGLE_PAY_FAILED = 5;
|
||||
public static final int GOOGLE_PAY_CANCEL = 6;
|
||||
public static final int GOOGLE_CONNECT_SUCCESS = 7;
|
||||
public static final int GOOGLE_CONNECT_FAILED = 8;
|
||||
public static final int QUERY_PRODUCT_SUCCESS = 9;
|
||||
public static final int QUERY_PRODUCT_FAILED = 10;
|
||||
public static final int QUERY_UNCOMPLETE_ORDER_FINISH = 11;
|
||||
// Google消耗
|
||||
public static final int GOOGLE_CONSUME_SUCCESS = 12;
|
||||
public static final int GOOGLE_CONSUME_FAILED = 13;
|
||||
// Google登出失败
|
||||
public static final int GOOGLE_LOGOUT_FAILED = 14;
|
||||
// fireBaseToken
|
||||
public static final int FIREBASE_TOKEN = 15;
|
||||
// Google订阅
|
||||
public static final int QUERY_SUBSCRIBE_FINISH = 16;
|
||||
}
|
||||
@ -1,459 +0,0 @@
|
||||
package com.juzu.dz.third;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.billingclient.api.AccountIdentifiers;
|
||||
import com.android.billingclient.api.AcknowledgePurchaseParams;
|
||||
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
|
||||
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.PurchasesUpdatedListener;
|
||||
import com.android.billingclient.api.SkuDetails;
|
||||
import com.android.billingclient.api.SkuDetailsParams;
|
||||
import com.android.billingclient.api.SkuDetailsResponseListener;
|
||||
import com.juzu.dz.message.BFMessage;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GoogleBilling {
|
||||
private static volatile GoogleBilling sInstance;
|
||||
private static final String LOG_TAG = "GoogleBilling";
|
||||
private static BillingClient mGoogleBillingClient;
|
||||
private Map<String, Purchase> mPurchase = new HashMap<String, Purchase>();
|
||||
private List<SkuDetails> mSubList = new ArrayList<SkuDetails>();
|
||||
private List<SkuDetails> mInAppList = new ArrayList<SkuDetails>();
|
||||
final private static String BASE_64_ENCODED_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm2Vcz26Jz82oYAkr8Wsk0z0hgwBLDRbmnQyARqusiSaJWOt9vEaTgLtLaWYYIiWIeWXUaKq35xDHjC5Xh+KI/pp5N7ck1yB5+lyaSsVD0ESFC/qjDWgElaxxL9QvOyLEHd23q9TmlF1aWziSc6ryFX9HVEGLJT2bTjVEz/bk/WpfN41HZafqQTCIWh8+vRgr0CXa/JEqysjDYRpbaBViPE9F7aTo8lCv/VQpE1ycFiOoaf768aispY5cXb0qP00li95HAI+fEaYgxOuRmN0oc5BFpNRNYTMmRX1Oi5F2vknw+u3+mh+a6GkbwD6FCK+fWIo8hZAWnkULgrxa1ReobQIDAQAB";
|
||||
|
||||
public static GoogleBilling getInstance()
|
||||
{
|
||||
if (sInstance == null) {
|
||||
synchronized (GoogleBilling.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new GoogleBilling();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public void init(Activity activity){
|
||||
mGoogleBillingClient = BillingClient.newBuilder(activity).setListener(payListener).enablePendingPurchases().build();
|
||||
connectGoogleStore();
|
||||
}
|
||||
|
||||
public void connectGoogleStore(){
|
||||
mGoogleBillingClient.startConnection(new BillingClientStateListener() {
|
||||
@Override
|
||||
public void onBillingSetupFinished(BillingResult billingResult) {
|
||||
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONNECT_SUCCESS, "");
|
||||
}else{
|
||||
String msg = billingResult.getDebugMessage();
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONNECT_FAILED, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBillingServiceDisconnected() {
|
||||
String msg = "disconnected";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONNECT_FAILED, msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 查询商品信息,本地化用
|
||||
public void queryProductsInfo(String payType, String productInfoJson){
|
||||
Log.d(LOG_TAG, "google queryProductsInfo info from unity:" + productInfoJson);
|
||||
try {
|
||||
JSONArray array = new JSONArray(productInfoJson);
|
||||
String[] proList = new String[array.length()];
|
||||
for (int i = 0; i < array.length(); i++){
|
||||
proList[i] = (String)array.get(i);
|
||||
}
|
||||
queryProducts(payType, proList);
|
||||
} catch (JSONException e) {
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_PRODUCT_FAILED, e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
//通过商品id查询商品详情
|
||||
private void queryProducts(String payType, String [] products){
|
||||
List<String> pList = Arrays.asList(products);
|
||||
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
|
||||
params.setSkusList(pList).setType(payType);
|
||||
mGoogleBillingClient.querySkuDetailsAsync(params.build(), new SkuDetailsResponseListener() {
|
||||
@Override
|
||||
public void onSkuDetailsResponse(BillingResult billingResult, List<SkuDetails> list) {
|
||||
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK && list != null){
|
||||
Log.d(LOG_TAG, "queryProducts success count:" + list.size());
|
||||
if (list.size() == 0){
|
||||
String msg = "未查询到商品信息,请检查传入的商品id,或者配置是否生效";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_PRODUCT_FAILED, msg);
|
||||
return;
|
||||
}
|
||||
JSONArray array = new JSONArray();
|
||||
List<SkuDetails> mList = new ArrayList<SkuDetails>();
|
||||
for (SkuDetails skuDetails : list) {
|
||||
mList.add(skuDetails);
|
||||
String sku = skuDetails.getSku();
|
||||
String price = skuDetails.getPrice();//实际价格
|
||||
String originPrice = skuDetails.getOriginalPrice();//原价,如果没折扣,原价=实际价格
|
||||
String description = skuDetails.getDescription();
|
||||
String originalJson = skuDetails.getOriginalJson();
|
||||
String title = skuDetails.getTitle();
|
||||
String priceAmountMicros = String.valueOf(skuDetails.getPriceAmountMicros());
|
||||
String currencyCode = skuDetails.getPriceCurrencyCode();
|
||||
JSONObject info = new JSONObject();
|
||||
try {
|
||||
info.put("sku", sku);
|
||||
info.put("price", price);
|
||||
info.put("originPrice", originPrice);
|
||||
info.put("description", description);
|
||||
info.put("originalJson", originalJson);
|
||||
info.put("title", title);
|
||||
info.put("priceCurrencyCode", currencyCode);
|
||||
info.put("priceAmountMicros", priceAmountMicros);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
array.put(info);
|
||||
}
|
||||
if(payType.equals(BillingClient.SkuType.INAPP)){
|
||||
mInAppList = mList;
|
||||
}
|
||||
if(payType.equals(BillingClient.SkuType.SUBS)){
|
||||
mSubList = mList;
|
||||
}
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_PRODUCT_SUCCESS, array.toString());
|
||||
}else{
|
||||
String msg = "queryProducts error:" + billingResult.getResponseCode();
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_PRODUCT_FAILED, msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 支付
|
||||
public void pay(Activity activity, String payType, String productId, String customMsg){
|
||||
List<SkuDetails> skuList = null;
|
||||
if(payType.equals(BillingClient.SkuType.INAPP)){
|
||||
skuList = mInAppList;
|
||||
}
|
||||
if(payType.equals(BillingClient.SkuType.SUBS)){
|
||||
skuList = mSubList;
|
||||
}
|
||||
if (skuList == null || skuList.size() == 0){
|
||||
String msg = "no sku";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
return ;
|
||||
}
|
||||
SkuDetails paySku = null;
|
||||
for (SkuDetails details:skuList){
|
||||
if (TextUtils.equals(productId, details.getSku())){
|
||||
paySku = details;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (paySku == null){
|
||||
String msg = "sku not found! please contact developer";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
return;
|
||||
}
|
||||
// Retrieve a value for "skuDetails" by calling querySkuDetailsAsync().
|
||||
BillingFlowParams flowParams = BillingFlowParams.newBuilder()
|
||||
.setSkuDetails(paySku)
|
||||
.setObfuscatedAccountId(customMsg)
|
||||
.build();
|
||||
BillingResult result = mGoogleBillingClient.launchBillingFlow(activity, flowParams);
|
||||
if (result.getResponseCode() != BillingClient.BillingResponseCode.OK){
|
||||
String msg = "Billing failed: + " + result.getDebugMessage();
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
}
|
||||
}
|
||||
|
||||
private PurchasesUpdatedListener payListener = new PurchasesUpdatedListener() {
|
||||
@Override
|
||||
public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List<Purchase> purchases) {
|
||||
switch (billingResult.getResponseCode()) {
|
||||
case BillingClient.BillingResponseCode.OK:
|
||||
if (null != purchases) {
|
||||
for (Purchase purchase : purchases) {
|
||||
handlePurchase(purchase);
|
||||
}
|
||||
} else {
|
||||
String msg = "Null Purchase List Returned from OK response!";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
}
|
||||
break;
|
||||
case BillingClient.BillingResponseCode.USER_CANCELED:
|
||||
Log.i(LOG_TAG, "onPurchasesUpdated: User canceled the purchase");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_CANCEL, "");
|
||||
break;
|
||||
case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:
|
||||
String msg = "onPurchasesUpdated: The user already owns this item";
|
||||
Log.i(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
break;
|
||||
case BillingClient.BillingResponseCode.DEVELOPER_ERROR:
|
||||
String msg2 = "onPurchasesUpdated: Developer error means that Google Play " +
|
||||
"does not recognize the configuration. If you are just getting started, " +
|
||||
"make sure you have configured the application correctly in the " +
|
||||
"Google Play Console. The SKU product ID must match and the APK you " +
|
||||
"are using must be signed with release keys.";
|
||||
|
||||
Log.e(LOG_TAG, msg2);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg2);
|
||||
break;
|
||||
default:
|
||||
String msg3 = "BillingResult [" + billingResult.getResponseCode() + "]: " + billingResult.getDebugMessage();
|
||||
Log.d(LOG_TAG, msg3);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg3);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void handlePurchase(Purchase purchase) {
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||
// 支付完成
|
||||
if(!purchase.isAcknowledged()){
|
||||
mPurchase.put(purchase.getPurchaseToken(),purchase);
|
||||
}
|
||||
//验证签名
|
||||
String orderId = purchase.getOrderId();
|
||||
String originalJson = purchase.getOriginalJson();
|
||||
String purchaseToken = purchase.getPurchaseToken();
|
||||
ArrayList<String> skus = purchase.getSkus();
|
||||
String signature = purchase.getSignature();
|
||||
AccountIdentifiers accountIdentifiers = purchase.getAccountIdentifiers();
|
||||
String obfuscatedAccountId = accountIdentifiers.getObfuscatedAccountId();
|
||||
boolean succ = verifyValidSignature(originalJson, signature);
|
||||
JSONObject productInfo = new JSONObject();
|
||||
try {
|
||||
productInfo.put("orderId", orderId);
|
||||
productInfo.put("purchaseToken", purchaseToken);
|
||||
productInfo.put("obfuscatedAccountId", obfuscatedAccountId);
|
||||
productInfo.put("signtureFlag", succ + "");
|
||||
if (skus.size() > 0)
|
||||
{
|
||||
productInfo.put("productId", skus.get(0));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_SUCCESS, productInfo.toString());
|
||||
}else{
|
||||
//未付款
|
||||
String msg = "purchase.getPurchaseState() != Purchase.PurchaseState.PURCHASED";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, msg);
|
||||
}
|
||||
}
|
||||
|
||||
//消耗
|
||||
public void consumeAsync(String purchaseToken){
|
||||
Purchase purchase = mPurchase.get(purchaseToken);
|
||||
boolean isSub = false;
|
||||
if(purchase != null){
|
||||
if(mSubList != null){
|
||||
for(SkuDetails Sku:mSubList){
|
||||
for ( String purchaseSku : purchase.getSkus() ) {
|
||||
if (purchaseSku.equals(Sku.getSku())) {
|
||||
isSub = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(isSub){
|
||||
handleSubsPurchase(purchase);
|
||||
}else{
|
||||
final ConsumeParams consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchaseToken)
|
||||
.build();
|
||||
mGoogleBillingClient.consumeAsync(consumeParams, (billingResult, purchaseToken1) -> {
|
||||
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||
Log.d(LOG_TAG, "消耗成功...");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONSUME_SUCCESS, "");
|
||||
} else {
|
||||
Log.d(LOG_TAG, "消耗失败...");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONSUME_FAILED, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSubsPurchase(Purchase purchase) {
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||
if (!purchase.isAcknowledged()) {
|
||||
AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder().setPurchaseToken(purchase.getPurchaseToken())
|
||||
.build();
|
||||
mGoogleBillingClient.acknowledgePurchase(acknowledgePurchaseParams, new AcknowledgePurchaseResponseListener() {
|
||||
@Override
|
||||
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
|
||||
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
|
||||
Log.d(LOG_TAG, "订阅成功...");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONSUME_SUCCESS, "");
|
||||
} else {
|
||||
Log.d(LOG_TAG, "订阅失败...");
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_CONSUME_FAILED, "");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//查询缓存的购买交易
|
||||
public void queryUncompleteOrder(String payType){
|
||||
if (mGoogleBillingClient == null){
|
||||
String msg = "queryPurchases billingClient is null";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_UNCOMPLETE_ORDER_FINISH, "");
|
||||
return;
|
||||
}
|
||||
mGoogleBillingClient.queryPurchasesAsync(payType, (billingResult, list) -> {
|
||||
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
||||
Log.d(LOG_TAG, "Billing client was null or result code is:" + billingResult.getDebugMessage());
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_UNCOMPLETE_ORDER_FINISH, "");
|
||||
} else {
|
||||
//消耗
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (Purchase purchase : list){
|
||||
//商品购买成功,系统还会生成购买令牌,它是一个唯一标识符,表示用户及其所购应用内商品的商品 I
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||
if (!purchase.isAcknowledged()){
|
||||
mPurchase.put(purchase.getPurchaseToken(), purchase);
|
||||
//验证签名
|
||||
String orderId = purchase.getOrderId();
|
||||
String originalJson = purchase.getOriginalJson();
|
||||
String purchaseToken = purchase.getPurchaseToken();
|
||||
ArrayList<String> skus = purchase.getSkus();
|
||||
String signature = purchase.getSignature();
|
||||
AccountIdentifiers accountIdentifiers = purchase.getAccountIdentifiers();
|
||||
String obfuscatedAccountId = accountIdentifiers.getObfuscatedAccountId();
|
||||
JSONObject productInfo = new JSONObject();
|
||||
try {
|
||||
productInfo.put("payType", payType);
|
||||
productInfo.put("orderId", orderId);
|
||||
productInfo.put("purchaseToken", purchaseToken);
|
||||
productInfo.put("obfuscatedAccountId", obfuscatedAccountId);
|
||||
boolean succ = verifyValidSignature(originalJson,signature);
|
||||
productInfo.put("signtureFlag", String.valueOf(succ));
|
||||
productInfo.put("purchaseState", "1");
|
||||
if (skus.size() > 0)
|
||||
{
|
||||
productInfo.put("productId", skus.get(0));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jsonArray.put(productInfo);
|
||||
}
|
||||
}else if (purchase.getPurchaseState() == Purchase.PurchaseState.PENDING){
|
||||
ArrayList<String> skus = purchase.getSkus();
|
||||
JSONObject productInfo = new JSONObject();
|
||||
try {
|
||||
productInfo.put("purchaseState", "2");
|
||||
if (skus.size() > 0)
|
||||
{
|
||||
productInfo.put("productId", skus.get(0));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jsonArray.put(productInfo);
|
||||
}
|
||||
}
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_UNCOMPLETE_ORDER_FINISH, jsonArray.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//查询缓存的訂閲状态
|
||||
public void querySubscribeOrder(String payType) {
|
||||
if (mGoogleBillingClient == null) {
|
||||
String msg = "queryPurchases billingClient is null";
|
||||
Log.d(LOG_TAG, msg);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_SUBSCRIBE_FINISH, "");
|
||||
return;
|
||||
}
|
||||
mGoogleBillingClient.queryPurchasesAsync(payType, (billingResult, list) -> {
|
||||
if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) {
|
||||
Log.d(LOG_TAG, "Billing client was null or result code is:" + billingResult.getDebugMessage());
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_SUBSCRIBE_FINISH, "");
|
||||
} else {
|
||||
//消耗
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (Purchase purchase : list){
|
||||
//商品购买成功,系统还会生成购买令牌,它是一个唯一标识符,表示用户及其所购应用内商品的商品 I
|
||||
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) {
|
||||
String orderId = purchase.getOrderId();
|
||||
String originalJson = purchase.getOriginalJson();
|
||||
String purchaseToken = purchase.getPurchaseToken();
|
||||
ArrayList<String> skus = purchase.getSkus();
|
||||
String signature = purchase.getSignature();
|
||||
AccountIdentifiers accountIdentifiers = purchase.getAccountIdentifiers();
|
||||
String obfuscatedAccountId = accountIdentifiers.getObfuscatedAccountId();
|
||||
JSONObject productInfo = new JSONObject();
|
||||
try {
|
||||
productInfo.put("payType", payType);
|
||||
productInfo.put("orderId", orderId);
|
||||
productInfo.put("purchaseToken", purchaseToken);
|
||||
productInfo.put("obfuscatedAccountId", obfuscatedAccountId);
|
||||
boolean succ = verifyValidSignature(originalJson,signature);
|
||||
productInfo.put("signtureFlag", String.valueOf(succ));
|
||||
productInfo.put("purchaseState", "1");
|
||||
if (skus.size() > 0)
|
||||
{
|
||||
productInfo.put("productId", skus.get(0));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
jsonArray.put(productInfo);
|
||||
}
|
||||
}
|
||||
Log.d(LOG_TAG, "订阅状态查询 " + jsonArray.toString());
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.QUERY_SUBSCRIBE_FINISH, jsonArray.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private boolean verifyValidSignature(String signedData, String signature) {
|
||||
return Security.verifyPurchase(BASE_64_ENCODED_PUBLIC_KEY, signedData, signature);
|
||||
}
|
||||
|
||||
public void onDestroy(){
|
||||
if (mGoogleBillingClient != null && mGoogleBillingClient.isReady()){
|
||||
mGoogleBillingClient.endConnection();
|
||||
mGoogleBillingClient = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,96 +0,0 @@
|
||||
package com.juzu.dz.third;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignIn;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
|
||||
import com.google.android.gms.common.Scopes;
|
||||
import com.google.android.gms.common.api.ApiException;
|
||||
import com.google.android.gms.common.api.Scope;
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.juzu.dz.message.BFMessage;
|
||||
|
||||
public class GoogleLogin {
|
||||
private static volatile GoogleLogin sInstance;
|
||||
private GoogleSignInClient mGoogleSignInClient;
|
||||
private static final int REQUEST_CODE_GOOGLE_SIGN_IN = 1001; /* unique request id */
|
||||
private static final String server_client_token = "526230333982-j465cnveghnr5el3701rtsc38s3l08cg.apps.googleusercontent.com";
|
||||
|
||||
public static GoogleLogin getInstance()
|
||||
{
|
||||
if (sInstance == null) {
|
||||
synchronized (GoogleLogin.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new GoogleLogin();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public void init(Activity activity){
|
||||
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
|
||||
.requestId()
|
||||
.requestIdToken(server_client_token)
|
||||
.requestServerAuthCode(server_client_token)
|
||||
.requestScopes(new Scope(Scopes.PLUS_ME))
|
||||
.build();
|
||||
mGoogleSignInClient = GoogleSignIn.getClient(activity, gso);
|
||||
}
|
||||
|
||||
public void login(Activity activity)
|
||||
{
|
||||
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
|
||||
activity.startActivityForResult(signInIntent, REQUEST_CODE_GOOGLE_SIGN_IN);
|
||||
}
|
||||
|
||||
public void logout(Activity activity)
|
||||
{
|
||||
mGoogleSignInClient.signOut().addOnCompleteListener(activity, new OnCompleteListener<Void>() {
|
||||
@Override
|
||||
public void onComplete(@NonNull Task<Void> task) {
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_LOGOUT_SUCCESS, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if (requestCode == REQUEST_CODE_GOOGLE_SIGN_IN) {
|
||||
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
|
||||
handleSignInResult(task);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSignInResult(Task<GoogleSignInAccount> completedTask) {
|
||||
try {
|
||||
GoogleSignInAccount account = completedTask.getResult(ApiException.class);
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_LOGIN_SUCCESS, createLoginInfo(account));
|
||||
} catch (ApiException e) {
|
||||
GooglePlugin.sendMessageToUnity(BFMessage.GOOGLE_LOGIN_FAILED, "google login failed e:" + e.getStatusCode() + " msg:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String createLoginInfo(GoogleSignInAccount account){
|
||||
String idToken = account.getIdToken();
|
||||
String uid = account.getId();
|
||||
JSONObject result = new JSONObject();
|
||||
try {
|
||||
result.put("Token", idToken);
|
||||
result.put("UserId", uid);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
@ -1,148 +0,0 @@
|
||||
package com.juzu.dz.third;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
// import com.google.firebase.messaging.FirebaseMessaging;
|
||||
import com.juzu.dz.message.BFMessage;
|
||||
import com.unity3d.player.UnityPlayer;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class GooglePlugin {
|
||||
private static final String LOG_TAG = "GooglePlugin";
|
||||
private static GoogleLogin mGoogleLogin = null;
|
||||
private static GoogleBilling mGoogleBilling = null;
|
||||
private static Activity _activity;
|
||||
|
||||
public static void init(Activity activity){
|
||||
_activity = activity;
|
||||
}
|
||||
|
||||
public static void initLogin()
|
||||
{
|
||||
if (mGoogleLogin == null)
|
||||
{
|
||||
mGoogleLogin = GoogleLogin.getInstance();
|
||||
mGoogleLogin.init(_activity);
|
||||
}
|
||||
}
|
||||
|
||||
public static void initBilling()
|
||||
{
|
||||
if (mGoogleBilling == null)
|
||||
{
|
||||
mGoogleBilling = GoogleBilling.getInstance();
|
||||
mGoogleBilling.init(_activity);
|
||||
}
|
||||
}
|
||||
|
||||
// 登录
|
||||
public static void login()
|
||||
{
|
||||
if (mGoogleLogin != null){
|
||||
mGoogleLogin.login(_activity);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_LOGIN_FAILED, "google login failed: not init");
|
||||
}
|
||||
}
|
||||
|
||||
// 登出
|
||||
public static void logout()
|
||||
{
|
||||
if (mGoogleLogin != null){
|
||||
mGoogleLogin.logout(_activity);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_LOGOUT_FAILED, "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void pay(String payType, String productId, String customMsg)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.pay(_activity, payType, productId, customMsg);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_PAY_FAILED, "billing not init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void queryProductsInfo(String payType, String productJson)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.queryProductsInfo(payType, productJson);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.QUERY_PRODUCT_FAILED, "billing not init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void consumeAsync(String purchaseToken)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.consumeAsync(purchaseToken);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_CONSUME_FAILED, "billing not init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void connectGoogleStore()
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.connectGoogleStore();
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.GOOGLE_CONNECT_FAILED, "billing not init");
|
||||
}
|
||||
}
|
||||
|
||||
public static void queryUncompleteOrder(String payType)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.queryUncompleteOrder(payType);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.QUERY_UNCOMPLETE_ORDER_FINISH, "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void querySubscribeOrder(String payType)
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.querySubscribeOrder(payType);
|
||||
}else{
|
||||
sendMessageToUnity(BFMessage.QUERY_SUBSCRIBE_FINISH, "");
|
||||
}
|
||||
}
|
||||
|
||||
public static void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if (mGoogleLogin != null){
|
||||
mGoogleLogin.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
public static void onDestroy()
|
||||
{
|
||||
if (mGoogleBilling != null){
|
||||
mGoogleBilling.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
public static void getFirebaseToken()
|
||||
{
|
||||
}
|
||||
|
||||
public static void sendMessageToUnity(int code, String msg){
|
||||
JSONObject data = new JSONObject();
|
||||
try {
|
||||
data.put("head", code);
|
||||
data.put("body", msg);
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
Log.d(LOG_TAG, code + ":" + msg);
|
||||
UnityPlayer.UnitySendMessage("SDKManager", "MsgFromAndroidOrIOS", data.toString());
|
||||
}
|
||||
}
|
||||
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.juzu.dz.third;
|
||||
/*
|
||||
* This class is an sample of how you can check to make sure your purchases on the device came
|
||||
* from Google Play. Putting code like this on your server will provide additional protection.
|
||||
* <p>
|
||||
* One thing that you may also wish to consider doing is caching purchase IDs to make replay
|
||||
* attacks harder. The reason this code isn't just part of the library is to allow
|
||||
* you to customize it (and rename it!) to make generic patching exploits more difficult.
|
||||
*/
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Security-related methods. For a secure implementation, all of this code should be implemented on
|
||||
* a server that communicates with the application on the device.
|
||||
*/
|
||||
class Security {
|
||||
static final private String TAG = "IABUtil/Security";
|
||||
static final private String KEY_FACTORY_ALGORITHM = "RSA";
|
||||
static final private String SIGNATURE_ALGORITHM = "SHA1withRSA";
|
||||
|
||||
/**
|
||||
* BASE_64_ENCODED_PUBLIC_KEY should be YOUR APPLICATION PUBLIC KEY. You currently get this
|
||||
* from the Google Play developer console under the "Monetization Setup" category in the
|
||||
* Licensing area. This build has been setup so that if you define base64EncodedPublicKey in
|
||||
* your local.properties, it will be echoed into BuildConfig.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Verifies that the data was signed with the given signature
|
||||
*
|
||||
* @param signedData the signed JSON string (signed, not encrypted)
|
||||
* @param signature the signature for the data, signed with the private key
|
||||
*/
|
||||
static public boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
|
||||
if ((TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey)
|
||||
|| TextUtils.isEmpty(signature))
|
||||
) {
|
||||
Log.w(TAG, "Purchase verification failed: missing data.");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
PublicKey key = generatePublicKey(base64PublicKey);
|
||||
return verify(key, signedData, signature);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error generating PublicKey from encoded key: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a PublicKey instance from a string containing the Base64-encoded public key.
|
||||
*
|
||||
* @param encodedPublicKey Base64-encoded public key
|
||||
* @throws IOException if encoding algorithm is not supported or key specification
|
||||
* is invalid
|
||||
*/
|
||||
static private 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;
|
||||
Log.w(TAG, msg);
|
||||
throw new IOException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the signature from the server matches the computed signature on the data.
|
||||
* Returns true if the data is correctly signed.
|
||||
*
|
||||
* @param publicKey public key associated with the developer account
|
||||
* @param signedData signed data from server
|
||||
* @param signature server signature
|
||||
* @return true if the data and signature match
|
||||
*/
|
||||
static private Boolean verify(PublicKey publicKey, String signedData, String signature) {
|
||||
byte[] signatureBytes;
|
||||
try {
|
||||
signatureBytes = Base64.decode(signature, Base64.DEFAULT);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.w(TAG, "Base64 decoding failed.");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Signature signatureAlgorithm = Signature.getInstance(SIGNATURE_ALGORITHM);
|
||||
signatureAlgorithm.initVerify(publicKey);
|
||||
signatureAlgorithm.update(signedData.getBytes());
|
||||
if (!signatureAlgorithm.verify(signatureBytes)) {
|
||||
Log.w(TAG, "Signature verification failed...");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
// "RSA" is guaranteed to be available.
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvalidKeyException e) {
|
||||
Log.e(TAG, "Invalid key specification.");
|
||||
} catch (SignatureException e) {
|
||||
Log.e(TAG, "Signature exception.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user