Skip to content

Commit

Permalink
v1.5.65
Browse files Browse the repository at this point in the history
  • Loading branch information
iGoogle-ink committed Dec 8, 2021
1 parent 42e2b0e commit 3f25b44
Show file tree
Hide file tree
Showing 13 changed files with 224 additions and 43 deletions.
6 changes: 3 additions & 3 deletions alipay/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ func (a *Client) RequestParam(bm gopay.BodyMap, method string) (string, error) {
if bm.GetString("sign") == "" {
sign, err = GetRsaSign(bm, bm.GetString("sign_type"), a.privateKey)
if err != nil {
return "", fmt.Errorf("GetRsaSign Error: %v", err)
return "", fmt.Errorf("GetRsaSign Error: %w", err)
}
bm.Set("sign", sign)
}
Expand Down Expand Up @@ -162,7 +162,7 @@ func (a *Client) doAliPaySelf(ctx context.Context, bm gopay.BodyMap, method stri
if bm.GetString("sign") == "" {
sign, err = GetRsaSign(bm, bm.GetString("sign_type"), a.privateKey)
if err != nil {
return nil, fmt.Errorf("GetRsaSign Error: %v", err)
return nil, fmt.Errorf("GetRsaSign Error: %w", err)
}
bm.Set("sign", sign)
}
Expand Down Expand Up @@ -243,7 +243,7 @@ func (a *Client) doAliPay(ctx context.Context, bm gopay.BodyMap, method string,
}
sign, err := GetRsaSign(pubBody, pubBody.GetString("sign_type"), a.privateKey)
if err != nil {
return nil, fmt.Errorf("GetRsaSign Error: %v", err)
return nil, fmt.Errorf("GetRsaSign Error: %w", err)
}
pubBody.Set("sign", sign)
if a.DebugSwitch == gopay.DebugOn {
Expand Down
13 changes: 13 additions & 0 deletions body_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,16 @@ func TestBodyMapMarshalSlice(t *testing.T) {
bss, _ := xml.Marshal(bm)
xlog.Debug("body:", string(bss))
}

func TestSliceTest(t *testing.T) {
var rs []string
rs = append(rs, "SOFTWARE")
rs = append(rs, "SECURITY")
rs = append(rs, "LOVE_MARRIAGE")

bm := make(BodyMap)
bm.Set("sub_mchid", "2021060717").
Set("advertising_industry_filters", rs)

xlog.Debugf("%s", bm.JsonBody())
}
6 changes: 5 additions & 1 deletion doc/wechat_v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,11 @@ wechat.V3DecryptScoreNotifyCipherText()
* 修改结算账号:`client.V3Apply4SubModifySettlement()`
* 查询结算账户:`client.V3Apply4SubQuerySettlement()`
* <font color='#07C160' size='4'>点金计划(服务商)</font>
* 待实现-[文档](https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_5_1.shtml)
* 点金计划管理:`client.V3GoldPlanManage()`
* 商家小票管理:`client.V3GoldPlanBillManage()`
* 同业过滤标签管理:`client.V3GoldPlanFilterManage()`
* 开通广告展示:`client.V3GoldPlanOpenAdShow()`
* 关闭广告展示:`client.V3GoldPlanCloseAdShow()`
* <font color='#07C160' size='4'>电商收付通(商户进件)</font>
* 二级商户进件:`client.V3EcommerceApply()`
* 查询申请状态:`client.V3EcommerceApplyStatus()`
Expand Down
9 changes: 8 additions & 1 deletion release_note.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
修改记录:
(1) 微信V3:新增 client.V3EcommerceApply(),二级商户进件
(2) 微信V3:新增 client.V3EcommerceApplyStatus(),查询申请状态
(3) 微信V3:公有化 wechat.GetReleaseSign()、wechat.GetSandBoxSign() 方法
(3) 微信V3:新增 client.V3GoldPlanManage(),点金计划管理
(4) 微信V3:新增 client.V3GoldPlanBillManage(),商家小票管理
(5) 微信V3:新增 client.V3GoldPlanFilterManage(),同业过滤标签管理
(6) 微信V3:新增 client.V3GoldPlanOpenAdShow(),开通广告展示
(7) 微信V3:新增 client.V3GoldPlanCloseAdShow(),关闭广告展示
(8) 微信V3:公有化 wechat.GetReleaseSign()、wechat.GetSandBoxSign() 方法
(9) 微信V3:修改 client.V3PartnerCloseOrder() 入参参数
(10) GoPay:一些小修改优化

版本号:Release 1.5.64
修改记录:
Expand Down
5 changes: 3 additions & 2 deletions wechat/v3/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func GetPlatformCerts(ctx context.Context, mchid, apiV3Key, serialNo, privateKey
}

// Deprecated
// 推荐直接使用 GetAndSelectNewestCert() 方法
// 推荐直接使用 client.GetAndSelectNewestCert() 方法
// 获取微信平台证书公钥(获取后自行保存使用,如需定期刷新功能,自行实现)
// 注意事项
// 如果自行实现验证平台签名逻辑的话,需要注意以下事项:
Expand Down Expand Up @@ -171,6 +171,7 @@ func (c *ClientV3) GetPlatformCerts() (certs *PlatformCertRsp, err error) {
}

// Deprecated
// client 已内部集成证书获取并维护,无需再Set正式
// 设置 微信支付平台证书 和 证书序列号
// 注意:请预先通过 client.GetPlatformCerts() 获取 微信平台公钥证书 和 证书序列号
// 部分接口请求参数中敏感信息加密,使用此 微信支付平台公钥 和 证书序列号
Expand All @@ -192,7 +193,7 @@ func (c *ClientV3) DecryptCerts(ciphertext, nonce, additional string) (wxCerts s
cipherBytes, _ := base64.StdEncoding.DecodeString(ciphertext)
decrypt, err := aes.GCMDecrypt(cipherBytes, []byte(nonce), []byte(additional), c.ApiV3Key)
if err != nil {
return "", fmt.Errorf("aes.GCMDecrypt, err:%+v", err)
return "", fmt.Errorf("aes.GCMDecrypt, err:%w", err)
}
return string(decrypt), nil
}
Expand Down
27 changes: 24 additions & 3 deletions wechat/v3/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package wechat

import (
"context"
"crypto/rsa"
"crypto/sha256"
"encoding/hex"
"io/ioutil"
Expand Down Expand Up @@ -103,20 +104,23 @@ func TestGetAndSelectNewestCert(t *testing.T) {
xlog.Infof("WxContent: \n%s", cert)
}

func TestV3VerifySign(t *testing.T) {
func TestV3VerifySignByPK(t *testing.T) {
// type SignInfo struct {
// HeaderTimestamp string `json:"Wechatpay-Timestamp"`
// HeaderNonce string `json:"Wechatpay-Nonce"`
// HeaderSignature string `json:"Wechatpay-Signature"`
// HeaderSerial string `json:"Wechatpay-Serial"`
// SignBody string `json:"sign_body"`
//}

wxPublicKey := &rsa.PublicKey{}

timestamp := "1609149813"
nonce := "c4682f0902e4c7fd5cfb7568a2a45e1b"
signBody := `{"code_url":"weixin://wxpay/bizpayurl?pr=5zPMHa4zz"}`
signature := "D/nRx+h1To/ybCJkJYTXptoSp6+UVPsKNlJ2AsHMf76rXq2qAYDSnoOTB4HRc8ZlPNck5JfeZ19lDXAJ/N9gyvWEwE3n01HNhaKqxOjW0C1KROCtxAj1Wd2qtMyiCzh/Azuk15eIHjht03teGQFDmowoOBSlMg9qOBaK8MNfwFcXvV3J12AMbFFR7s4cXbqzuk2qBeMAz6VrKDAwDHxZOWFqME59mg4bPWwBTNyYeCQVR2sqPflLvY1zttEGMN3s/CDvgLQ/SXZrAsHlS2lkDVHEc/sP9q0x9oU8lFL6DhD6eDU2mVP3pt7CPD/5QAnGnINaHIcZVj6Vb4l3PKzeog=="

err = V3VerifySign(timestamp, nonce, signBody, signature, "WxPublicKeyContent")
err = V3VerifySignByPK(timestamp, nonce, signBody, signature, wxPublicKey)
if err != nil {
xlog.Error(err)
return
Expand Down Expand Up @@ -301,7 +305,6 @@ func TestV3BillDownLoadBill(t *testing.T) {
}

func TestV3ProfitSharingOrder(t *testing.T) {
client.autoSign = true
var rs []*ProfitSharingReceiver
item := &ProfitSharingReceiver{
Type: "PERSONAL_OPENID",
Expand Down Expand Up @@ -448,3 +451,21 @@ func TestClientV3_V3ComplaintUploadImage(t *testing.T) {
}
xlog.Errorf("wxRsp: %s", wxRsp.Error)
}

func TestV3GoldPlanFilterManage(t *testing.T) {
var rs []string
rs = append(rs, "SOFTWARE")
rs = append(rs, "SECURITY")
rs = append(rs, "LOVE_MARRIAGE")

bm := make(gopay.BodyMap)
bm.Set("sub_mchid", "2021060717").
Set("advertising_industry_filters", rs)

wxRsp, err := client.V3GoldPlanFilterManage(ctx, bm)
if err != nil {
xlog.Error(err)
return
}
xlog.Debugf("wxRsp: %#v", wxRsp)
}
2 changes: 1 addition & 1 deletion wechat/v3/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ const (
v3GoldPlanBillManage = "/v3/goldplan/merchants/changecustompagestatus" // 商家小票管理 POST
v3GoldPlanFilterManage = "/v3/goldplan/merchants/set-advertising-industry-filter" // 同业过滤标签管理 POST
v3GoldPlanOpenAdShow = "/v3/goldplan/merchants/open-advertising-show" // 开通广告展示 PATCH
v3GoldPlanCloseAdShow = "/v3/goldplan/merchants/close-advertising-show" // 关闭广告展示 PATCH
v3GoldPlanCloseAdShow = "/v3/goldplan/merchants/close-advertising-show" // 关闭广告展示 POST

// 消费者投诉2.0
v3ComplaintList = "/v3/merchant-service/complaints-v2" // 查询投诉单列表 GET
Expand Down
28 changes: 14 additions & 14 deletions wechat/v3/encrypt_decrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ func V3DecryptNotifyCipherText(ciphertext, nonce, additional, apiV3Key string) (
cipherBytes, _ := base64.StdEncoding.DecodeString(ciphertext)
decrypt, err := aes.GCMDecrypt(cipherBytes, []byte(nonce), []byte(additional), []byte(apiV3Key))
if err != nil {
return nil, fmt.Errorf("aes.GCMDecrypt, err:%+v", err)
return nil, fmt.Errorf("aes.GCMDecrypt, err:%w", err)
}
result = &V3DecryptResult{}
if err = json.Unmarshal(decrypt, result); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s), err:%+v", string(decrypt), err)
return nil, fmt.Errorf("json.Unmarshal(%s), err:%w", string(decrypt), err)
}
return result, nil
}
Expand All @@ -85,11 +85,11 @@ func V3DecryptPartnerNotifyCipherText(ciphertext, nonce, additional, apiV3Key st
cipherBytes, _ := base64.StdEncoding.DecodeString(ciphertext)
decrypt, err := aes.GCMDecrypt(cipherBytes, []byte(nonce), []byte(additional), []byte(apiV3Key))
if err != nil {
return nil, fmt.Errorf("aes.GCMDecrypt, err:%+v", err)
return nil, fmt.Errorf("aes.GCMDecrypt, err:%w", err)
}
result = &V3DecryptPartnerResult{}
if err = json.Unmarshal(decrypt, result); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s), err:%+v", string(decrypt), err)
return nil, fmt.Errorf("json.Unmarshal(%s), err:%w", string(decrypt), err)
}
return result, nil
}
Expand All @@ -99,11 +99,11 @@ func V3DecryptRefundNotifyCipherText(ciphertext, nonce, additional, apiV3Key str
cipherBytes, _ := base64.StdEncoding.DecodeString(ciphertext)
decrypt, err := aes.GCMDecrypt(cipherBytes, []byte(nonce), []byte(additional), []byte(apiV3Key))
if err != nil {
return nil, fmt.Errorf("aes.GCMDecrypt, err:%+v", err)
return nil, fmt.Errorf("aes.GCMDecrypt, err:%w", err)
}
result = &V3DecryptRefundResult{}
if err = json.Unmarshal(decrypt, result); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s), err:%+v", string(decrypt), err)
return nil, fmt.Errorf("json.Unmarshal(%s), err:%w", string(decrypt), err)
}
return result, nil
}
Expand All @@ -113,11 +113,11 @@ func V3DecryptPartnerRefundNotifyCipherText(ciphertext, nonce, additional, apiV3
cipherBytes, _ := base64.StdEncoding.DecodeString(ciphertext)
decrypt, err := aes.GCMDecrypt(cipherBytes, []byte(nonce), []byte(additional), []byte(apiV3Key))
if err != nil {
return nil, fmt.Errorf("aes.GCMDecrypt, err:%+v", err)
return nil, fmt.Errorf("aes.GCMDecrypt, err:%w", err)
}
result = &V3DecryptPartnerRefundResult{}
if err = json.Unmarshal(decrypt, result); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s), err:%+v", string(decrypt), err)
return nil, fmt.Errorf("json.Unmarshal(%s), err:%w", string(decrypt), err)
}
return result, nil
}
Expand All @@ -127,11 +127,11 @@ func V3DecryptCombineNotifyCipherText(ciphertext, nonce, additional, apiV3Key st
cipherBytes, _ := base64.StdEncoding.DecodeString(ciphertext)
decrypt, err := aes.GCMDecrypt(cipherBytes, []byte(nonce), []byte(additional), []byte(apiV3Key))
if err != nil {
return nil, fmt.Errorf("aes.GCMDecrypt, err:%+v", err)
return nil, fmt.Errorf("aes.GCMDecrypt, err:%w", err)
}
result = &V3DecryptCombineResult{}
if err = json.Unmarshal(decrypt, result); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s), err:%+v", string(decrypt), err)
return nil, fmt.Errorf("json.Unmarshal(%s), err:%w", string(decrypt), err)
}
return result, nil
}
Expand All @@ -141,11 +141,11 @@ func V3DecryptProfitShareNotifyCipherText(ciphertext, nonce, additional, apiV3Ke
cipherBytes, _ := base64.StdEncoding.DecodeString(ciphertext)
decrypt, err := aes.GCMDecrypt(cipherBytes, []byte(nonce), []byte(additional), []byte(apiV3Key))
if err != nil {
return nil, fmt.Errorf("aes.GCMDecrypt, err:%+v", err)
return nil, fmt.Errorf("aes.GCMDecrypt, err:%w", err)
}
result = &V3DecryptProfitShareResult{}
if err = json.Unmarshal(decrypt, result); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s), err:%+v", string(decrypt), err)
return nil, fmt.Errorf("json.Unmarshal(%s), err:%w", string(decrypt), err)
}
return result, nil
}
Expand All @@ -155,11 +155,11 @@ func V3DecryptScoreNotifyCipherText(ciphertext, nonce, additional, apiV3Key stri
cipherBytes, _ := base64.StdEncoding.DecodeString(ciphertext)
decrypt, err := aes.GCMDecrypt(cipherBytes, []byte(nonce), []byte(additional), []byte(apiV3Key))
if err != nil {
return nil, fmt.Errorf("aes.GCMDecrypt, err:%+v", err)
return nil, fmt.Errorf("aes.GCMDecrypt, err:%w", err)
}
result = &V3DecryptScoreResult{}
if err = json.Unmarshal(decrypt, result); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s), err:%+v", string(decrypt), err)
return nil, fmt.Errorf("json.Unmarshal(%s), err:%w", string(decrypt), err)
}
return result, nil
}
123 changes: 123 additions & 0 deletions wechat/v3/gold_plan.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package wechat

