Ver código fonte

修改支付取消订单

wangkaiyue 6 anos atrás
pai
commit
a0d2a27f96

+ 48 - 0
src/jfw/modules/weixin/src/jrpc/jrpc.go

@@ -400,3 +400,51 @@ func (w *WeiXinRpc) SendCustomMsg(p *[]byte, ret *string) error {
 	}
 	return nil
 }
+
+//支付订单关闭
+func (w *WeiXinRpc) CloseOrder(param map[string]string, res *bool) error {
+	defer util.Catch()
+	appid := param["appid"]
+	mchid := param["mchid"]
+	tradeno := param["tradeno"]
+	key := param["key"]
+	//匿名结构体
+	data := struct {
+		XMLName    xml.Name `xml:"xml"`
+		Appid      string   `xml:"appid"`
+		MchId      string   `xml:"mch_id"`       //商家ID
+		NonceStr   string   `xml:"nonce_str"`    //随机码
+		OutTradeNo string   `xml:"out_trade_no"` //商家订单编号
+		Sign       string   `xml:"sign"`         //签名
+	}{
+		Appid:      appid,
+		MchId:      mchid,
+		NonceStr:   util.GetRandom(16) + util.GetLetterRandom(16),
+		OutTradeNo: tradeno, //"qmx201611290018",
+	}
+	data.Sign = util.CreateWxSign(fmt.Sprintf("&key=%s", key), data)
+	//生成预订单
+	bs, err := w.Wwx.PostXmlCustom("https://api.mch.weixin.qq.com/pay/closeorder?token=", data)
+	if err != nil {
+		log.Println(tradeno, err.Error(), string(bs))
+		return err
+	}
+	ret := util.XmlToMap(string(bs))
+	respSign := util.CreateWxSign(fmt.Sprintf("&key=%s", key), ret, "sign")
+	if respSign == ret["sign"] {
+		if ret["return_code"] == "SUCCESS" { //订单关闭完成
+			if ret["result_code"] == "SUCCESS" {
+				*res = true
+			} else {
+				if ret["result_code"] == "ORDERPAID" {
+					log.Println(tradeno, "订单已支付")
+				} else if ret["result_code"] == "" {
+					log.Println(tradeno, "订单已关闭")
+				}
+			}
+		}
+	} else {
+		log.Println(tradeno, "签名错误!", respSign, ret["sign"])
+	}
+	return nil
+}

+ 62 - 0
src/jfw/pay/aliPay.go

