master
李光春 2 years ago
parent b15a3dc16d
commit b47d8317e2

@ -34,9 +34,9 @@ func NewCertificatesResult(result CertificatesResponse, body []byte, http gorequ
// Certificates 获取平台证书列表
// https://pay.weixin.qq.com/wiki/doc/apiv3/apis/wechatpay5_1.shtml
func (app *App) Certificates() *CertificatesResult {
func (c *Client) Certificates() *CertificatesResult {
// 请求
request, err := app.request("https://api.mch.weixin.qq.com/v3/certificates", map[string]interface{}{}, http.MethodGet)
request, err := c.request("https://api.mch.weixin.qq.com/v3/certificates", map[string]interface{}{}, http.MethodGet)
if err != nil {
return NewCertificatesResult(CertificatesResponse{}, request.ResponseBody, request, err)
}

@ -10,7 +10,7 @@ const (
// SDK 相关信息
const (
Version = "1.0.0" // SDK 版本
Version = "1.0.1" // SDK 版本
UserAgentFormat = "WechatPay-Go/%s (%s) GO/%s" // UserAgent中的信息
)

@ -22,26 +22,26 @@ type GetJsApiResult struct {
}
// GetJsApi JSAPI调起支付API https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_4.shtml
func (app *App) GetJsApi(param GetJsApi) (result GetJsApiResult, err error) {
func (c *Client) GetJsApi(param GetJsApi) (result GetJsApiResult, err error) {
// sign params
timeStamp := time.Now().Unix()
nonce := gorandom.Alphanumeric(32)
result.AppId = app.subAppid
result.AppId = c.config.SubAppid
result.TimeStamp = fmt.Sprintf("%v", timeStamp) // 时间戳
result.NonceStr = nonce // 随机字符串
result.Package = param.Package // 订单详情扩展字符串
// 签名
message := fmt.Sprintf("%s\n%s\n%s\n%s\n", app.subAppid, fmt.Sprintf("%v", timeStamp), nonce, param.Package)
message := fmt.Sprintf("%s\n%s\n%s\n%s\n", c.config.SubAppid, fmt.Sprintf("%v", timeStamp), nonce, param.Package)
signBytes, err := app.signPKCS1v15(message, []byte(app.mchSslKey))
signBytes, err := c.signPKCS1v15(message, []byte(c.config.MchSslKey))
if err != nil {
return result, err
}
sign := app.base64EncodeStr(signBytes)
sign := c.base64EncodeStr(signBytes)
result.PaySign = sign // 签名
result.SignType = "RSA" // 签名方式
return result, nil

@ -64,12 +64,12 @@ func NewPayPartnerTransactionsIdResult(result PayPartnerTransactionsIdResponse,
// PayPartnerTransactionsId 微信支付订单号查询
// https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_2.shtml
func (app *App) PayPartnerTransactionsId(transactionId string) *PayPartnerTransactionsIdResult {
func (c *Client) PayPartnerTransactionsId(transactionId string) *PayPartnerTransactionsIdResult {
// 参数
params := gorequest.NewParams()
// 请求
// 请求
request, err := app.request(fmt.Sprintf("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/id/%s?sp_mchid=%s&sub_mchid=%s", transactionId, app.spMchId, app.subMchId), params, http.MethodGet)
request, err := c.request(fmt.Sprintf("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/id/%s?sp_mchid=%s&sub_mchid=%s", transactionId, c.config.SpMchId, c.config.SubMchId), params, http.MethodGet)
if err != nil {
return NewPayPartnerTransactionsIdResult(PayPartnerTransactionsIdResponse{}, request.ResponseBody, request, err)
}

@ -23,15 +23,15 @@ func NewPayPartnerTransactionsJsapiResult(result PayPartnerTransactionsJsapiResp
// PayPartnerTransactionsJsapi JSAPI下单
// https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_1.shtml
func (app *App) PayPartnerTransactionsJsapi(notMustParams ...gorequest.Params) *PayPartnerTransactionsJsapiResult {
func (c *Client) PayPartnerTransactionsJsapi(notMustParams ...gorequest.Params) *PayPartnerTransactionsJsapiResult {
// 参数
params := gorequest.NewParamsWith(notMustParams...)
params.Set("sp_appid", app.spAppid) // 服务商应用ID
params.Set("sp_mchid", app.spMchId) // 服务商户号
params.Set("sub_appid", app.subAppid) // 子商户应用ID
params.Set("sub_mchid", app.subMchId) // 子商户号
params.Set("sp_appid", c.config.SpAppid) // 服务商应用ID
params.Set("sp_mchid", c.config.SpMchId) // 服务商户号
params.Set("sub_appid", c.config.SubAppid) // 子商户应用ID
params.Set("sub_mchid", c.config.SubMchId) // 子商户号
// 请求
request, err := app.request("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi", params, http.MethodPost)
request, err := c.request("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi", params, http.MethodPost)
if err != nil {
return NewPayPartnerTransactionsJsapiResult(PayPartnerTransactionsJsapiResponse{}, request.ResponseBody, request, err)
}

@ -18,13 +18,13 @@ func NewPayPartnerTransactionsOutTradeNoCloseResult(body []byte, http gorequest.
// PayPartnerTransactionsOutTradeNoClose 关闭订单API
// https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_3.shtml
func (app *App) PayPartnerTransactionsOutTradeNoClose(outTradeNo string) *PayPartnerTransactionsOutTradeNoCloseResult {
func (c *Client) PayPartnerTransactionsOutTradeNoClose(outTradeNo string) *PayPartnerTransactionsOutTradeNoCloseResult {
// 参数
params := gorequest.NewParams()
params.Set("sp_mchid", app.spMchId) // 服务商户号
params.Set("sub_mchid", app.subMchId) // 子商户号
params.Set("sp_mchid", c.config.SpMchId) // 服务商户号
params.Set("sub_mchid", c.config.SubMchId) // 子商户号
// 请求
request, err := app.request(fmt.Sprintf("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/%s/close", outTradeNo), params, http.MethodPost)
request, err := c.request(fmt.Sprintf("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/%s/close", outTradeNo), params, http.MethodPost)
if err != nil {
return NewPayPartnerTransactionsOutTradeNoCloseResult(request.ResponseBody, request, err)
}

@ -67,11 +67,11 @@ func NewPayPartnerTransactionsOutTradeNoResult(result PayPartnerTransactionsOutT
// PayPartnerTransactionsOutTradeNo 商户订单号查询
// https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_2.shtml
func (app *App) PayPartnerTransactionsOutTradeNo(outTradeNo string) *PayPartnerTransactionsOutTradeNoResult {
func (c *Client) PayPartnerTransactionsOutTradeNo(outTradeNo string) *PayPartnerTransactionsOutTradeNoResult {
// 参数
params := gorequest.NewParams()
// 请求
request, err := app.request(fmt.Sprintf("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/%s?sp_mchid=%s&sub_mchid=%s", outTradeNo, app.spMchId, app.subMchId), params, http.MethodGet)
request, err := c.request(fmt.Sprintf("https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/%s?sp_mchid=%s&sub_mchid=%s", outTradeNo, c.config.SpMchId, c.config.SubMchId), params, http.MethodGet)
if err != nil {
return NewPayPartnerTransactionsOutTradeNoResult(PayPartnerTransactionsOutTradeNoResponse{}, request.ResponseBody, request, err)
}

@ -62,12 +62,12 @@ func NewRefundDomesticRefundsResult(result RefundDomesticRefundsResponse, body [
// RefundDomesticRefunds 申请退款API
// https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_9.shtml
func (app *App) RefundDomesticRefunds(notMustParams ...gorequest.Params) *RefundDomesticRefundsResult {
func (c *Client) RefundDomesticRefunds(notMustParams ...gorequest.Params) *RefundDomesticRefundsResult {
// 参数
params := gorequest.NewParamsWith(notMustParams...)
params.Set("sub_mchid", app.subMchId) // 子商户号
params.Set("sub_mchid", c.config.SubMchId) // 子商户号
// 请求
request, err := app.request("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds", params, http.MethodPost)
request, err := c.request("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds", params, http.MethodPost)
if err != nil {
return NewRefundDomesticRefundsResult(RefundDomesticRefundsResponse{}, request.ResponseBody, request, err)
}

@ -62,11 +62,11 @@ func NewRefundDomesticRefundsOutRefundNoResult(result RefundDomesticRefundsOutRe
// RefundDomesticRefundsOutRefundNo 查询单笔退款API
// https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_9.shtml
func (app *App) RefundDomesticRefundsOutRefundNo(outRefundNo string) *RefundDomesticRefundsOutRefundNoResult {
func (c *Client) RefundDomesticRefundsOutRefundNo(outRefundNo string) *RefundDomesticRefundsOutRefundNoResult {
// 参数
params := gorequest.NewParams()
// 请求
request, err := app.request("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/"+outRefundNo+"?sub_mchid="+app.subMchId, params, http.MethodGet)
request, err := c.request("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/"+outRefundNo+"?sub_mchid="+c.config.SubMchId, params, http.MethodGet)
if err != nil {
return NewRefundDomesticRefundsOutRefundNoResult(RefundDomesticRefundsOutRefundNoResponse{}, request.ResponseBody, request, err)
}

@ -19,7 +19,7 @@ import (
)
// 对消息的散列值进行数字签名
func (app *App) signPKCS1v15(msg string, privateKey []byte) ([]byte, error) {
func (c *Client) signPKCS1v15(msg string, privateKey []byte) ([]byte, error) {
block, _ := pem.Decode(privateKey)
if block == nil {
@ -36,7 +36,7 @@ func (app *App) signPKCS1v15(msg string, privateKey []byte) ([]byte, error) {
return nil, errors.New("private key format error")
}
sign, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, app.haSha256(msg))
sign, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, c.haSha256(msg))
if err != nil {
return nil, errors.New("sign error")
}
@ -45,12 +45,12 @@ func (app *App) signPKCS1v15(msg string, privateKey []byte) ([]byte, error) {
}
// base编码
func (app *App) base64EncodeStr(src []byte) string {
func (c *Client) base64EncodeStr(src []byte) string {
return base64.StdEncoding.EncodeToString(src)
}
// sha256加密
func (app *App) haSha256(str string) []byte {
func (c *Client) haSha256(str string) []byte {
h := sha256.New()
h.Write([]byte(str))
return h.Sum(nil)
@ -58,7 +58,7 @@ func (app *App) haSha256(str string) []byte {
// 生成身份认证信息
// https://wechatpay-api.gitbook.io/wechatpay-api-v3/qian-ming-zhi-nan-1/qian-ming-sheng-cheng
func (app *App) authorization(method string, paramMap map[string]interface{}, rawUrl string) (token string, err error) {
func (c *Client) authorization(method string, paramMap map[string]interface{}, rawUrl string) (token string, err error) {
// 请求报文主体
var signBody string
@ -86,7 +86,7 @@ func (app *App) authorization(method string, paramMap map[string]interface{}, ra
// 构造签名串
message := fmt.Sprintf(SignatureMessageFormat, method, canonicalUrl, timestamp, nonce, signBody)
sign, err := app.signSHA256WithRSA(message, app.getRsa([]byte(app.mchSslKey)))
sign, err := c.signSHA256WithRSA(message, c.getRsa([]byte(c.config.MchSslKey)))
if err != nil {
return token, err
@ -94,14 +94,14 @@ func (app *App) authorization(method string, paramMap map[string]interface{}, ra
authorization := fmt.Sprintf(
HeaderAuthorizationFormat, getAuthorizationType(),
app.spMchId, nonce, timestamp, app.mchSslSerialNo, sign,
c.config.SpMchId, nonce, timestamp, c.config.MchSslSerialNo, sign,
)
return authorization, nil
}
// 报文解密
func (app *App) decryptGCM(aesKey, nonceV, ciphertextV, additionalDataV string) ([]byte, error) {
func (c *Client) decryptGCM(aesKey, nonceV, ciphertextV, additionalDataV string) ([]byte, error) {
key := []byte(aesKey)
nonce := []byte(nonceV)
additionalData := []byte(additionalDataV)
@ -125,7 +125,7 @@ func (app *App) decryptGCM(aesKey, nonceV, ciphertextV, additionalDataV string)
}
// 对消息的散列值进行数字签名
func (app *App) getRsa(privateKey []byte) *rsa.PrivateKey {
func (c *Client) getRsa(privateKey []byte) *rsa.PrivateKey {
block, _ := pem.Decode(privateKey)
if block == nil {
@ -146,7 +146,7 @@ func (app *App) getRsa(privateKey []byte) *rsa.PrivateKey {
}
// 通过私钥对字符串以 SHA256WithRSA 算法生成签名信息
func (app *App) signSHA256WithRSA(source string, privateKey *rsa.PrivateKey) (signature string, err error) {
func (c *Client) signSHA256WithRSA(source string, privateKey *rsa.PrivateKey) (signature string, err error) {
if privateKey == nil {
return "", fmt.Errorf("private key should not be nil")
}

@ -6,58 +6,64 @@ import (
"gorm.io/gorm"
)
// App 微信支付服务器
type App struct {
spAppid string // 服务商应用ID
spMchId string // 服务商户号
subAppid string // 子商户应用ID
subMchId string // 子商户号
apiV2 string // APIv2密钥
apiV3 string // APIv3密钥
serialNo string // 序列号
mchSslSerialNo string // pem 证书号
mchSslCer string // pem 内容
mchSslKey string // pem key 内容
pgsql *gorm.DB // pgsql数据库
client *gorequest.App // 请求客户端
log *golog.Api // 日志服务
logTableName string // 日志表名
logStatus bool // 日志状态
type ConfigClient struct {
SpAppid string // 服务商应用ID
SpMchId string // 服务商户号
SubAppid string // 子商户应用ID
SubMchId string // 子商户号
ApiV2 string // APIv2密钥
ApiV3 string // APIv3密钥
SerialNo string // 序列号
MchSslSerialNo string // pem 证书号
MchSslCer string // pem 内容
MchSslKey string // pem key 内容
PgsqlDb *gorm.DB // pgsql数据库
}
// NewApp 实例化
func NewApp(spAppid, spMchId, subAppid, subMchId, apiV2, apiV3, serialNo, mchSslSerialNo, mchSslCer, mchSslKey string, pgsql *gorm.DB) *App {
app := &App{spAppid: spAppid, spMchId: spMchId, subAppid: subAppid, subMchId: subMchId, apiV2: apiV2, apiV3: apiV3, serialNo: serialNo, mchSslSerialNo: mchSslSerialNo, mchSslCer: mchSslCer, mchSslKey: mchSslKey}
app.client = gorequest.NewHttp()
if pgsql != nil {
app.pgsql = pgsql
app.logStatus = true
app.logTableName = "wechatpayopen"
app.log = golog.NewApi(&golog.ApiConfig{
Db: pgsql,
TableName: app.logTableName,
// Client 微信支付服务
type Client struct {
client *gorequest.App // 请求客户端
log *golog.Api // 日志服务
logTableName string // 日志表名
logStatus bool // 日志状态
config *ConfigClient // 配置
}
// NewClient 实例化
func NewClient(config *ConfigClient) *Client {
c := &Client{config: config}
c.client = gorequest.NewHttp()
if c.config.PgsqlDb != nil {
c.logStatus = true
c.logTableName = "wechatpayopen"
c.log = golog.NewApi(&golog.ApiConfig{
Db: c.config.PgsqlDb,
TableName: c.logTableName,
})
}
return app
return c
}
// NewAppConfig 实例化
func (app *App) NewAppConfig(subAppid, subMchId string) *App {
app.subAppid = subAppid
app.subMchId = subMchId
return app
// SubConfig 子商户配置
func (c *Client) SubConfig(subAppid, subMchId string) *Client {
c.config.SpAppid = subAppid
c.config.SubMchId = subMchId
return c
}
func (app *App) request(url string, params map[string]interface{}, method string) (resp gorequest.Response, err error) {
func (c *Client) request(url string, params map[string]interface{}, method string) (resp gorequest.Response, err error) {
// 认证
authorization, err := app.authorization(method, params, url)
authorization, err := c.authorization(method, params, url)
if err != nil {
return gorequest.Response{}, err
}
// 创建请求
client := app.client
client := c.client
// 设置请求地址
client.SetUri(url)
@ -83,8 +89,8 @@ func (app *App) request(url string, params map[string]interface{}, method string
}
// 日志
if app.logStatus == true {
go app.postgresqlLog(request)
if c.logStatus == true {
go c.postgresqlLog(request)
}
return request, err

Loading…
Cancel
Save