package wxpay import ( "encoding/xml" "errors" "github.com/gin-gonic/gin" "github.com/json-iterator/go" "io/ioutil" "net/http" "recook/internal/api/mobile/pay/public" "recook/internal/back" "recook/internal/dbc" "recook/internal/model/order" "recook/tools" "strings" ) type appQueryParam struct { OrderID uint `json:"orderId" validate:"required"` } func queryMore(virtualID uint) (error, uint) { var od []order.Information if err := dbc.DB.Select("status").Find(&od, "virtual_id = ?", virtualID).Error; err != nil { return err, 0 } var status uint for _, v := range od { if v.Status != 1 && v.Status != 0 && !v.IsSplit { if v.Status == 3 && v.IsSplit { continue } return errors.New("当前状态不可查询"), 0 } status = v.Status } return nil, status } func QueryOrderPay(c *gin.Context) { var p appQueryParam err := tools.ParseParams(&p, c) if err != nil { back.Fail(c, err.Error()) return } if !public.Judge(p.OrderID) { if err, status := queryMore(p.OrderID); err != nil { back.Fail(c, err.Error()) return } else { back.Suc(c, "", map[string]interface{}{"status": status}) return } } var orderInfo order.Information err = dbc.DB.Select("status").First(&orderInfo, "id = ?", p.OrderID).Error if err != nil { back.Err(c, err.Error()) return } if orderInfo.Status == 1 || orderInfo.Status == 0 { back.Suc(c, "", map[string]interface{}{"status": orderInfo.Status}) } else { back.Fail(c, "当前状态不可查询") } } /*===========================================订单查询参数=================================================== */ type OrderQueryParam struct { XMLName xml.Name `xml:"xml"` AppID string `xml:"appid"` MchId string `xml:"mch_id"` // 商户号 NonceStr string `xml:"nonce_str"` // 随机字符串 OutTradeNo string `xml:"out_trade_no"` Sign string `xml:"sign"` } func (r *OrderQueryParam) GenerateSignResult(nonceStr string, outTradeNo string) { r.AppID = AppID r.MchId = MchID r.NonceStr = nonceStr r.OutTradeNo = outTradeNo signStr := "appid=" + AppID signStr = signStr + "&" + "mch_id=" + MchID signStr = signStr + "&" + "nonce_str=" + nonceStr signStr = signStr + "&" + "out_trade_no=" + outTradeNo signStr = signStr + "&key=" + APIKey r.Sign = strings.ToUpper(tools.MD5(signStr)) } /*=================================================================================================== */ type OrderQueryResult struct { XMLName xml.Name `xml:"xml"` OutTradeNo string `xml:"out_trade_no"` ReturnCode string `xml:"return_code" json:"returnCode"` ResultCode string `xml:"result_code" json:"result_code"` TradeState string `xml:"trade_state" json:"trade_state"` // SUCCESS—支付成功 REFUND—转入退款 NOTPAY—未支付 CLOSED—已关闭 REVOKED—已撤销(付款码支付) USERPAYING--用户支付中(付款码支付) PAYERROR--支付失败(其他原因,如银行返回失败) TradeType string `xml:"trade_type" json:"trade_type"` // 交易类型 JSAPI,NATIVE,APP,MICROPAY TotalFee uint `xml:"total_fee" json:"total_fee"` TradeStateDesc string `xml:"trade_state_desc" json:"trade_state_desc"` // 交易状态描述 支付失败,请重新下单支付 IsSubscribe string `xml:"is_subscribe" json:"is_subscribe"` // 是否关注公众账号 TimeEnd string `xml:"time_end" json:"time_end"` } func (r *OrderQueryResult) IsOk() bool { return (r.ReturnCode == "SUCCESS") && (r.TradeState == "SUCCESS") } func requestQueryOrder(param *OrderQueryParam) (*OrderQueryResult, string, error) { xmlStr, err := xml.MarshalIndent(¶m, "", "\t") if err != nil { return nil, "", err } client := &http.Client{} request, err := http.NewRequest("POST", OrderQueryURL, strings.NewReader(string(xmlStr))) if err != nil { return nil, "", err } request.Header.Set("Content-Type", "application/xml; charset=UTF-8") response, err := client.Do(request) defer func() { _ = response.Body.Close() }() result, err := ioutil.ReadAll(response.Body) if err != nil { return nil, "", err } var r OrderQueryResult err = xml.Unmarshal(result, &r) if err != nil { return nil, "", err } json := jsoniter.ConfigCompatibleWithStandardLibrary js, err := json.Marshal(&r) if err != nil { return nil, "", err } return &r, string(js), nil }