@@ -12,9 +12,11 @@ import (
 	"errors"
 	"fmt"
 	"hash"
+	"io/ioutil"
 	"jfw/config"
 	"jfw/public"
 	"log"
+	"net/http"
 	"net/url"
 	"qfw/util"
 	"strings"
@@ -45,6 +47,10 @@ type BizContent struct {
 	Time_expire  string  `json:"time_expire"` //支付超时时间yyyy-MM-dd HH:mm:ss
 }
 
+//支付订单关闭请求参数
+type CloseContent struct {
+	OutTradeNo string `json:"out_trade_no"`
+}
 type AliPayAction struct {
 	*xweb.Action
 	payCallback xweb.Mapper `xweb:"/alipay/pay/callback"` //微信支付回调
@@ -269,3 +275,59 @@ func (a *AliPayAction) PayCallback() {
 		log.Println("insertAliPay", insertAliPay)
 	}
 }
+
+//支付宝关闭订单
+func (a *AliPayStruct) CloseOrder(tradeno string) bool {
+	toClose := CloseContent{
+		OutTradeNo: tradeno,
+	}
+	bizbyte, err := json.Marshal(toClose)
+	if err != nil {
+		log.Println()
+		return false
+	}
+	var data = url.Values{}
+	data.Add("app_id", Alipay.Appid)
+	data.Add("method", "alipay.trade.close")
+	data.Add("format", "json")
+	data.Add("charset", "UTF-8")
+	data.Add("sign_type", "RSA2")
+	data.Add("timestamp", time.Now().Format("2006-01-02 15:04:05"))
+	data.Add("version", "1.0")
+	data.Add("biz_content", string(bizbyte))
+	signContentBytes, _ := url.QueryUnescape(data.Encode())
+	log.Println(signContentBytes)
+	signature, err := a.getSign([]byte(signContentBytes))
+	if err != nil {
+		log.Println(tradeno, "获取签名出错", err)
+		return false
+	}
+	data.Add("sign", signature)
+
+	url := a.Requseturl + "?" + data.Encode()
+	//clien 优化
+	client := http.Client{Jar: nil}
+	req, _ := http.NewRequest("POST", url, nil)
+	res, err := client.Do(req)
+	if err != nil {
+		log.Printf("%s支付宝关闭订单  请求出错%v\n", tradeno, err)
+		return false
+	}
+	bArr, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		log.Printf("%s支付宝关闭订单  读取相应出错%v\n", tradeno, err)
+		return false
+	}
+	m := map[string]interface{}{}
+	err = json.Unmarshal(bArr, &m)
+	if err != nil {
+		log.Println(string(bArr))
+		log.Println("%s支付宝关闭订单   解析相应参数出错%v\n", tradeno, err)
+	}
+	msg := (*util.ObjToMap(m["alipay_trade_close_response"]))["sub_msg"]
+	log.Printf("%s订单关闭相应参数%+v", tradeno, m)
+	if msg == "交易状态不合法" || msg == "REASON_ILLEGAL_STATUS" { //已支付
+		return false
+	}
+	return true
+}

+ 31 - 5
src/jfw/pay/dataExportPay.go

@@ -46,6 +46,7 @@ func (p *DataExportPayAction) SacnPay_WaitPay() error {
 		}
 		orderid := util.Int64All((*data)["id"])
 		orderMoney := util.IntAll((*data)["order_money"])
