Commit f7bc9d5b authored by wangp's avatar wangp

lakala

parent cad1509d
...@@ -64,6 +64,28 @@ payurl: ...@@ -64,6 +64,28 @@ payurl:
# checkorder: 'https://tpay.pet-dbc.cn/v1/pay/unified_order' # checkorder: 'https://tpay.pet-dbc.cn/v1/pay/unified_order'
# orderstate: 'https://tpay.pet-dbc.cn/v1/pay/order_state/' # orderstate: 'https://tpay.pet-dbc.cn/v1/pay/order_state/'
# 拉卡拉支付
lakala:
#通用
version: '3.0'
appid: 'OP00000003'
serial_no: '00dfba8194c41b84cf'
#1.聚合收银台(微信H5、支付宝H5)
merchant_no1: '8222900701107M5'
term_no1: ''
#2.聚合收银台(微信扫码、支付宝扫码)
merchant_no2: '8221210594300JY'
term_no2: ''
#3.聚合主扫(微信JSAPI、微信小程序)
merchant_no3: '8222900581201QB'
term_no3: 'D0027598'
sub_appid3: 'wxc3e4d1682da3053c'
user_id3: 'oLvoQ5deygCMj2WrDjPVPvV1L1t8'
#4.扫码枪
merchant_no4: '822290070111135' #结算商户号
term_no4: '29034705' #结算终端号
# gateway # gateway
#gateway: #gateway:
# url: 'http://saas.pet-dbc.cn' # url: 'http://saas.pet-dbc.cn'
......
...@@ -59,12 +59,33 @@ sms: ...@@ -59,12 +59,33 @@ sms:
sendsmsurl: 'https://sms.pet-dbc.cn/v1/send' sendsmsurl: 'https://sms.pet-dbc.cn/v1/send'
smscontent: '【谛宝多多】登录验证码为:%s' smscontent: '【谛宝多多】登录验证码为:%s'
# 支付 # 支付
#payurl: payurl:
domainname: 'http://tpay-v2.pet-dbc.cn:14880'
# checkorder: 'https://pay.pet-dbc.cn/v1/pay/unified_order' # checkorder: 'https://pay.pet-dbc.cn/v1/pay/unified_order'
# orderstate: 'https://pay.pet-dbc.cn/v1/pay/order_state/' # orderstate: 'https://pay.pet-dbc.cn/v1/pay/order_state/'
# 拉卡拉支付
lakala:
#通用
version: '3.0'
appid: 'OP00000003'
serial_no: '00dfba8194c41b84cf'
#1.聚合收银台(微信H5、支付宝H5)
merchant_no1: '8222900701107M5'
term_no1: ''
#2.聚合收银台(微信扫码、支付宝扫码)
merchant_no2: '8221210594300JY'
term_no2: ''
#3.聚合主扫(微信JSAPI、微信小程序)
merchant_no3: '8222900581201QB'
term_no3: 'D0027598'
sub_appid3: 'wxc3e4d1682da3053c'
user_id3: 'oLvoQ5deygCMj2WrDjPVPvV1L1t8'
#4.扫码枪
merchant_no4: '822290070111135' #结算商户号
term_no4: '29034705' #结算终端号
# gateway # gateway
#gateway: #gateway:
......
...@@ -38,6 +38,12 @@ func (l *PayController) WxNotice(c *gin.Context) { ...@@ -38,6 +38,12 @@ func (l *PayController) WxNotice(c *gin.Context) {
//} //}
//fmt.Println(ph2) //fmt.Println(ph2)
//验证签名
//_, err := verySignByPublicKey(c)
//if err != nil {
// fmt.Println(err)
//}
ph := new(models.WxNoticeInput) ph := new(models.WxNoticeInput)
err := c.ShouldBindJSON(ph) err := c.ShouldBindJSON(ph)
if err != nil { if err != nil {
...@@ -55,3 +61,95 @@ func (l *PayController) WxNotice(c *gin.Context) { ...@@ -55,3 +61,95 @@ func (l *PayController) WxNotice(c *gin.Context) {
fmt.Println("拉卡拉微信回调end") fmt.Println("拉卡拉微信回调end")
base.ResponseWxNotice(c, response) base.ResponseWxNotice(c, response)
} }
//func verify(c *gin.Context) error {
// //String appid = getHeadValue(response, "Lklapi-Appid");
// //String lklapiSerial = getHeadValue(response, "Lklapi-Serial");
// //String timestamp = getHeadValue(response, "Lklapi-Timestamp");
// //String nonce = getHeadValue(response, "Lklapi-Nonce");
// //String signature = getHeadValue(response, "Lklapi-Signature");
// //String responseStr = IOUtils.toString(response.getEntity().getContent(), ENCODING);
// //
// //System.out.println("responseStr " + responseStr);
// //
// //String source = appid + "\n" + lklapiSerial + "\n" + timestamp + "\n" + nonce + "\n" + responseStr + "\n";
//
// appid := c.GetHeader("Lklapi-Appid")
// lklapiSerial := c.GetHeader("Lklapi-Serial")
// timestamp := c.GetHeader("Lklapi-Timestamp")
// nonce := c.GetHeader("Lklapi-Nonce")
// signature := c.GetHeader("Lklapi-Signature")
// responseStr := c.GetHeader("")
//
// source := appid + "\n" + lklapiSerial + "\n" + timestamp + "\n" + nonce + "\n" + responseStr + "\n";
//
// rtn, err := utils.VerifyDerCert([]byte(source), "./cert/lkl-apigw-v2.cer")
// if err == nil {
// fmt.Println("验证签名成功!")
// return errors.New("验证签名成功!")
// } else {
// fmt.Println("验证签名失败!")
// return err
// }
// fmt.Println(rtn)
// return errors.New("wangpei签名测试中。。。。。")
//}
//func verySignByPublicKey(c *gin.Context) (bool, error) {
//
// //publicKey string, data []byte, signData []byte
// //String responseStr = IOUtils.toString(response.getEntity().getContent(), ENCODING);
// appid := c.GetHeader("Lklapi-Appid")
// lklapiSerial := c.GetHeader("Lklapi-Serial")
// timestamp := c.GetHeader("Lklapi-Timestamp")
// nonce := c.GetHeader("Lklapi-Nonce")
// signature := c.GetHeader("Lklapi-Signature")
// responseStr := c.GetHeader("")
//
// source := appid + "\n" + lklapiSerial + "\n" + timestamp + "\n" + nonce + "\n" + responseStr + "\n";
//
// publicKey =
// signData
// publicKey = FormatPrivateKey(publicKey)
// // 2、解码私钥字节,生成加密对象
// block, _ := pem.Decode([]byte(publicKey))
// if block == nil {
// return false, errors.New("私钥信息错误!")
// }
// // 3、解析DER编码的私钥,生成私钥对象
// pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
// if err != nil {
// return false, err
// }
//
// hashed := sha256.Sum256(data)
//
// fmt.Println("pubKey.(*rsa.PublicKey): ", pubKey.(*rsa.PublicKey))
//
// pubK := pubKey.(*rsa.PublicKey)
//
// sig, err := base64.StdEncoding.DecodeString(string(signData))
// fmt.Println("err: ", err)
//
// err = rsa.VerifyPKCS1v15(pubK, crypto.SHA256, hashed[:], sig)
// if err != nil {
// return false, err
// }
//
// return true, nil
//}
//
//const (
// PEM_BEGIN = "-----BEGIN RSA PRIVATE KEY-----\n"
// PEM_END = "\n-----END RSA PRIVATE KEY-----"
//)
//
//func FormatPrivateKey(privateKey string) string {
// if !strings.HasPrefix(privateKey, PEM_BEGIN) {
// privateKey = PEM_BEGIN + privateKey
// }
// if !strings.HasSuffix(privateKey, PEM_END) {
// privateKey = privateKey + PEM_END
// }
// return privateKey
//}
\ No newline at end of file
...@@ -48,7 +48,7 @@ type PlaceAnOrderParamInput struct { ...@@ -48,7 +48,7 @@ type PlaceAnOrderParamInput struct {
//退款 //退款
type RefundParamInput struct { type RefundParamInput struct {
OrderId string `json:"order_id" description:"订单号"` OrderId string `json:"order_id" description:"随机生成的订单号 商户订单号"`
GoodsPrice float64 `json:"goods_price" description:"商品金额,个位为分"` GoodsPrice float64 `json:"goods_price" description:"商品金额,个位为分"`
} }
......
...@@ -78,7 +78,7 @@ func WxNotice(input *models.WxNoticeInput) (*base.ResponseDataWxNotice, error) { ...@@ -78,7 +78,7 @@ func WxNotice(input *models.WxNoticeInput) (*base.ResponseDataWxNotice, error) {
// } // }
//} //}
//2.存入 notice_request_body //2.「拉卡拉返回数据」存入 notice_request_body
err = InsertPayBillDetailNoticeRequestBody(tx, billID, input) err = InsertPayBillDetailNoticeRequestBody(tx, billID, input)
if err != nil { if err != nil {
//beego.Error("微信回调, 根据订单id 插入回调Request参数 失败: ", err) //beego.Error("微信回调, 根据订单id 插入回调Request参数 失败: ", err)
...@@ -117,8 +117,8 @@ func WxNotice(input *models.WxNoticeInput) (*base.ResponseDataWxNotice, error) { ...@@ -117,8 +117,8 @@ func WxNotice(input *models.WxNoticeInput) (*base.ResponseDataWxNotice, error) {
callbackResponse.ReturnMsg = "SUCCESS" callbackResponse.ReturnMsg = "SUCCESS"
//callbackResponse.OutTradeNo = input.OutTradeNo //callbackResponse.OutTradeNo = input.OutTradeNo
//callbackResponse.TransactionID = input.TransactionId //callbackResponse.TransactionID = input.TransactionId
callbackResponse.OutTradeNo = input.OutOrderNo //交易凭据单号 todo callbackResponse.OutTradeNo = input.OutOrderNo //交易凭据单号 todo ?
callbackResponse.TransactionID = input.OutOrderNo //交易凭据单号 todo strconv.Itoa( callbackResponse.TransactionID = input.OutOrderNo //交易凭据单号 todo ? strconv.Itoa(
attachMap := make(map[string]interface{}, 0) attachMap := make(map[string]interface{}, 0)
_ = json.Unmarshal([]byte(attach), &attachMap) _ = json.Unmarshal([]byte(attach), &attachMap)
......
This diff is collapsed.
...@@ -24,11 +24,12 @@ type Config struct { ...@@ -24,11 +24,12 @@ type Config struct {
Esign *Esign `mapstructure:"esign"` Esign *Esign `mapstructure:"esign"`
JwtSecret string `mapstructure:"jwtsecret"` JwtSecret string `mapstructure:"jwtsecret"`
DesKey string `mapstructure:"deskey"` DesKey string `mapstructure:"deskey"`
PayUrl *PayUrlDetail `mapstructure:"payurl"`
Lakala *Lakala `mapstructure:"lakala"`
//SmsInternational *SmsInternationalConfig `mapstructure:"newsms"` //SmsInternational *SmsInternationalConfig `mapstructure:"newsms"`
//GateWay *GateWayDetail `mapstructure:"gateway"` //GateWay *GateWayDetail `mapstructure:"gateway"`
//GateWayDev *GateWayDevDetail `mapstructure:"gatewaydev"` //GateWayDev *GateWayDevDetail `mapstructure:"gatewaydev"`
//Mongo *MongoConfig `mapstructure:"mongo"` //Mongo *MongoConfig `mapstructure:"mongo"`
PayUrl *PayUrlDetail `mapstructure:"payurl"`
} }
type App struct { type App struct {
...@@ -109,13 +110,36 @@ type SmsInternationalConfig struct { ...@@ -109,13 +110,36 @@ type SmsInternationalConfig struct {
// Port string `mapstructure:"port"` // Port string `mapstructure:"port"`
//} //}
// //
//// PayUrlDetail 网关 // PayUrlDetail 网关
type PayUrlDetail struct { type PayUrlDetail struct {
DomainName string `mapstructure:"domainname"` DomainName string `mapstructure:"domainname"`
//CheckOrder string `mapstructure:"checkorder"` //CheckOrder string `mapstructure:"checkorder"`
//OrderState string `mapstructure:"orderstate"` //OrderState string `mapstructure:"orderstate"`
} }
// 拉卡拉支付
type Lakala struct {
// 通用
Version string `mapstructure:"version"`
Appid string `mapstructure:"appid"`
SerialNo string `mapstructure:"serial_no"`
// 1.聚合收银台(微信H5、支付宝H5)
MerchantNo1 string `mapstructure:"merchant_no1"`
TermNo1 string `mapstructure:"term_no1"`
// 2.聚合收银台(微信扫码、支付宝扫码)
MerchantNo2 string `mapstructure:"merchant_no2"`
TermNo2 string `mapstructure:"term_no2"`
// 3.聚合主扫(微信JSAPI、微信小程序)
MerchantNo3 string `mapstructure:"merchant_no3"`
TermNo3 string `mapstructure:"term_no3"`
SubAppid3 string `mapstructure:"sub_appid3"`
UserId3 string `mapstructure:"user_id3"`
// 4.扫码枪
MerchantNo4 string `mapstructure:"merchant_no4"`
TermNo4 string `mapstructure:"term_no4"`
}
type UploadImage struct { type UploadImage struct {
UploadDir string `mapstructure:"upload_dir"` UploadDir string `mapstructure:"upload_dir"`
MaxFileSize int `mapstructure:"max_file_size"` MaxFileSize int `mapstructure:"max_file_size"`
......
...@@ -4,12 +4,13 @@ import ( ...@@ -4,12 +4,13 @@ import (
"crypto" "crypto"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/sha1"
"crypto/x509" "crypto/x509"
"encoding/base64" "encoding/base64"
"encoding/hex"
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"hash"
"io/ioutil" "io/ioutil"
) )
...@@ -79,24 +80,19 @@ func ReadParsePublicKey(filename string) (*rsa.PublicKey, error) { ...@@ -79,24 +80,19 @@ func ReadParsePublicKey(filename string) (*rsa.PublicKey, error) {
if block == nil { if block == nil {
return nil, errors.New("公钥信息错误!") return nil, errors.New("公钥信息错误!")
} }
fmt.Println(block.Type)
// 3、解析DER编码的公钥,生成公钥接口 // 3、解析DER编码的公钥,生成公钥接口
//publicKeyInterface2, err := asn1.Marshal(block.Bytes)
//fmt.Println(publicKeyInterface2)
publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes) publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
//publicKeyInterface, err := x509.ParseCertificate(block.Bytes)
if err != nil { if err != nil {
fmt.Println(444) fmt.Println(8888888888)
return nil, err return nil, err
} }
// 4、公钥接口转型成公钥对象 // 4、公钥接口转型成公钥对象
publicKey := publicKeyInterface.(*rsa.PublicKey) publicKey := publicKeyInterface.(*rsa.PublicKey)
//publicKey, err := x509.ParsePKCS1PublicKey(block.Bytes)
//if err != nil {
// fmt.Println(222)
// return nil, err
//}
return publicKey, nil return publicKey, nil
} }
...@@ -127,39 +123,121 @@ func ReadParsePrivaterKey(filename string) (*rsa.PrivateKey, error) { ...@@ -127,39 +123,121 @@ func ReadParsePrivaterKey(filename string) (*rsa.PrivateKey, error) {
return privateKey, nil return privateKey, nil
} }
//(3)签名:采用sha1算法进行签名并输出为hex格式(私钥PKCS8格式)
func RsaSignWithSha1Hex(data string, prvKey string) (string, error) {
//keyByts, err := hex.DecodeString(prvKey)
keyByts := []byte(prvKey)
//if err != nil {
// fmt.Println("DecodeString err", err)
// return "", err
//}
privateKey, err := x509.ParsePKCS8PrivateKey(keyByts)
if err != nil {
fmt.Println("ParsePKCS8PrivateKey err", err)
return "", err
}
h := sha1.New()
h.Write([]byte([]byte(data)))
hash := h.Sum(nil)
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey.(*rsa.PrivateKey), crypto.SHA1, hash[:])
if err != nil {
fmt.Printf("Error from signing: %s\n", err)
return "", err
}
out := hex.EncodeToString(signature)
return out, nil
}
//(4)验签:对采用sha1算法进行签名后转base64格式的数据进行验签
func RsaVerySignWithSha1Base64(originalData, signData, pubKey string) error{
sign, err := base64.StdEncoding.DecodeString(signData)
if err != nil {
return err
}
//public, _ := base64.StdEncoding.DecodeString(pubKey)
public := []byte(pubKey)
pub, err := x509.ParsePKIXPublicKey(public)
if err != nil {
return err
}
hash := sha1.New()
hash.Write([]byte(originalData))
return rsa.VerifyPKCS1v15(pub.(*rsa.PublicKey), crypto.SHA1, hash.Sum(nil), sign)
}
//func VerifySignCert(signData, sign, signType, aliPayPublicKeyPath string) (err error) {
// var (
// h hash.Hash
// hashs crypto.Hash
// block *pem.Block
// pubKey *x509.Certificate
// publicKey *rsa.PublicKey
// ok bool
// bytes []byte
// )
// if bytes, err = ioutil.ReadFile(aliPayPublicKeyPath); err != nil {
// return fmt.Errorf("支付宝公钥文件读取失败: %w", err)
// }
// signBytes, _ := base64.StdEncoding.DecodeString(sign)
// if block, _ = pem.Decode(bytes); block == nil {
// return errors.New("支付宝公钥Decode错误")
// }
// if pubKey, err = x509.ParseCertificate(block.Bytes); err != nil {
// return fmt.Errorf("x509.ParseCertificate:%w", err)
// }
// if publicKey, ok = pubKey.PublicKey.(*rsa.PublicKey); !ok {
// return errors.New("支付宝公钥转换错误")
// }
// switch signType {
// case "RSA":
// hashs = crypto.SHA1
// case "RSA2":
// hashs = crypto.SHA256
// default:
// hashs = crypto.SHA256
// }
// h = hashs.New()
// h.Write([]byte(signData))
// return rsa.VerifyPKCS1v15(publicKey, hashs, h.Sum(nil), signBytes)
//}
//func VerifyDerCert(der_cert []byte, der_signing_cert []byte) (bool, error) {
func VerifyDerCert(der_cert []byte, filename string) (bool, error) {
// 1、读取私钥文件,获取私钥字节
der_signing_cert, err := ioutil.ReadFile(filename)
if err != nil {
return false, err
}
roots := x509.NewCertPool()
opts := x509.VerifyOptions{
Roots: roots,
}
// Verify key
policy_cert, err := x509.ParseCertificate(der_signing_cert)
if err != nil {
return false, errors.New("Signing ParseCertificate fails")
}
roots.AddCert(policy_cert)
fmt.Printf("Root cert: %x\n", der_signing_cert)
// Verify key
cert, err := x509.ParseCertificate(der_cert)
if err != nil {
return false, errors.New("Cert ParseCertificate fails")
}
roots.AddCert(policy_cert)
opts.Roots = roots
chains, err := cert.Verify(opts)
if err != nil {
return false, errors.New("Verify fails")
}
if chains != nil {
return true, nil
} else {
return false, nil
}
func VerifySignCert(signData, sign, signType, aliPayPublicKeyPath string) (err error) {
var (
h hash.Hash
hashs crypto.Hash
block *pem.Block
pubKey *x509.Certificate
publicKey *rsa.PublicKey
ok bool
bytes []byte
)
if bytes, err = ioutil.ReadFile(aliPayPublicKeyPath); err != nil {
return fmt.Errorf("支付宝公钥文件读取失败: %w", err)
}
signBytes, _ := base64.StdEncoding.DecodeString(sign)
if block, _ = pem.Decode(bytes); block == nil {
return errors.New("支付宝公钥Decode错误")
}
if pubKey, err = x509.ParseCertificate(block.Bytes); err != nil {
return fmt.Errorf("x509.ParseCertificate:%w", err)
}
if publicKey, ok = pubKey.PublicKey.(*rsa.PublicKey); !ok {
return errors.New("支付宝公钥转换错误")
}
switch signType {
case "RSA":
hashs = crypto.SHA1
case "RSA2":
hashs = crypto.SHA256
default:
hashs = crypto.SHA256
}
h = hashs.New()
h.Write([]byte(signData))
return rsa.VerifyPKCS1v15(publicKey, hashs, h.Sum(nil), signBytes)
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment