notice.go 8.24 KB
Newer Older
1 2 3
package pay

import (
wangp's avatar
wangp committed
4 5
	"crypto"
	"crypto/rsa"
wangp's avatar
wangp committed
6
	"crypto/sha256"
wangp's avatar
wangp committed
7 8
	"crypto/x509"
	"encoding/base64"
wangp's avatar
wangp committed
9
	"encoding/json"
wangp's avatar
wangp committed
10
	"encoding/pem"
wangp's avatar
wangp committed
11
	"errors"
wangp's avatar
wangp committed
12
	"fmt"
13
	"github.com/gin-gonic/gin"
wangp's avatar
wangp committed
14
	"github.com/gin-gonic/gin/binding"
wangp's avatar
wangp committed
15
	"io/ioutil"
wangp's avatar
wangp committed
16
	"strings"
17
	"system_pay/controller/base"
wangp's avatar
wangp committed
18 19
	"system_pay/models"
	"system_pay/repository/pay"
20 21 22 23 24 25
)

// 卡拉卡统一支付回调
type NoticeController struct {
}

wangp's avatar
wangp committed
26 27 28
// CashierNotice 拉卡拉统一支付回调(收银台)
// @Summary 拉卡拉统一支付回调(收银台)
// @Description 拉卡拉统一支付回调(收银台)
29 30 31
// @Tags 拉卡拉统一支付回调
// @Accept application/json
// @Produce application/json
wangp's avatar
wangp committed
32
// @Param   body    body  models.CashierNoticeInput   true	 "参数"
wangp's avatar
wangp committed
33
// @Param language header string ture "语言类型 zh-CN简体中文 en-US英文 ja-JP日文 默认中文"
34
// @Success 200
wangp's avatar
wangp committed
35 36 37
// @router /api/v1/pay/cashier_notice [post]
func (l *PayController) CashierNotice(c *gin.Context) {
	fmt.Println("拉卡拉回调(收银台)start")
wangp's avatar
wangp committed
38

wangp's avatar
wangp committed
39
	//验证签名
wangp's avatar
wangp committed
40 41 42 43 44 45 46 47 48 49
	//err := VerifySignCert(c)
	//if err != nil {
	//	fmt.Println("verySignByPublicKey err: ", err)
	//	response := new(base.ResponseDataWxNotice)
	//	response.Code = "FAIL"
	//	response.Message = "验证签名失败"
	//	base.ResponseWxNotice(c, response)
	//	return
	//}
	//fmt.Println("验证签名成功")
wangp's avatar
wangp committed
50

wangp's avatar
wangp committed
51
	ph := new(models.CashierNoticeInput)
wangp's avatar
wangp committed
52
	err := c.ShouldBindBodyWith(&ph, binding.JSON)
wangp's avatar
wangp committed
53 54 55 56 57 58 59 60
	if err != nil {
		response := new(base.ResponseDataWxNotice)
		response.Code = "FAIL"
		response.Message = "执行失败2"
		base.ResponseWxNotice(c, response)
		return
	}
	fmt.Println(ph)
wangp's avatar
wangp committed
61

wangp's avatar
wangp committed
62 63
	// 拉卡拉统一支付微信回调
	response, err := pay.CashierNotice(ph)
wangp's avatar
wangp committed
64

wangp's avatar
wangp committed
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
	fmt.Println("拉卡拉回调(收银台)end")
	base.ResponseWxNotice(c, response)
}

// ScanNotice 拉卡拉统一支付回调(聚合扫码)
// @Summary 拉卡拉统一支付回调(聚合扫码)
// @Description 拉卡拉统一支付回调(聚合扫码)
// @Tags 拉卡拉统一支付回调
// @Accept application/json
// @Produce application/json
// @Param   body    body  models.ScanNoticeInput   true	 "参数"
// @Param language header string ture "语言类型 zh-CN简体中文 en-US英文 ja-JP日文 默认中文"
// @Success 200
// @router /api/v1/pay/scan_notice [post]
func (l *PayController) ScanNotice(c *gin.Context) {
	fmt.Println("拉卡拉回调(聚合扫码)start")

	//验证签名
	//err := VerifySignCert(c)
	//if err != nil {
	//	fmt.Println("verySignByPublicKey err: ", err)
	//	response := new(base.ResponseDataWxNotice)
	//	response.Code = "FAIL"
	//	response.Message = "验证签名失败"
	//	base.ResponseWxNotice(c, response)
	//	return
	//}
	//fmt.Println("验证签名成功")

	ph := new(models.ScanNoticeInput)
wangp's avatar
wangp committed
95
	//err := c.ShouldBindJSON(ph)
wangp's avatar
wangp committed
96
	err := c.ShouldBindBodyWith(&ph, binding.JSON)
wangp's avatar
wangp committed
97 98 99 100 101 102 103 104 105 106
	if err != nil {
		response := new(base.ResponseDataWxNotice)
		response.Code = "FAIL"
		response.Message = "执行失败2"
		base.ResponseWxNotice(c, response)
		return
	}
	fmt.Println(ph)

	// 拉卡拉统一支付微信回调
wangp's avatar
wangp committed
107
	response, err := pay.ScanNotice(ph)
wangp's avatar
wangp committed
108

wangp's avatar
wangp committed
109
	fmt.Println("拉卡拉回调(聚合扫码)end")
wangp's avatar
wangp committed
110
	base.ResponseWxNotice(c, response)
111
}
wangp's avatar
wangp committed
112

