pay.go 31.5 KB
Newer Older
wangp's avatar
wangp committed
1 2 3 4 5 6 7 8
package pay

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
wangp's avatar
wangp committed
9
	"database/sql"
wangp's avatar
wangp committed
10 11 12 13 14 15
	"encoding/base64"
	"encoding/json"
	"encoding/pem"
	"errors"
	"fmt"
	"github.com/astaxie/beego/httplib"
wangp's avatar
wangp committed
16
	uID "github.com/satori/go.uuid"
wangp's avatar
wangp committed
17 18
	"strings"
	"system_pay/models"
19
	"system_pay/mysql"
wangp's avatar
wangp committed
20
	"system_pay/setting"
wangp's avatar
wangp committed
21
	"time"
wangp's avatar
wangp committed
22 23 24
)

// 拉卡拉支付
wangp's avatar
wangp committed
25
func UnifiedOrder(input *models.PlaceAnOrderParamInput, ip string) (interface{}, error) {
wangp's avatar
wangp committed
26

wangp's avatar
wangp committed
27 28 29
	if input.SourceCode==0 {
		return nil, errors.New("输入项「source_code」为空错误")
	}
wangp's avatar
wangp committed
30

wangp's avatar
wangp committed
31
	fmt.Println("谛宝多多输入参数")
wangp's avatar
wangp committed
32 33
	fmt.Println(input)

wangp's avatar
wangp committed
34 35
	orderID := GetUID()

wangp's avatar
wangp committed
36
	//beego.Info("AttachInfo: ", input.AttachInfo)
wangp's avatar
wangp committed
37 38 39 40 41 42 43 44 45

	attachMap := make(map[string]interface{}, 0)
	attachMap["store_sn"] = input.StoreSn
	attachMap["old_attach"] = input.AttachInfo

	attach, _ := json.Marshal(attachMap)
	input.AttachInfo = string(attach)

	// 插入数据库
wangp's avatar
wangp committed
46
	db, err := mysql.NewPayConn()
wangp's avatar
wangp committed
47 48 49 50 51 52 53 54 55
	if err != nil {
		return 0, err
	}

	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}

wangp's avatar
wangp committed
56
	defer mysql.CloseTx(tx, err)
wangp's avatar
wangp committed
57 58 59 60 61 62

	billID, err := InsertPayBill(tx, input, orderID)
	if err != nil {
		return nil, err
	}

wangp's avatar
wangp committed
63
	//数据重组 - start
wangp's avatar
wangp committed
64
	data := make(map[string]interface{})
wangp's avatar
wangp committed
65
	var url string
wangp's avatar
wangp committed
66 67 68 69
	now := time.Now()
	now.Add(time.Minute * 60)
	date_time1 := now.Format("20060102150405")
	date_time2 := now.Add(time.Minute * 60).Format("20060102150405")
wangp's avatar
wangp committed
70 71
	//source_code 1: 微信 Native 2:微信小程序 3:微信内支付 4:h5 跳微信
	//5:支付宝(web)-扫码或登录支付宝账户 6:alipay(mobile) 7:alipay(app)
wangp's avatar
wangp committed
72 73 74 75 76
	//9: B2C 10:bk支付宝web 11:bk 支付宝手机
	if input.SourceCode==4 || input.SourceCode==6 ||input.SourceCode==1 || input.SourceCode==5 {
		//聚合收银台(微信H5、支付宝H5、微信扫码、支付宝扫码)
		url = "https://test.wsmsd.cn/sit/api/v3/ccss/counter/order/create" //聚合收银台

wangp's avatar
wangp committed
77
		data["req_time"] = date_time1
wangp's avatar
wangp committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
		data["version"] = "3.0"
		data["out_org_code"] = "OP00000003"

		//input.ReturnURL = "https://test.pet-dbc.cn"

		// 构造回调url
		input.NoticeURL = GetNoticeURL(input.SourceCode)
		// 传递给支付渠道的
		//p.ServeNoticeUrl = noticeURLx

		data2 := make(map[string]interface{})
		//data2["merchant_no"] = "8222900701107M5"
		//data2["merchant_no"] = "8221210701101SB"
		//data2["merchant_no"] = "8222900581201QB"
		data2["merchant_no"] = "8221210594300JY"
		//data2["term_no"] = "29034705" //不需要传?

		//data2["total_amount"] = "1"
		data2["total_amount"] = input.GoodsPrice*100
		//data2["out_trade_no"] = orderID //随机生成的订单号 //商户交易流水号
		//data2["out_trade_no"] = RandomString(32)
		data2["out_order_no"] = orderID //随机生成的订单号 //商户订单号
		//data2["out_order_no"] = RandomString(32)
		//data2["out_trade_no"] = input.AttachInfo
		//data2["out_order_no"] = input.AttachInfo

		if input.SourceCode < 5 {
			//微信
			data2["counter_param"] = "{\"pay_mode\":\"WECHAT\"}"
		} else {
			//支付宝
			data2["counter_param"] = "{\"pay_mode\":\"ALIPAY\"}"
		}
wangp's avatar
wangp committed
111

wangp's avatar
wangp committed
112
		data2["order_efficient_time"] = date_time2 //订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
wangp's avatar
wangp committed
113 114 115 116 117 118 119 120 121 122 123 124
		data2["notify_url"] = input.NoticeURL            //订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com
		data2["callback_url"] = input.ReturnURL          //客户端下单完成支付后返回的商户网页跳转地址
		data2["order_info"] = "必康测试订单标题2"                //订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
		//data2["goods_mark"] = input.AttachInfo //商品信息标识 (1:含商品信息,不填默认不含商品信息)

		data["req_data"] = make(map[string]interface{})
		data["req_data"] = data2

	} else if input.SourceCode==2 || input.SourceCode==3 {
		//聚合主扫(微信JSAPI、微信小程序)
		url = "https://test.wsmsd.cn/sit/api/v3/labs/trans/preorder" //聚合主扫

wangp's avatar
wangp committed
125
		data["req_time"] = date_time1
wangp's avatar
wangp committed
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
		data["version"] = "3.0"
		data["out_org_code"] = "OP00000003"

		//input.ReturnURL = "https://test.pet-dbc.cn"

		// 构造回调url
		input.NoticeURL = GetNoticeURL(input.SourceCode)
		// 传递给支付渠道的
		//p.ServeNoticeUrl = noticeURL

		data2 := make(map[string]interface{})
		//data2["merchant_no"] = "8222900701107M5"
		//data2["term_no"] = "A1062976"
		//data2["merchant_no"] = "8221210701101SB"
		data2["merchant_no"] = "8222900581201QB"
		data2["term_no"] = "D0027598"
		//tempMoney, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", p.GoodsPrice*100), 64)
		data2["total_amount"] = input.GoodsPrice*100
		data2["out_trade_no"] = orderID //随机生成的订单号 //商户交易流水号

wangp's avatar
wangp committed
146
		data2["order_efficient_time"] = date_time2 //订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
wangp's avatar
wangp committed
147 148 149 150 151
		data2["notify_url"] = input.NoticeURL            //订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com
		data2["callback_url"] = input.ReturnURL          //客户端下单完成支付后返回的商户网页跳转地址
		data2["order_info"] = "必康测试订单标题2"                //订单标题,在使用收银台扫码支付时必输入,交易时送往账户端
		//data2["goods_mark"] = input.AttachInfo //商品信息标识 (1:含商品信息,不填默认不含商品信息)

wangp's avatar
wangp committed
152 153 154 155
		//微信JSAPI、微信小程序
		data2["counter_param"] = "{\"pay_mode\":\"WECHAT\"}"
		data2["account_type"] = "WECHAT" //钱包类型
		data2["trans_type"] = "51"       //接入方式
wangp's avatar
wangp committed
156

wangp's avatar
wangp committed
157 158 159 160 161
		//地址位置信息
		data3 := make(map[string]interface{})
		data3["request_ip"] = ip
		data2["location_info"] = make(map[string]interface{})
		data2["location_info"] = data3
wangp's avatar
wangp committed
162

wangp's avatar
wangp committed
163 164 165
		//地址位置信息
		data4 := make(map[string]interface{})
		//data4["open_id"] = input.OpenID //此参数 支付类型是 JS API 的时候 必传
wangp's avatar
wangp committed
166

wangp's avatar
wangp committed
167 168
		data4["sub_appid"] = "wxc3e4d1682da3053c"
		data4["user_id"] = "oLvoQ5deygCMj2WrDjPVPvV1L1t8"
wangp's avatar
wangp committed
169

wangp's avatar
wangp committed
170 171
		data2["acc_busi_fields"] = make(map[string]interface{})
		data2["acc_busi_fields"] = data4
wangp's avatar
wangp committed
172

wangp's avatar
wangp committed
173 174
		data["req_data"] = make(map[string]interface{})
		data["req_data"] = data2
wangp's avatar
wangp committed
175

wangp's avatar
wangp committed
176
	} else if input.SourceCode==9 {
wangp's avatar
wangp committed
177
		//扫码枪
wangp's avatar
wangp committed
178 179 180 181 182 183
		if input.DynamicID=="" {
			return nil, errors.New("输入项「dynamic_id」为空错误")
		}

		url = "https://test.wsmsd.cn/sit/api/v3/labs/trans/micropay" //聚合被扫

wangp's avatar
wangp committed
184
		data["req_time"] = date_time1
wangp's avatar
wangp committed
185 186 187 188 189 190
		data["version"] = "3.0"
		data["out_org_code"] = "OP00000003"

		data2 := make(map[string]interface{})
		data2["merchant_no"] = "822290070111135"
		data2["term_no"] = "29034705"
wangp's avatar
wangp committed
191 192
		//data2["merchant_no"] = "8222900581201QB"
		//data2["term_no"] = "D0027598"
wangp's avatar
wangp committed
193 194 195 196 197 198
		data2["out_trade_no"] = orderID //随机生成的订单号 //商户交易流水号
		//data2["out_trade_no"] = RandomString(32)
		//扫码支付授权码,设备读取用户APP中的条码或者二维码信息,用户付款码条形码规则见说明
		//data2["auth_code"] = "135178236713755038"
		data2["auth_code"] = input.DynamicID
		data2["total_amount"] = input.GoodsPrice*100
wangp's avatar
wangp committed
199

wangp's avatar
wangp committed
200 201 202 203 204 205 206 207 208 209 210 211 212
		data3 := make(map[string]interface{})
		//data3["request_ip"] = "10.176.1.192"
		data3["request_ip"] = ip
		//data3["location"] = "+37.123456789,-121.123456789"
		data2["location_info"] = make(map[string]interface{})
		data2["location_info"] = data3

		data["req_data"] = make(map[string]interface{})
		data["req_data"] = data2

	} else {
		return nil, errors.New("输入参数「source_code」错误,有效值为[1-6,9]")
	}
wangp's avatar
wangp committed
213 214 215
	//数据重组 - end
	fmt.Println("拉卡拉输入参数")
	fmt.Println(data)
wangp's avatar
wangp committed
216 217
	fmt.Println("拉卡拉接口url")
	fmt.Println(url)
wangp's avatar
wangp committed
218

wangp's avatar
wangp committed
219 220 221 222 223 224
	// 插入下单请求参数
	err = InsertPayBillDetailRequestBody(tx, billID, data)
	if err != nil {
		return nil, err
	}

wangp's avatar
wangp committed
225 226 227 228 229 230 231 232
	data_json, err := json.Marshal(data)
	if err != nil {
		//this.Data["json"] = utils.CheckError(errors.New("Map转化为byte数组失败"),"异常")
		//this.ServeJSON()
		return nil, err
	}

	//调拉卡拉接口
wangp's avatar
wangp committed
233
	err, response, lakala_rtn := lakala_post(input.SourceCode, url, data_json)
wangp's avatar
wangp committed
234
	if err != nil {
wangp's avatar
wangp committed
235
		InsertPayBillDetailResponseBody(tx, billID, err) //todo
wangp's avatar
wangp committed
236 237 238
		return nil, err
	}

wangp's avatar
wangp committed
239 240 241
	// 插入下单成功后返回的参数
	err = InsertPayBillDetailResponseBody(tx, billID, lakala_rtn)
	if err != nil {
wangp's avatar
wangp committed
242
		//beego.Error("下单请求成功 --- 但插入成功后的参数失败")
wangp's avatar
wangp committed
243 244
		return nil, err
	}
wangp's avatar
wangp committed
245

wangp's avatar
wangp committed
246 247 248 249 250 251 252
	if input.SourceCode==9 {
		//收钱吧(扫码枪)
		response := make(map[string]string)
		response["payment_order_code"] = orderID //随机生成的订单号
		return response, nil
	}

wangp's avatar
wangp committed
253 254 255
	return response, nil
}

