使用的包:
github.com/iGoogle-ink/gopay
前端用的uniapp
//上面是根据订单ID获取订单的一些基础数据
....
client := wechat.NewClient("微信开放平台申请的移动应用APPid", "商户ID", "商户APIkey", true)
//设置国家
client.SetCountry(wechat.China)
//初始化参数Map
bm := make(gopay.BodyMap)
bm.Set("nonce_str", util.GetRandomString(32)).
Set("body", "商品名称").
Set("out_trade_no", "你自己系统的订单号").
Set("total_fee", 商品价格*100).
Set("spbill_create_ip","下单人的IP").
Set("notify_url", "回调地址").
Set("trade_type", wechat.TradeType_App).
Set("device_info", "APP").
Set("sign_type", wechat.SignType_MD5)
//请求支付下单,成功后得到结果
wxRsp, err := client.UnifiedOrder(bm)
if err != nil {
xlog.Error(err)
}
xlog.Debug("Response:", wxRsp)
timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
//二次验证 重新生成签名
paySign := wechat.GetAppPaySign("微信开放平台申请的移动应用APPid","商户ID", wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, "商户APIkey")
xlog.Debug("paySign:", paySign)
rv := make(map[string]interface{})
rv["appId"] = "微信开放平台申请的移动应用APPid"
rv["nonceStr"] = wxRsp.NonceStr
rv["package"] = "Sign=WXPay"
rv["partnerid"] = wxRsp.MchId
rv["prepayid"] = wxRsp.PrepayId
rv["timeStamp"] = timeStamp
rv["sign"] = paySign
回调函数
// WXPayNotifyReq 异步通知的数据结构
type WXPayNotifyReq struct {
ReturnCode string `xml:"return_code"`
ReturnMsg string `xml:"return_msg"`
Appid string `xml:"appid"`
MchId string `xml:"mch_id"`
Nonce string `xml:"nonce_str"`
Sign string `xml:"sign"`
ResultCode string `xml:"result_code"`
Openid string `xml:"openid"`
IsSubscribe string `xml:"is_subscribe"`
TradeType string `xml:"trade_type"`
BankType string `xml:"bank_type"`
TotalFee int `xml:"total_fee"`
FeeType string `xml:"fee_type"`
CashFee int `xml:"cash_fee"`
CashFeeType string `xml:"cash_fee_type"`
TransactionId string `xml:"transaction_id"`
OutTradeNo string `xml:"out_trade_no"`
Attach string `xml:"attach"`
TimeEnd string `xml:"time_end"`
}
type WXPayNotifyResp struct {
ReturnCode string `xml:"return_code"`
ReturnMsg string `xml:"return_msg"`
}
// JsApiNotify 公众号在线购买JSAPI回调函数(user内的到期时间与商品到期时间一致)
func JsApiNotify(c echo.Context) error {
ackSuccess := `<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>`
ackFail := `<xml><return_code><![CDATA[FAIL]]></return_code></xml>`
body, err := ioutil.ReadAll(c.Request().Body)
if err != nil {
_ = log4go.Error("接收错误")
return c.String(200, ackFail)
}
var mr WXPayNotifyReq
err = xml.Unmarshal(body, &mr)
if err != nil {
_ = log4go.Error("解析HTTP Body格式到xml失败,原因!", err)
return c.String(200, ackFail)
}
var reqMap map[string]interface{}
reqMap = make(map[string]interface{}, 0)
reqMap["return_code"] = mr.ReturnCode
reqMap["return_msg"] = mr.ReturnMsg
reqMap["appid"] = mr.Appid
reqMap["mch_id"] = mr.MchId
reqMap["nonce_str"] = mr.Nonce
reqMap["result_code"] = mr.ResultCode
reqMap["openid"] = mr.Openid
reqMap["is_subscribe"] = mr.IsSubscribe
reqMap["trade_type"] = mr.TradeType
reqMap["bank_type"] = mr.BankType
reqMap["total_fee"] = mr.TotalFee
reqMap["fee_type"] = mr.FeeType
reqMap["cash_fee"] = mr.CashFee
reqMap["cash_fee_type"] = mr.CashFeeType
reqMap["transaction_id"] = mr.TransactionId
reqMap["out_trade_no"] = mr.OutTradeNo
reqMap["attach"] = mr.Attach
reqMap["time_end"] = mr.TimeEnd
//自己系统的订单号
orderNo := mr.OutTradeNo//获取自己系统的订单号
//修改订单状态
//把业务日志最好记录一下 方便定位错误
//....
//发成功短信
}
return c.String(200, ackSuccess)
}