You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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"` // 交易类型 JSAPINATIVEAPPMICROPAY
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(&param, "", "\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
}