1.GooglePlay内购服务器验单配置 (新版本好像不需要API 配置关联,好像不需要了)
详细配置url: https://blog.csdn.net/wuyutaoktm/article/details/122450878
2. 用golang代码实现,主要是验证订单和发币,PAY_JSON 是上一个步骤申请的
func verifyAndConsumePurchase(info *PurchaseInfo) (bool, error, int8) {ctx := context.Background()rawByte, _ := json.Marshal(info)googlePayLog := &handler.GooglePayLog{UserID: info.UserId,Raw: string(rawByte),RespRaw: "",PurchaseTokenMD5: "",CheckStatus: -1,ConsumptionStatus: -1,GoldStatus: -1,RechargeID: 0,MsgErr: "",}// 使用服务账号创建凭证conf, err := google.JWTConfigFromJSON([]byte(PAY_JSON), androidpublisher.AndroidpublisherScope)if err != nil {googlePayLog.MsgErr = "1:" + err.Error()db_common.ApplyInsertGooglePayLog(googlePayLog)zlog.F().Errorf("user_id:%d,producd_id:%s,%v", info.UserId, info.ProductID, googlePayLog.MsgErr)return false, err, 0}// 使用凭证创建Google Play Developer服务service, err := androidpublisher.NewService(ctx, option.WithTokenSource(conf.TokenSource(ctx)))if err != nil {googlePayLog.MsgErr = "2:" + err.Error()db_common.ApplyInsertGooglePayLog(googlePayLog)zlog.F().Errorf("user_id:%d,producd_id:%s,%v", info.UserId, info.ProductID, googlePayLog.MsgErr)return false, err, 0}// 调用API验证购买call := service.Purchases.Products.Get(info.PackageName, info.ProductID, info.PurchaseToken)response, err := call.Do()if err != nil {googlePayLog.MsgErr = "3:" + err.Error()db_common.ApplyInsertGooglePayLog(googlePayLog)zlog.F().Errorf("user_id:%d,producd_id:%s,%v", info.UserId, info.ProductID, googlePayLog.MsgErr)return false, err, 1}str, _ := json.Marshal(response)zlog.F().Infof("userId:%d,productId:%d,response: %+v", info.UserId, info.ProductID, str)//0:表示交易已成功,并且商品未被消费。//1:表示交易被取消。//2:可能表示交易被拒绝,或某些其他的错误状态。// 验证购买状态:0表示购买成功if response.PurchaseState != 0 {zlog.F().Errorf("user_id:%d,producd_id:%s,PurchaseState:%d", info.UserId, info.ProductID, response.PurchaseState)googlePayLog.CheckStatus = int8(response.PurchaseState)googlePayLog.PurchaseTokenMD5 = utils.Md5(response.PurchaseToken)db_common.ApplyInsertGooglePayLog(googlePayLog)return false, nil, 0}// 调用API确认消费(消耗商品)//consumeCall := service.Purchases.Products.Acknowledge(info.PackageName, info.ProductID, info.PurchaseToken, &androidpublisher.ProductPurchasesAcknowledgeRequest{})consumeCall := service.Purchases.Products.Consume(info.PackageName, info.ProductID, info.PurchaseToken)if err := consumeCall.Do(); err != nil {googlePayLog.CheckStatus = int8(response.PurchaseState)googlePayLog.PurchaseTokenMD5 = utils.Md5(response.PurchaseToken)googlePayLog.ConsumptionStatus = 0 // 0表示消费失败googlePayLog.MsgErr = "4:" + err.Error()db_common.ApplyInsertGooglePayLog(googlePayLog)zlog.F().Errorf("user_id:%d,producd_id:%s,%v", info.UserId, info.ProductID, googlePayLog.MsgErr)return false, err, 1}// 加币操作if err = dealMysql(info, googlePayLog); err != nil {googlePayLog.CheckStatus = int8(response.PurchaseState)googlePayLog.PurchaseTokenMD5 = utils.Md5(response.PurchaseToken)googlePayLog.ConsumptionStatus = 1 // 1表示消费失败googlePayLog.GoldStatus = 0 // 0 加币失败googlePayLog.MsgErr = "5:" + err.Error()db_common.ApplyInsertGooglePayLog(googlePayLog)zlog.F().Errorf("user_id:%d,producd_id:%s,%v", info.UserId, info.ProductID, googlePayLog.MsgErr)return false, err, 1} else {// successgooglePayLog.CheckStatus = int8(response.PurchaseState)googlePayLog.PurchaseTokenMD5 = utils.Md5(response.PurchaseToken)googlePayLog.ConsumptionStatus = 1 // 1表示消费失败googlePayLog.GoldStatus = 1 // 0 加币失败db_common.ApplyInsertGooglePayLog(googlePayLog)}return true, nil, 0
}
3. 注意丢单情况,改成客户端主动查询丢单
丢单因为主要是因为支付操作都是在客户端完成的,非常容易受到网络等因素的影响,造成互相通信失败。比如:用户确认支付后,把请求提交给google play,可能因为网络不好造成,客户端没有接收到支付成功能消息(但有可能已经支付成功了,只是没收到支付结果而已);还有客户端把支付结果通知给服务器时,也有可能因丢包等问题造成通知失败。
4. 官网服务端api
api接口,get 和 确认消耗consume
服务端api官网地址: https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products/consume?hl=zh-cn
安卓api:
https://developer.android.com/reference/com/android/billingclient/api/BillingFlowParams.Builder#setobfuscatedaccountid