|
|
@@ -0,0 +1,202 @@ |
|
|
|
package pay |
|
|
|
|
|
|
|
import ( |
|
|
|
zhios_pay_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/utils" |
|
|
|
"crypto" |
|
|
|
"crypto/md5" |
|
|
|
"crypto/rand" |
|
|
|
"crypto/rsa" |
|
|
|
"crypto/x509" |
|
|
|
"encoding/base64" |
|
|
|
"encoding/json" |
|
|
|
"encoding/pem" |
|
|
|
"errors" |
|
|
|
"fmt" |
|
|
|
"github.com/forgoer/openssl" |
|
|
|
"github.com/syyongx/php2go" |
|
|
|
"golang.org/x/crypto/ssh" |
|
|
|
mathRand "math/rand" |
|
|
|
"sort" |
|
|
|
"time" |
|
|
|
) |
|
|
|
|
|
|
|
/*** |
|
|
|
method fastPay.agreement.signSms |
|
|
|
|
|
|
|
data 请求交易的数据,具体参数见下表 |
|
|
|
|
|
|
|
mch_no 商户在支付平台系统的唯一身份标识。(注:商户编号和商户密钥在汇聚商户后台获取) |
|
|
|
pub_key 公钥 |
|
|
|
|
|
|
|
pri_key 私钥 |
|
|
|
*/ |
|
|
|
|
|
|
|
func GetSms(pubKey, platformKey, priKey, mch_no string, args map[string]string) (string, error) { |
|
|
|
param := map[string]string{ |
|
|
|
"mch_no": mch_no, |
|
|
|
} |
|
|
|
param["sec_key"] = randomString(16) |
|
|
|
args["payer_name"] = AesEncryptECB([]byte(args["payer_name"]), []byte(param["sec_key"])) |
|
|
|
args["id_no"] = AesEncryptECB([]byte(args["id_no"]), []byte(param["sec_key"])) |
|
|
|
args["bank_card_no"] = AesEncryptECB([]byte(args["bank_card_no"]), []byte(param["sec_key"])) |
|
|
|
args["mobile_no"] = AesEncryptECB([]byte(args["mobile_no"]), []byte(param["sec_key"])) |
|
|
|
data, _ := json.Marshal(args) |
|
|
|
param["data"] = string(data) |
|
|
|
send, err := Send("fastPay.agreement.signSms", platformKey, priKey, param) |
|
|
|
return send, err |
|
|
|
} |
|
|
|
|
|
|
|
func SignContract(pubKey, platformKey, priKey, mch_no string, args map[string]string) (string, error) { |
|
|
|
param := map[string]string{ |
|
|
|
"mch_no": mch_no, |
|
|
|
} |
|
|
|
param["sec_key"] = randomString(16) |
|
|
|
data, _ := json.Marshal(args) |
|
|
|
param["data"] = string(data) |
|
|
|
send, err := Send("fastPay.agreement.smsSign", platformKey, priKey, param) |
|
|
|
return send, err |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
func UnSignContract(pubKey, platformKey, priKey, mch_no string, args map[string]string) (string, error) { |
|
|
|
param := map[string]string{ |
|
|
|
"mch_no": mch_no, |
|
|
|
} |
|
|
|
param["sec_key"] = randomString(16) |
|
|
|
args["sign_no"] = AesEncryptECB([]byte(args["sign_no"]), []byte(param["sec_key"])) |
|
|
|
data, _ := json.Marshal(args) |
|
|
|
param["data"] = string(data) |
|
|
|
send, err := Send("fastPay.agreement.unSign", platformKey, priKey, param) |
|
|
|
return send, err |
|
|
|
} |
|
|
|
func GetPaySms(pubKey, platformKey, priKey, mchNo string, args map[string]string) (string, error) { |
|
|
|
param := map[string]string{ |
|
|
|
"mch_no": mchNo, |
|
|
|
} |
|
|
|
param["sec_key"] = randomString(16) |
|
|
|
args["sign_no"] = AesEncryptECB([]byte(args["sign_no"]), []byte(param["sec_key"])) |
|
|
|
data, _ := json.Marshal(args) |
|
|
|
param["data"] = string(data) |
|
|
|
send, err := Send("fastPay.agreement.paySms", platformKey, priKey, param) |
|
|
|
return send, err |
|
|
|
} |
|
|
|
func PayDoing(pubKey, platformKey, priKey, mchNo string, args map[string]string) (string, error) { |
|
|
|
param := map[string]string{ |
|
|
|
"mch_no": mchNo, |
|
|
|
} |
|
|
|
param["sec_key"] = randomString(16) |
|
|
|
data, _ := json.Marshal(args) |
|
|
|
param["data"] = string(data) |
|
|
|
send, err := Send("fastPay.agreement.smsPay", platformKey, priKey, param) |
|
|
|
return send, err |
|
|
|
} |
|
|
|
|
|
|
|
func Send(method, platformKey, priKey string, param map[string]string) (string, error) { |
|
|
|
//priKey = strings.ReplaceAll(priKey, "+", "\n") |
|
|
|
//priKey = "-----BEGIN PRIVATE KEY-----\n" + priKey + "\n-----END PRIVATE KEY-----" |
|
|
|
router := "https://api.joinpay.com/fastpay" |
|
|
|
param["method"] = method |
|
|
|
param["version"] = "1.0" |
|
|
|
param["rand_str"] = randomString(32) |
|
|
|
param["sign_type"] = "2" |
|
|
|
sign, err := GetSign(priKey, param) |
|
|
|
if err != nil { |
|
|
|
return "", err |
|
|
|
} |
|
|
|
param["sign"] = sign |
|
|
|
if param["sec_key"] != "" { //rsa加密 |
|
|
|
encrypts, err := RsaEncrypts([]byte(param["sec_key"]), []byte(platformKey)) |
|
|
|
if err != nil { |
|
|
|
return "", err |
|
|
|
} |
|
|
|
param["sec_key"] = string(encrypts) |
|
|
|
} |
|
|
|
post, err := zhios_pay_utils.CurlPost(router, param, nil) |
|
|
|
fmt.Println(string(post)) |
|
|
|
fmt.Println(err) |
|
|
|
return string(post), nil |
|
|
|
} |
|
|
|
|
|
|
|
func GetSign(privateKeyStr string, param map[string]string) (string, error) { |
|
|
|
privateKey, err := ssh.ParseRawPrivateKey([]byte(privateKeyStr)) |
|
|
|
if err != nil { |
|
|
|
return "", err |
|
|
|
} |
|
|
|
keys := make([]string, 0, len(param)) |
|
|
|
for k := range param { |
|
|
|
keys = append(keys, k) |
|
|
|
} |
|
|
|
sort.Strings(keys) |
|
|
|
data := "" |
|
|
|
for _, v := range keys { |
|
|
|
if v == "sign" || v == "sec_key" { |
|
|
|
continue |
|
|
|
} |
|
|
|
if data != "" { |
|
|
|
data += "&" + v + "=" + param[v] |
|
|
|
} else { |
|
|
|
data += v + "=" + param[v] |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fmt.Println("md5 before2:>>>>", data) |
|
|
|
hashMd5 := md5.Sum([]byte(data)) |
|
|
|
fmt.Println("md5 before2:>>>>", hashMd5) |
|
|
|
hashed := hashMd5[:] |
|
|
|
fmt.Println("hashed:>>>>", hashed) |
|
|
|
fmt.Println("hashed_string:>>>>", string(hashed)) |
|
|
|
sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.MD5, hashed) |
|
|
|
if err != nil { |
|
|
|
return "", err |
|
|
|
} |
|
|
|
return base64.StdEncoding.EncodeToString(sign), nil |
|
|
|
} |
|
|
|
|
|
|
|
// 公钥加密 |
|
|
|
func RsaEncrypts(data, keyBytes []byte) (string, error) { |
|
|
|
var ciphertext string |
|
|
|
//解密pem格式的公钥 |
|
|
|
block, _ := pem.Decode(keyBytes) |
|
|
|
if block == nil { |
|
|
|
return ciphertext, errors.New("公钥错误") |
|
|
|
} |
|
|
|
// 解析公钥 |
|
|
|
pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes) |
|
|
|
if err != nil { |
|
|
|
return ciphertext, err |
|
|
|
} |
|
|
|
// 类型断言 |
|
|
|
pub := pubInterface.(*rsa.PublicKey) |
|
|
|
//加密 |
|
|
|
ciphertext1, err := rsa.EncryptPKCS1v15(rand.Reader, pub, data) |
|
|
|
if err != nil { |
|
|
|
return ciphertext, err |
|
|
|
} |
|
|
|
return base64.StdEncoding.EncodeToString(ciphertext1), nil |
|
|
|
} |
|
|
|
func randomString(ln int) string { |
|
|
|
letters := []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") |
|
|
|
b := make([]rune, ln) |
|
|
|
r := mathRand.New(mathRand.NewSource(time.Now().UnixNano())) |
|
|
|
for i := range b { |
|
|
|
b[i] = letters[r.Intn(len(letters))] |
|
|
|
} |
|
|
|
return string(b) |
|
|
|
} |
|
|
|
|
|
|
|
func AesEncryptECB(origData []byte, key []byte) string { |
|
|
|
str, _ := openssl.AesECBEncrypt(origData, key, openssl.PKCS7_PADDING) |
|
|
|
value := php2go.Base64Encode(string(str)) |
|
|
|
|
|
|
|
return value |
|
|
|
} |
|
|
|
func generateKey(key []byte) (genKey []byte) { |
|
|
|
genKey = make([]byte, 16) |
|
|
|
copy(genKey, key) |
|
|
|
for i := 16; i < len(key); { |
|
|
|
for j := 0; j < 16 && i < len(key); j, i = j+1, i+1 { |
|
|
|
genKey[j] ^= key[i] |
|
|
|
} |
|
|
|
} |
|
|
|
return genKey |
|
|
|
} |