完成华为支付的验单

This commit is contained in:
ayflying
2025-08-06 10:26:08 +08:00
parent 039acea0af
commit d2e49276f5
3 changed files with 52 additions and 19 deletions

View File

@@ -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_"

View File

@@ -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)

View File

@@ -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渠道"`
}