-
Notifications
You must be signed in to change notification settings - Fork 773
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
be393c5
commit f9d617e
Showing
14 changed files
with
874 additions
and
760 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ const ( | |
OK = "OK" | ||
DebugOff = 0 | ||
DebugOn = 1 | ||
Version = "1.5.25" | ||
Version = "1.5.26" | ||
) | ||
|
||
type DebugSwitch int8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package wechat | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/iGoogle-ink/gotil/xlog" | ||
) | ||
|
||
func TestDecryptOpenDataToStruct(t *testing.T) { | ||
data := "Kf3TdPbzEmhWMuPKtlKxIWDkijhn402w1bxoHL4kLdcKr6jT1jNcIhvDJfjXmJcgDWLjmBiIGJ5acUuSvxLws3WgAkERmtTuiCG10CKLsJiR+AXVk7B2TUQzsq88YVilDz/YAN3647REE7glGmeBPfvUmdbfDzhL9BzvEiuRhABuCYyTMz4iaM8hFjbLB1caaeoOlykYAFMWC5pZi9P8uw==" | ||
iv := "Cds8j3VYoGvnTp1BrjXdJg==" | ||
session := "lyY4HPQbaOYzZdG+JcYK9w==" | ||
phone := new(UserPhone) | ||
//解密开放数据 | ||
// encryptedData:包括敏感数据在内的完整用户信息的加密数据 | ||
// iv:加密算法的初始向量 | ||
// sessionKey:会话密钥 | ||
// beanPtr:需要解析到的结构体指针 | ||
err := DecryptOpenDataToStruct(data, iv, session, phone) | ||
if err != nil { | ||
xlog.Error(err) | ||
return | ||
} | ||
xlog.Debug("PhoneNumber:", phone.PhoneNumber) | ||
xlog.Debug("PurePhoneNumber:", phone.PurePhoneNumber) | ||
xlog.Debug("CountryCode:", phone.CountryCode) | ||
xlog.Debug("Watermark:", phone.Watermark) | ||
|
||
sessionKey := "tiihtNczf5v6AKRyjwEUhQ==" | ||
encryptedData := "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew==" | ||
iv2 := "r7BXXKkLb8qrSNn05n0qiA==" | ||
|
||
//微信小程序 用户信息 | ||
userInfo := new(AppletUserInfo) | ||
|
||
err = DecryptOpenDataToStruct(encryptedData, iv2, sessionKey, userInfo) | ||
if err != nil { | ||
xlog.Error(err) | ||
return | ||
} | ||
xlog.Debug("NickName:", userInfo.NickName) | ||
xlog.Debug("AvatarUrl:", userInfo.AvatarUrl) | ||
xlog.Debug("Country:", userInfo.Country) | ||
xlog.Debug("Province:", userInfo.Province) | ||
xlog.Debug("City:", userInfo.City) | ||
xlog.Debug("Gender:", userInfo.Gender) | ||
xlog.Debug("OpenId:", userInfo.OpenId) | ||
xlog.Debug("UnionId:", userInfo.UnionId) | ||
xlog.Debug("Watermark:", userInfo.Watermark) | ||
} | ||
|
||
func TestGetAppletAccessToken(t *testing.T) { | ||
token, err := GetAppletAccessToken("wxdaa2ab9ef87b5497", "AppSecret") | ||
if err != nil { | ||
xlog.Error(err) | ||
return | ||
} | ||
xlog.Debug("token:", token) | ||
} | ||
|
||
func TestCode2Session(t *testing.T) { | ||
session, err := Code2Session("wx2e92b2ff5ed4db71", "AppSecret", "081XxRPj1e8Krp0uGUQj1s0MPj1XxRP5") | ||
if err != nil { | ||
xlog.Error(err) | ||
return | ||
} | ||
xlog.Debug("Openid:", session.Openid) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
package wechat | ||
|
||
import ( | ||
"crypto/tls" | ||
"encoding/xml" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/iGoogle-ink/gopay" | ||
"github.com/iGoogle-ink/gotil" | ||
) | ||
|
||
// 统一下单 | ||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/open/chapter3_1.shtml | ||
func (w *Client) UnifiedOrder(bm gopay.BodyMap) (wxRsp *UnifiedOrderResponse, err error) { | ||
err = bm.CheckEmptyError("nonce_str", "body", "out_trade_no", "total_fee", "spbill_create_ip", "notify_url", "trade_type") | ||
if err != nil { | ||
return nil, err | ||
} | ||
var bs []byte | ||
if w.IsProd { | ||
bs, err = w.doProdPost(bm, unifiedOrder, nil) | ||
} else { | ||
bm.Set("total_fee", 101) | ||
bs, err = w.doSanBoxPost(bm, sandboxUnifiedOrder) | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
wxRsp = new(UnifiedOrderResponse) | ||
if err = xml.Unmarshal(bs, wxRsp); err != nil { | ||
return nil, fmt.Errorf("xml.Unmarshal(%s):%w", string(bs), err) | ||
} | ||
return wxRsp, nil | ||
} | ||
|
||
// 提交付款码支付 | ||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/open/chapter4_1.shtml | ||
func (w *Client) Micropay(bm gopay.BodyMap) (wxRsp *MicropayResponse, err error) { | ||
err = bm.CheckEmptyError("nonce_str", "body", "out_trade_no", "total_fee", "spbill_create_ip", "auth_code") | ||
if err != nil { | ||
return nil, err | ||
} | ||
var bs []byte | ||
if w.IsProd { | ||
bs, err = w.doProdPost(bm, microPay, nil) | ||
} else { | ||
bm.Set("total_fee", 1) | ||
bs, err = w.doSanBoxPost(bm, sandboxMicroPay) | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
wxRsp = new(MicropayResponse) | ||
if err = xml.Unmarshal(bs, wxRsp); err != nil { | ||
return nil, fmt.Errorf("xml.Unmarshal(%s):%w", string(bs), err) | ||
} | ||
return wxRsp, nil | ||
} | ||
|
||
// 查询订单 | ||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/open/chapter3_2.shtml | ||
func (w *Client) QueryOrder(bm gopay.BodyMap) (wxRsp *QueryOrderResponse, resBm gopay.BodyMap, err error) { | ||
err = bm.CheckEmptyError("nonce_str") | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
if bm.Get("out_trade_no") == gotil.NULL && bm.Get("transaction_id") == gotil.NULL { | ||
return nil, nil, errors.New("out_trade_no and transaction_id are not allowed to be null at the same time") | ||
} | ||
var bs []byte | ||
if w.IsProd { | ||
bs, err = w.doProdPost(bm, orderQuery, nil) | ||
} else { | ||
bs, err = w.doSanBoxPost(bm, sandboxOrderQuery) | ||
} | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
wxRsp = new(QueryOrderResponse) | ||
if err = xml.Unmarshal(bs, wxRsp); err != nil { | ||
return nil, nil, fmt.Errorf("xml.UnmarshalStruct(%s):%w", string(bs), err) | ||
} | ||
resBm = make(gopay.BodyMap) | ||
if err = xml.Unmarshal(bs, &resBm); err != nil { | ||
return nil, nil, fmt.Errorf("xml.UnmarshalBodyMap(%s):%w", string(bs), err) | ||
} | ||
return wxRsp, resBm, nil | ||
} | ||
|
||
// 关闭订单 | ||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/open/chapter3_3.shtml | ||
func (w *Client) CloseOrder(bm gopay.BodyMap) (wxRsp *CloseOrderResponse, err error) { | ||
err = bm.CheckEmptyError("nonce_str", "out_trade_no") | ||
if err != nil { | ||
return nil, err | ||
} | ||
var bs []byte | ||
if w.IsProd { | ||
bs, err = w.doProdPost(bm, closeOrder, nil) | ||
} else { | ||
bs, err = w.doSanBoxPost(bm, sandboxCloseOrder) | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
wxRsp = new(CloseOrderResponse) | ||
if err = xml.Unmarshal(bs, wxRsp); err != nil { | ||
return nil, fmt.Errorf("xml.Unmarshal(%s):%w", string(bs), err) | ||
} | ||
return wxRsp, nil | ||
} | ||
|
||
// 申请退款 | ||
// 注意:如已使用client.AddCertFilePath()或client.AddCertFileContent()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传 nil,否则,3证书Path均不可空 | ||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/open/chapter3_4.shtml | ||
func (w *Client) Refund(bm gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath interface{}) (wxRsp *RefundResponse, resBm gopay.BodyMap, err error) { | ||
if err = checkCertFilePathOrContent(certFilePath, keyFilePath, pkcs12FilePath); err != nil { | ||
return nil, nil, err | ||
} | ||
err = bm.CheckEmptyError("nonce_str", "out_refund_no", "total_fee", "refund_fee") | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
if bm.Get("out_trade_no") == gotil.NULL && bm.Get("transaction_id") == gotil.NULL { | ||
return nil, nil, errors.New("out_trade_no and transaction_id are not allowed to be null at the same time") | ||
} | ||
var ( | ||
bs []byte | ||
tlsConfig *tls.Config | ||
) | ||
if w.IsProd { | ||
if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil { | ||
return nil, nil, err | ||
} | ||
bs, err = w.doProdPost(bm, refund, tlsConfig) | ||
} else { | ||
bs, err = w.doSanBoxPost(bm, sandboxRefund) | ||
} | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
wxRsp = new(RefundResponse) | ||
if err = xml.Unmarshal(bs, wxRsp); err != nil { | ||
return nil, nil, fmt.Errorf("xml.UnmarshalStruct(%s):%w", string(bs), err) | ||
} | ||
resBm = make(gopay.BodyMap) | ||
if err = xml.Unmarshal(bs, &resBm); err != nil { | ||
return nil, nil, fmt.Errorf("xml.UnmarshalBodyMap(%s):%w", string(bs), err) | ||
} | ||
return wxRsp, resBm, nil | ||
} | ||
|
||
// 查询退款 | ||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/open/chapter3_5.shtml | ||
func (w *Client) QueryRefund(bm gopay.BodyMap) (wxRsp *QueryRefundResponse, resBm gopay.BodyMap, err error) { | ||
err = bm.CheckEmptyError("nonce_str") | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
if bm.Get("refund_id") == gotil.NULL && bm.Get("out_refund_no") == gotil.NULL && bm.Get("transaction_id") == gotil.NULL && bm.Get("out_trade_no") == gotil.NULL { | ||
return nil, nil, errors.New("refund_id, out_refund_no, out_trade_no, transaction_id are not allowed to be null at the same time") | ||
} | ||
var bs []byte | ||
if w.IsProd { | ||
bs, err = w.doProdPost(bm, refundQuery, nil) | ||
} else { | ||
bs, err = w.doSanBoxPost(bm, sandboxRefundQuery) | ||
} | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
wxRsp = new(QueryRefundResponse) | ||
if err = xml.Unmarshal(bs, wxRsp); err != nil { | ||
return nil, nil, fmt.Errorf("xml.UnmarshalStruct(%s):%w", string(bs), err) | ||
} | ||
resBm = make(gopay.BodyMap) | ||
if err = xml.Unmarshal(bs, &resBm); err != nil { | ||
return nil, nil, fmt.Errorf("xml.UnmarshalBodyMap(%s):%w", string(bs), err) | ||
} | ||
return wxRsp, resBm, nil | ||
} | ||
|
||
// 撤销订单 | ||
// 注意:如已使用client.AddCertFilePath()或client.AddCertFileContent()添加过证书,参数certFilePath、keyFilePath、pkcs12FilePath全传 nil,否则,3证书Path均不可空 | ||
// 文档地址:https://pay.weixin.qq.com/wiki/doc/api/wxpay_v2/open/chapter4_3.shtml | ||
func (w *Client) Reverse(bm gopay.BodyMap, certFilePath, keyFilePath, pkcs12FilePath interface{}) (wxRsp *ReverseResponse, err error) { | ||
if err = checkCertFilePathOrContent(certFilePath, keyFilePath, pkcs12FilePath); err != nil { | ||
return nil, err | ||
} | ||
err = bm.CheckEmptyError("nonce_str", "out_trade_no") | ||
if err != nil { | ||
return nil, err | ||
} | ||
var ( | ||
bs []byte | ||
tlsConfig *tls.Config | ||
) | ||
if w.IsProd { | ||
if tlsConfig, err = w.addCertConfig(certFilePath, keyFilePath, pkcs12FilePath); err != nil { | ||
return nil, err | ||
} | ||
bs, err = w.doProdPost(bm, reverse, tlsConfig) | ||
} else { | ||
bs, err = w.doSanBoxPost(bm, sandboxReverse) | ||
} | ||
if err != nil { | ||
return nil, err | ||
} | ||
wxRsp = new(ReverseResponse) | ||
if err = xml.Unmarshal(bs, wxRsp); err != nil { | ||
return nil, fmt.Errorf("xml.Unmarshal(%s):%w", string(bs), err) | ||
} | ||
return wxRsp, nil | ||
} |
Oops, something went wrong.