详细配置url: https://blog.csdn.net/wuyutaoktm/article/details/122450878
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 {
// success
googlePayLog.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
}
丢单因为主要是因为支付操作都是在客户端完成的,非常容易受到网络等因素的影响,造成互相通信失败。比如:用户确认支付后,把请求提交给google play,可能因为网络不好造成,客户端没有接收到支付成功能消息(但有可能已经支付成功了,只是没收到支付结果而已);还有客户端把支付结果通知给服务器时,也有可能因丢包等问题造成通知失败。
api接口,get 和 确认消耗consume
服务端api官网地址: https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products/consume?hl=zh-cn