wangp's avatar
wangp committed
256
func lakala_post(source_code uint8, url string, data_json []byte) (error, interface{}, interface{}) {
wangp's avatar
wangp committed
257 258 259 260
	if source_code<0 || source_code>6 {
		return errors.New("输入参数「source_code」错误"), "", nil
	}

wangp's avatar
wangp committed
261 262
	authorization, err := getAuthorization(string(data_json))
	if err != nil {
wangp's avatar
wangp committed
263
		return err, "", nil
wangp's avatar
wangp committed
264 265 266 267 268 269 270 271 272 273 274 275 276
	}

	fmt.Println(url)
	fmt.Println(authorization)

	req := httplib.Post(url)
	//req.Header("Authorization", "LKLAPI-SHA256withRSA appid=\"\", serial_no=\"\", timestamp=\"\", nonce_str=\"\", signature=\"2233\"")
	req.Header("Authorization", authorization)
	req.Header("Accept", "application/json")
	req.Header("Content-Type", "application/json")
	req.Body(data_json)
	body, err := req.Bytes()
	if err != nil {
wangp's avatar
wangp committed
277
		return err, "", nil
wangp's avatar
wangp committed
278 279 280 281
	}

	temp := make(map[string]interface{}, 0)
	if err = json.Unmarshal(body, &temp); err != nil {
wangp's avatar
wangp committed
282
		return err, "", nil
wangp's avatar
wangp committed
283 284 285 286 287
	}

	fmt.Println("拉卡拉返回值")
	fmt.Println(temp)
	//todo
wangp's avatar
wangp committed
288
	if temp["code"] != "000000" && temp["code"] != "BBS00000"{
wangp's avatar
wangp committed
289 290
		//this.Data["json"] = utils.CheckError(errors.New("拉卡拉错误"), temp["msg"].(string))  //todo
		//this.ServeJSON()
wangp's avatar
wangp committed
291
		return errors.New(temp["msg"].(string)), "", temp
wangp's avatar
wangp committed
292
	}
wangp's avatar
wangp committed
293
	//return nil, temp["resp_data"]["counter_url"]
wangp's avatar
wangp committed
294

wangp's avatar
wangp committed
295 296 297 298 299 300 301
	response := make(map[string]string)
	if source_code==4 || source_code==6 || source_code==1 || source_code==5 {
		//聚合收银台(微信H5、支付宝H5、微信扫码、支付宝扫码)
		temp2, _ := temp["resp_data"].(map[string]interface{})
		if temp2["counter_url"]=="" {
			return errors.New("拉卡拉返回值「counter_url」为空错误"), "", temp
		}
wangp's avatar
wangp committed
302 303 304 305 306 307 308 309
		if source_code==4 || source_code==6 {
			//微信H5、支付宝H5
			response["m_web_url"] = temp2["counter_url"].(string)
		} else {
			//微信扫码、支付宝扫码
			response["qr_code_url"] = temp2["counter_url"].(string)
		}

wangp's avatar
wangp committed
310 311 312 313
	} else if source_code==2 || source_code==3 {
		//聚合主扫(微信JSAPI+微信小程序)
		temp2, _ := temp["resp_data"].(map[string]interface{})
		temp3, _ := temp2["acc_resp_fields"].(map[string]interface{})
wangp's avatar
wangp committed
314 315 316
		if temp2["acc_resp_fields"]=="" {
			return errors.New("拉卡拉返回值「acc_resp_fields」为空错误"), "", temp
		}
wangp's avatar
wangp committed
317 318 319 320 321 322 323
		response["app_id"] = temp3["app_id"].(string)
		response["nonce_str"] = temp3["nonce_str"].(string)
		response["package"] = temp3["package"].(string)
		response["pay_sign"] = temp3["pay_sign"].(string)
		response["prepay_id"] = temp3["prepay_id"].(string)
		response["sign_type"] = temp3["sign_type"].(string)
		response["timeStamp"] = temp3["time_stamp"].(string)
wangp's avatar
wangp committed
324 325
	}

wangp's avatar
wangp committed
326
	return nil, response, temp
wangp's avatar
wangp committed
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
}

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"

	//String nonceStr = generateNonceStr();
	//long timestamp = generateTimestamp();

	message := appid + "\n" + mchSerialNo + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";

	//System.out.println("getToken message :  " + message);

	//PrivateKey merchantPrivateKey = loadPrivateKey(new FileInputStream(new File(merchantPrivateKeyPath)));

	//String signature = this.sign(message.getBytes(ENCODING), merchantPrivateKey);
	//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-----"