wangp's avatar
wangp committed
113 114 115
//读取证书文件,验证签名
func VerifySignCert(c *gin.Context) error {
	// 1、读取证书文件,获取证书字节
wangp's avatar
wangp committed
116 117
	//certPEM, err := ioutil.ReadFile("./cert/dev/lkl-apigw-v2.cer") //测试
	certPEM, err := ioutil.ReadFile("./cert/prod/bk/lkl-apigw-v1.cer") //正式
wangp's avatar
wangp committed
118 119
	if err != nil {
		fmt.Println("ioutil.ReadFile failed")
wangp's avatar
wangp committed
120
		return err
wangp's avatar
wangp committed
121
	}
wangp's avatar
wangp committed
122

wangp's avatar
wangp committed
123 124 125
	block, _ := pem.Decode([]byte(certPEM))
	if block == nil {
		fmt.Println("failed to parse certificate PEM")
wangp's avatar
wangp committed
126
		return errors.New("failed to parse certificate")
wangp's avatar
wangp committed
127 128 129 130
	}
	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		fmt.Println("failed to parse certificate: " + err.Error())
wangp's avatar
wangp committed
131
		return err
wangp's avatar
wangp committed
132 133
	}

wangp's avatar
wangp committed
134 135 136
	authorization := c.GetHeader("Authorization")
	fmt.Println("wangpei test 验证签名0...")
	fmt.Println("Authorization1="+authorization)
wangp's avatar
wangp committed
137

wangp's avatar
wangp committed
138 139 140
	authorization = strings.Replace(authorization, "LKLAPI-SHA256withRSA ", "", -1)
	authorization = strings.Replace(authorization, ",","&", -1)
	authorization = strings.Replace(authorization, "\"","", -1)
wangp's avatar
wangp committed
141

wangp's avatar
wangp committed
142
	//authorization = "timestamp=1689752771&nonce_str=5HO2w0AjbhJc&signature=VNk9oio0rUMOs1X2j37p9+6o2EyAL3SaLwq2riO0C2FIbTbCZaOrpLSHt6LmgWHHYf50GOQnjZb3oWiTW6LBhF/2ROisEtl78tef6HtMl4mrnDy8BkQGpJS3IL/du+t35OlxeKpBjrpr6ObdZlaA26OZf4uMXRnSv15tvntSi0zM0GA7+dcUCBd4sFPGRgU0qfABiqC7bzzOZFrUpEe7ZZRfXQ2PLkJO0uBQt7vUoqt0fVXsPR+FjR++e1JASg821Gf7+J+Tr73MoAVkRJ0HwJX72HbbffVMNAYF/5cc/sL50WtFJ8JrLj6WAJdesSmeFBrs+tOEMH62b+Wr/mPnXw=="
wangp's avatar
wangp committed
143

wangp's avatar
wangp committed
144 145 146 147 148
	auth_parts := strings.Split(authorization, "&")
	params := make(map[string]string)
	for _, param := range auth_parts {
		item := strings.Split(param, "=")
		params[item[0]] = item[1]
wangp's avatar
wangp committed
149
	}
wangp's avatar
wangp committed
150 151 152
	//if params["signature"] != "" && len(params["signature"]) > 10 {
	//	//params["signature"] = substr($query, strrpos($query, 'signature=') + 10);
	//	params["signature"] = params["signature"][0:10]
wangp's avatar
wangp committed
153
	//}
wangp's avatar
wangp committed
154 155 156 157 158 159 160
	timestamp := params["timestamp"]
	nonce := params["nonce_str"]
	signature := params["signature"]
	signature = signature + "=="
	//signature = "VNk9oio0rUMOs1X2j37p9+6o2EyAL3SaLwq2riO0C2FIbTbCZaOrpLSHt6LmgWHHYf50GOQnjZb3oWiTW6LBhF/2ROisEtl78tef6HtMl4mrnDy8BkQGpJS3IL/du+t35OlxeKpBjrpr6ObdZlaA26OZf4uMXRnSv15tvntSi0zM0GA7+dcUCBd4sFPGRgU0qfABiqC7bzzOZFrUpEe7ZZRfXQ2PLkJO0uBQt7vUoqt0fVXsPR+FjR++e1JASg821Gf7+J+Tr73MoAVkRJ0HwJX72HbbffVMNAYF/5cc/sL50WtFJ8JrLj6WAJdesSmeFBrs+tOEMH62b+Wr/mPnXw=="

	//b, err := c.GetRawData()
wangp's avatar
wangp committed
161
	//if err != nil {
wangp's avatar
wangp committed
162
	//	fmt.Println("failed to get request body: " + err.Error())
wangp's avatar
wangp committed
163 164
	//	return err
	//}
