Skip to content

Commit

Permalink
Merge pull request #14 from huangxingx/master
Browse files Browse the repository at this point in the history
支付宝添加企业付款功能和RSA2加密
  • Loading branch information
milkbobo authored Aug 27, 2019
2 parents a8f8b25 + 4c4c806 commit b850bcf
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 72 deletions.
2 changes: 1 addition & 1 deletion callback.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func AliAppCallback(w http.ResponseWriter, r *http.Request) (*common.AliWebPayRe
}
sort.Strings(signSlice)
signData := strings.Join(signSlice, "&")
if m["sign_type"] != "RSA" {
if m["sign_type"] != "RSA2" {
result = "error"
panic("签名类型未知")
}
Expand Down
152 changes: 152 additions & 0 deletions client/alipay.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package client

import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"github.com/milkbobo/gopay/common"
"hash"
"net/url"
"sort"
"strings"
"time"
)

type AliPayClient struct {
AppID string // 应用ID

PrivateKey *rsa.PrivateKey
PublicKey *rsa.PublicKey

RSAType string // RSA or RSA2
}

func (this *AliPayClient) PayToClient(charge *common.Charge) (map[string]string, error) {
var result = make(map[string]string)
var m = make(map[string]string)
var bizContent = make(map[string]string)
m["app_id"] = this.AppID
m["method"] = "alipay.fund.trans.toaccount.transfer"
m["format"] = "JSON"
m["charset"] = "utf-8"
m["timestamp"] = time.Now().Format("2006-01-02 15:04:05")
m["version"] = "1.0"
m["sign_type"] = this.RSAType

bizContent["out_biz_no"] = charge.TradeNum
bizContent["amount"] = AliyunMoneyFeeToString(charge.MoneyFee)
bizContent["payee_account"] = charge.AliAccount
bizContent["payee_type"] = charge.AliAccountType

bizContent["remark"] = TruncatedText(charge.Describe, 32)

bizContentJson, err := json.Marshal(bizContent)
if err != nil {
return result, errors.New("json.Marshal: " + err.Error())
}
m["biz_content"] = string(bizContentJson)

m["sign"] = this.GenSign(m)

requestUrl := fmt.Sprintf("%s?%s", "https://openapi.alipay.com/gateway.do", this.ToURL(m))

var resp map[string]interface{}
bytes, err := HTTPSC.GetData(requestUrl)
if err != nil {
return result, err
}
err = json.Unmarshal(bytes, &resp)
if err != nil {
return result, err
}

result, ok := resp["alipay_fund_trans_toaccount_transfer_response"].(map[string]string)
if !ok {
return result, errors.New(fmt.Sprintf("返回结果错误:%s", resp))
}

return result, nil
}

// GenSign 产生签名
func (this *AliPayClient) GenSign(m map[string]string) string {
var data []string

for k, v := range m {
if v != "" && k != "sign" {
data = append(data, fmt.Sprintf(`%s=%s`, k, v))
}
}
sort.Strings(data)
signData := strings.Join(data, "&")

s := this.getHash(this.RSAType)

_, err := s.Write([]byte(signData))
if err != nil {
panic(err)
}
hashByte := s.Sum(nil)
signByte, err := this.PrivateKey.Sign(rand.Reader, hashByte, crypto.SHA256)
if err != nil {
panic(err)
}

return base64.StdEncoding.EncodeToString(signByte)
}

// CheckSign 检测签名
func (this *AliPayClient) CheckSign(signData, sign string) {
signByte, err := base64.StdEncoding.DecodeString(sign)
if err != nil {
panic(err)
}
s := this.getHash(this.RSAType)
_, err = s.Write([]byte(signData))
if err != nil {
panic(err)
}
hashByte := s.Sum(nil)
err = rsa.VerifyPKCS1v15(this.PublicKey, this.getCrypto(), hashByte, signByte)
if err != nil {
panic(err)
}
}

// ToURL
func (this *AliPayClient) ToURL(m map[string]string) string {
var buf []string
for k, v := range m {
buf = append(buf, fmt.Sprintf("%s=%s", k, url.QueryEscape(v)))
}
return strings.Join(buf, "&")
}

func (this *AliPayClient) getRsa() string {
if this.RSAType == "" {
this.RSAType = "RSA"
}

return this.RSAType
}

func (this *AliPayClient) getCrypto() crypto.Hash {
if this.RSAType == "RSA2" {
return crypto.SHA256
}
return crypto.SHA1

}

func (this *AliPayClient) getHash(rasType string) hash.Hash {
if rasType == "RSA2" {
return sha256.New()
}
return sha1.New()
}
129 changes: 61 additions & 68 deletions client/alipayApp.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
package client

import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"github.com/milkbobo/gopay/common"
"net/url"
"sort"
"strings"
"time"
)

var defaultAliAppClient *AliAppClient

type AliAppClient struct {
*AliPayClient
SellerID string //合作者ID
AppID string // 应用ID
PrivateKey *rsa.PrivateKey
PublicKey *rsa.PublicKey
//AppID string // 应用ID
//PrivateKey *rsa.PrivateKey
//PublicKey *rsa.PublicKey
}

