From f7bc9d5b1baed25ce8f087ab3f36fe6882eb5f36 Mon Sep 17 00:00:00 2001
From: wangp <wangpei@gmail.com>
Date: Thu, 6 Jul 2023 18:38:56 +0800
Subject: [PATCH] lakala

---
 conf/dev/config.yaml            |  22 +++
 conf/prod/config.yaml           |  25 +++-
 controller/api/v1/pay/notice.go |  98 +++++++++++++
 models/pay.go                   |   2 +-
 repository/pay/notice.go        |   6 +-
 repository/pay/pay.go           | 250 +++++++++++++++++++++-----------
 setting/setting.go              |  28 +++-
 utils/cert.go                   | 168 +++++++++++++++------
 8 files changed, 458 insertions(+), 141 deletions(-)

diff --git a/conf/dev/config.yaml b/conf/dev/config.yaml
index 07f0d7b..d498592 100755
--- a/conf/dev/config.yaml
+++ b/conf/dev/config.yaml
@@ -64,6 +64,28 @@ payurl:
 #  checkorder: 'https://tpay.pet-dbc.cn/v1/pay/unified_order'
 #  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:
 #  url: 'http://saas.pet-dbc.cn'
diff --git a/conf/prod/config.yaml b/conf/prod/config.yaml
index 1c98d17..9e29ddd 100755
--- a/conf/prod/config.yaml
+++ b/conf/prod/config.yaml
@@ -59,12 +59,33 @@ sms:
   sendsmsurl: 'https://sms.pet-dbc.cn/v1/send'
   smscontent: '【谛宝多多】登录验证码为:%s'
 
-
 # 支付
-#payurl:
+payurl:
+  domainname: 'http://tpay-v2.pet-dbc.cn:14880'
 #  checkorder: 'https://pay.pet-dbc.cn/v1/pay/unified_order'
 #  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:
