Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ADD: PostFormAliPayAPISelfV2 实现用于支付宝带有文件上传的接口自行实现方法 #363

Merged
merged 6 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions alipay/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,72 @@
return nil
}

// FormAliPayAPISelfV2 用于支付宝带有文件上传的接口自行实现方法
// 注意:最新版本的支付宝接口,对于文件的上传已统一改为通过formData上传
// 请求form格式如下: {file: "fileData", "data": BodyMap{"key": "value"}}
// 其中file为file请求字段名称,data为其他请求参数(key为文件名,value为文件内容)
func (a *Client) PostFormAliPayAPISelfV2(ctx context.Context, bm gopay.BodyMap, method string, aliRsp any) (err error) {
var (
url string
sign string
)
fm := make(gopay.BodyMap)
if bm != nil {

Check failure on line 50 in alipay/request.go

View workflow job for this annotation

GitHub Actions / lint

S1031: unnecessary nil check around range (gosimple)
for k, v := range bm {
if _, ok := v.(*util.File); ok {
fm.Set(k, v)
bm.Remove(k)
continue
} else {
// 对form内容字段进行加密
str := bm.GetString(k)
bm.Remove(k)
if signedData, err := a.getStrRsaSign(str, bm.GetString("sign_type")); err == nil {
bm.Set(k, signedData)
}
}
}
}
bm.Set("method", method)
// check public parameter
a.checkPublicParam(bm)
// check sign, 需要先移除文件字段
if bm.GetString("sign") == "" {
sign, err = a.getRsaSign(bm, bm.GetString("sign_type"))
if err != nil {
return fmt.Errorf("GetRsaSign Error: %w", err)
}
bm.Set("sign", sign)
}
// 增加文件字段
for k, v := range fm {
bm.Set(k, v)
}
if a.DebugSwitch == gopay.DebugOn {
xlog.Debugf("Alipay_Request: %s", bm.JsonBody())
}
if a.IsProd {
url = baseUrlUtf8
} else {
url = sandboxBaseUrlUtf8
}
res, bs, err := a.hc.Req(xhttp.TypeMultipartFormData).Post(url).
SendMultipartBodyMap(bm).EndBytes(ctx)
if err != nil {
return nil
}
if a.DebugSwitch == gopay.DebugOn {
xlog.Debugf("Alipay_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
}
if res.StatusCode != 200 {
return fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
}
if err = json.Unmarshal(bs, aliRsp); err != nil {
return err
}
return nil
}

// 向支付宝发送自定义请求
func (a *Client) doAliPaySelf(ctx context.Context, bm gopay.BodyMap, method string) (bs []byte, err error) {
var (
Expand Down
30 changes: 30 additions & 0 deletions alipay/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,36 @@ func (a *Client) getRsaSign(bm gopay.BodyMap, signType string) (sign string, err
return
}

func (a *Client) getStrRsaSign(signParams string, signType string) (sign string, err error) {
var (
h hash.Hash
hashs crypto.Hash
encryptedBytes []byte
)
switch signType {
case RSA:
h = sha1.New()
hashs = crypto.SHA1
case RSA2:
h = sha256.New()
hashs = crypto.SHA256
default:
h = sha256.New()
hashs = crypto.SHA256
}
if a.DebugSwitch == gopay.DebugOn {
xlog.Debugf("Alipay_Request_SignStr: %s", signParams)
}
if _, err = h.Write([]byte(signParams)); err != nil {
return
}
if encryptedBytes, err = rsa.SignPKCS1v15(rand.Reader, a.privateKey, hashs, h.Sum(nil)); err != nil {
return util.NULL, fmt.Errorf("[%w]: %+v", gopay.SignatureErr, err)
}
sign = base64.StdEncoding.EncodeToString(encryptedBytes)
return
}

// =============================== 获取SignData ===============================

// 需注意的是,公钥签名模式和公钥证书签名模式的不同之处
Expand Down
Loading