|
|
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 {
|
|
|
if orderInfo.Status == 3 && orderInfo.IsSplit {
|
|
|
if err, status := queryMore(p.OrderID); err != nil {
|
|
|
back.Fail(c, err.Error())
|
|
|
return
|
|
|
} else {
|
|
|
back.Suc(c, "", map[string]interface{}{"status": status})
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
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
|
|
|
}
|