调整oppo支付,不引用外部包
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
package pay
|
||||
package common
|
||||
|
||||
import "strings"
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"github.com/ayflying/utility_go/package/pay"
|
||||
"github.com/ayflying/utility_go/package/pay/common"
|
||||
)
|
||||
|
||||
type Pay struct {
|
||||
@@ -35,7 +35,7 @@ func (p *Pay) VerifyRSASignature(data []byte, sign string) (bool, error) {
|
||||
return false, errors.New("签名解码失败: " + err.Error())
|
||||
}
|
||||
|
||||
pubkey := pay.FormatPublicKey(p.PubKey)
|
||||
pubkey := common.FormatPublicKey(p.PubKey)
|
||||
// 解析PEM格式的公钥
|
||||
block, _ := pem.Decode([]byte(pubkey))
|
||||
if block == nil {
|
||||
|
||||
9
package/pay/oppo/const.go
Normal file
9
package/pay/oppo/const.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package oppo
|
||||
|
||||
const (
|
||||
LoginUrl = "https://iopen.game.oppomobile.com/sdkopen/user/fileIdInfo?fileId=%s&token=%s"
|
||||
LocationShanghai = "Asia/Shanghai"
|
||||
|
||||
RSA = "RSA"
|
||||
RSA2 = "RSA2"
|
||||
)
|
||||
32
package/pay/oppo/notify.go
Normal file
32
package/pay/oppo/notify.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package oppo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func (p *OppoType) ParseNotifyToBodyMap(req *http.Request) (bm map[string]interface{}, err error) {
|
||||
if err = req.ParseForm(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var form map[string][]string = req.Form
|
||||
bm = make(map[string]interface{}, len(form)+1)
|
||||
for k, v := range form {
|
||||
if len(v) == 1 {
|
||||
bm[k] = v[0]
|
||||
//bm.Set(k, v[0])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (p *OppoType) ParseNotifyByURLValues(value url.Values) (bm map[string]interface{}, err error) {
|
||||
bm = make(map[string]interface{}, len(value)+1)
|
||||
for k, v := range value {
|
||||
if len(v) == 1 {
|
||||
bm[k] = v[0]
|
||||
//bm.Set(k, v[0])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -3,7 +3,6 @@ package oppo
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/haxqer/xthird/oppo"
|
||||
)
|
||||
|
||||
// 跟充值平台通信的加密key
|
||||
@@ -30,12 +29,12 @@ func (p *OppoType) Verify(ctx context.Context) (err error) {
|
||||
oppoPublicKey := "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCmreYIkPwVovKR8rLHWlFVw7YDfm9uQOJKL89Smt6ypXGVdrAKKl0wNYc3/jecAoPi2ylChfa2iRu5gunJyNmpWZzlCNRIau55fxGW0XEu553IiprOZcaw5OuYGlf60ga8QT6qToP0/dpiL/ZbmNUO9kUhosIjEu22uFgR+5cYyQIDAQAB"
|
||||
//oppoPublicKey := p.PublicKey
|
||||
// 解析请求参数
|
||||
bodyMap, err := oppo.ParseNotifyToBodyMap(g.RequestFromCtx(ctx).Request)
|
||||
bodyMap, err := p.ParseNotifyToBodyMap(g.RequestFromCtx(ctx).Request)
|
||||
if err != nil {
|
||||
// 解析失败, 处理错误逻辑
|
||||
return
|
||||
}
|
||||
|
||||
err = oppo.VerifySign(oppoPublicKey, bodyMap)
|
||||
err = p.VerifySign(oppoPublicKey, bodyMap)
|
||||
return
|
||||
}
|
||||
|
||||
80
package/pay/oppo/sign.go
Normal file
80
package/pay/oppo/sign.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package oppo
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/hmac"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ayflying/utility_go/package/pay/common"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
"hash"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (p *OppoType) GenLoginBaseStr(bm map[string]interface{}, appKey, appSecret string) (string, string) {
|
||||
baseStr := fmt.Sprintf("oauthConsumerKey=%s&oauthToken=%s&oauthSignatureMethod=HMAC-SHA1&oauthTimestamp=%d&oauthNonce=%d&oauthVersion=1.0&",
|
||||
appKey, url.QueryEscape(gconv.String(bm["token"])), time.Now().Unix(), rand.Int31n(100000000))
|
||||
|
||||
var h hash.Hash
|
||||
h = hmac.New(sha1.New, []byte(appSecret+"&"))
|
||||
h.Write([]byte(baseStr))
|
||||
|
||||
sign := url.QueryEscape(base64.StdEncoding.EncodeToString(h.Sum(nil)))
|
||||
return baseStr, sign
|
||||
}
|
||||
|
||||
func (p *OppoType) VerifySign(oppoPayPublicKey string, bm map[string]interface{}) (err error) {
|
||||
if oppoPayPublicKey == "" || bm == nil {
|
||||
return errors.New("oppoPayPublicKey or bm is nil")
|
||||
}
|
||||
|
||||
bodySign := bm["sign"].(string)
|
||||
bodySignType := RSA
|
||||
signData := fmt.Sprintf("notifyId=%s&partnerOrder=%s&productName=%s&productDesc=%s&price=%s&count=%s&attach=%s",
|
||||
bm["notifyId"], bm["partnerOrder"], bm["productName"],
|
||||
bm["productDesc"], bm["price"], bm["count"], bm["attach"])
|
||||
pKey := common.FormatPublicKey(oppoPayPublicKey)
|
||||
if err = p.verifySign(signData, bodySign, bodySignType, pKey); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *OppoType) verifySign(signData, sign, signType, oppoPayPublicKey string) (err error) {
|
||||
var (
|
||||
h hash.Hash
|
||||
hashs crypto.Hash
|
||||
block *pem.Block
|
||||
pubKey interface{}
|
||||
publicKey *rsa.PublicKey
|
||||
ok bool
|
||||
)
|
||||
signBytes, _ := base64.StdEncoding.DecodeString(sign)
|
||||
if block, _ = pem.Decode([]byte(oppoPayPublicKey)); block == nil {
|
||||
return errors.New("OPPO公钥Decode错误")
|
||||
}
|
||||
if pubKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
|
||||
return fmt.Errorf("x509.ParsePKIXPublicKey:%w", err)
|
||||
}
|
||||
if publicKey, ok = pubKey.(*rsa.PublicKey); !ok {
|
||||
return errors.New("OPPO公钥转换错误")
|
||||
}
|
||||
switch signType {
|
||||
case RSA:
|
||||
hashs = crypto.SHA1
|
||||
case RSA2:
|
||||
hashs = crypto.SHA256
|
||||
default:
|
||||
hashs = crypto.SHA256
|
||||
}
|
||||
h = hashs.New()
|
||||
h.Write([]byte(signData))
|
||||
return rsa.VerifyPKCS1v15(publicKey, hashs, h.Sum(nil), signBytes)
|
||||
}
|
||||
Reference in New Issue
Block a user