diff --git a/controller/api/v1/pay/notice.go b/controller/api/v1/pay/notice.go
index ee1c9bb..a0b195a 100755
--- a/controller/api/v1/pay/notice.go
+++ b/controller/api/v1/pay/notice.go
@@ -38,6 +38,12 @@ func (l *PayController) WxNotice(c *gin.Context) {
 	//}
 	//fmt.Println(ph2)
 
+	//验证签名
+	//_, err := verySignByPublicKey(c)
+	//if err != nil {
+	//	fmt.Println(err)
+	//}
+
 	ph := new(models.WxNoticeInput)
 	err := c.ShouldBindJSON(ph)
 	if err != nil {
@@ -55,3 +61,95 @@ func (l *PayController) WxNotice(c *gin.Context) {
 	fmt.Println("拉卡拉微信回调end")
 	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
diff --git a/models/pay.go b/models/pay.go
index 443d56e..f1b69b2 100755
--- a/models/pay.go
+++ b/models/pay.go
@@ -48,7 +48,7 @@ type PlaceAnOrderParamInput struct {
 
 //退款
 type RefundParamInput struct {
-	OrderId    string  `json:"order_id" description:"订单号"`
+	OrderId    string  `json:"order_id" description:"随机生成的订单号 商户订单号"`
 	GoodsPrice float64 `json:"goods_price" description:"商品金额,个位为分"`
 }
 
diff --git a/repository/pay/notice.go b/repository/pay/notice.go
index 7ff67d3..ae13908 100755
--- a/repository/pay/notice.go
+++ b/repository/pay/notice.go
@@ -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)
 	if err != nil {
 		//beego.Error("微信回调, 根据订单id 插入回调Request参数 失败: ", err)
@@ -117,8 +117,8 @@ func WxNotice(input *models.WxNoticeInput) (*base.ResponseDataWxNotice, error) {
 		callbackResponse.ReturnMsg = "SUCCESS"
 		//callbackResponse.OutTradeNo = input.OutTradeNo
 		//callbackResponse.TransactionID = input.TransactionId
-		callbackResponse.OutTradeNo = input.OutOrderNo //交易凭据单号 todo
-		callbackResponse.TransactionID = input.OutOrderNo //交易凭据单号 todo strconv.Itoa(
+		callbackResponse.OutTradeNo = input.OutOrderNo //交易凭据单号 todo ?
+		callbackResponse.TransactionID = input.OutOrderNo //交易凭据单号 todo ? strconv.Itoa(
 
 		attachMap := make(map[string]interface{}, 0)
 		_ = json.Unmarshal([]byte(attach), &attachMap)
diff --git a/repository/pay/pay.go b/repository/pay/pay.go
index c2a7204..7703658 100755
--- a/repository/pay/pay.go
+++ b/repository/pay/pay.go
@@ -14,10 +14,13 @@ import (
 	"fmt"
 	"github.com/astaxie/beego/httplib"
 	uID "github.com/satori/go.uuid"
+	rand2 "math/rand"
+	"strconv"
 	"strings"
 	"system_pay/models"
 	"system_pay/mysql"
 	"system_pay/setting"
+	"system_pay/utils"
 	"time"
 )
 
@@ -61,12 +64,28 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput, ip string) (interface{},
 	}
 
 	//数据重组 - start
-	data := make(map[string]interface{})
-	var url string
 	now := time.Now()
 	now.Add(time.Minute * 60)
 	date_time1 := now.Format("20060102150405")
 	date_time2 := now.Add(time.Minute * 60).Format("20060102150405")
+	version := setting.Conf.Lakala.Version
+	out_org_code := setting.Conf.Lakala.Appid
+	merchant_no1 := setting.Conf.Lakala.MerchantNo1
+	merchant_no2 := setting.Conf.Lakala.MerchantNo2
+	merchant_no3 := setting.Conf.Lakala.MerchantNo3
+	term_no3 := setting.Conf.Lakala.TermNo3
+	sub_appid3 := setting.Conf.Lakala.SubAppid3
+	user_id3 := setting.Conf.Lakala.UserId3
+	merchant_no4 := setting.Conf.Lakala.MerchantNo4
+	term_no4 := setting.Conf.Lakala.TermNo4
+
+	var url string
+	data := make(map[string]interface{}) //数据结构
+	data["req_time"] = date_time1
+	data["version"] = version
+	data["out_org_code"] = out_org_code
+
+
 	//source_code 1: 微信 Native 2:微信小程序 3:微信内支付 4:h5 跳微信
 	//5:支付宝(web)-扫码或登录支付宝账户 6:alipay(mobile) 7:alipay(app)
 	//9: B2C 10:bk支付宝web 11:bk 支付宝手机
@@ -74,9 +93,7 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput, ip string) (interface{},
 		//聚合收银台(微信H5、支付宝H5、微信扫码、支付宝扫码)
 		url = "https://test.wsmsd.cn/sit/api/v3/ccss/counter/order/create" //聚合收银台
 
-		data["req_time"] = date_time1
-		data["version"] = "3.0"
-		data["out_org_code"] = "OP00000003"
+
 
 		//input.ReturnURL = "https://test.pet-dbc.cn"
 
@@ -89,9 +106,9 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput, ip string) (interface{},
 		//data2["merchant_no"] = "8221210701101SB"
 		//data2["merchant_no"] = "8222900581201QB"
 		if input.SourceCode==4 || input.SourceCode==6 {
-			data2["merchant_no"] = "8222900701107M5" //微信H5、支付宝H5
+			data2["merchant_no"] = merchant_no1 //微信H5、支付宝H5
 		} else {
-			data2["merchant_no"] = "8221210594300JY" //微信扫码、支付宝扫码
+			data2["merchant_no"] = merchant_no2 //微信扫码、支付宝扫码
 		}
 		//data2["term_no"] = "29034705" //不需要传?
 
@@ -126,10 +143,6 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput, ip string) (interface{},
 		//聚合主扫(微信JSAPI、微信小程序)
 		url = "https://test.wsmsd.cn/sit/api/v3/labs/trans/preorder" //聚合主扫
 
-		data["req_time"] = date_time1
-		data["version"] = "3.0"
-		data["out_org_code"] = "OP00000003"
-
 		//input.ReturnURL = "https://test.pet-dbc.cn"
 
 		// 构造回调url
@@ -141,8 +154,8 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput, ip string) (interface{},
 		//data2["merchant_no"] = "8222900701107M5"
 		//data2["term_no"] = "A1062976"
 		//data2["merchant_no"] = "8221210701101SB"
-		data2["merchant_no"] = "8222900581201QB"
-		data2["term_no"] = "D0027598"
+		data2["merchant_no"] = merchant_no3
+		data2["term_no"] = term_no3
 		//tempMoney, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", p.GoodsPrice*100), 64)
 		data2["total_amount"] = input.GoodsPrice*100
 		data2["out_trade_no"] = orderID //随机生成的订单号 //商户交易流水号
@@ -168,8 +181,8 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput, ip string) (interface{},
 		data4 := make(map[string]interface{})
 		//data4["open_id"] = input.OpenID //此参数 支付类型是 JS API 的时候 必传
 
-		data4["sub_appid"] = "wxc3e4d1682da3053c"
-		data4["user_id"] = "oLvoQ5deygCMj2WrDjPVPvV1L1t8"
+		data4["sub_appid"] = sub_appid3
+		data4["user_id"] = user_id3
 
 		data2["acc_busi_fields"] = make(map[string]interface{})
 		data2["acc_busi_fields"] = data4
@@ -185,13 +198,9 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput, ip string) (interface{},
 
 		url = "https://test.wsmsd.cn/sit/api/v3/labs/trans/micropay" //聚合被扫
 
-		data["req_time"] = date_time1
-		data["version"] = "3.0"
-		data["out_org_code"] = "OP00000003"
-
 		data2 := make(map[string]interface{})
-		data2["merchant_no"] = "822290070111135"
-		data2["term_no"] = "29034705"
+		data2["merchant_no"] = merchant_no4
+		data2["term_no"] = term_no4
 		//data2["merchant_no"] = "8222900581201QB"
 		//data2["term_no"] = "D0027598"
 		data2["out_trade_no"] = orderID //随机生成的订单号 //商户交易流水号
@@ -325,24 +334,32 @@ func lakala_post(source_code uint8, url string, data_json []byte) (error, interf
 		response["prepay_id"] = temp3["prepay_id"].(string)
 		response["sign_type"] = temp3["sign_type"].(string)
 		response["timeStamp"] = temp3["time_stamp"].(string)
+	} else if source_code==9 {
+		//扫码枪
 	}
 
 	return nil, response, temp
 }
 
 func getAuthorization(body string) (string, error) {
-	appid := "OP00000003"
-	mchSerialNo := "00dfba8194c41b84cf"
-	//nonceStr := strconv.Itoa(rand.Intn(32)) // 构造随机数
-	nonceStr := "12345678901234567890123456789012" // 构造随机数
-	//timestamp := strconv.FormatInt(time.Now().Unix(), 10)
-	timestamp := "1686808027"
+	//appid := "OP00000003"
+	//mchSerialNo := "00dfba8194c41b84cf"
+	//nonceStr = gopay.GetRandomString(32)
+	////nonceStr := strconv.Itoa(rand.Intn(32)) // 构造随机数
+	//nonceStr := "12345678901234567890123456789012" // 构造随机数
+	////timestamp := strconv.FormatInt(time.Now().Unix(), 10)
+	//timestamp := "1686808027"
+
+	appid := setting.Conf.Lakala.Appid
+	mchSerialNo := setting.Conf.Lakala.SerialNo
+	nonceStr := RandomString(32) // 构造随机数
+	timestamp := strconv.FormatInt(time.Now().Unix(), 10)
 
 	//String nonceStr = generateNonceStr();
 	//long timestamp = generateTimestamp();
 
 	message := appid + "\n" + mchSerialNo + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";
-
+	//fmt.Println(message); return "", errors.New("测试")
 	//System.out.println("getToken message :  " + message);
 
 	//PrivateKey merchantPrivateKey = loadPrivateKey(new FileInputStream(new File(merchantPrivateKeyPath)));
@@ -351,34 +368,45 @@ func getAuthorization(body string) (string, error) {
 	//privateRaw := "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDokGGq7SlDoULN\nPULY8lcb2uXJcrFKkJI/lSfPppIkGH4xPfQytZXRlonpXqgOvovflJT5VhRvoLe2\ninJ/59kRF59KTerbCG5sG2IHhR/qCUGHervnZuPwgrjOOlnB19VCCUKY1tcplkZa\nKIksUU3TVh09GB3lUngkuOeO15ihcFHMIknOiSpL+Q04+qQf0g++9CxdQUtNY5za\nZ2Jdvch/4yFstR59qQu73ZCCYHFqXaVakyfOC3xOQkRB58jPOUvIab9zwo2hPukT\n+6qkqfokqMhX979HhNshPAJEEUXp4szk0QtP+2n8hq8t3Dws+GY8ElAFvmeGHx5j\nWzPYAcXvAgMBAAECggEBALIsu8caf/zCdc2MW8SelkJPCLG330DDVmjEO4YJlfl1\nkmjjkE2xdSDn9q0GyjbRoZQf36rPWkTTmyyNEYAQ/urrcCybWY2J/h9xMz+TrIm/\noabMT13QJF5FqJTHe7DZTReUxKMYJixEZ433dHCxsbByT2BZM75X2pg32aBEaTl0\nv9OfIMwfaJ5fSBmleJv4q/Lfd232/oOPzyr+EHfsMpTwOrgzQwPNoah1GvH+jBhz\ngoafi36vT8HVjJ+ZjOreH+Z2zVas683Le62rQaN/51jHS5vQGd2+z3qrI3kvu8KK\nWu0kIDQwCKtSFUT00MiKSaklE9JHf8rCNm3+en4kjfECgYEA/0Z2QaP4sOUt1+cZ\nIOprsMkJOl2sLTTDx3MseD2BxUukLDT8P3HTWLtBN9AkGlL6XD8WSs1k9YlGCqf2\ny9qC43Bgwsky8CH1ACk5K4PuWidGUQiqW4Oll/ris2vjagE+QfMHFFa7IalV5FvI\nv9L01jMqSL4duoM5w/WlLyLu8s0CgYEA6TlppWuxUMbxhEL5jmCZSSvsyhmIOdRk\nt4V9MuxwiRuItzywMo4+O7Hs6tjAxTnV/ROa33qyQtm4Olmd4Oa/TkmAJFX+mUrW\njUohDvm7Js2Y7/eeSRcRQLcgCjncpNe3AJoeVEvrGeaJMERYXnTwboUDKxsRyFFq\nAyuZHfuh86sCgYAm3pjFF+2XKd5YIKUv4OHy8jmIfJjp7T3eUcg0qtDmtMTTwmGi\nW3ed7C1bDUNiCr56a1S+oRW9WWCj4L1wft4tOYBSSIaMD++ZTa2Z1aXmblKDpjki\nZCJDyPzZ6xSeoH/VVOcADtDBqGIeumcP5lRHhVTr7J7kNnUGRJIZYk1WBQKBgQCl\nLAIEI4cKnDrD3uL60LL+vVsPrpFp02AZETMf84+nqpZin1pyE4dDo7kUgbnUdCd2\n+oF+sFi7O5Jb0MgdVY47FZbpJPYQ/o2AtvU+s+K1knozyPyS6wFPAeJxG5WGMTfr\n9zpvnOy+BSU3x8+F5e+5df5OcvdfFTmtUR05vNJvzQKBgHUtziAeWo7H6vxknFcc\nkVv7++a4IWF59eP+rpxlaHOtPTI43PLxJgSHEbw3epEzTUnCL9dpP8n48fuYuwM+\n+vpAujDcaGjGffmxW40E6wuGjOYBNg1zjSfEyjxF2fY+D9WoICSPHnrWB0/BEAZB\naL9Lho8+BUEFergUMjxUdvAS"
 	//privateRaw := "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW"
 	//privateRaw := "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW\n-----END PRIVATE KEY-----";
-	privateRaw := "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW"
 	//privateRaw := "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW\n-----END PRIVATE KEY-----"
 
+	//privateRaw := "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDvDBZyHUDndAGx\nrIcsCV2njhNO3vCEZotTaWYSYwtDvkcAb1EjsBFabXZaKigpqFXk5XXNI3NIHP9M\n8XKzIgGvc65NpLAfRjVql8JiTvLyYd1gIUcOXMInabu+oX7dQSI1mS8XzqaoVRhD\nZQWhXcJW9bxMulgnzvk0Ggw07AjGF7si+hP/Va8SJmN7EJwfQq6TpSxR+WdIHpbW\ndhZ+NHwitnQwAJTLBFvfk28INM39G7XOsXdVLfsooFdglVTOHpNuRiQAj9gShCCN\nrpGsNQxDiJIxE43qRsNsRwigyo6DPJk/klgDJa417E2wgP8VrwiXparO4FMzOGK1\n5quuoD7DAgMBAAECggEBANhmWOt1EAx3OBFf3f4/fEjylQgRSiqRqg8Ymw6KGuh4\nmE4Md6eW/B6geUOmZjVP7nIIR1wte28M0REWgn8nid8LGf+v1sB5DmIwgAf+8G/7\nqCwd8/VMg3aqgQtRp0ckb5OV2Mv0h2pbnltkWHR8LDIMwymyh5uCApbn/aTrCAZK\nNXcPOyAn9tM8Bu3FHk3Pf24Er3SN+bnGxgpzDrFjsDSHjDFT9UMIc2WdA3tuMv9X\n3DDn0bRCsHnsIw3WrwY6HQ8mumdbURk+2Ey3eRFfMYxyS96kOgBC2hqZOlDwVPAK\nTPtS4hoq+cQ0sRaJQ4T0UALJrBVHa+EESgRaTvrXqAECgYEA+WKmy9hcvp6IWZlk\n9Q1JZ+dgIVxrO65zylK2FnD1/vcTx2JMn73WKtQb6vdvTuk+Ruv9hY9PEsf7S8gH\nSTTmzHOUgo5x0F8yCxXFnfji2juoUnDdpkjtQK5KySDcpQb5kcCJWEVi9v+zObM0\nZr1Nu5/NreE8EqUl3+7MtHOu1TMCgYEA9WM9P6m4frHPW7h4gs/GISA9LuOdtjLv\nAtgCK4cW2mhtGNAMttD8zOBQrRuafcbFAyU9de6nhGwetOhkW9YSV+xRNa7HWTeI\nRgXJuJBrluq5e1QGTIwZU/GujpNaR4Qiu0B8TodM/FME7htsyxjmCwEfT6SDYlke\nMzTbMa9Q0DECgYBqsR/2+dvD2YMwAgZFKKgNAdoIq8dcwyfamUQ5mZ5EtGQL2yw4\n8zibHh/LiIxgUD1Kjk/qQgNsX45NP4iOc0mCkrgomtRqdy+rumbPTNmQ0BEVJCBP\nscd+8pIgNiTvnWpMRvj7gMP0NDTzLI3wnnCRIq8WAtR2jZ0Ejt+ZHBziLQKBgQDi\nbEe/zqNmhDuJrpXEXmO7fTv3YB/OVwEj5p1Z/LSho2nHU3Hn3r7lbLYEhUvwctCn\nLl2fzC7Wic1rsGOqOcWDS5NDrZpUQGGF+yE/JEOiZcPwgH+vcjaMtp0TAfRzuQEz\nNzV8YGwxB4mtC7E/ViIuVULHAk4ZGZI8PbFkDxjKgQKBgG8jEuLTI1tsP3kyaF3j\nAylnw7SkBc4gfe9knsYlw44YlrDSKr8AOp/zSgwvMYvqT+fygaJ3yf9uIBdrIilq\nCHKXccZ9uA/bT5JfIi6jbg3EoE9YhB0+1aGAS1O2dBvUiD8tJ+BjAT4OB0UDpmM6\nQsFLQgFyXgvDnzr/o+hQJelW"
 
-	signature, err := Sha256WithRsa(privateRaw, message)
-	if err != nil {
-		return signature, err
-	}
-	//fmt.Println(777)
-	//fmt.Println(signature)
-
-	fmt.Println("签名1:", signature)
-
-	//base64Sig, err := utils.RSASign([]byte(message), "./cert/OP00000003_private_key.pem")
+	//signature, err := Sha256WithRsa(privateRaw, message)
 	//if err != nil {
 	//	return signature, err
 	//}
+	////fmt.Println(777)
+	////fmt.Println(signature)
 	//
-	//fmt.Println("签名2:", base64Sig)
-	//
+	//fmt.Println("签名1:", signature)
+
+	base64Sig, err := utils.RSASign([]byte(message), "./cert/OP00000003_private_key.pem")
+	//base64Sig, err := utils.RSASign([]byte(message), "./cert/demo/api_private_key.pem")
+	//prvKey := "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDokGGq7SlDoULN\nPULY8lcb2uXJcrFKkJI/lSfPppIkGH4xPfQytZXRlonpXqgOvovflJT5VhRvoLe2\ninJ/59kRF59KTerbCG5sG2IHhR/qCUGHervnZuPwgrjOOlnB19VCCUKY1tcplkZa\nKIksUU3TVh09GB3lUngkuOeO15ihcFHMIknOiSpL+Q04+qQf0g++9CxdQUtNY5za\nZ2Jdvch/4yFstR59qQu73ZCCYHFqXaVakyfOC3xOQkRB58jPOUvIab9zwo2hPukT\n+6qkqfokqMhX979HhNshPAJEEUXp4szk0QtP+2n8hq8t3Dws+GY8ElAFvmeGHx5j\nWzPYAcXvAgMBAAECggEBALIsu8caf/zCdc2MW8SelkJPCLG330DDVmjEO4YJlfl1\nkmjjkE2xdSDn9q0GyjbRoZQf36rPWkTTmyyNEYAQ/urrcCybWY2J/h9xMz+TrIm/\noabMT13QJF5FqJTHe7DZTReUxKMYJixEZ433dHCxsbByT2BZM75X2pg32aBEaTl0\nv9OfIMwfaJ5fSBmleJv4q/Lfd232/oOPzyr+EHfsMpTwOrgzQwPNoah1GvH+jBhz\ngoafi36vT8HVjJ+ZjOreH+Z2zVas683Le62rQaN/51jHS5vQGd2+z3qrI3kvu8KK\nWu0kIDQwCKtSFUT00MiKSaklE9JHf8rCNm3+en4kjfECgYEA/0Z2QaP4sOUt1+cZ\nIOprsMkJOl2sLTTDx3MseD2BxUukLDT8P3HTWLtBN9AkGlL6XD8WSs1k9YlGCqf2\ny9qC43Bgwsky8CH1ACk5K4PuWidGUQiqW4Oll/ris2vjagE+QfMHFFa7IalV5FvI\nv9L01jMqSL4duoM5w/WlLyLu8s0CgYEA6TlppWuxUMbxhEL5jmCZSSvsyhmIOdRk\nt4V9MuxwiRuItzywMo4+O7Hs6tjAxTnV/ROa33qyQtm4Olmd4Oa/TkmAJFX+mUrW\njUohDvm7Js2Y7/eeSRcRQLcgCjncpNe3AJoeVEvrGeaJMERYXnTwboUDKxsRyFFq\nAyuZHfuh86sCgYAm3pjFF+2XKd5YIKUv4OHy8jmIfJjp7T3eUcg0qtDmtMTTwmGi\nW3ed7C1bDUNiCr56a1S+oRW9WWCj4L1wft4tOYBSSIaMD++ZTa2Z1aXmblKDpjki\nZCJDyPzZ6xSeoH/VVOcADtDBqGIeumcP5lRHhVTr7J7kNnUGRJIZYk1WBQKBgQCl\nLAIEI4cKnDrD3uL60LL+vVsPrpFp02AZETMf84+nqpZin1pyE4dDo7kUgbnUdCd2\n+oF+sFi7O5Jb0MgdVY47FZbpJPYQ/o2AtvU+s+K1knozyPyS6wFPAeJxG5WGMTfr\n9zpvnOy+BSU3x8+F5e+5df5OcvdfFTmtUR05vNJvzQKBgHUtziAeWo7H6vxknFcc\nkVv7++a4IWF59eP+rpxlaHOtPTI43PLxJgSHEbw3epEzTUnCL9dpP8n48fuYuwM+\n+vpAujDcaGjGffmxW40E6wuGjOYBNg1zjSfEyjxF2fY+D9WoICSPHnrWB0/BEAZB\naL9Lho8+BUEFergUMjxUdvAS"
+	//base64Sig, err := utils.RsaSignWithSha1Hex(message, prvKey)
+	if err != nil {
+		return "", err
+	}
+
+	fmt.Println("签名2:", base64Sig)
+	signature := base64Sig
+
 	//err = utils.RSAVerify([]byte(message), signature, "./cert/OP00000003_cert.cer")
-	////err = utils.RSAVerify([]byte(message), signature, "./cert/lkl-apigw-v2.cer")
+
+	//err = utils.RSAVerify([]byte(message), signature, "./cert/OP00000003_private_key.pem")
+	//err = utils.RSAVerify([]byte(message), signature, "./cert/demo/lkl-apigw-v3.cer")
+	//pubKey := "MIIEMTCCAxmgAwIBAgIGAXRTgcMnMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNVBAYT\nAkNOMRAwDgYDVQQIDAdCZWlKaW5nMRAwDgYDVQQHDAdCZWlKaW5nMRcwFQYDVQQK\nDA5MYWthbGEgQ28uLEx0ZDEqMCgGA1UEAwwhTGFrYWxhIE9yZ2FuaXphdGlvbiBW\nYWxpZGF0aW9uIENBMB4XDTIwMTAxMDA1MjQxNFoXDTMwMTAwODA1MjQxNFowZTEL\nMAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaUppbmcxEDAOBgNVBAcMB0JlaUppbmcx\nFzAVBgNVBAoMDkxha2FsYSBDby4sTHRkMRkwFwYDVQQDDBBBUElHVy5MQUtBTEEu\nQ09NMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt1zHL54HiI8d2sLJ\nlwoQji3/ln0nsvfZ/XVpOjuB+1YR6/0LdxEDMC/hxI6iH2Rm5MjwWz3dmN/6BZeI\ngwGeTOWJUZFARo8UduKrlhC6gWMRpAiiGC8wA8stikc5gYB+UeFVZi/aJ0WN0cpP\nJYCvPBhxhMvhVDnd4hNohnR1L7k0ypuWg0YwGjC25FaNAEFBYP9EYUyCJjE//9Z7\nsMzHR9SJYCqqo6r9bOH9G6sWKuEp+osuAh+kJIxJMHfipw7w3tEcWG0hce9u/el4\ncYJtg8/PPMVoccKmeCzMvarr7jdKP4lenJbtwlgyfs+JgNu60KMUJH8RS72wC9NY\nuFz09wIDAQABo4HVMIHSMIGSBgNVHSMEgYowgYeAFCnH4DkZPR6CZxRn/kIqVsMo\ndJHpoWekZTBjMQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpSmluZzEQMA4GA1UE\nBwwHQmVpSmluZzEXMBUGA1UECgwOTGFrYWxhIENvLixMdGQxFzAVBgNVBAMMDkxh\na2FsYSBSb290IENBggYBaiUALIowHQYDVR0OBBYEFJ2Kx9YZfmWpkKFnC33C0r5D\nK3rFMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUA\nA4IBAQBZoeU0XyH9O0LGF9R+JyGwfU/O5amoB97VeM+5n9v2z8OCiIJ8eXVGKN9L\ntl9QkpTEanYwK30KkpHcJP1xfVkhPi/cCMgfTWQ5eKYC7Zm16zk7n4CP6IIgZIqm\nTVGsIGKk8RzWseyWPB3lfqMDR52V1tdA1S8lJ7a2Xnpt5M2jkDXoArl3SVSwCb4D\nAmThYhak48M++fUJNYII9JBGRdRGbfJ2GSFdPXgesUL2CwlReQwbW4GZkYGOg9LK\nCNPK6XShlNdvgPv0CCR08KCYRwC3HZ0y1F0NjaKzYdGNPrvOq9lA495ONZCvzYDo\ngmsu/kd6eqxTs/JwdaIYr4sCMg8Z"
+	//err = utils.RsaVerySignWithSha1Base64(message, signature, pubKey)
+	//rtn, err := utils.VerifyDerCert([]byte(message), "./cert/lkl-apigw-v2.cer")
 	//if err == nil {
-	//	fmt.Println("验证成功!")
+	//	fmt.Println("验证签名成功!")
+	//	return "", errors.New("验证签名成功!")x
 	//} else {
-	//	fmt.Println("验证失败!")
+	//	fmt.Println("验证签名失败!")
 	//	return "", err
 	//}
+	//fmt.Println(rtn)
 	//return "", errors.New("wangpei签名测试中。。。。。")
 
 	authorization := "LKLAPI-SHA256withRSA " + "appid=\"" + appid + "\"," + "serial_no=\"" + mchSerialNo + "\"," + "timestamp=\"" + timestamp + "\"," + "nonce_str=\"" + nonceStr + "\"," + "signature=\"" + signature + "\"";
@@ -392,7 +420,7 @@ func Sha256WithRsa(privateRaw string, msg string) (string, error) {
 	if !strings.HasPrefix(privateRaw, "-----BEGIN RSA PRIVATE KEY-----") {
 		privateRaw = fmt.Sprintf("%s\n%s\n%s", "-----BEGIN RSA PRIVATE KEY-----", privateRaw, "-----END RSA PRIVATE KEY-----")
 	}
-fmt.Println(privateRaw)
+	//fmt.Println(privateRaw)
 	blockPri, _ := pem.Decode([]byte(privateRaw))
 	if blockPri == nil {
 		return "", fmt.Errorf("blockPri is nil")
@@ -657,10 +685,10 @@ func UnifiedRefund(input *models.RefundParamInput, ip string) (interface{}, erro
 	defer mysql.CloseTx(tx, err)
 
 	//订单存在check
-	//err = SelectPayBill(tx, input)
-	//if err != nil {
-	//	return nil, err
-	//}
+	log_no, trans_term_no, source_code, err := selectPayBill(tx, input)
+	if err != nil {
+		return nil, err
+	}
 
 	billID, err := InsertRefundBill(tx, input, refundID)
 	if err != nil {
@@ -668,38 +696,60 @@ func UnifiedRefund(input *models.RefundParamInput, ip string) (interface{}, erro
 	}
 
 	//数据重组 - start
-	data := make(map[string]interface{})
-	var url string
 	now := time.Now()
 	now.Add(time.Minute * 60)
 	date_time1 := now.Format("20060102150405")
+	version := setting.Conf.Lakala.Version
+	out_org_code := setting.Conf.Lakala.Appid
+	merchant_no1 := setting.Conf.Lakala.MerchantNo1
+	merchant_no2 := setting.Conf.Lakala.MerchantNo2
+	merchant_no3 := setting.Conf.Lakala.MerchantNo3
+	term_no3 := setting.Conf.Lakala.TermNo3
+	merchant_no4 := setting.Conf.Lakala.MerchantNo4
+	term_no4 := setting.Conf.Lakala.TermNo4
+
+	var url string
+	data := make(map[string]interface{})
 
 	url = "https://test.wsmsd.cn/sit/api/v3/labs/relation/refund" //扫码-退款交易
 
 	data["req_time"] = date_time1
-	data["version"] = "3.0"
-	data["out_org_code"] = "OP00000003"
+	data["version"] = version
+	data["out_org_code"] = out_org_code
 
 	data2 := make(map[string]interface{})
 
-	//聚合收银台(微信H5、支付宝H5、微信扫码、支付宝扫码)
-	data2["merchant_no"] = "8222900701107M5" //微信H5、支付宝H5
-	data2["term_no"] = "A1062976" //收银台不传「term_no」,所以需要取得返回值的「trans_term_no」
-	//if input.SourceCode==4 || input.SourceCode==6 {
-	//	data2["merchant_no"] = "8222900701107M5" //微信H5、支付宝H5
-	//} else {
-	//	data2["merchant_no"] = "8221210594300JY" //微信扫码、支付宝扫码
-	//}
-
+	//source_code 1: 微信 Native 2:微信小程序 3:微信内支付 4:h5 跳微信
+	//5:支付宝(web)-扫码或登录支付宝账户 6:alipay(mobile) 7:alipay(app)
+	//9: B2C 10:bk支付宝web 11:bk 支付宝手机
+	if source_code==4 || source_code==6 ||source_code==1 || source_code==5 {
+		//聚合收银台(微信H5、支付宝H5、微信扫码、支付宝扫码)
+		//data2["merchant_no"] = "8221210701101SB"
+		//data2["merchant_no"] = "8222900581201QB"
+		if source_code==4 || source_code==6 {
+			data2["merchant_no"] = merchant_no1 //微信H5、支付宝H5
+		} else {
+			data2["merchant_no"] = merchant_no2 //微信扫码、支付宝扫码
+		}
+		//收银台支付时,没有传「term_no」,所以需要取得支付返回值的「trans_term_no」
+		data2["term_no"] = trans_term_no
 
-	//聚合主扫(微信JSAPI、微信小程序)
-	//data2["merchant_no"] = "8222900581201QB"
-	//data2["term_no"] = "D0027598"
+	} else if source_code==2 || source_code==3 {
+		//聚合主扫(微信JSAPI、微信小程序)
+		//data2["merchant_no"] = "8222900701107M5"
+		//data2["term_no"] = "A1062976"
+		//data2["merchant_no"] = "8221210701101SB"
+		data2["merchant_no"] = merchant_no3
+		data2["term_no"] = term_no3
 
+	} else if source_code==9 {
+		//扫码枪
+		data2["merchant_no"] = merchant_no4
+		data2["term_no"] = term_no4
 
-	//扫码枪
-	//data2["merchant_no"] = "822290070111135"
-	//data2["term_no"] = "29034705"
+	} else {
+		return nil, errors.New("「source_code」错误,有效值为[1-6,9]")
+	}
 
 	data2["out_trade_no"] = refundID //随机生成的订单号 //商户交易流水号
 	//data2["out_trade_no"] = RandomString(32)
@@ -712,9 +762,8 @@ func UnifiedRefund(input *models.RefundParamInput, ip string) (interface{}, erro
 	//input.OrderId = "2023070566210308960791"
 	//data2["origin_out_trade_no"] = input.OrderId //原商户交易流水号
 	//data2["origin_trade_no"] = input.OrderId //原拉卡拉交易流水号
-	data2["origin_log_no"] = input.OrderId //原对账单流水号
-
-
+	//data2["origin_log_no"] = input.OrderId //原对账单流水号
+	data2["origin_log_no"] = log_no //原对账单流水号
 
 	data3 := make(map[string]interface{})
 	//data3["request_ip"] = "10.176.1.192"
@@ -766,39 +815,64 @@ func UnifiedRefund(input *models.RefundParamInput, ip string) (interface{}, erro
 	return response, nil
 }
 
-func SelectPayBill(tx *sql.Tx, input *models.RefundParamInput) error {
+func selectPayBill(tx *sql.Tx, input *models.RefundParamInput) (string, string, uint8, error) {
 
 	var billID int64
 	var status uint
+	var source_code uint8
+	var notice_request models.WxNoticeInput
+	var notice_request2 []byte
 
 	//payment_order_code, paymoney
-	selectPayBillDetailSQL := `select id, result_code from system_pay_bill where _type=0 and payment_order_code=?`
-	err := tx.QueryRow(selectPayBillDetailSQL, input.OrderId).Scan(&billID, &status)
+	selectPayBillDetailSQL := `select b.id, b.result_code, b.source_code, bd.notice_request_body 
+		from system_pay_bill b
+		left join system_pay_bill_detail bd on b.id=bd.pay_bill_id
+		where b._type=0 and b.payment_order_code=?`
+	err := tx.QueryRow(selectPayBillDetailSQL, input.OrderId).Scan(&billID, &status, &source_code, &notice_request2)
 	if err != nil {
-		return errors.New("订单不存在1")
+		return "", "", 0, err
 	}
+	if err := json.Unmarshal(notice_request2, &notice_request); err != nil {
+		return "", "", 0, err
+	}
+
+	//fmt.Println(notice_request2)
+	//fmt.Println(notice_request)
 
 	// 订单不存在
 	if billID <= 0 {
-		return errors.New("订单不存在2")
+		return "", "", 0, errors.New("订单不存在2")
 	}
 
 	// 订单未结算
 	if status != 1 {
-		return errors.New("订单未结算")
+		return "", "", 0, errors.New("订单未结算")
 	}
 
-	return nil
+	if source_code==0 {
+		return "", "", 0, errors.New("「source_code」错误,有效值为[1-6,9]")
+	}
+
+	// 获取「对账单流水号」和「交易终端号」,退款用
+	log_no := notice_request.OrderTradeInfo.(map[string]interface{})["log_no"].(string)
+	if log_no=="" {
+		return "", "", 0, errors.New("「对账单流水号」未取得错误")
+	}
+	if notice_request.TransTermNo=="" {
+		//todo
+		return "", "", 0, errors.New("「交易终端号」未取得错误")
+	}
+
+	return log_no, notice_request.TransTermNo, source_code, nil
 }
 
 //生产随机字符串
-//func RandomString(n int) string {
-//	var letters = []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
-//	result := make([]byte, n)
-//	rand2.Seed(time.Now().Unix())
-//	for i := range result {
-//		result[i] = letters[rand2.Intn(len(letters))]
-//	}
-//	return string(result)
-//}
-
+func RandomString(n int) string {
+	var letters = []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
+	result := make([]byte, n)
+	rand2.Seed(time.Now().Unix())
+	for i := range result {
+		result[i] = letters[rand2.Intn(len(letters))]
+	}
+	return string(result)
+}
diff --git a/setting/setting.go b/setting/setting.go
index 68aa349..3f25b6d 100755
--- a/setting/setting.go
+++ b/setting/setting.go
@@ -24,11 +24,12 @@ type Config struct {
 	Esign           *Esign                  `mapstructure:"esign"`
 	JwtSecret       string                  `mapstructure:"jwtsecret"`
 	DesKey          string                  `mapstructure:"deskey"`
+	PayUrl          *PayUrlDetail           `mapstructure:"payurl"`
+	Lakala          *Lakala                 `mapstructure:"lakala"`
 	//SmsInternational *SmsInternationalConfig `mapstructure:"newsms"`
 	//GateWay          *GateWayDetail          `mapstructure:"gateway"`
 	//GateWayDev       *GateWayDevDetail       `mapstructure:"gatewaydev"`
 	//Mongo            *MongoConfig            `mapstructure:"mongo"`
-	PayUrl           *PayUrlDetail           `mapstructure:"payurl"`
 }
 
 type App struct {
@@ -109,13 +110,36 @@ type SmsInternationalConfig struct {
 //	Port string `mapstructure:"port"`
 //}
 //
-//// PayUrlDetail 网关
+// PayUrlDetail 网关
 type PayUrlDetail struct {
 	DomainName string `mapstructure:"domainname"`
 	//CheckOrder string `mapstructure:"checkorder"`
 	//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 {
 	UploadDir       string `mapstructure:"upload_dir"`
 	MaxFileSize     int    `mapstructure:"max_file_size"`
diff --git a/utils/cert.go b/utils/cert.go
index 76f6e48..66a1981 100755
--- a/utils/cert.go
+++ b/utils/cert.go
@@ -4,12 +4,13 @@ import (
 	"crypto"
 	"crypto/rand"
 	"crypto/rsa"
+	"crypto/sha1"
 	"crypto/x509"
 	"encoding/base64"
+	"encoding/hex"
 	"encoding/pem"
 	"errors"
 	"fmt"
-	"hash"
 	"io/ioutil"
 )
 
@@ -79,24 +80,19 @@ func ReadParsePublicKey(filename string) (*rsa.PublicKey, error) {
 	if block == nil {
 		return nil, errors.New("公钥信息错误!")
 	}
-
-	fmt.Println(block.Type)
 	// 3、解析DER编码的公钥,生成公钥接口
+	//publicKeyInterface2, err := asn1.Marshal(block.Bytes)
+	//fmt.Println(publicKeyInterface2)
+
 	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
+	//publicKeyInterface, err := x509.ParseCertificate(block.Bytes)
 	if err != nil {
-		fmt.Println(444)
+		fmt.Println(8888888888)
 		return nil, err
 	}
-
 	// 4、公钥接口转型成公钥对象
 	publicKey := publicKeyInterface.(*rsa.PublicKey)
 
-	//publicKey, err := x509.ParsePKCS1PublicKey(block.Bytes)
-	//if err != nil {
-	//	fmt.Println(222)
-	//	return nil, err
-	//}
-
 	return publicKey, nil
 }
 
@@ -127,39 +123,121 @@ func ReadParsePrivaterKey(filename string) (*rsa.PrivateKey, error) {
 	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
-- 
2.18.1