浏览代码

v1.0.0开发:调整华为支付逻辑

#Suyghur 2 年之前
父节点
当前提交
9f49c516fe
共有 22 个文件被更改,包括 489 次插入656 次删除
  1. 1 0
      demo/src/main/kotlin/com/eyuancomm/demo/DemoActivity.kt
  2. 5 7
      demo/src/main/res/values/strings.xml
  3. 2 2
      library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/entity/ChannelId.kt
  4. 1 0
      library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/entity/Function.kt
  5. 5 2
      library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/ext/CountDownTimerExt.kt
  6. 58 26
      library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/impl/CommSdkImpl.kt
  7. 1 1
      library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/internal/feature/IOrder.kt
  8. 1 0
      library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/network/SdkRequest.kt
  9. 4 3
      library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/network/VolleyRequest.kt
  10. 1 1
      library_impl/build.gradle
  11. 2 2
      library_impl/src/main/java/cn/yyxx/eyuancomm/impl/ImplSdkProxy.kt
  12. 4 4
      library_impl/src/main/java/cn/yyxx/eyuancomm/impl/SdkGenerator.kt
  13. 28 9
      library_impl/src/main/java/cn/yyxx/eyuancomm/impl/channel/huawei/ChannelSdkHuawei.kt
  14. 42 89
      library_impl/src/main/java/cn/yyxx/eyuancomm/impl/channel/huawei/HuaweiInAppPay.kt
  15. 1 1
      module_eyuan/library_eyuan/build.gradle
  16. 1 2
      module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/GameSdkImpl.kt
  17. 317 0
      module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/InAppBilling.kt
  18. 0 351
      module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/iab/ChargeImpl.kt
  19. 0 144
      module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/iab/InAppBilling.kt
  20. 6 5
      module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/login/UserSignInImpl.kt
  21. 7 5
      module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/utils/SessionUtils.kt
  22. 2 2
      settings.gradle

+ 1 - 0
demo/src/main/kotlin/com/eyuancomm/demo/DemoActivity.kt

@@ -17,6 +17,7 @@ import cn.yyxx.eyuancomm.comm.EYuanCommSdk
 import cn.yyxx.eyuancomm.comm.entity.SdkChargeInfo
 import cn.yyxx.eyuancomm.comm.entity.SdkRoleInfo
 import cn.yyxx.eyuancomm.comm.internal.ICallback
+import cn.yyxx.eyuancomm.comm.utils.Logger
 import cn.yyxx.support.hawkeye.LogUtils
 import cn.yyxx.support.hawkeye.ToastUtils
 import kotlin.system.exitProcess

+ 5 - 7
demo/src/main/res/values/strings.xml

@@ -1,11 +1,9 @@
 <resources>
-    <!--    <string name="facebook_app_id">265361418929970</string>-->
-    <!--    <string name="fb_login_protocol_scheme">fb265361418929970</string>-->
-    <!--    <string name="facebook_app_id" translatable="false">229604925839347</string>-->
-    <!--    <string name="fb_login_protocol_scheme" translatable="false">fb229604925839347</string>-->
-    <!--    <string name="app_name" translatable="false">EYuanCommSdk-KTX-Oppo</string>-->
-    <!--    <string name="google_app_id">242301350243</string>-->
-    <!--    <string name="google_client_id">242301350243-0qdvdetd5j13movtkvv2cno0jh9843no.apps.googleusercontent.com</string>-->
+<!--    <string name="facebook_app_id">265361418929970</string>-->
+<!--    <string name="fb_login_protocol_scheme">fb265361418929970</string>-->
+<!--    <string name="app_name" translatable="false">EYuanCommSdk-KTX-Huawei</string>-->
+<!--    <string name="google_app_id">242301350243</string>-->
+<!--    <string name="google_client_id">242301350243-0qdvdetd5j13movtkvv2cno0jh9843no.apps.googleusercontent.com</string>-->
 
     <string name="facebook_app_id" translatable="false">229604925839347</string>
     <string name="fb_login_protocol_scheme" translatable="false">fb229604925839347</string>

+ 2 - 2
library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/entity/ChannelId.kt

@@ -6,7 +6,7 @@ package cn.yyxx.eyuancomm.comm.entity
  */
 object ChannelId {
     const val OPPO = "1"
-    const val HUAWEI = "2"
-    const val VIVO = "3"
+    const val VIVO = "2"
+    const val HUAWEI = "3"
     const val EYUANGAME = "4"
 }

+ 1 - 0
library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/entity/Function.kt