wangp's avatar
wangp committed
352 353


wangp's avatar
wangp committed
354 355 356 357 358 359 360
	signature, err := Sha256WithRsa(privateRaw, message)
	if err != nil {
		return signature, err
	}
	//fmt.Println(777)
	//fmt.Println(signature)

wangp's avatar
wangp committed
361 362
	fmt.Println("签名1:", signature)

wangp's avatar
wangp committed
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
	//base64Sig, err := utils.RSASign([]byte(message), "./cert/OP00000003_private_key.pem")
	//if err != nil {
	//	return signature, err
	//}
	//
	//fmt.Println("签名2:", base64Sig)
	//
	//err = utils.RSAVerify([]byte(message), signature, "./cert/OP00000003_cert.cer")
	////err = utils.RSAVerify([]byte(message), signature, "./cert/lkl-apigw-v2.cer")
	//if err == nil {
	//	fmt.Println("验证成功!")
	//} else {
	//	fmt.Println("验证失败!")
	//	return "", err
	//}
	//return "", errors.New("wangpei签名测试中。。。。。")
wangp's avatar
wangp committed
379

wangp's avatar
wangp committed
380 381 382 383 384 385 386 387 388 389 390
	authorization := "LKLAPI-SHA256withRSA " + "appid=\"" + appid + "\"," + "serial_no=\"" + mchSerialNo + "\"," + "timestamp=\"" + timestamp + "\"," + "nonce_str=\"" + nonceStr + "\"," + "signature=\"" + signature + "\"";

	//System.out.println("authorization message :" + authorization);
	return authorization, nil
}

func Sha256WithRsa(privateRaw string, msg string) (string, error) {
	privateRaw = strings.Trim(privateRaw, "\n")
	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-----")
	}
wangp's avatar
wangp committed
391
fmt.Println(privateRaw)
wangp's avatar
wangp committed
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
	blockPri, _ := pem.Decode([]byte(privateRaw))
	if blockPri == nil {
		return "", fmt.Errorf("blockPri is nil")
	}

	rsaPri, e := genPriKey(blockPri.Bytes, PKCS8)
	if e != nil {
		panic(e)
	}

	h := sha256.New()
	h.Write([]byte(msg))
	d := h.Sum(nil)

	signature, err := rsa.SignPKCS1v15(rand.Reader, rsaPri, crypto.SHA256, d)
	if err != nil {
		//return "", errorx.Wrap(err)
		return "", err
	}
	encodedSig := base64.StdEncoding.EncodeToString(signature)
	return encodedSig, nil
}

const (
	PKCS1 int64 = iota
	PKCS8
)

func genPriKey(privateKey []byte, privateKeyType int64) (*rsa.PrivateKey, error) {
	var priKey *rsa.PrivateKey
	var err error
	switch privateKeyType {
	case PKCS1:
		{
			priKey, err = x509.ParsePKCS1PrivateKey([]byte(privateKey))
			if err != nil {
				return nil, err
			}
		}
	case PKCS8:
		{
			prkI, err := x509.ParsePKCS8PrivateKey([]byte(privateKey))
			if err != nil {
				return nil, err
			}
			priKey = prkI.(*rsa.PrivateKey)
		}
	default:
		{
			return nil, fmt.Errorf("unsupport private key type")
		}
	}
	return priKey, nil
}
wangp's avatar
wangp committed
446

447 448 449
// GetNoticeURL is 获取回调地址
func GetNoticeURL(sourceCode uint8) string {

wangp's avatar
wangp committed
450 451 452
	//domainName := beego.AppConfig.String("DomainName")
	domainName := setting.Conf.PayUrl.DomainName
	//domainName = "http://tpay-v2.pet-dbc.cn:14880";
wangp's avatar
wangp committed
453
	return domainName + "/api/v1/pay/wx_notice"
454 455 456

	// <= 5 是微信
	if sourceCode < 5 {
wangp's avatar
wangp committed
457
		return domainName + "/api/v1/pay/wx_notice"
458 459 460
	}

	// > 5 是支付宝
wangp's avatar
wangp committed
461
	return domainName + "/api/v1/pay/alipay_notice"
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486
	//
	//if isServe == 0 {
	//	// payType 1: 原生  2: paymax
	//	if payType == 1 {
	//
	//		// <= 5 是微信    > 5 是支付宝
	//		if sourceCode < 5 {
	//			return domainName + "/v1/notice/wx"
	//		}
	//
	//		return domainName + "/v1/notice/ali"
	//	}
	//
	//	return domainName + "/v1/notice/paymax"
	//}
	//
	//// <= 5 是微信    > 5 是支付宝
	//if sourceCode < 5 {
	//	return domainName + "/v1/notice/serve_wx"
	//}
	//
	//return domainName + "/v1/notice/serve_ali"
}