import (
"context"
"encoding/json"
"fmt"
"net/http"

"github.com/go-pay/gopay"
)

// 点金计划管理API
// Code = 0 is success
// 服务商文档:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_5_1.shtml
func (c *ClientV3) V3GoldPlanManage(ctx context.Context, bm gopay.BodyMap) (wxRsp *GoldPlanManageRsp, err error) {
authorization, err := c.authorization(MethodPost, v3GoldPlanManage, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(ctx, bm, v3GoldPlanManage, authorization)
if err != nil {
return nil, err
}
wxRsp = &GoldPlanManageRsp{Code: Success, SignInfo: si}
wxRsp.Response = new(GoldPlanManage)
if err = json.Unmarshal(bs, wxRsp.Response); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s):%w", string(bs), err)
}
if res.StatusCode != http.StatusOK {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 商家小票管理API
// Code = 0 is success
// 服务商文档:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_5_2.shtml
func (c *ClientV3) V3GoldPlanBillManage(ctx context.Context, bm gopay.BodyMap) (wxRsp *GoldPlanManageRsp, err error) {
authorization, err := c.authorization(MethodPost, v3GoldPlanBillManage, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(ctx, bm, v3GoldPlanBillManage, authorization)
if err != nil {
return nil, err
}
wxRsp = &GoldPlanManageRsp{Code: Success, SignInfo: si}
wxRsp.Response = new(GoldPlanManage)
if err = json.Unmarshal(bs, wxRsp.Response); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s):%w", string(bs), err)
}
if res.StatusCode != http.StatusOK {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 同业过滤标签管理API
// Code = 0 is success
// 服务商文档:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_5_3.shtml
func (c *ClientV3) V3GoldPlanFilterManage(ctx context.Context, bm gopay.BodyMap) (wxRsp *EmptyRsp, err error) {
authorization, err := c.authorization(MethodPost, v3GoldPlanFilterManage, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(ctx, bm, v3GoldPlanFilterManage, authorization)
if err != nil {
return nil, err
}
wxRsp = &EmptyRsp{Code: Success, SignInfo: si}
if res.StatusCode != http.StatusNoContent {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 开通广告展示API
// Code = 0 is success
// 服务商文档:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_5_4.shtml
func (c *ClientV3) V3GoldPlanOpenAdShow(ctx context.Context, bm gopay.BodyMap) (wxRsp *EmptyRsp, err error) {
authorization, err := c.authorization(MethodPATCH, v3GoldPlanOpenAdShow, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPatch(ctx, bm, v3GoldPlanOpenAdShow, authorization)
if err != nil {
return nil, err
}
wxRsp = &EmptyRsp{Code: Success, SignInfo: si}
if res.StatusCode != http.StatusNoContent {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 关闭广告展示API
// Code = 0 is success
// 服务商文档:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_5_5.shtml
func (c *ClientV3) V3GoldPlanCloseAdShow(ctx context.Context, bm gopay.BodyMap) (wxRsp *EmptyRsp, err error) {
authorization, err := c.authorization(MethodPATCH, v3GoldPlanCloseAdShow, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(ctx, bm, v3GoldPlanCloseAdShow, authorization)
if err != nil {
return nil, err
}
wxRsp = &EmptyRsp{Code: Success, SignInfo: si}
if res.StatusCode != http.StatusNoContent {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}
Loading

0 comments on commit 3f25b44

Please sign in to comment.