Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c19a66cb5 | ||
|
|
90b72129a5 |
@@ -47,7 +47,7 @@ func (p *OppoType) FileIdInfo(ctx context.Context, oauthToken string, ssoid stri
|
|||||||
})
|
})
|
||||||
getRes := getHtml.ReadAllString()
|
getRes := getHtml.ReadAllString()
|
||||||
gjson.DecodeTo(getRes, &res)
|
gjson.DecodeTo(getRes, &res)
|
||||||
g.Log().Debugf(ctx, "当前登陆请求的:%v", res)
|
//g.Log().Debugf(ctx, "当前登陆请求的:%v", res)
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
15
package/pay/vivo/client.go
Normal file
15
package/pay/vivo/client.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package vivo
|
||||||
|
|
||||||
|
type Pay struct {
|
||||||
|
AppId string
|
||||||
|
AppKey string
|
||||||
|
//AppSecret string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(cfg *Pay) (client *Pay) {
|
||||||
|
return &Pay{
|
||||||
|
AppId: cfg.AppId,
|
||||||
|
AppKey: cfg.AppKey,
|
||||||
|
//AppSecret: cfg.AppSecret,
|
||||||
|
}
|
||||||
|
}
|
||||||
9
package/pay/vivo/const.go
Normal file
9
package/pay/vivo/const.go
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package vivo
|
||||||
|
|
||||||
|
const (
|
||||||
|
AuthTokenUrl = "https://joint-account.vivo.com.cn/cp/user/auth"
|
||||||
|
LocationShanghai = "Asia/Shanghai"
|
||||||
|
|
||||||
|
RSA = "RSA"
|
||||||
|
RSA2 = "RSA2"
|
||||||
|
)
|
||||||
34
package/pay/vivo/model.go
Normal file
34
package/pay/vivo/model.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package vivo
|
||||||
|
|
||||||
|
type TokenAuthResponse struct {
|
||||||
|
ReturnCode int `json:"retcode"`
|
||||||
|
Data *TokenAuthResponseData `json:"data,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenAuthResponseData struct {
|
||||||
|
Success bool `json:"success,omitempty"`
|
||||||
|
OpenId string `json:"openid,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginType struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
Ssoid string `json:"ssoid"`
|
||||||
|
Channel int `json:"channel"`
|
||||||
|
AdId string `json:"adId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PayCallback struct {
|
||||||
|
AppId string `json:"appId"`
|
||||||
|
CpId string `json:"cpId"`
|
||||||
|
CpOrderNumber string `json:"cpOrderNumber"`
|
||||||
|
ExtInfo string `json:"extInfo"`
|
||||||
|
OrderAmount string `json:"orderAmount"`
|
||||||
|
OrderNumber string `json:"orderNumber"`
|
||||||
|
PayTime string `json:"payTime"`
|
||||||
|
RespCode string `json:"respCode"`
|
||||||
|
RespMsg string `json:"respMsg"`
|
||||||
|
SignMethod string `json:"signMethod"`
|
||||||
|
Signature string `json:"signature"`
|
||||||
|
TradeStatus string `json:"tradeStatus"`
|
||||||
|
TradeType string `json:"tradeType"`
|
||||||
|
}
|
||||||
3
package/pay/vivo/payment_api.go
Normal file
3
package/pay/vivo/payment_api.go
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
package vivo
|
||||||
|
|
||||||
|
|
||||||
48
package/pay/vivo/sign.go
Normal file
48
package/pay/vivo/sign.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package vivo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/gogf/gf/v2/crypto/gmd5"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/util/gconv"
|
||||||
|
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Pay) VerifySign(bm g.Map, key string) bool {
|
||||||
|
signature := bm["signature"]
|
||||||
|
delete(bm, "signature")
|
||||||
|
delete(bm, "signMethod")
|
||||||
|
sign := p.sign(bm, key)
|
||||||
|
return signature == sign
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pay) sign(bm g.Map, key string) string {
|
||||||
|
s, _ := p.buildSignStr(bm)
|
||||||
|
s += "&" + gmd5.MustEncrypt(key)
|
||||||
|
return gmd5.MustEncrypt(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pay) buildSignStr(bm g.Map) (string, error) {
|
||||||
|
var (
|
||||||
|
buf strings.Builder
|
||||||
|
keyList []string
|
||||||
|
)
|
||||||
|
for k := range bm {
|
||||||
|
keyList = append(keyList, k)
|
||||||
|
}
|
||||||
|
sort.Strings(keyList)
|
||||||
|
for _, k := range keyList {
|
||||||
|
if v := bm[k]; v != "" {
|
||||||
|
buf.WriteString(k)
|
||||||
|
buf.WriteByte('=')
|
||||||
|
buf.WriteString(gconv.String(v))
|
||||||
|
buf.WriteByte('&')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if buf.Len() <= 0 {
|
||||||
|
return "", errors.New("length is error")
|
||||||
|
}
|
||||||
|
return buf.String()[:buf.Len()-1], nil
|
||||||
|
}
|
||||||
49
package/pay/vivo/sign_test.go
Normal file
49
package/pay/vivo/sign_test.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
package vivo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestVerifySign(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
bm g.Map
|
||||||
|
key string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "testCase-01",
|
||||||
|
args: args{
|
||||||
|
bm: map[string]interface{}{
|
||||||
|
"appId": "111",
|
||||||
|
"cpId": "11",
|
||||||
|
"cpOrderNumber": "111",
|
||||||
|
"extInfo": "扩展参数",
|
||||||
|
"orderAmount": "1",
|
||||||
|
"orderNumber": "11",
|
||||||
|
"payTime": "20210610213219",
|
||||||
|
"respCode": "200",
|
||||||
|
"respMsg": "交易成功",
|
||||||
|
"signMethod": "MD5",
|
||||||
|
"signature": "111",
|
||||||
|
"tradeStatus": "0000",
|
||||||
|
"tradeType": "01",
|
||||||
|
"uid": "111",
|
||||||
|
},
|
||||||
|
key: "1111",
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := New(nil).VerifySign(tt.args.bm, tt.args.key); got != tt.want {
|
||||||
|
t.Errorf("VerifySign() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
52
package/pay/vivo/user_api.go
Normal file
52
package/pay/vivo/user_api.go
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package vivo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"github.com/gogf/gf/v2/os/gctx"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *Pay) AuthToken(bm g.Map) (rsp *TokenAuthResponse, err error) {
|
||||||
|
if _, ok := bm["opentoken"]; !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
//err = bm.CheckEmptyError("opentoken")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bs, err := p.doAuthToken(bm)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rsp = new(TokenAuthResponse)
|
||||||
|
if err = json.Unmarshal(bs, rsp); err != nil {
|
||||||
|
return nil, fmt.Errorf("json.Unmarshal(%s):%w", string(bs), err)
|
||||||
|
}
|
||||||
|
return rsp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pay) doAuthToken(bm g.Map) (bs []byte, err error) {
|
||||||
|
param := p.FormatURLParam(bm)
|
||||||
|
//httpClient := xhttp.NewClient()
|
||||||
|
//res, bs, errs := httpClient.Type(xhttp.TypeFormData).Post(AuthTokenUrl).SendString(param).EndBytes()
|
||||||
|
res, err := g.Client().Post(gctx.New(), AuthTokenUrl, param)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if res.StatusCode != 200 {
|
||||||
|
return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
|
||||||
|
}
|
||||||
|
return res.ReadAll(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化请求URL参数
|
||||||
|
func (p *Pay) FormatURLParam(body g.Map) (urlParam string) {
|
||||||
|
v := url.Values{}
|
||||||
|
for key, value := range body {
|
||||||
|
v.Add(key, value.(string))
|
||||||
|
}
|
||||||
|
return v.Encode()
|
||||||
|
}
|
||||||
70
package/pay/vivo/user_api_test.go
Normal file
70
package/pay/vivo/user_api_test.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package vivo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/gogf/gf/v2/frame/g"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAuthToken(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
bm g.Map
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantRsp *TokenAuthResponse
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "testCase-01",
|
||||||
|
args: args{
|
||||||
|
bm: map[string]interface{}{
|
||||||
|
"opentoken": "_STV1_797e3324f7e3f1a3_797e3324f7e3f1a3_8db97942_Awykia3hpb90kcu3l",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
wantRsp: nil,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
gotRsp, err := New(nil).AuthToken(tt.args.bm)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("AuthToken() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(gotRsp, tt.wantRsp) {
|
||||||
|
if gotRsp != nil {
|
||||||
|
marshal, _ := json.Marshal(gotRsp)
|
||||||
|
println(string(marshal))
|
||||||
|
}
|
||||||
|
t.Errorf("AuthToken() gotRsp = %v, want %v", gotRsp, tt.wantRsp)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFormatURLParam(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
body g.Map
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantUrlParam string
|
||||||
|
}{
|
||||||
|
{name: "testCase-01", args: args{body: map[string]interface{}{
|
||||||
|
"opentoken": "_STV1_797e3324f7e3f1a3_797e3324f7e3f1a3_8db97942_Abbccayhpb90kvd3m",
|
||||||
|
"123": "123",
|
||||||
|
}}},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if gotUrlParam := New(nil).FormatURLParam(tt.args.body); gotUrlParam != tt.wantUrlParam {
|
||||||
|
t.Errorf("FormatURLParam() = %v, want %v", gotUrlParam, tt.wantUrlParam)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user