// BillPayStateSuccess is 微信回调后 把订单状态 置为结算成功
wangp's avatar
wangp committed
487
func BillPayStateSuccess(tx *sql.Tx, billID int64) error {
488

wangp's avatar
wangp committed
489 490
	insertPayBillDetailSQL := `update system_pay_bill set result_code = 1 where id = ?`
	result, err := tx.Exec(insertPayBillDetailSQL, billID)
491 492 493 494 495 496 497 498 499 500 501 502
	if err != nil {
		return err
	}

	_, err = result.RowsAffected()
	if err != nil {
		return err
	}
	return nil
}

// BillPayStateFail is 微信回调后 把订单状态 置为结算失败
wangp's avatar
wangp committed
503
func BillPayStateFail(tx *sql.Tx, billID int64) error {
504

wangp's avatar
wangp committed
505 506
	insertPayBillDetailSQL := `update system_pay_bill set result_code = 2 where id = ?`
	result, err := tx.Exec(insertPayBillDetailSQL, billID)
507 508 509 510 511 512 513 514 515 516 517
	if err != nil {
		return err
	}

	_, err = result.RowsAffected()
	if err != nil {
		return err
	}
	return nil
}

wangp's avatar
wangp committed
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
//InsertRefundBill is 插入 支付订单表中
func InsertRefundBill(tx *sql.Tx, p *models.RefundParamInput, refundID string) (int64, error) {

	var billID int64

	//todo
	//insertSQL := `insert system_pay_bill set platform_type = ?, source_code = ?,
	//payment_order_code = ?, paymoney = ?*1000, pay_type = 4, attach = ?, _type = 1, original_payment_order_code = ?`

	//platformType, sourceCode, checkSn, refundAmount, attach, orderID
	//result, err := tx.Exec(insertSQL, p.PlatformType, p.PlatformInfo, p.SourceCode,
	//	orderID, p.GoodsPrice, p.GoodsDes, p.GoodsDetail, p.AttachInfo, p.NoticeURL, p.PayType, p.IsServe)

	insertSQL := `insert system_pay_bill set original_payment_order_code=?, payment_order_code=?, paymoney=?*1000, pay_type=4, _type=1`

	//platformType, sourceCode, checkSn, refundAmount, attach, orderID
	result, err := tx.Exec(insertSQL, p.OrderId, refundID, p.GoodsPrice)
	if err != nil {
		return billID, err
	}

	billID, err = result.LastInsertId()
	if err != nil {
		return billID, err
	}
	return billID, nil
}

546
//InsertPayBill is 插入 支付订单表中
wangp's avatar
wangp committed
547
func InsertPayBill(tx *sql.Tx, p *models.PlaceAnOrderParamInput, orderID string) (int64, error) {
548 549 550

	var billID int64

wangp's avatar
wangp committed
551
	insertSQL := `insert system_pay_bill set platform_type = ?, platform_info = ?,
552 553 554
source_code = ?, payment_order_code = ?, paymoney = ?*1000, commodity_describe = ?,
commodity_detail = ?, attach = ?, notify_pay_url = ?, pay_type = ?, is_serve = ?`

wangp's avatar
wangp committed
555
	result, err := tx.Exec(insertSQL, p.PlatformType, p.PlatformInfo, p.SourceCode,
556 557 558 559 560 561 562 563 564 565 566 567 568
		orderID, p.GoodsPrice, p.GoodsDes, p.GoodsDetail, p.AttachInfo, p.NoticeURL, p.PayType, p.IsServe)
	if err != nil {
		return billID, err
	}

	billID, err = result.LastInsertId()
	if err != nil {
		return billID, err
	}
	return billID, nil
}