wangp's avatar
wangp committed
165
	//reqBody := string(b) //获取response body
wangp's avatar
wangp committed
166

wangp's avatar
wangp committed
167
	var body interface{}
wangp's avatar
wangp committed
168 169
	err = c.ShouldBindBodyWith(&body, binding.JSON)
	if err != nil {
wangp's avatar
wangp committed
170 171
		//log.Default().Error("should bind body error", zap.Error(err))
		fmt.Println("should bind body error: " + err.Error())
wangp's avatar
wangp committed
172 173
		return err
	}
wangp's avatar
wangp committed
174
	byteBody, err := json.Marshal(body)
wangp's avatar
wangp committed
175
	if err != nil {
wangp's avatar
wangp committed
176
		fmt.Println("json.Marshal error: " + err.Error())
wangp's avatar
wangp committed
177 178
		return err
	}
wangp's avatar
wangp committed
179 180
	reqBody := string(byteBody)
	//reqBody, _ := json.MarshalToString(body)
wangp's avatar
wangp committed
181

wangp's avatar
wangp committed
182 183 184 185 186
	//JAVA demo
	//timestamp = "1630905585";
	//nonce = "9003323344";
	//signature = "tnjIAcEISq/ClrOppv/nojeZnE/pB1wNfQC/hMTME+rQMapWzvs9v1J68ueDpVzs1RW22dNotmUVy2sM6thNFRkaOx4qQGslX6kIttwvlsJsSEIR3qrjdPdUAkbP2KDRLujspxE9X0daJ6BU+rOoJ8p4c6y1/QSOMtDJoO3EABOF4O6RFHR3N7JW8o4qcf7lOOO7D4rlAB2vw6tV8WeG+OEyJ++Q0K3V1oM5uJEIPPuJkb2qlEqVYKiYLyvIdEJ1Z5qMbC9U7rKuHdeTQPl7last/h5nd6WauzDfYPKlAjZBEPYjiDqRv6Dm+4FeNtALoy6Mg7Ruxeq1pJudfj0iKg==";
	//reqBody = "{\"payOrderNo\":\"21090611012001970631000463034\",\"merchantOrderNo\":\"CH2021090613190866292\",\"orderInfo\":null,\"merchantNo\":\"822126090640003\",\"termId\":\"47781282\",\"tradeMerchantNo\":\"822126090640003\",\"tradeTermId\":\"47781282\",\"channelId\":\"10000038\",\"currency\":\"156\",\"amount\":1,\"tradeType\":\"PAY\",\"payStatus\":\"S\",\"notifyStatus\":0,\"orderCreateTime\":\"2021-09-06T05:19:43.000+00:00\",\"orderEfficientTime\":\"2021-09-06T05:19:43.000+00:00\",\"extendField\":null,\"payTime\":\"2021-09-06T05:19:43.000+00:00\",\"remark\":\"\",\"noticeNum\":1,\"sign\":null,\"notifyUrl\":null,\"notifyMode\":\"2\",\"payInfo\":\"1#1#ALIPAY#0#2021090622001432581427657317\",\"lklOrderNo\":\"2021090666210003610012\",\"crdFlg\":\"92\",\"payerId1\":\"2088702852632582\",\"payerId2\":\"rob***@126.com\",\"smCrdFlg\":\"01\",\"tradeTime\":\"20210906131943\",\"accountChannelOrderNo\":\"2021090622001432581427657317\",\"actualPayAmount\":1,\"logNo\":\"66210003610012\"}";
wangp's avatar
wangp committed
187

wangp's avatar
wangp committed
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
	preSignData := timestamp +"\n" + nonce + "\n" +reqBody + "\n";
	fmt.Println("wangpei test 验证签名1...")
	fmt.Println("params=");fmt.Println(params)
	fmt.Println("wangpei test 验证签名2...")
	fmt.Println("signature="+signature)
	fmt.Println("wangpei test 验证签名3...")
	fmt.Println("Authorization2="+authorization)
	fmt.Println("wangpei test 验证签名4...")
	fmt.Println("preSignData=" + preSignData)
	fmt.Println("wangpei test 验证签名5...")
	//证书 => 公钥
	publicKey := cert.PublicKey.(*rsa.PublicKey)

	//验证签名
	bytes, err := base64.StdEncoding.DecodeString(signature)
wangp's avatar
wangp committed
203
	if err != nil {
wangp's avatar
wangp committed
204
		fmt.Println("failed to base64.StdEncoding.DecodeString: " + err.Error())
wangp's avatar
wangp committed
205 206
		return err
	}
wangp's avatar
wangp committed
207 208
	hashed := sha256.Sum256([]byte(preSignData))
	err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hashed[:], bytes)
wangp's avatar
wangp committed
209
	if err != nil {
wangp's avatar
wangp committed
210
		fmt.Println("failed to VerifyPKCS1v15: " + err.Error())
wangp's avatar
wangp committed
211 212
		return err
	}
wangp's avatar
wangp committed
213 214

	fmt.Println("wangpei test ok")
wangp's avatar
wangp committed
215
	return nil
wangp's avatar
wangp committed
216
}