diff --git a/package/pay/huawei/consts.go b/package/pay/huawei/consts.go index 1aba07d..327d209 100644 --- a/package/pay/huawei/consts.go +++ b/package/pay/huawei/consts.go @@ -6,21 +6,14 @@ import ( ) const ( - AuthTokenUrl = "https://oauth-api.cloud.huawei.com/rest.php?nsp_fmt=JSON&nsp_svc=huawei.oauth2.user.getTokenInfo" - OrderUrl = "https://orders-drcn.iap.hicloud.com/applications/purchases/tokens/verify" - LocationShanghai = "Asia/Shanghai" - - RSA = "RSA" - RSA2 = "RSA2" - - OrderResponseOk = "0" - PurchaseStateOk = 0 + TokenUrl = "https://oauth-login.cloud.huawei.com/oauth2/v3/token" ) func getOrderUrl(accountFlag int) string { if accountFlag == 1 { // site for telecom carrier - return "https://orders-at-dre.iap.dbankcloud.com" + //return "https://orders-at-dre.iap.dbankcloud.com" + return "https://orders-drcn.iap.cloud.huawei.com.cn" } else { // TODO: replace the (ip:port) to the real one return "http://exampleserver/_mockserver_" diff --git a/package/pay/huawei/huawei.go b/package/pay/huawei/huawei.go index 7e30ecb..5cf66aa 100644 --- a/package/pay/huawei/huawei.go +++ b/package/pay/huawei/huawei.go @@ -10,6 +10,9 @@ import ( "encoding/json" "errors" "fmt" + "github.com/gogf/gf/v2/encoding/gjson" + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/os/gctx" "io" "log" "net/http" @@ -17,9 +20,9 @@ import ( ) type Pay struct { - ClientSecret string `json:"client_secret"` - ClientId string `json:"client_id"` - TokenUrl string `json:"token_url"` + ClientSecret string `json:"client_secret"` + ClientId string `json:"client_id"` + //TokenUrl string `json:"token_url"` ApplicationPublicKey string `json:"application_public_key"` } @@ -46,21 +49,24 @@ func (p *Pay) ConfirmPurchase(purchaseToken, productId string, accountFlag int) log.Printf("err is %s", err) } // 打印响应结果(实际业务中需替换为具体处理逻辑,如更新订单状态、校验响应数据等) - // TODO: 建议根据华为支付文档解析响应数据(如检查code是否为0表示成功) + // TODO: 建议根据华为支付文档解析响应数据(如检查responseCode是否为0表示成功) log.Printf("%s", bodyBytes) } // VerifyToken 验证回调订单 //您可以调用本接口向华为应用内支付服务器校验支付结果中的购买令牌,确认支付结果的准确性。 -func (p *Pay) VerifyToken(purchaseToken, productId string, accountFlag int) { +func (p *Pay) VerifyToken(purchaseToken, productId string, accountFlag int) (res *PurchaseTokenData, err error) { bodyMap := map[string]string{"purchaseToken": purchaseToken, "productId": productId} url := getOrderUrl(accountFlag) + "/applications/purchases/tokens/verify" bodyBytes, err := p.SendRequest(url, bodyMap) if err != nil { - log.Printf("err is %s", err) + g.Log().Error(gctx.New(), "err is %s", err) } - // TODO: display the response as string in console, you can replace it with your business logic. - log.Printf("%s", bodyBytes) + var data *VerifyTokenRes + err = gjson.DecodeTo(bodyBytes, &data) + err = gjson.DecodeTo(data.PurchaseTokenData, &res) + + return } func (p *Pay) SendRequest(url string, bodyMap map[string]string) (string, error) { @@ -97,6 +103,7 @@ func (p *Pay) SendRequest(url string, bodyMap map[string]string) (string, error) } func (p *Pay) VerifyRsaSign(content string, sign string, publicKey string) error { + //publicKey = common.FormatPublicKey(publicKey) publicKeyByte, err := base64.StdEncoding.DecodeString(publicKey) if err != nil { return err @@ -120,7 +127,7 @@ func (p *Pay) GetAppAt() (string, error) { "client_secret": {p.ClientSecret}, "client_id": {p.ClientId}, } - resp, err := RequestHttpClient.PostForm(p.TokenUrl, urlValue) + resp, err := RequestHttpClient.PostForm(TokenUrl, urlValue) defer resp.Body.Close() bodyBytes, err := io.ReadAll(resp.Body) diff --git a/package/pay/huawei/model.go b/package/pay/huawei/model.go index 4685f62..d91b52c 100644 --- a/package/pay/huawei/model.go +++ b/package/pay/huawei/model.go @@ -47,3 +47,36 @@ type StatusUpdateNotification struct { type AtResponse struct { AccessToken string `json:"access_token"` } + +type VerifyTokenRes struct { + ResponseCode string `json:"responseCode"` + PurchaseTokenData string `json:"purchaseTokenData"` + DataSignature string `json:"dataSignature"` + SignatureAlgorithm string `json:"signatureAlgorithm"` +} + +type PurchaseTokenData struct { + AutoRenewing bool `json:"autoRenewing" dc:"表示订阅是否自动续费"` + OrderId string `json:"orderId" dc:"订单ID,唯一标识一笔订单"` + PackageName string `json:"packageName" dc:"应用的包名"` + ApplicationId int `json:"applicationId" dc:"应用ID,以整数形式表示"` + ApplicationIdString string `json:"applicationIdString" dc:"应用ID的字符串形式"` + Kind int `json:"kind" dc:"购买类型的某种标识,具体含义可能取决于业务逻辑"` + ProductId string `json:"productId" dc:"商品ID,用于标识购买的商品"` + ProductName string `json:"productName" dc:"商品名称"` + PurchaseTime int64 `json:"purchaseTime" dc:"购买时间,可能是某种特定格式的时间表示"` + PurchaseTimeMillis int64 `json:"purchaseTimeMillis" dc:"购买时间,以毫秒为单位的时间戳"` + PurchaseState int `json:"purchaseState" dc:"购买状态,不同的整数值代表不同的状态,具体含义取决于业务逻辑"` + DeveloperPayload string `json:"developerPayload" dc:"开发者自定义负载数据"` + PurchaseToken string `json:"purchaseToken" dc:"购买令牌"` + ResponseCode string `json:"responseCode" dc:"响应代码,用于表示购买操作的响应结果"` + ConsumptionState int `json:"consumptionState" dc:"消费状态,不同的整数值代表不同的消费状态,具体含义取决于业务逻辑"` + Confirmed int `json:"confirmed" dc:"确认状态,不同的整数值代表不同的确认情况,具体含义取决于业务逻辑"` + PurchaseType int `json:"purchaseType" dc:"购买类型,不同的整数值代表不同的购买类型,具体含义取决于业务逻辑"` + Currency string `json:"currency" dc:"货币类型"` + Price int `json:"price" dc:"商品价格"` + Country string `json:"country" dc:"购买所在国家"` + PayOrderId string `json:"payOrderId" dc:"支付订单ID"` + PayType string `json:"payType" dc:"支付类型"` + SdkChannel string `json:"sdkChannel" dc:"SDK渠道"` +}