func InitAliAppClient(c *AliAppClient) {
Expand All @@ -44,7 +37,7 @@ func (this *AliAppClient) Pay(charge *common.Charge) (map[string]string, error)
m["timestamp"] = time.Now().Format("2006-01-02 15:04:05")
m["version"] = "1.0"
m["notify_url"] = charge.CallbackURL
m["sign_type"] = "RSA"
m["sign_type"] = this.AliPayClient.RSAType
bizContent["subject"] = TruncatedText(charge.Describe, 32)
bizContent["out_trade_no"] = charge.TradeNum
bizContent["product_code"] = "QUICK_MSECURITY_PAY"
Expand All @@ -65,9 +58,9 @@ func (this *AliAppClient) CloseOrder(charge *common.Charge) (map[string]string,
return map[string]string{}, errors.New("暂未开发该功能")
}

func (this *AliAppClient) PayToClient(charge *common.Charge) (map[string]string, error) {
return map[string]string{}, errors.New("暂未开发该功能")
}
//func (this *AliAppClient) PayToClient(charge *common.Charge) (map[string]string, error) {
// return map[string]string{}, errors.New("暂未开发该功能")
//}

// 订单查询
func (this *AliAppClient) QueryOrder(outTradeNo string) (common.AliWebAppQueryResult, error) {
Expand All @@ -78,7 +71,7 @@ func (this *AliAppClient) QueryOrder(outTradeNo string) (common.AliWebAppQueryRe
m["charset"] = "utf-8"
m["timestamp"] = time.Now().Format("2006-01-02 15:04:05")
m["version"] = "1.0"
m["sign_type"] = "RSA"
m["sign_type"] = this.AliPayClient.RSAType
bizContent := map[string]string{"out_trade_no": outTradeNo}
bizContentJson, err := json.Marshal(bizContent)
if err != nil {
Expand All @@ -93,55 +86,55 @@ func (this *AliAppClient) QueryOrder(outTradeNo string) (common.AliWebAppQueryRe
return GetAlipayApp(url)
}

// GenSign 产生签名
func (this *AliAppClient) GenSign(m map[string]string) string {
var data []string

for k, v := range m {
if v != "" && k != "sign" {
data = append(data, fmt.Sprintf(`%s=%s`, k, v))
}
}
sort.Strings(data)
signData := strings.Join(data, "&")

s := sha1.New()
_, err := s.Write([]byte(signData))
if err != nil {
panic(err)
}
hashByte := s.Sum(nil)
signByte, err := this.PrivateKey.Sign(rand.Reader, hashByte, crypto.SHA1)
if err != nil {
panic(err)
}

return base64.StdEncoding.EncodeToString(signByte)
}

// CheckSign 检测签名
func (this *AliAppClient) CheckSign(signData, sign string) {
signByte, err := base64.StdEncoding.DecodeString(sign)
if err != nil {
panic(err)
}
s := sha1.New()
_, err = s.Write([]byte(signData))
if err != nil {
panic(err)
}
hash := s.Sum(nil)
err = rsa.VerifyPKCS1v15(this.PublicKey, crypto.SHA1, hash, signByte)
if err != nil {
panic(err)
}
}

// ToURL
func (this *AliAppClient) ToURL(m map[string]string) string {
var buf []string
for k, v := range m {
buf = append(buf, fmt.Sprintf("%s=%s", k, url.QueryEscape(v)))
}
return strings.Join(buf, "&")
}
//// GenSign 产生签名
//func (this *AliAppClient) GenSign(m map[string]string) string {
// var data []string
//
// for k, v := range m {
// if v != "" && k != "sign" {
// data = append(data, fmt.Sprintf(`%s=%s`, k, v))
// }
// }
// sort.Strings(data)
// signData := strings.Join(data, "&")
//
// s := sha1.New()
// _, err := s.Write([]byte(signData))
// if err != nil {
// panic(err)
// }
// hashByte := s.Sum(nil)
// signByte, err := this.PrivateKey.Sign(rand.Reader, hashByte, crypto.SHA1)
// if err != nil {
// panic(err)
// }
//
// return base64.StdEncoding.EncodeToString(signByte)
//}
//
////CheckSign 检测签名
//func (this *AliAppClient) CheckSign(signData, sign string) {
// signByte, err := base64.StdEncoding.DecodeString(sign)
// if err != nil {
// panic(err)
// }
// s := sha1.New()
// _, err = s.Write([]byte(signData))
// if err != nil {
// panic(err)
// }
// hash := s.Sum(nil)
// err = rsa.VerifyPKCS1v15(this.PublicKey, crypto.SHA1, hash, signByte)
// if err != nil {
// panic(err)
// }
//}
//
//// ToURL
//func (this *AliAppClient) ToURL(m map[string]string) string {
// var buf []string
// for k, v := range m {
// buf = append(buf, fmt.Sprintf("%s=%s", k, url.QueryEscape(v)))
// }
// return strings.Join(buf, "&")
//}
2 changes: 1 addition & 1 deletion client/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (c *HTTPSClient) PostData(url string, contentType string, data string) ([]b
return ioutil.ReadAll(resp.Body)
}

// PostData 提交post数据
// GetData get数据
func (c *HTTPSClient) GetData(url string) ([]byte, error) {
resp, err := c.Get(url)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions client/wechatApp.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ func (this *WechatAppClient) CloseOrder(outTradeNo string) (common.WeChatQueryRe

// 支付到用户的微信账号
func (this *WechatAppClient) PayToClient(charge *common.Charge) (map[string]string, error) {

this.httpsClient = NewHTTPSClient(this.PublicKey, this.PrivateKey)

return WachatCompanyChange(this.AppID, this.MchID, this.Key, this.httpsClient, charge)
}

Expand Down
5 changes: 3 additions & 2 deletions common/common.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package common

import ()

// PayClient 支付客户端接口
type PayClient interface {
// 用户下单付款
Expand All @@ -25,6 +23,9 @@ type Charge struct {
OpenID string `json:"openid,omitempty"`
CheckName bool `json:"check_name,omitempty"`
ReUserName string `json:"re_user_name,omitempty"`
// 阿里提现
AliAccount string `json:"ali_account"`
AliAccountType string `json:"ali_account_type"`
}

//PayCallback 支付返回
Expand Down

0 comments on commit b850bcf

Please sign in to comment.