+		orderMoney = 1
 		pay_way := util.ObjToString((*data)["pay_way"])
 		realToken := public.GetWaitPayToken(orderid, orderMoney, code, pay_way, openid)
 		if realToken != token {
@@ -142,7 +143,7 @@ func (p *DataExportPayAction) SacnPay_CreateOrder() {
 	oldOrder := public.Mysql.FindOne("dataexport_order", map[string]interface{}{
 		"user_openid": openId,
 		"filter_id":   id,
-	}, "id,order_status,order_code,order_money,user_mail,user_phone,data_spec,prepay_time,pay_way", "")
+	}, "id,order_status,order_code,order_money,user_mail,user_phone,data_spec,prepay_time,pay_way,out_trade_no", "")
 	if oldOrder != nil {
 		if user_mail != "" && user_mail != util.ObjToString((*oldOrder)["user_mail"]) {
 			public.Mysql.Update("dataexport_order", map[string]interface{}{
@@ -168,8 +169,15 @@ func (p *DataExportPayAction) SacnPay_CreateOrder() {
 			})
 			return
 		}
-		//价格支付方式变动需要重新生成订单二维码
+		//价格支付方式变动需要重新生成订单二维码(关闭之前的订单)
 		if (data_spec != "" && data_spec != util.ObjToString((*oldOrder)["data_spec"])) || pay_way != util.ObjToString((*oldOrder)["pay_way"]) {
+			//在此关闭之前的订单
+			if !closeDataExportOrder(util.ObjToString((*oldOrder)["pay_way"]), util.ObjToString((*oldOrder)["out_trade_no"])) {
+				p.ServeJson(map[string]interface{}{
+					"status": "n",
+				})
+				return
+			}
 			data_count := public.GetDataExportSearchCountUseId(id)
 			if data_count > public.ExConf.MsgMaxCount {
 				data_count = public.ExConf.MsgMaxCount
@@ -230,8 +238,8 @@ func (p *DataExportPayAction) SacnPay_CreateOrder() {
 	}
 	order_money := int(order_money_ * 100)
 	original_price := int(original_price_ * 100)
-	//order_money = 1
-	//original_price = 1
+	order_money = 1
+	original_price = 1
 	filter_keys, filter_publishtime, filter := "", "", ""
 	//
 	isPass := func() bool {
@@ -382,7 +390,7 @@ func (p *DataExportPayAction) GetOrderPayMsg() {
 		queryOrder := public.Mysql.FindOne("dataexport_order", map[string]interface{}{
 			"user_openid": openid,
 			"order_code":  code,
-		}, "id,order_status,order_money", "")
+		}, "id,order_status,order_money,out_trade_no,pay_way", "")
 
 		if queryOrder == nil {
 			return "", "订单异常", false
@@ -390,6 +398,10 @@ func (p *DataExportPayAction) GetOrderPayMsg() {
 		if util.IntAll((*queryOrder)["order_status"]) != 0 {
 			return "", "订单状态异常", false
 		}
+		//在此关闭之前的订单
+		if !closeDataExportOrder(util.ObjToString((*queryOrder)["pay_way"]), util.ObjToString((*queryOrder)["out_trade_no"])) {
+			return "", "订单关闭异常", false
+		}
 		//修改支付方式
 		orderid := util.Int64All((*queryOrder)["id"])
 		orderMoney := util.IntAll((*queryOrder)["order_money"])
@@ -447,3 +459,17 @@ func (p *DataExportPayAction) GetOrderPayMsg() {
 	})
 
 }
+func closeDataExportOrder(payWay, tradeno string) (status bool) {
+	log.Printf("%s取消订单,订单号%s\n", payWay, tradeno)
+
+	if payWay == "支付宝" {
+		status = Alipay.CloseOrder(tradeno)
+	}
+	if payWay == "微信" {
+		status = public.WxStruct.CloseOrder(config.Sysconfig["weixinrpc"].(string), tradeno)
+	}
+	if !status {
+		log.Printf("%s订单关闭失败:%s\n", payWay, tradeno)
+	}
+	return status
+}

+ 23 - 0
src/jfw/public/dataexport.go

@@ -580,3 +580,26 @@ func GetPriceDes_SieveCondition(minPrice, maxPrice string) string {
 	}
 	return des
 }
+
+//微信支付订单关闭
+func (w *WeixinStruct) CloseOrder(weixinrpc, tradeno string) (r bool) {
+	util.Try(func() {
+		client, err := rpc.DialHTTP("tcp", weixinrpc)
+		defer client.Close()
+		if err != nil {
+			return
+		}
+		err = client.Call("WeiXinRpc.CloseOrder",
+			map[string]string{
+				"tradeno": tradeno,
+				"key":     w.Key,
+				"mchid":   w.Mchid,
+				"appid":   w.Appid,
+			}, &r)
+		if err != nil {
+			log.Println(err.Error())
+			return
+		}
+	}, func(e interface{}) {})
+	return r
+}

+ 2 - 2
src/web/templates/pc/myOrder.html

@@ -536,8 +536,6 @@
 				if ($(this).hasClass("underline")) {
 					return
 				}
-				clearInterval(interval);
-				$(this).addClass("underline").parent('li').siblings().children().removeClass("underline");
 				payway = "微信"
 				if ($(this).text() == "支付宝") {
 					payway = "支付宝"
@@ -548,6 +546,8 @@
 					prepaytime: prepaytime
 				}, function(r) {
 					if (r.success) {
+            $(this).addClass("underline").parent('li').siblings().children().removeClass("underline");
+            clearInterval(interval);
 						showCode(payway, price, r.payUrl, r.prepay_time);
 						$(".item.clearfix>li:eq(" + listIndex + ")").find(".pay").attr("time", r.prepay_time).attr("payway", payway).attr(
 							"code", r.payUrl);