@@ -12,6 +12,7 @@ object Function {
     const val LOGIN = "login"
     const val LOGOUT = "logout"
     const val CHARGE = "charge"
+    const val NOTIFY_ORDER = "notifyOrder"
     const val GET_ORDER_EXT = "getOrderExt"
     const val HAS_EXIT_VIEW = "hasExitView"
     const val OPEN_EXIT_VIEW = "openExitView"

+ 5 - 2
library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/ext/CountDownTimerExt.kt

@@ -1,6 +1,9 @@
 package cn.yyxx.eyuancomm.core.ext
 
-import kotlinx.coroutines.*
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
 import kotlinx.coroutines.flow.*
 
 /**
@@ -11,7 +14,7 @@ import kotlinx.coroutines.flow.*
 /**
  * 倒计时
  */
-fun countDownCoroutines(total: Int, onTick: (Int) -> Unit, onFinish: () -> Unit, scope: CoroutineScope = GlobalScope): Job {
+fun countDownCoroutines(total: Int, onTick: (Int) -> Unit, onFinish: () -> Unit, scope: CoroutineScope = CoroutineScope(Dispatchers.IO)): Job {
     return flow {
         for (i in total downTo 0) {
             emit(i)

+ 58 - 26
library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/impl/CommSdkImpl.kt

@@ -6,10 +6,8 @@ import android.content.Context
 import android.content.Intent
 import android.text.TextUtils
 import cn.yyxx.eyuancomm.comm.EYuanCommInstaller
+import cn.yyxx.eyuancomm.comm.entity.*
 import cn.yyxx.eyuancomm.comm.entity.Function
-import cn.yyxx.eyuancomm.comm.entity.SdkChargeInfo
-import cn.yyxx.eyuancomm.comm.entity.SdkLoginInfo
-import cn.yyxx.eyuancomm.comm.entity.SdkRoleInfo
 import cn.yyxx.eyuancomm.comm.internal.ICallback
 import cn.yyxx.eyuancomm.comm.network.SdkRequest
 import cn.yyxx.eyuancomm.comm.utils.Logger
@@ -278,32 +276,39 @@ internal class CommSdkImpl(context: Context) {
         }
 
         showPayLoadingDialog(activity)
-        // 判断渠道
-//        if (channelId == ChannelId.EYUANGAME) {
-//            // 特殊渠道,先调用渠道sdk生成支付扩展参数,在请求生成订单
-//            // 获取拿到channel_ext
-//            SdkProxyManager.call(
-//                Function.GET_ORDER_EXT,
-//                arrayOf(Activity::class.java, SdkChargeInfo::class.java, ICallback::class.java),
-//                arrayOf(activity, chargeInfo, object : ICallback {
-//                    override fun onResult(code: Int, result: String) {
-//                        if (code == 0 && !TextUtils.isEmpty(result)) {
-//                            chargeInfo.channelExt = result
-//                            doCharge(activity, chargeInfo, callback)
-//                        } else {
-//                            dismissPayLoadingDsmiialog(activity)
-//                            callback.onResult(-1, result)
-//                        }
-//                    }
-//                })
-//            )
-//        } else {
-//            doCharge(activity, chargeInfo, callback)
-//        }
-        doCharge(activity, chargeInfo, callback)
+        SdkRequest.instance.createOrder(activity, "", chargeInfo) { resultInfo ->
+            dismissPayLoadingDsmiialog(activity)
+            if (resultInfo.code == 1 && !TextUtils.isEmpty(resultInfo.data)) {
+                val jsonObject = JSONObject(resultInfo.data)
+                chargeInfo.orderId = if (JsonUtils.hasJsonKey(jsonObject, "order_id")) {
+                    jsonObject.getString("order_id")
+                } else {
+                    ""
+                }
+                chargeInfo.channelNotifyUrl = if (JsonUtils.hasJsonKey(jsonObject, "notify_url")) {
+                    jsonObject.getString("notify_url")
+                } else {
+                    ""
+                }
+                chargeInfo.payment = if (JsonUtils.hasJsonKey(jsonObject, "payment")) {
+                    jsonObject.getInt("payment")
+                } else {
+                    1
+                }
+                // 调用渠道sdk支付
+                SdkProxyManager.call(
+                    Function.CHARGE,
+                    arrayOf(Activity::class.java, SdkChargeInfo::class.java, ICallback::class.java),
+                    arrayOf(activity, chargeInfo, callback)
+                )
+            } else {
+                callback.onResult(-1, resultInfo.msg)
+            }
+        }
     }
 
     private fun doCharge(activity: Activity, chargeInfo: SdkChargeInfo, callback: ICallback) {
+        showPayLoadingDialog(activity)
         SdkRequest.instance.createOrder(activity, "", chargeInfo) { resultInfo ->
             dismissPayLoadingDsmiialog(activity)
             if (resultInfo.code == 1 && !TextUtils.isEmpty(resultInfo.data)) {
@@ -335,6 +340,33 @@ internal class CommSdkImpl(context: Context) {
         }
     }
 
+    private fun notifyOrder(activity: Activity, chargeInfo: SdkChargeInfo, callback: ICallback) {
+
+        val channelCallback = object : ICallback {
+            override fun onResult(code: Int, result: String) {
+                if (code == 0 && !TextUtils.isEmpty(result)) {
+                    val jsonObject = JSONObject()
+                    jsonObject.put("order_id", chargeInfo.orderId)
+                    jsonObject.put("order_notify_data", result)
+                    SdkRequest.instance.notifyOrder(activity, jsonObject) { resultInfo ->
+                        if (resultInfo.code == 1) {
+                            // 客户端通知发货成功,支付流程完成
+                            callback.onResult(0, "支付流程完成")
+                        } else {
+                            callback.onResult(-1, "支付失败")
+                        }
+                    }
+                }
+            }
+
+        }
+        SdkProxyManager.call(
+            Function.NOTIFY_ORDER,
+            arrayOf(Activity::class.java, SdkChargeInfo::class.java, ICallback::class.java),
+            arrayOf(activity, chargeInfo, channelCallback)
+        )
+    }
+
     /**
      * SDK角色创建信息上报
      *

+ 1 - 1
library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/internal/feature/IOrder.kt

@@ -13,5 +13,5 @@ interface IOrder {
      * 获取订单号
      * 不是所有渠道都需要自定义获取订单号
      */
-    fun getOrderExt(activity: Activity, chargeInfo: SdkChargeInfo, callback: (Int, String) -> Unit)
+    fun notifyOrder(activity: Activity, chargeInfo: SdkChargeInfo, callback: (Int, String) -> Unit)
 }

+ 1 - 0
library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/network/SdkRequest.kt

@@ -3,6 +3,7 @@ package cn.yyxx.eyuancomm.comm.network
 import android.content.Context
 import cn.yyxx.eyuancomm.comm.entity.ResultInfo
 import cn.yyxx.eyuancomm.comm.entity.SdkChargeInfo
+import cn.yyxx.eyuancomm.comm.utils.Logger
 import org.json.JSONException
 import org.json.JSONObject
 

+ 4 - 3
library_comm/src/main/kotlin/cn/yyxx/eyuancomm/comm/network/VolleyRequest.kt

@@ -17,9 +17,10 @@ import cn.yyxx.support.volley.entity.FileEntity
 import cn.yyxx.support.volley.source.*
 import cn.yyxx.support.volley.source.toolbox.HttpHeaderParser
 import cn.yyxx.support.volley.source.toolbox.JsonObjectRequest
+import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
 import org.json.JSONException
 import org.json.JSONObject
 import java.io.File
@@ -127,9 +128,9 @@ object VolleyRequest {
             override fun deliverResponse(response: ByteArray) {
                 Logger.d("volley download image file success, start to save file ...")
                 try {
-                    GlobalScope.launch(Dispatchers.IO) {
-                        Logger.d("with io coroutines do save file")
+                    runBlocking {
                         FileUtils.saveFile(filePath, response)
+                        cancel()
                     }
                     callback(0, "download file success, path: $filePath")
                 } catch (e: IOException) {

+ 1 - 1
library_impl/build.gradle

@@ -46,6 +46,6 @@ dependencies {
     compileOnly project(':module_eyuan:library_eyuan')
     compileOnly project(':channel_registry:channel_oppo')
     compileOnly project(':channel_registry:channel_vivo')
-    compileOnly project(':channel_registry:channel_huawei')
+    compileOnly project(':channel_registry:channel_huawei2')
 
 }

+ 2 - 2
library_impl/src/main/java/cn/yyxx/eyuancomm/impl/ImplSdkProxy.kt

@@ -53,9 +53,9 @@ class ImplSdkProxy(channelId: String) {
         mImpl?.charge(activity, chargeInfo, callback)
     }
 
-    fun getOrderExt(activity: Activity, chargeInfo: SdkChargeInfo, callback: ICallback) {
+    fun notifyOrder(activity: Activity, chargeInfo: SdkChargeInfo, callback: ICallback) {
         if (mImpl is IOrder) {
-            (mImpl as IOrder).getOrderExt(activity, chargeInfo) { code, result ->
+            (mImpl as IOrder).notifyOrder(activity, chargeInfo) { code, result ->
                 callback.onResult(code, result)
             }
         } else {

+ 4 - 4
library_impl/src/main/java/cn/yyxx/eyuancomm/impl/SdkGenerator.kt

@@ -16,9 +16,9 @@ object SdkGenerator {
     fun getSdkInstance(channelId: String): IFeature? {
         return when (channelId) {
             ChannelId.OPPO -> ChannelSdkOppo()
-            ChannelId.EYUANGAME -> ChannelSdkEYuanGame()
-            ChannelId.HUAWEI -> ChannelSdkHuawei()
             ChannelId.VIVO -> ChannelSdkVivo()
+            ChannelId.HUAWEI -> ChannelSdkHuawei()
+            ChannelId.EYUANGAME -> ChannelSdkEYuanGame()
             else -> null
         }
     }
@@ -26,10 +26,10 @@ object SdkGenerator {
     @JvmStatic
     fun getSdkName(channelId: String): String {
         return when (channelId) {
-            ChannelId.EYUANGAME -> "eyuangame"
             ChannelId.OPPO -> "oppo"
-            ChannelId.HUAWEI -> "huawei"
             ChannelId.VIVO -> "vivo"
+            ChannelId.HUAWEI -> "huawei"
+            ChannelId.EYUANGAME -> "eyuangame"
             else -> ""
         }
     }

+ 28 - 9
library_impl/src/main/java/cn/yyxx/eyuancomm/impl/channel/huawei/ChannelSdkHuawei.kt

@@ -15,6 +15,7 @@ import cn.yyxx.eyuancomm.comm.internal.feature.IApplication
 import cn.yyxx.eyuancomm.comm.internal.feature.IFeature
 import cn.yyxx.eyuancomm.comm.internal.feature.IFloatBall
 import cn.yyxx.eyuancomm.comm.internal.feature.ILifeCycle
+import cn.yyxx.eyuancomm.comm.network.SdkRequest
 import cn.yyxx.eyuancomm.comm.utils.Logger
 import cn.yyxx.eyuancomm.comm.widget.ScaleLoadingDialog
 import cn.yyxx.eyuancomm.impl.channel.huawei.floatview.FloatBall
@@ -23,7 +24,6 @@ import cn.yyxx.eyuancomm.impl.channel.huawei.floatview.FloatCenterServiceManager
 import cn.yyxx.eyuancomm.impl.channel.huawei.floatview.FloatFeature
 import cn.yyxx.support.ResUtils
 import cn.yyxx.support.hawkeye.ToastUtils
-
 import com.huawei.agconnect.AGCRoutePolicy
 import com.huawei.agconnect.AGConnectInstance
 import com.huawei.agconnect.AGConnectOptionsBuilder
@@ -183,8 +183,6 @@ class ChannelSdkHuawei : IFeature, IApplication, ILifeCycle, IFloatBall {
             // showFloatWindowNewWay();
             // 必须在init成功后,才可以实现登录功能
             // signIn();
-            Logger.d("Sdk init on success")
-
             AGConnectApi.getInstance().activityLifecycle().onCreate(activity)
 
             buoyClient = Games.getBuoyClient(activity)
@@ -198,12 +196,10 @@ class ChannelSdkHuawei : IFeature, IApplication, ILifeCycle, IFloatBall {
                 loginCallback.onResult(0, jsonObject.toString())
             }
             FloatCenterServiceManager.instance.init(activity, isLandscape, floatBallCallback)
-
-            callback.onResult(0, "Sdk初始化成功")
+            callback.onResult(0, "SDK初始化成功")
         }.addOnFailureListener { e ->
-            Logger.d("Sdk init on failure")
+            Logger.d("华为SDK初始化失败, ${e.message}")
             if (e is ApiException) {
-                Logger.d("Sdk init on failure, code: ${e.statusCode}, msg: ${e.localizedMessage}")
                 when (e.statusCode) {
                     JosStatusCodes.JOS_PRIVACY_PROTOCOL_REJECTED -> {
                         // 错误码为7401时表示用户未同意华为联运隐私协议
@@ -218,7 +214,6 @@ class ChannelSdkHuawei : IFeature, IApplication, ILifeCycle, IFloatBall {
                         // 此处您可提示玩家检查网络,请不要重复调用init接口,否则断网情况下可能会造成手机高耗电。
                         Logger.e("Network error")
                     }
-
                     else -> {
                         // 在此处实现其他错误码的处理
                     }
@@ -260,9 +255,33 @@ class ChannelSdkHuawei : IFeature, IApplication, ILifeCycle, IFloatBall {
 
     override fun charge(activity: Activity, chargeInfo: SdkChargeInfo, callback: ICallback) {
         this.activity = activity
+        showLoadingDialog(activity)
         HuaweiInAppPay.instance.charge(activity, chargeInfo, object : HuaweiInAppPay.InAppPayCallback {
             override fun onResult(code: Int, result: String) {
-                callback.onResult(code, result)
+                if (code == 0 || code == 1) {
+                    val jsonObject = JSONObject(result)
+                    SdkRequest.instance.notifyOrder(activity, jsonObject) { resultInfo ->
+                        if (resultInfo.code == 1 || resultInfo.code == -3) {
+                            if (code == 0) {
+                                dismissLoadingDialog()
+                                Logger.d("支付流程完成")
+                                callback.onResult(0, "支付流程完成")
+                            } else {
+                                Logger.d("重新消耗成功,继续发起支付")
+                                HuaweiInAppPay.instance.obtainProductInfo(activity, chargeInfo)
+                            }
+                        } else {
+                            // 消耗失败
+                            dismissLoadingDialog()
+                            Logger.d("通知发货发生异常")
+                            callback.onResult(-1, "通知发货发生异常")
+                        }
+                    }
+                } else {
+                    dismissLoadingDialog()
+                    Logger.d("支付发生异常")
+                    callback.onResult(-1, "通知发货发生异常")
+                }
             }
         })
     }

+ 42 - 89
library_impl/src/main/java/cn/yyxx/eyuancomm/impl/channel/huawei/HuaweiInAppPay.kt

@@ -1,14 +1,10 @@
 package cn.yyxx.eyuancomm.impl.channel.huawei
 
 import android.app.Activity
-import android.content.Context
 import android.content.Intent
 import android.content.IntentSender
-import cn.yyxx.eyuancomm.comm.entity.ResultInfo
 import cn.yyxx.eyuancomm.comm.entity.SdkChargeInfo
-import cn.yyxx.eyuancomm.comm.network.SdkRequest
 import cn.yyxx.eyuancomm.comm.utils.Logger
-import cn.yyxx.eyuancomm.comm.widget.ScaleLoadingDialog
 import cn.yyxx.support.JsonUtils
 import com.huawei.hms.iap.Iap
 import com.huawei.hms.iap.IapApiException
@@ -25,8 +21,7 @@ import org.json.JSONObject
  */
 internal class HuaweiInAppPay {
 
-    private var loadingDialog: ScaleLoadingDialog? = null
-    private var callback: InAppPayCallback? = null
+    private lateinit var callback: InAppPayCallback
 
     companion object {
         val instance: HuaweiInAppPay by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
@@ -35,14 +30,12 @@ internal class HuaweiInAppPay {
     }
 
     fun charge(activity: Activity, chargeInfo: SdkChargeInfo, callback: InAppPayCallback) {
-        showLoadingDialog(activity)
         this.callback = callback
         Iap.getIapClient(activity).isEnvReady.addOnSuccessListener {
             // 获取接口请求的结果
-//            obtainProductInfo(activity, chargeInfo, callback)
             obtainOwnedPurchases(activity, chargeInfo)
         }.addOnFailureListener { e ->
-            dismissLoadingDialog()
+            e.log()
             if (e is IapApiException) {
                 val status: Status = e.status
                 when (status.statusCode) {
@@ -61,15 +54,18 @@ internal class HuaweiInAppPay {
                     OrderStatusCode.ORDER_ACCOUNT_AREA_NOT_SUPPORTED -> {
                         // 用户当前登录的华为帐号所在的服务地不在华为IAP支持结算的国家/地区中
                         Logger.e("用户当前登录的华为帐号所在的服务地不在华为IAP支持结算的国家/地区中")
+                        callback.onResult(-1, "用户当前登录的华为帐号所在的服务地不在华为IAP支持结算的国家/地区中")
                     }
                     else -> {
                         // 其他外部错误
                         Logger.e("其他外部错误")
+                        callback.onResult(-1, "其他外部错误")
                     }
                 }
             } else {
                 // 其他外部错误
                 Logger.e("其他外部错误")
+                callback.onResult(-1, "其他外部错误")
             }
         }
     }
@@ -91,31 +87,27 @@ internal class HuaweiInAppPay {
                 // 永远保持只有一笔未消耗订单
                 val purchaseData = result.inAppPurchaseDataList[0]
                 val signature = result.inAppSignature[0]
-                notifyOrder2Backend(activity, purchaseData, signature) { resultInfo ->
-                    dismissLoadingDialog()
-                    if (resultInfo.code == 1) {
-                        // 重新消耗成功,继续发起支付
-                        obtainProductInfo(activity, chargeInfo)
+                val jsonObject = JSONObject()
+                with(JSONObject(purchaseData)) {
+                    if (JsonUtils.hasJsonKey(this, "developerPayload")) {
+                        jsonObject.put("order_id", getString("developerPayload"))
                     } else {
-                        // 消耗失败
-                        callback?.onResult(-1, "obtainOwnedPurchases: 支付发生异常")
+                        jsonObject.put("order_id", "")
                     }
+                    val notifyData = JSONObject()
+                    notifyData.put("purchase_data", purchaseData)
+                    notifyData.put("signature", signature)
+                    jsonObject.put("order_notify_data", notifyData.toString())
                 }
+                callback.onResult(1, jsonObject.toString())
             }
         }.addOnFailureListener { e ->
-            dismissLoadingDialog()
-            callback?.onResult(-1, "obtainOwnedPurchases: 支付发生异常")
-            if (e is IapApiException) {
-                val apiException = e as IapApiException
-                val status: Status = apiException.status
-                val returnCode = apiException.statusCode
-            } else {
-                // 其他外部错误
-            }
+            e.log()
+            callback.onResult(-1, "查询未消耗订单异常")
         }
     }
 
-    private fun obtainProductInfo(activity: Activity, chargeInfo: SdkChargeInfo) {
+    fun obtainProductInfo(activity: Activity, chargeInfo: SdkChargeInfo) {
         val productIdList: MutableList<String> = ArrayList()
         // 查询的商品必须是您在AppGallery Connect网站配置的商品
         productIdList.add(chargeInfo.productId)
@@ -129,15 +121,8 @@ internal class HuaweiInAppPay {
             // 获取接口请求成功时返回的商品详情信息
             createPurchaseIntent(activity, chargeInfo)
         }.addOnFailureListener { e ->
-            dismissLoadingDialog()
-            Logger.e(e.localizedMessage)
-            callback?.onResult(-1, "obtainProductInfo: 支付发生异常")
-            if (e is IapApiException) {
-                val apiException = e as IapApiException
-                val returnCode = apiException.statusCode
-            } else {
-                // 其他外部错误
-            }
+            e.log()
+            callback.onResult(-1, "查询商品信息发生异常")
         }
     }
 
@@ -158,39 +143,16 @@ internal class HuaweiInAppPay {
                     // 启动IAP返回的收银台页面
                     result.status.startResolutionForResult(activity, 8888)
                 } catch (exp: IntentSender.SendIntentException) {
-                    callback?.onResult(-1, "支付发生异常")
+                    callback.onResult(-1, "调用支付接口异常")
                 }
             } else {
-                callback?.onResult(-1, "支付发生异常")
+                callback.onResult(-1, "调用支付接口异常")
             }
         }.addOnFailureListener { e ->
-            dismissLoadingDialog()
-            Logger.d(e.localizedMessage)
-            callback?.onResult(-1, "createPurchaseIntent: 支付发生异常")
-            if (e is IapApiException) {
-                val apiException = e as IapApiException
-                val status: Status = apiException.status
-                val returnCode = apiException.statusCode
-            } else {
-                // 其他外部错误
-            }
-        }
-    }
-
-    private fun notifyOrder2Backend(activity: Activity, purchaseData: String, signature: String, onResponse: (ResultInfo) -> Unit) {
-        val jsonObject = JSONObject()
-        with(JSONObject(purchaseData)) {
-            if (JsonUtils.hasJsonKey(this, "developerPayload")) {
-                jsonObject.put("order_id", getString("developerPayload"))
-            } else {
-                jsonObject.put("order_id", "")
-            }
-            val notifyData = JSONObject()
-            notifyData.put("purchase_data", purchaseData)
-            notifyData.put("signature", signature)
-            jsonObject.put("order_notify_data", notifyData.toString())
+//            dismissLoadingDialog()
+            e.log()
+            callback.onResult(-1, "调用支付接口异常")
         }
-        SdkRequest.instance.notifyOrder(activity, jsonObject, onResponse)
     }
 
     fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
@@ -202,52 +164,43 @@ internal class HuaweiInAppPay {
                 val purchaseResultInfo = Iap.getIapClient(activity).parsePurchaseResultInfoFromIntent(data)
                 when (purchaseResultInfo.returnCode) {
                     OrderStatusCode.ORDER_STATE_CANCEL -> {
-                        Logger.d("cancel")
-                        dismissLoadingDialog()
-                        callback?.onResult(-1, "支付发生异常")
+                        callback.onResult(-1, "取消支付")
                     }
                     OrderStatusCode.ORDER_STATE_FAILED, OrderStatusCode.ORDER_PRODUCT_OWNED, OrderStatusCode.ORDER_STATE_DEFAULT_CODE -> {
-                        dismissLoadingDialog()
-                        callback?.onResult(-1, "支付发生异常")
+                        callback.onResult(-1, "支付发生异常")
                     }
                     OrderStatusCode.ORDER_STATE_SUCCESS -> {
                         // 支付成功
+                        Logger.d("支付成功")
                         with(purchaseResultInfo) {
                             // consumeOwnedPurchase(activity, inAppPurchaseData, inAppDataSignature)
                             // 通知服务端支付流程完成,验证订单并确认交易
-                            notifyOrder2Backend(activity, inAppPurchaseData, inAppDataSignature) { resultInfo ->
-                                dismissLoadingDialog()
-                                if (resultInfo.code == 1) {
-                                    callback?.onResult(0, "支付流程完成")
+                            val jsonObject = JSONObject()
+                            with(JSONObject(inAppPurchaseData)) {
+                                if (JsonUtils.hasJsonKey(this, "developerPayload")) {
+                                    jsonObject.put("order_id", getString("developerPayload"))
                                 } else {
-                                    callback?.onResult(-1, "支付发生异常")
+                                    jsonObject.put("order_id", "")
                                 }
+                                val notifyData = JSONObject()
+                                notifyData.put("purchase_data", inAppPurchaseData)
+                                notifyData.put("signature", inAppDataSignature)
+                                jsonObject.put("order_notify_data", notifyData.toString())
                             }
+                            callback.onResult(0, jsonObject.toString())
                         }
                     }
                     else -> {
-                        dismissLoadingDialog()
-                        callback?.onResult(-1, "支付发生异常")
+//                        dismissLoadingDialog()
+                        callback.onResult(-1, "解析支付结果异常")
                     }
                 }
             }
         }
     }
 
-    private fun showLoadingDialog(context: Context) {
-        loadingDialog?.apply {
-            dismiss()
-            loadingDialog = null
-        }
-        loadingDialog = ScaleLoadingDialog(context, "")
-        loadingDialog?.show()
-    }
-
-    private fun dismissLoadingDialog() {
-        loadingDialog?.apply {
-            dismiss()
-            loadingDialog = null
-        }
+    private fun Exception.log() {
+        Logger.d("华为支付发生异常, msg: $message")
     }
 
 

+ 1 - 1
module_eyuan/library_eyuan/build.gradle

@@ -70,7 +70,7 @@ dependencies {
     implementation 'com.google.android.play:core:1.10.3'
     implementation 'com.google.android.gms:play-services-auth:20.1.0'
     //4.0.0的billing库消耗商品会回调两次,后续在排查,先用3.0.3
-    implementation "com.android.billingclient:billing-ktx:3.0.3"
+    implementation 'com.android.billingclient:billing-ktx:3.0.3'
     implementation 'com.google.firebase:firebase-analytics-ktx:20.1.0'
     implementation 'com.google.firebase:firebase-crashlytics-ktx:18.2.8'
 

+ 1 - 2
module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/GameSdkImpl.kt

@@ -14,7 +14,6 @@ import cn.yyxx.eyuancomm.core.entity.SdkEvent
 import cn.yyxx.eyuancomm.core.entity.bean.init.InitBean
 import cn.yyxx.eyuancomm.core.impl.center.HybridFeatureContainer
 import cn.yyxx.eyuancomm.core.impl.floatball.FloatCenterServiceManager
-import cn.yyxx.eyuancomm.core.impl.iab.ChargeImpl
 import cn.yyxx.eyuancomm.core.impl.login.LoginActivity
 import cn.yyxx.eyuancomm.core.impl.share.ShareImpl
 import cn.yyxx.eyuancomm.core.network.SdkRequest
@@ -135,7 +134,7 @@ class GameSdkImpl {
             callback(-1, "支付失败,支付信息对象拷贝过程异常")
             return
         }
-        ChargeImpl.instance.charge(activity, innerChargeInfo) { code, result ->
+        InAppBilling.instance.charge(activity, innerChargeInfo) { code, result ->
             when (code) {
                 0 -> {
                     TraceEventManager.instance.charge(activity, innerChargeInfo)

+ 317 - 0
module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/InAppBilling.kt

@@ -0,0 +1,317 @@
+package cn.yyxx.eyuancomm.core.impl
+
+import android.app.Activity
+import android.text.TextUtils
+import cn.yyxx.eyuancomm.comm.entity.SdkChargeInfo
+import cn.yyxx.eyuancomm.comm.network.SdkRequest
+import cn.yyxx.eyuancomm.comm.utils.Logger
+import cn.yyxx.eyuancomm.comm.utils.MMKVHandler
+import cn.yyxx.support.ResUtils
+import cn.yyxx.support.hawkeye.ToastUtils
+import com.android.billingclient.api.*
+import com.google.android.gms.common.ConnectionResult
+import com.google.android.gms.common.GoogleApiAvailability
+import org.json.JSONException
+import org.json.JSONObject
+
+/**
+ * @author #Suyghur.
+ * Created on 2021/06/17
+ */
+ class InAppBilling {
+
+    private lateinit var billingClient: BillingClient
+
+    private lateinit var callback: InAppBillingCallback
+    private lateinit var chargeInfo: SdkChargeInfo
+
+    companion object {
+        val instance: InAppBilling by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
+            InAppBilling()
+        }
+    }
+
+    fun charge(activity: Activity, chargeInfo: SdkChargeInfo, callback: InAppBillingCallback) {
+        this.callback = callback
+        this.chargeInfo = chargeInfo
+        if (checkGoogleApiAvailability(activity)) {
+            createOrder(activity)
+        } else {
+            ToastUtils.toastInfo(activity, "Your phone or Google account does not support In-app Billing")
+            callback.onResult(-1, "谷歌iab支付服务不可用")
+        }
+    }
+
+    /**
+     * 获取订单号
+     */
+    private fun createOrder(activity: Activity) {
+        Logger.d("order_id ---> ${chargeInfo.orderId}")
+        Logger.d("payment ---> ${chargeInfo.payment}")
+        when (chargeInfo.payment) {
+            1 -> {
+                // 获取订单号成功,初始化IAB收银台客户端
+                Logger.d("获取订单号成功,初始化IAB收银台客户端")
+                initializeBillingClient(activity)
+                connectGooglePlay(activity, false)
+            }
+            3 -> {
+                // 切换第三方支付
+                callback.onResult(1, "切换第三方支付")
+            }
+        }
+    }
+
+
+    /**
+     * 初始化IAB收银台客户端
+     */
+    private fun initializeBillingClient(activity: Activity) {
+        billingClient = BillingClient.newBuilder(activity).setListener { billingResult, list ->
+            //谷歌支付结果在这里回调
+            billingResult.log("onPurchasesUpdated")
+            if (billingResult.isOk()) {
+                if (list.isNullOrEmpty()) {
+                    disConnection()
+                    callback.onResult(-1, "支付失败")
+                } else {
+                    list.forEach { purchase ->
+                        notifyOrder2Backend(activity, chargeInfo.orderId, purchase, false)
+                    }
+                }
+            } else {
+                disConnection()
+                callback.onResult(-1, "支付失败")
+            }
+        }.enablePendingPurchases().build()
+    }
+
+
+    /**
+     * 连接谷歌商店
+     */
+    private fun connectGooglePlay(activity: Activity, isPreReward: Boolean = false) {
+        billingClient.apply {
+            Logger.d("start connection Google Play ...")
+            startConnection(object : BillingClientStateListener {
+                override fun onBillingSetupFinished(billingResult: BillingResult) {
+                    billingResult.log("onBillingSetupFinished")
+                    if (billingResult.isOk()) {
+                        queryChargeInfo(activity)
+                    } else {
+                        disConnection()
+                        callback.onResult(-1, "连接谷歌商店失败")
+                    }
+                }
+
+                override fun onBillingServiceDisconnected() {
+                    Logger.e("onBillingServiceDisconnected")
+                    connectGooglePlay(activity, isPreReward)
+                }
+            })
+        }
+    }
+
+    /**
+     * 查询未消耗订单
+     */
+    private fun queryChargeInfo(activity: Activity) {
+        billingClient.apply {
+            val list = queryPurchases(BillingClient.SkuType.INAPP).purchasesList
+            if (list.isNullOrEmpty()) {
+                //正常发起支付流程
+                querySkuDetails(activity)
+            } else {
+                Logger.e("存在未消耗订单,发起补单流程,size : ${list.size}")
+                if (list.isNullOrEmpty()) {
+                    //发起正常支付流程
+                    querySkuDetails(activity)
+                } else {
+                    list.forEach { purchase ->
+                        consumeCacheOrder(activity, purchase)
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 查询商品信息
+     */
+    private fun querySkuDetails(activity: Activity) {
+        val skus = mutableListOf<String>()
+        skus.add(chargeInfo.productId)
+        val params = SkuDetailsParams.newBuilder().setType(BillingClient.SkuType.INAPP).setSkusList(skus).build()
+        billingClient.querySkuDetailsAsync(params) { billingResult, list ->
+            billingResult.log("onSkuDetailsResponse")
+            if (list.isNullOrEmpty()) {
+                //查询商品信息失败
+                Logger.e("查询商品信息失败")
+                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
+                callback.onResult(-1, "查询商品信息失败")
+                disConnection()
+            } else {
+                if (list.size == 1) {
+                    val skuDetails = list[0]
+                    Logger.d("product id : ${skuDetails.sku}")
+                    launchBillingFlow(activity, skuDetails)
+                } else {
+                    ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
+                    callback.onResult(-1, "查询商品信息异常")
+                    disConnection()
+                }
+            }
+        }
+    }
+
+    /**
+     * 消耗订单
+     */
+    private fun consumeAsync(activity: Activity, purchase: Purchase, isCache: Boolean = false) {
+        val consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build()
+        billingClient.apply {
+            if (isReady) {
+                consumeAsync(consumeParams) { billingResult, _ ->
+                    billingResult.log("onConsumeResponse")
+                    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
+                        if (isCache) {
+                            querySkuDetails(activity)
+                        } else {
+                            callback.onResult(0, "支付成功")
+                            disConnection()
+                        }
+                        removeOrderInfo(purchase.orderId)
+                    } else {
+                        callback.onResult(-1, "消耗订单异常")
+                        disConnection()
+                        ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
+                    }
+                }
+            } else {
+                disConnection()
+                callback.onResult(-1, "消耗订单异常")
+                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
+            }
+        }
+    }
+
+    /**
+     * 启动收银台
+     */
+    private fun launchBillingFlow(activity: Activity, skuDetails: SkuDetails) {
+        billingClient.apply {
+            if (isReady) {
+                val flowParams = BillingFlowParams.newBuilder().setObfuscatedAccountId(chargeInfo.orderId).setSkuDetails(skuDetails).build()
+                val billingResult = launchBillingFlow(activity, flowParams)
+                billingResult.log("launchBillingFlow")
+                if (billingResult.isOk()) {
+                    disConnection()
+                    ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
+                    callback.onResult(-1, "启动谷歌收银台失败")
+                }
+            } else {
+                disConnection()
+                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
+                callback.onResult(-1, "启动谷歌收银台失败")
+            }
+        }
+    }
+
+    /**
+     * 通知服务端发货
+     */
+    private fun notifyOrder2Backend(activity: Activity, orderId: String, purchase: Purchase, isCache: Boolean = false) {
+        val jsonObject = JSONObject()
+        jsonObject.put("order_id", orderId)
+        jsonObject.put("order_notify_data", purchase.originalJson)
+        SdkRequest.instance.notifyOrder(activity, jsonObject) { resultInfo ->
+            when (resultInfo.code) {
+                1 -> {
+                    //消耗订单
+                    consumeAsync(activity, purchase, isCache)
+                }
+                2 -> {
+                    Logger.d(resultInfo.msg)
+                    consumeAsync(activity, purchase, isCache)
+                }
+                else -> {
+                    //失败则缓存订单
+                    saveOrderInfo(purchase.orderId, orderId)
+                    disConnection()
+                    val msg = if (TextUtils.isEmpty(resultInfo.msg)) {
+                        ResUtils.getResString(activity, "yyxx_charge_tv_error")
+                    } else {
+                        resultInfo.msg
+                    }
+                    ToastUtils.toastInfo(activity, msg)
+                    callback.onResult(-1, "发货失败")
+                }
+            }
+        }
+    }
+
+    /**
+     * 消耗缓存订单
+     */
+    private fun consumeCacheOrder(activity: Activity, purchase: Purchase) {
+        // 消耗完了再发起支付
+        Logger.d("消耗缓存订单 : $purchase")
+        var orderId = ""
+        purchase.accountIdentifiers?.apply {
+            orderId = if (!TextUtils.isEmpty(obfuscatedAccountId)) {
+                obfuscatedAccountId!!
+            } else {
+                getOrderInfo(purchase.orderId)
+            }
+        }
+        notifyOrder2Backend(activity, orderId, purchase, true)
+    }
+
+
+    private fun disConnection() {
+        billingClient.apply {
+            if (isReady) {
+                Logger.d("断开谷歌收银台连接,以清空被消耗或者失败的缓存订单")
+                endConnection()
+            }
+        }
+    }
+
+    private fun saveOrderInfo(googleOrderId: String, orderId: String) {
+        try {
+            MMKVHandler.instance.orderKV.encode(googleOrderId, orderId)
+        } catch (e: JSONException) {
+            e.printStackTrace()
+        }
+    }
+
+    private fun getOrderInfo(googleOrderId: String): String {
+        val info = MMKVHandler.instance.orderKV.decodeString(googleOrderId)
+        Logger.d("getOrderInfo : $info")
+        return if (TextUtils.isEmpty(info)) {
+            ""
+        } else {
+            info!!
+        }
+    }
+
+    private fun removeOrderInfo(googleOrderId: String) {
+        MMKVHandler.instance.orderKV.removeValueForKey(googleOrderId)
+    }
+
+    private fun BillingResult.isOk(): Boolean {
+        return responseCode == BillingClient.BillingResponseCode.OK
+    }
+
+    private fun checkGoogleApiAvailability(activity: Activity): Boolean {
+        return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(activity) == ConnectionResult.SUCCESS
+    }
+
+    private fun BillingResult.log(callbackFuncName: String) {
+        Logger.d("$callbackFuncName , code : $responseCode , msg : $debugMessage")
+    }
+
+    interface InAppBillingCallback {
+        fun onResult(code: Int, result: String)
+    }
+}

+ 0 - 351
module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/iab/ChargeImpl.kt

@@ -1,351 +0,0 @@
-package cn.yyxx.eyuancomm.core.impl.iab
-
-import android.app.Activity
-import android.text.TextUtils
-import cn.yyxx.eyuancomm.comm.entity.SdkChargeInfo
-import cn.yyxx.eyuancomm.comm.network.SdkRequest
-import cn.yyxx.eyuancomm.comm.utils.Logger
-import cn.yyxx.eyuancomm.comm.utils.MMKVHandler
-import cn.yyxx.eyuancomm.core.impl.GameSdkImpl
-import cn.yyxx.support.ResUtils
-import cn.yyxx.support.hawkeye.ToastUtils
-import com.android.billingclient.api.*
-import org.json.JSONException
-import org.json.JSONObject
-
-/**
- * @author #Suyghur.
- * Created on 2021/06/28
- */
-class ChargeImpl : InAppBilling() {
-
-    //初始化IAB收银台客户端
-    //连接谷歌商店
-    private lateinit var implCallback: (Int, String) -> Unit
-    private lateinit var chargeInfo: SdkChargeInfo
-
-    fun charge(activity: Activity, chargeInfo: SdkChargeInfo, callback: (Int, String) -> Unit) {
-        if (!checkGoogleApiAvailability(activity)) {
-            ToastUtils.toastInfo(activity, "Your phone or Google account does not support In-app Billing")
-            callback(-1, "谷歌iab支付服务不可用")
-            return
-        }
-        this.implCallback = callback
-        this.chargeInfo = chargeInfo
-        showDialog(activity)
-        createOrder(activity)
-    }
-
-    override fun chargePurchasesUpdated(activity: Activity, purchase: Purchase) {
-        notifyOrder2Backend(activity, chargeInfo.orderId, purchase, false)
-    }
-
-    override fun preRewardPurchasesUpdated(activity: Activity, purchase: Purchase) {
-    }
-
-    override fun queryRewardInfo(activity: Activity) {
-    }
-
-    /**
-     * 查询未消耗订单
-     */
-    override fun queryChargeInfo(activity: Activity) {
-        billingClient?.apply {
-            val list = queryPurchases(BillingClient.SkuType.INAPP).purchasesList
-            if (list.isNullOrEmpty()) {
-                //正常发起支付流程
-                querySkuDetails(activity)
-            } else {
-                Logger.e("存在未消耗订单,发起补单流程,size : ${list.size}")
-                run breaking@{
-                    if (list.size > 0) {
-                        list.forEach { purchase ->
-                            if (purchase.sku == GameSdkImpl.initBean.rewardId) {
-                                Logger.e("存在阻塞的预注册奖励,停止支付流程")
-                                if (list.size == 1) {
-                                    dismissDialog()
-                                    disConnection()
-                                    ToastUtils.toastInfo(activity, "In-app Billing has some error , please restart app and try again")
-                                    implCallback(-1, "存在阻塞的预注册奖励,停止支付流程")
-                                }
-                                //跳出支付流程
-                                return@breaking
-                            } else {
-                                consumeCacheOrder(activity, purchase)
-                            }
-                        }
-                    } else {
-                        //发起正常支付流程
-                        querySkuDetails(activity)
-                    }
-                }
-            }
-
-
-//            queryPurchasesAsync(BillingClient.SkuType.INAPP, object : PurchasesResponseListener {
-//                override fun onQueryPurchasesResponse(billingResult: BillingResult, list: MutableList<Purchase>) {
-//                    logBillingResult("onQueryPurchasesResponse", billingResult)
-//                    if (list.isNullOrEmpty()) {
-//                        //正常发起支付流程
-//                        Logger.d("正常发起支付流程")
-//                        querySkuDetails(activity)
-//                    } else {
-//                        Logger.e("存在未消耗订单,发起补单流程,size : ${list.size}")
-//                        run breaking@{
-//                            list.forEach { purchase ->
-//                                purchase.skus.forEach {
-//                                    if (it.equals(SdkBridgeImpl.initBean.rewardId)) {
-//                                        Logger.e("存在阻塞的预注册奖励,停止支付流程")
-//                                        if (list.size == 1) {
-//                                            dismissDialog()
-//                                            disConnection()
-//                                            ToastUtils.toastInfo(activity, "In-app Billing has some error , please restart app and try again")
-//                                            implCallback.onResult(-1, "存在阻塞的预注册奖励,停止支付流程")
-//                                        }
-//                                        //跳出支付流程
-//                                        return@breaking
-//                                    } else {
-//                                        consumeCacheOrder(activity, purchase)
-//                                    }
-//                                }
-//                            }
-//                        }
-//                    }
-//                }
-//            })
-        }
-    }
-
-    override fun purchasesUpdatedFailed() {
-        disConnection()
-        dismissDialog()
-        implCallback(-1, "支付失败")
-    }
-
-    override fun connectGooglePlayFailed() {
-        disConnection()
-        dismissDialog()
-        implCallback(-1, "连接谷歌商店失败")
-    }
-
-    /**
-     * 检查本地通知发货失败订单
-     */
-    private fun checkLocalNotifyFailedOrder(activity: Activity) {
-
-    }
-
-    /**
-     * 获取订单号
-     */
-    private fun createOrder(activity: Activity) {
-        Logger.d("order_id ---> ${chargeInfo.orderId}")
-        Logger.d("payment ---> ${chargeInfo.payment}")
-        when (chargeInfo.payment) {
-            1 -> {
-                // 获取订单号成功,初始化IAB收银台客户端
-                Logger.d("获取订单号成功,初始化IAB收银台客户端")
-                initializeBillingClient(activity)
-                connectGooglePlay(activity, false)
-            }
-            3 -> {
-                // 切换第三方支付
-                dismissDialog()
-                implCallback(1, "切换第三方支付")
-            }
-        }
-    }
-
-    /**
-     * 查询商品信息
-     */
-    private fun querySkuDetails(activity: Activity) {
-        val skus = mutableListOf<String>()
-        skus.add(chargeInfo.productId)
-        val params = SkuDetailsParams.newBuilder().setType(BillingClient.SkuType.INAPP).setSkusList(skus).build()
-        billingClient?.querySkuDetailsAsync(params) { billingResult, list ->
-            logBillingResult("onSkuDetailsResponse", billingResult)
-            dismissDialog()
-            if (list.isNullOrEmpty()) {
-                //查询商品信息失败
-                Logger.e("查询商品信息失败")
-                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
-                implCallback(-1, "查询商品信息失败")
-                disConnection()
-            } else {
-                if (list.size == 1) {
-                    val skuDetails = list[0]
-                    Logger.d("product id : ${skuDetails.sku}")
-                    launchBillingFlow(activity, skuDetails)
-                } else {
-                    ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
-                    implCallback(-1, "查询商品信息异常")
-                    disConnection()
-                }
-            }
-        }
-    }
-
-    /**
-     * 启动收银台
-     */
-    private fun launchBillingFlow(activity: Activity, skuDetails: SkuDetails) {
-        billingClient?.apply {
-            if (isReady) {
-                val flowParams = BillingFlowParams.newBuilder().setObfuscatedAccountId(chargeInfo.orderId).setSkuDetails(skuDetails).build()
-                val billingResult = launchBillingFlow(activity, flowParams)
-                logBillingResult("launchBillingFlow", billingResult)
-                if (billingResult.responseCode != BillingClient.BillingResponseCode.OK) {
-                    dismissDialog()
-                    disConnection()
-                    ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
-                    implCallback(-1, "启动谷歌收银台失败")
-                }
-            } else {
-                dismissDialog()
-                disConnection()
-                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
-                implCallback(-1, "启动谷歌收银台失败")
-            }
-        }
-    }
-
-    /**
-     * 通知服务端发货
-     */
-    private fun notifyOrder2Backend(activity: Activity, orderId: String, purchase: Purchase, isCache: Boolean = false) {
-        val jsonObject=JSONObject()
-        jsonObject.put("order_id",orderId)
-        jsonObject.put("order_notify_data",purchase.originalJson)
-        SdkRequest.instance.notifyOrder(activity,jsonObject){resultInfo ->
-            when (resultInfo.code) {
-                1 -> {
-                    //消耗订单
-                    consumeAsync(activity, purchase, isCache)
-                }
-                2 -> {
-                    Logger.d(resultInfo.msg)
-                    consumeAsync(activity, purchase, isCache)
-                }
-                else -> {
-                    //失败则缓存订单
-                    saveOrderInfo(purchase.orderId, orderId)
-                    dismissDialog()
-                    disConnection()
-                    val msg = if (TextUtils.isEmpty(resultInfo.msg)) {
-                        ResUtils.getResString(activity, "yyxx_charge_tv_error")
-                    } else {
-                        resultInfo.msg
-                    }
-                    ToastUtils.toastInfo(activity, msg)
-                    implCallback(-1, "发货失败")
-                }
-            }
-        }
-//        SdkRequest.instance.notifyOrder(activity, orderId, purchase.originalJson) { resultInfo ->
-//            when (resultInfo.code) {
-//                1 -> {
-//                    //消耗订单
-//                    consumeAsync(activity, purchase, isCache)
-//                }
-//                2 -> {
-//                    Logger.d(resultInfo.msg)
-//                    consumeAsync(activity, purchase, isCache)
-//                }
-//                else -> {
-//                    //失败则缓存订单
-//                    saveOrderInfo(purchase.orderId, orderId)
-//                    dismissDialog()
-//                    disConnection()
-//                    val msg = if (TextUtils.isEmpty(resultInfo.msg)) {
-//                        ResUtils.getResString(activity, "yyxx_charge_tv_error")
-//                    } else {
-//                        resultInfo.msg
-//                    }
-//                    ToastUtils.toastInfo(activity, msg)
-//                    implCallback(-1, "发货失败")
-//                }
-//            }
-//        }
-    }
-
-    /**
-     * 消耗缓存订单
-     */
-    private fun consumeCacheOrder(activity: Activity, purchase: Purchase) {
-        //消耗完了再发起支付
-        Logger.d("消耗缓存订单 : $purchase")
-        var orderId = ""
-        purchase.accountIdentifiers?.apply {
-            orderId = if (!TextUtils.isEmpty(obfuscatedAccountId)) {
-                obfuscatedAccountId!!
-            } else {
-                getOrderInfo(purchase.orderId)
-            }
-        }
-        notifyOrder2Backend(activity, orderId, purchase, true)
-    }
-
-    /**
-     * 消耗订单
-     */
-    private fun consumeAsync(activity: Activity, purchase: Purchase, isCache: Boolean = false) {
-        val consumeParams = ConsumeParams.newBuilder().setPurchaseToken(purchase.purchaseToken).build()
-        billingClient?.apply {
-            if (isReady) {
-                consumeAsync(consumeParams) { billingResult, token ->
-                    logBillingResult("onConsumeResponse", billingResult)
-                    dismissDialog()
-                    if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
-                        // saveOrder2Local()
-                        if (isCache) {
-                            querySkuDetails(activity)
-                        } else {
-                            implCallback(0, "支付成功")
-                            disConnection()
-                        }
-                        removeOrderInfo(purchase.orderId)
-                    } else {
-                        implCallback(-1, "消耗订单异常")
-                        disConnection()
-                        ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
-                    }
-                }
-            } else {
-                dismissDialog()
-                disConnection()
-                implCallback(-1, "消耗订单异常")
-                ToastUtils.toastInfo(activity, ResUtils.getResString(activity, "yyxx_charge_tv_error"))
-            }
-        }
-    }
-
-    private fun saveOrderInfo(googleOrderId: String, orderId: String) {
-        try {
-            MMKVHandler.instance.orderKV.encode(googleOrderId, orderId)
-        } catch (e: JSONException) {
-            e.printStackTrace()
-        }
-    }
-
-    private fun getOrderInfo(googleOrderId: String): String {
-        val info = MMKVHandler.instance.orderKV.decodeString(googleOrderId)
-        Logger.d("getOrderInfo : $info")
-        return if (TextUtils.isEmpty(info)) {
-            ""
-        } else {
-            info!!
-        }
-    }
-
-    private fun removeOrderInfo(googleOrderId: String) {
-        MMKVHandler.instance.orderKV.removeValueForKey(googleOrderId)
-    }
-
-
-    companion object {
-        val instance: ChargeImpl by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
-            ChargeImpl()
-        }
-    }
-}

+ 0 - 144
module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/iab/InAppBilling.kt

@@ -1,144 +0,0 @@
-package cn.yyxx.eyuancomm.core.impl.iab
-
-import android.app.Activity
-import android.content.Context
-import cn.yyxx.eyuancomm.comm.utils.Logger
-import cn.yyxx.eyuancomm.core.impl.GameSdkImpl
-import cn.yyxx.eyuancomm.core.widget.dialog.ScaleLoadingDialog
-import cn.yyxx.support.ResUtils
-import com.android.billingclient.api.BillingClient
-import com.android.billingclient.api.BillingClientStateListener
-import com.android.billingclient.api.BillingResult
-import com.android.billingclient.api.Purchase
-import com.google.android.gms.common.ConnectionResult
-import com.google.android.gms.common.GoogleApiAvailability
-
-/**
- * @author #Suyghur.
- * Created on 2021/06/17
- */
-abstract class InAppBilling {
-
-    protected var billingClient: BillingClient? = null
-    private var loadingDialog: ScaleLoadingDialog? = null
-
-    protected fun checkGoogleApiAvailability(activity: Activity): Boolean {
-        return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(activity) == ConnectionResult.SUCCESS
-    }
-
-    /**
-     * 初始化IAB收银台客户端
-     */
-    protected fun initializeBillingClient(activity: Activity) {
-        billingClient = BillingClient.newBuilder(activity).setListener { billingResult, list ->
-            //谷歌支付结果在这里回调
-            logBillingResult("onPurchasesUpdated", billingResult)
-            if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
-                if (list != null && list.size > 0) {
-                    for (purchase in list) {
-                        if (purchase.sku == GameSdkImpl.initBean.rewardId) {
-                            //预注册
-                            preRewardPurchasesUpdated(activity, purchase)
-                        } else {
-                            //支付
-                            chargePurchasesUpdated(activity, purchase)
-                        }
-                    }
-                } else {
-                    purchasesUpdatedFailed()
-                }
-            } else {
-                purchasesUpdatedFailed()
-            }
-        }.enablePendingPurchases().build()
-    }
-
-
-    /**
-     * 连接谷歌商店
-     */
-    protected fun connectGooglePlay(activity: Activity, isPreReward: Boolean = false) {
-        billingClient?.apply {
-            if (!isReady) {
-                Logger.d("start connection Google Play ...")
-                startConnection(object : BillingClientStateListener {
-                    override fun onBillingSetupFinished(billingResult: BillingResult) {
-                        logBillingResult("onBillingSetupFinished", billingResult)
-                        if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
-                            if (isPreReward) {
-                                queryRewardInfo(activity)
-                            } else {
-                                queryChargeInfo(activity)
-                            }
-                        } else {
-                            connectGooglePlayFailed()
-                        }
-                    }
-
-                    override fun onBillingServiceDisconnected() {
-                        Logger.e("onBillingServiceDisconnected")
-                        connectGooglePlay(activity, isPreReward)
-                    }
-                })
-            } else {
-                dismissDialog()
-                disConnection()
-            }
-        }
-    }
-
-//    protected fun handlePurchase(list)
-
-    protected fun disConnection() {
-        billingClient?.apply {
-            if (isReady) {
-                Logger.d("断开谷歌收银台连接,以清空被消耗或者失败的缓存订单")
-                endConnection()
-            }
-        }
-    }
-
-    protected fun logBillingResult(callbackFuncName: String, billingResult: BillingResult) {
-        val code = billingResult.responseCode
-        val msg = billingResult.debugMessage
-        Logger.d("$callbackFuncName , code : $code , msg : $msg")
-    }
-
-    protected fun showDialog(context: Context) {
-        loadingDialog?.apply {
-            dismiss()
-            loadingDialog = null
-        }
-
-        loadingDialog = ScaleLoadingDialog(context, ResUtils.getResString(context, "yyxx_charge_loading_tips"))
-        loadingDialog?.show()
-    }
-
-    protected fun dismissDialog() {
-        loadingDialog?.apply {
-            dismiss()
-            loadingDialog = null
-        }
-    }
-
-    /**
-     * charge
-     * Purchase{"orderId":"GPA.3325-4558-9050-03633","packageName":"com.flyfun.demo","productId":"com.flyfun.ylj.60","purchaseTime":1618367632652,"purchaseState":4,"purchaseToken":"mpfdmeeoemplddgfknnkgnlf.AO-J1Owpfua8OfxpU_sjOBTY_ZgRoN3Km-mNJdmie9Qpd1w-DDQjtkUfcWOGhScHHeJ9ogWqkP_01w5WHp9Pfnpvgx1_nffDYA","acknowledged":false}
-     */
-    protected abstract fun chargePurchasesUpdated(activity: Activity, purchase: Purchase)
-
-    /**
-     * pre reward
-     * Purchase{"packageName":"com.flyfun.demo","productId":"com.flyfun.demo70","purchaseTime":1618367980837,"purchaseState":0,"purchaseToken":"cdphbkooagehckdcmkhmbhmd.AO-J1OzHTtCRDhd8k1Qfp3FU0GgYQUSaCx6I6W6Oi_P2tiS3LWKIdb6jTkc-tTqfcCagPxw2nPqujl9s10KuCunTl3OLSiIN9A"}
-     */
-    protected abstract fun preRewardPurchasesUpdated(activity: Activity, purchase: Purchase)
-
-    protected abstract fun queryRewardInfo(activity: Activity)
-
-    protected abstract fun queryChargeInfo(activity: Activity)
-
-    protected abstract fun purchasesUpdatedFailed()
-
-    protected abstract fun connectGooglePlayFailed()
-
-}

+ 6 - 5
module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/impl/login/UserSignInImpl.kt

@@ -25,9 +25,7 @@ import com.google.android.gms.common.ConnectionResult
 import com.google.android.gms.common.GoogleApiAvailability
 import com.google.android.gms.common.api.ApiException
 import com.google.android.gms.tasks.Task
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.*
 import org.json.JSONException
 import org.json.JSONObject
 import java.util.*
@@ -180,8 +178,9 @@ class UserSignInImpl constructor(val activity: LoginActivity, private val callba
                             loginType = SdkLoginInfo.instance.loginType
                             this.userName = userName
                             this.pwd = pwd
-                            GlobalScope.launch(Dispatchers.IO) {
+                            CoroutineScope(Dispatchers.IO).launch {
                                 SessionUtils.instance.saveSession(this@with)
+                                cancel()
                             }
                         }
                         callback.onSuccess(SdkLoginInfo.instance.toJsonString())
@@ -237,8 +236,10 @@ class UserSignInImpl constructor(val activity: LoginActivity, private val callba
                             userName = loginParams.getString("uname")
                             pwd = loginParams.getString("pwd")
                         }
-                        GlobalScope.launch(Dispatchers.IO) {
+
+                        CoroutineScope(Dispatchers.IO).launch {
                             SessionUtils.instance.saveSession(this@with)
+                            cancel()
                         }
                     }
                     callback.onSuccess(SdkLoginInfo.instance.toJsonString())

+ 7 - 5
module_eyuan/library_eyuan/src/main/kotlin/cn/yyxx/eyuancomm/core/utils/SessionUtils.kt

@@ -18,6 +18,12 @@ import org.json.JSONObject
  */
 class SessionUtils private constructor() {
 
+    companion object {
+        val instance: SessionUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
+            SessionUtils()
+        }
+    }
+
     @Synchronized
     fun saveSession(currentSession: Session) {
         val userList = getLocalSession()
@@ -184,9 +190,5 @@ class SessionUtils private constructor() {
         return infoList
     }
 
-    companion object {
-        val instance: SessionUtils by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
-            SessionUtils()
-        }
-    }
+
 }

+ 2 - 2
settings.gradle

@@ -7,8 +7,8 @@ include ':library_impl'
 // 渠道库
 include ':channel_registry:channel_oppo'
 include ':channel_registry:channel_vivo'
-include ':channel_registry:channel_huawei'
-//include ':channel_registry:channel_huawei2'
+//include ':channel_registry:channel_huawei'
+include ':channel_registry:channel_huawei2'
 
 // 组件
 //include ':component:google-auth:play-services-auth'