// InsertPayBillDetailRequestBody is 插入支付订单详情表中的 下单参数字段 request_body
wangp's avatar
wangp committed
569
func InsertPayBillDetailRequestBody(tx *sql.Tx, billID int64, requestBody interface{}) error {
570 571 572 573 574

	body, err := json.Marshal(requestBody)
	if err != nil {
		return err
	}
wangp's avatar
wangp committed
575 576
	insertPayBillDetailSQL := `insert system_pay_bill_detail set pay_bill_id = ?, request_body = ?`
	result, err := tx.Exec(insertPayBillDetailSQL, billID, string(body))
577 578 579 580 581 582 583 584 585 586 587 588
	if err != nil {
		return err
	}

	_, err = result.LastInsertId()
	if err != nil {
		return err
	}
	return nil
}

// InsertPayBillDetailResponseBody is 插入支付订单详情表中的 下单参数字段 response_body
wangp's avatar
wangp committed
589
func InsertPayBillDetailResponseBody(tx *sql.Tx, billID int64, responseBody interface{}) error {
590 591 592 593 594

	body, err := json.Marshal(responseBody)
	if err != nil {
		return err
	}
wangp's avatar
wangp committed
595 596
	insertPayBillDetailSQL := `update system_pay_bill_detail set response_body = ? where pay_bill_id = ?`
	result, err := tx.Exec(insertPayBillDetailSQL, string(body), billID)
597 598 599 600 601 602 603 604 605 606 607
	if err != nil {
		return err
	}

	_, err = result.RowsAffected()
	if err != nil {
		return err
	}
	return nil
}

wangp's avatar
wangp committed
608
func InsertPayBillDetailResponseBodyString(tx *sql.Tx, billID int64, responseBody string) error {
609

wangp's avatar
wangp committed
610 611
	insertPayBillDetailSQL := `update system_pay_bill_detail set response_body = ? where pay_bill_id = ?`
	result, err := tx.Exec(insertPayBillDetailSQL, responseBody, billID)
612 613 614 615 616 617 618 619 620 621
	if err != nil {
		return err
	}

	_, err = result.RowsAffected()
	if err != nil {
		return err
	}
	return nil
}
wangp's avatar
wangp committed
622 623 624 625 626 627 628 629 630 631

func GetUID() string {

	u4 := uID.NewV4()
	//if err != nil {
	//	return ""
	//}

	id := fmt.Sprintf("%s", u4)
	return strings.Replace(id, "-", "", -1)
wangp's avatar
wangp committed
632 633
}

