|
|
package pay_service
import ( "encoding/xml" "errors" "fmt" "github.com/iGoogle-ink/gopay/v2" "github.com/iGoogle-ink/gopay/v2/wechat" "github.com/ouxuanserver/osmanthuswine/src/core" "hudongzhuanjia/libs/wx" "hudongzhuanjia/models" "net/http" "time" )
const CALLBACK_REFUND_URL = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackRefund"
func RefundExtend(bm gopay.BodyMap) (*wechat.RefundResponse, error) {
err := bm.CheckEmptyError("nonce_str", "out_refund_no", "total_fee", "refund_fee") if err != nil { return nil, err } if bm.Get("out_trade_no") == gopay.NULL && bm.Get("transaction_id") == gopay.NULL { return nil, errors.New("out_trade_no and transaction_id are not allowed to be null at the same time") }
bs, err := ClientExtend(bm, wx.RefundURL) if err != nil { return nil, err } wxRsp := new(wechat.RefundResponse) if err = xml.Unmarshal(bs, wxRsp); err != nil { return nil, fmt.Errorf("xml.Unmarshal(%s):%s", string(bs), err) } return wxRsp, nil }
func Refund(reason, outTradeNo, openId string, goodType, totalFee, refundFee int, userId, activityId int64) (*wechat.RefundResponse, error) { //client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true)
outRefundNo := gopay.GetRandomString(64) // 初始化参数结构体
body := make(gopay.BodyMap) body.Set("out_trade_no", outTradeNo) body.Set("nonce_str", gopay.GetRandomString(32)) body.Set("sign_type", wechat.SignType_MD5) body.Set("out_refund_no", outRefundNo) body.Set("total_fee", totalFee) body.Set("refund_fee", refundFee) body.Set("notify_url", CALLBACK_REFUND_URL) body.Set("refund_desc", reason) body.Set("refund_fee_type", "CNY") body.Set("appid", wx.Appid) body.Set("mch_id", wx.Mchid)
res, err := RefundExtend(body) if err != nil { return nil, err }
//ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res)
//if err != nil {
// return nil, err
//}
//
//if !ok {
// return nil, errors.New("签名验证失败")
//}
if res.ReturnCode != wx.CODE_SUCCESS { return nil, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) }
if res.ResultCode != wx.CODE_SUCCESS { return nil, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) }
refund := new(models.UserRefund) refund.OutTradeNo = outTradeNo refund.Status = 0 refund.TotalFee = totalFee refund.GoodType = goodType refund.RefundDesc = reason refund.FeeType = "CNY" refund.OpenId = openId refund.UserId = userId refund.ActivityId = activityId refund.IsDelete = false refund.CreatedAt = time.Now() refund.UpdatedAt = time.Now() if _, err := core.GetXormAuto().InsertOne(refund); err != nil { return nil, err }
return res, err }
func CallbackRefund(req *http.Request) error { res, err := wechat.ParseRefundNotifyResult(req) if err != nil { return err } //ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res)
//if err != nil {
// return err
//}
//if !ok {
// return errors.New("sign verify failed")
//}
if res.ReturnCode != wx.CODE_SUCCESS { return fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) }
info, err := wechat.DecryptRefundNotifyReqInfo(res.ReqInfo, wx.ApiKey) if err != nil { return err }
userRefund := new(models.UserRefund) exist, err := userRefund.GetByOutRefundNo(info.OutRefundNo) if err != nil { return err } if !exist { return errors.New("user refund not exist") }
userRefund.Status = 1 userRefund.RefundStatus = info.RefundStatus userRefund.TransactionId = info.TransactionId userRefund.OutTradeNo = info.OutTradeNo userRefund.RefundRecvAccount = info.RefundRecvAccout userRefund.RefundAccount = info.RefundAccount userRefund.SuccessTime = info.SuccessTime if _, err := core.GetXormAuto().Id(userRefund.Id).Update(userRefund); err != nil { return err } return nil }
func QueryRefund(outTradeNo string) (*wechat.QueryRefundResponse, error) { client := wechat.NewClient(wx.Appid, wx.Mchid, wx.ApiKey, true)
// 初始化参数结构体
body := make(gopay.BodyMap) body.Set("out_trade_no", outTradeNo) body.Set("nonce_str", gopay.GetRandomString(32)) body.Set("sign_type", wechat.SignType_MD5)
//请求申请退款
res, err := client.QueryRefund(body) if err != nil { return nil, err }
ok, err := wechat.VerifySign(wx.ApiKey, wechat.SignType_MD5, res) if err != nil { return nil, err } if !ok { return nil, errors.New("签名验证失败") }
if res.ReturnCode != wx.CODE_SUCCESS { return nil, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) }
if res.ResultCode != wx.CODE_SUCCESS { return nil, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) }
fmt.Println("wxRsp:", *res) return res, nil }
func BatchQueryRefundByUserId(userId int64) error { refunds := make([]*models.UserRefund, 0) if err := core.GetXormAuto().Where("status = 0 and user_id=?", userId).Find(&refunds); err != nil { return err } if err := batchQueryRefund(refunds); err != nil { return err } return nil } func BatchQueryRefundByActivityId(activityId int64) error { refunds := make([]*models.UserRefund, 0) if err := core.GetXormAuto().Where("status = 0 and user_id=?", activityId).Find(&refunds); err != nil { return err } if err := batchQueryRefund(refunds); err != nil { return err } return nil }
func batchQueryRefund(refunds []*models.UserRefund) error { for _, refund := range refunds { res, err := QueryRefund(refund.OutTradeNo) if err != nil { return err } refund.RefundAccount = res.RefundAccount0 refund.RefundRecvAccount = res.RefundRecvAccout0 refund.RefundStatus = res.RefundStatus0 refund.Status = 1 refund.SuccessTime = res.RefundSuccessTime0 refund.WxRefundId = res.RefundId0 refund.TransactionId = res.TransactionId if _, err = core.GetXormAuto().Id(refund.Id).Cols("refund_account, refund_recv_account, " + "status, refund_status, success_time, wx_refund_id, transaction_id").Update(refund); err != nil { return err } } return nil }
|