wangp's avatar
wangp committed
634 635
// 拉卡拉退款
func UnifiedRefund(input *models.RefundParamInput, ip string) (interface{}, error) {
wangp's avatar
wangp committed
636

wangp's avatar
wangp committed
637 638
	fmt.Println("谛宝多多输入参数(退款)")
	fmt.Println(input)
wangp's avatar
wangp committed
639

wangp's avatar
wangp committed
640
	refundID := GetUID()
wangp's avatar
wangp committed
641

wangp's avatar
wangp committed
642 643 644 645 646
	// 插入数据库
	db, err := mysql.NewPayConn()
	if err != nil {
		return 0, err
	}
wangp's avatar
wangp committed
647

wangp's avatar
wangp committed
648 649 650 651
	tx, err := db.Begin()
	if err != nil {
		return nil, err
	}
wangp's avatar
wangp committed
652

wangp's avatar
wangp committed
653
	defer mysql.CloseTx(tx, err)
wangp's avatar
wangp committed
654

wangp's avatar
wangp committed
655 656 657 658 659
	//订单存在check
	err = SelectPayBill(tx, input)
	if err != nil {
		return nil, err
	}
wangp's avatar
wangp committed
660

wangp's avatar
wangp committed
661 662 663 664
	billID, err := InsertRefundBill(tx, input, refundID)
	if err != nil {
		return nil, err
	}
wangp's avatar
wangp committed
665

wangp's avatar
wangp committed
666 667 668 669 670 671
	//数据重组 - start
	data := make(map[string]interface{})
	var url string
	now := time.Now()
	now.Add(time.Minute * 60)
	date_time1 := now.Format("20060102150405")
wangp's avatar
wangp committed
672

wangp's avatar
wangp committed
673
	url = "https://test.wsmsd.cn/sit/api/v3/labs/relation/refund" //扫码-退款交易
wangp's avatar
wangp committed
674

wangp's avatar
wangp committed
675
	data["req_time"] = date_time1
wangp's avatar
wangp committed
676 677 678 679
	data["version"] = "3.0"
	data["out_org_code"] = "OP00000003"

	data2 := make(map[string]interface{})
wangp's avatar
wangp committed
680 681 682 683 684 685 686 687 688 689 690 691 692 693

	//聚合收银台(微信H5、支付宝H5、微信扫码、支付宝扫码)
	//data2["merchant_no"] = "8221210594300JY"

	//聚合主扫(微信JSAPI、微信小程序)
	data2["merchant_no"] = "8222900581201QB"
	data2["term_no"] = "D0027598"

	//扫码枪
	//data2["merchant_no"] = "822290070111135"
	//data2["term_no"] = "29034705"

	data2["out_trade_no"] = refundID //随机生成的订单号 //商户交易流水号
	//data2["out_trade_no"] = RandomString(32)
wangp's avatar
wangp committed
694
	//扫码支付授权码,设备读取用户APP中的条码或者二维码信息,用户付款码条形码规则见说明
wangp's avatar
wangp committed
695 696 697 698 699 700 701 702 703 704 705
	//data2["auth_code"] = "135178236713755038"
	//data2["auth_code"] = input.DynamicID
	data2["refund_amount"] = input.GoodsPrice*100 //退款金额
	data2["refund_reason"] = "" //退款原因

	//input.OrderId = "23070311012001101011001021042"
	data2["origin_out_trade_no"] = input.OrderId //原商户交易流水号
	//data2["origin_trade_no"] = input.OrderId //原拉卡拉交易流水号
	//data2["origin_log_no"] = input.OrderId //原对账单流水号


wangp's avatar
wangp committed
706 707

	data3 := make(map[string]interface{})
wangp's avatar
wangp committed
708 709 710
	//data3["request_ip"] = "10.176.1.192"
	data3["request_ip"] = ip
	//data3["location"] = "+37.123456789,-121.123456789"
wangp's avatar
wangp committed
711 712 713
	data2["location_info"] = make(map[string]interface{})
	data2["location_info"] = data3

wangp's avatar
wangp committed
714 715
	data["req_data"] = make(map[string]interface{})
	data["req_data"] = data2
wangp's avatar
wangp committed
716

wangp's avatar
wangp committed
717
	//return nil, errors.New("输入参数「source_code」错误,有效值为[1-6,9]")
wangp's avatar
wangp committed
718 719

	//数据重组 - end
wangp's avatar
wangp committed
720 721 722 723
	fmt.Println("拉卡拉输入参数(退款)")
	fmt.Println(data)
	fmt.Println("拉卡拉接口url(退款)")
	fmt.Println(url)
wangp's avatar
wangp committed
724

wangp's avatar
wangp committed
725 726 727 728 729
	// 插入退款请求参数
	err = InsertPayBillDetailRequestBody(tx, billID, data)
	if err != nil {
		return nil, err
	}
wangp's avatar
wangp committed
730 731 732 733 734 735 736 737 738

	data_json, err := json.Marshal(data)
	if err != nil {
		//this.Data["json"] = utils.CheckError(errors.New("Map转化为byte数组失败"),"异常")
		//this.ServeJSON()
		return nil, err
	}

	//调拉卡拉接口
wangp's avatar
wangp committed
739
	err, _, lakala_rtn := lakala_post(0, url, data_json)
wangp's avatar
wangp committed
740
	if err != nil {
wangp's avatar
wangp committed
741
		InsertPayBillDetailResponseBody(tx, billID, lakala_rtn)
wangp's avatar
wangp committed
742 743 744
		return nil, err
	}

wangp's avatar
wangp committed
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791
	// 插入退款成功后返回的参数
	err = InsertPayBillDetailResponseBody(tx, billID, lakala_rtn)
	if err != nil {
		//beego.Error("退款请求成功 --- 但退款成功后的参数失败")
		return nil, err
	}

	response := make(map[string]string)
	response["payment_order_code"] = refundID
	return response, nil
}

func SelectPayBill(tx *sql.Tx, input *models.RefundParamInput) error {

	var billID int64
	var status uint

	//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)
	if err != nil {
		return errors.New("订单不存在1")
	}

	// 订单不存在
	if billID <= 0 {
		return errors.New("订单不存在2")
	}

	// 订单未结算
	if status != 1 {
		return errors.New("订单未结算")
	}

	return 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)
//}
wangp's avatar
wangp committed
792