From e6058504c1f6fe9e82f98e1fc1b9ec23d65e0783 Mon Sep 17 00:00:00 2001 From: tommy <3405129587@qq.com> Date: Fri, 22 May 2020 14:01:48 +0800 Subject: [PATCH] pay --- controllers/client/bully_screen.go | 2 +- controllers/client/lottery.go | 3 +- controllers/client/reward.go | 2 +- controllers/client/wx.go | 6 +- controllers/pc/activity.go | 2 +- libs/wechat/wx.go | 8 +-- libs/wx/code.go | 32 --------- libs/wx/params.go | 44 ++++++------ libs/wx/pay.go | 70 +++++++++--------- libs/wx/wx.go | 9 +-- services/lottery/lottery.go | 16 ++++- services/pay/client.go | 3 +- services/pay/const.go | 141 +++++++++++++++++++------------------ services/pay/handle.go | 105 ++++++++++++++++++++++++++- services/pay/order.go | 101 +++----------------------- services/pay/order_test.go | 16 +++++ services/pay/transfer.go | 17 ++--- test/pay_test.go | 2 +- utils/define/define.go | 67 +++++++++++++++++- 19 files changed, 360 insertions(+), 286 deletions(-) delete mode 100644 libs/wx/code.go create mode 100644 services/pay/order_test.go diff --git a/controllers/client/bully_screen.go b/controllers/client/bully_screen.go index 3e92310..4ade6cf 100644 --- a/controllers/client/bully_screen.go +++ b/controllers/client/bully_screen.go @@ -51,7 +51,7 @@ func (t *BullyScreenCtl) PaScreen() { res["out_trade_no"] = "" if activity.RehearsalId == 0 { res, err = pay_service.UnifiedOrder("欧轩互动-霸屏支付", user.Openid, int64(amount*100), 1, user.Id, - activityId, time.Now().Add(24*time.Hour).Unix()) + activityId, time.Now().Add(48*time.Hour).Unix()) t.CheckErr(err) } diff --git a/controllers/client/lottery.go b/controllers/client/lottery.go index 9426068..8ffa18a 100644 --- a/controllers/client/lottery.go +++ b/controllers/client/lottery.go @@ -93,8 +93,7 @@ func (t *LotteryCtl) Winners() { t.CheckErr(err) t.Assert(exist, code.MSG_LOTTERY_RULE_NOT_EXIST, "抽奖规则不存在") - result := make([]*LotteryUsersResult, 0) - err = models.GetLotteryUsersResultByLotteryDrawRecord(result, ladderId, activity.RehearsalId, ladder.RollNum) + result, err := lottery_service.GetLotteryUsersResultByRollNum(ladderId, activity.RehearsalId, ladder.RollNum) t.CheckErr(err) t.JSON(map[string]interface{}{ "total": len(result), diff --git a/controllers/client/reward.go b/controllers/client/reward.go index 668928b..f58ac23 100644 --- a/controllers/client/reward.go +++ b/controllers/client/reward.go @@ -57,7 +57,7 @@ func (t *RewardCtl) Reward() { res["out_trade_no"] = "" if activity.RehearsalId == 0 || _type == 1 { // 直播不用彩排 res, err = pay_service.UnifiedOrder("欧轩互动-打赏支付", user.Openid, int64(amount*100), 2, - user.Id, activityId, time.Now().Add(24*time.Hour).Unix()) + user.Id, activityId, time.Now().Add(48*time.Hour).Unix()) t.CheckErr(err) } diff --git a/controllers/client/wx.go b/controllers/client/wx.go index cd866b1..4ff8a4f 100644 --- a/controllers/client/wx.go +++ b/controllers/client/wx.go @@ -2,10 +2,10 @@ package client import ( "fmt" - "github.com/ouxuanserver/osmanthuswine/src/helper" "hudongzhuanjia/controllers" "hudongzhuanjia/libs/wx" "hudongzhuanjia/utils" + "hudongzhuanjia/utils/define" "time" ) @@ -29,7 +29,7 @@ var cache TicketCache // 检测ticket是否过期 func (t *WxCtl) Ticket() { url := t.MustGet("url") - nonceStr := helper.CreateUUID() + nonceStr := utils.RandomStr(32) timestamp := time.Now().Unix() if cache.TokenExpired <= time.Now().Unix() { @@ -57,7 +57,7 @@ func (t *WxCtl) Ticket() { "noncestr": nonceStr, "timestamp": timestamp, "ticket": cache.Ticket, - "appid": wx.Appid, + "appid": define.AppId, }) } diff --git a/controllers/pc/activity.go b/controllers/pc/activity.go index 9bd0666..f0b4be4 100644 --- a/controllers/pc/activity.go +++ b/controllers/pc/activity.go @@ -52,7 +52,7 @@ func (t *ActivityCtl) StartActivity() { activity.Status = define.StatusRunning activity.UpdatedAt = time.Now() // todo: 校验 - _, err = models.Update(activity.Id, "status", "rehearsal_id") + _, err = models.Update(activity.Id, activity, "status", "rehearsal_id") t.CheckErr(err) t.JSON(map[string]interface{}{ "rehearsal_id": activity.RehearsalId, diff --git a/libs/wechat/wx.go b/libs/wechat/wx.go index 2a24222..5a8a795 100644 --- a/libs/wechat/wx.go +++ b/libs/wechat/wx.go @@ -3,14 +3,10 @@ package wechat import ( mpoauth2 "github.com/chanxuehong/wechat/mp/oauth2" "github.com/chanxuehong/wechat/oauth2" + "hudongzhuanjia/utils/define" ) -var ( - Appid = "wx7b0bcf476552c5e9" - Secret = "f6aabdd40ea25272f4442603a7dc8028" -) - -var Endpoint = mpoauth2.NewEndpoint(Appid, Secret) +var Endpoint = mpoauth2.NewEndpoint(define.AppId, define.Secret) func GetToken(code string) (*oauth2.Token, error) { client := oauth2.Client{ diff --git a/libs/wx/code.go b/libs/wx/code.go deleted file mode 100644 index 19a7dfa..0000000 --- a/libs/wx/code.go +++ /dev/null @@ -1,32 +0,0 @@ -package wx - -const CODE_SUCCESS = "SUCCESS" // 成功 -const CODE_FAIL = "FAIL" // 失败 -const CODE_NOTPAY = "NOTPAY" // 未支付 -const CODE_CHANGE = "CHANGE" // 退款异常 -const CODE_REFUNDCLOSE = "REFUNDCLOSE" // 退款关闭 -const CODE_ERROR = "ERROR" // 业务错误 -const CODE_INVALID_REQUEST = "INVALID_REQUEST" // 无效请求 -const CODE_NOAUTH = "NOAUTH" // 异常IP请求不予受理 -const CODE_NOTENOUGH = "NOTENOUGH" // 余额不足 -const CODE_ORDERPAID = "ORDERPAID" // 订单已支付 -const CODE_ORDERCLOSED = "ORDERCLOSED" // 订单已关闭 -const CODE_SYSTEMERROR = "SYSTEMERROR" // 系统错误 -const CODE_APPID_NOT_EXIST = "APPID_NOT_EXIST" // APPID不存在 -const CODE_MCHID_NOT_EXIST = "MCHID_NOT_EXIST" // MCHID不存在 -const CODE_APPID_MCHID_NOT_MATCH = "APPID_MCHID_NOT_MATCH" // APPID MCHID 不匹配 -const CODE_LACK_PARAMS = "LACK_PARAMS" // 缺少参数 -const CODE_OUT_TRADE_NO_USED = "OUT_TRADE_NO_USED" // 商户订单号重复 -const CODE_SIGNERROR = "SIGNERROR" // 签名错误 -const CODE_XML_FORMAT_ERROR = "XML_FORMAT_ERROR" // xml格式错误 -const CODE_REQUIRE_POST_METHOD = "REQUIRE_POST_METHOD" // 请使用post请求方法 -const CODE_POST_DATA_EMPTY = "POST_DATA_EMPTY" // post数据为空 -const CODE_NOT_UTF8 = "NOT_UTF8" // 编码错误 -const CODE_ORDERNOTEXIST = "ORDERNOTEXIST" // 交易订单号不存在 -const CODE_BIZERR_NEED_RETRY = "BIZERR_NEED_RETRY" // 退款业务流程错误,需要商户触发重试来解决 -const CODE_TRADE_OVERDUE = "TRADE_OVERDUE" // 订单已经超过退款期限 -const CODE_USER_ACCOUNT_ABNORMAL = "USER_ACCOUNT_ABNORMAL" // 退款请求失败用户帐号注销 -const CODE_INVALID_REQ_TOO_MUCH = "INVALID_REQ_TOO_MUCH" // 无效请求过多 -const CODE_INVALID_TRANSACTIONID = "INVALID_TRANSACTIONID" // 无效transaction_id -const CODE_PARAM_ERROR = "PARAM_ERROR" // 参数错误 -const CODE_FREQUENCY_LIMITED = "FREQUENCY_LIMITED" // 请求频率限制 diff --git a/libs/wx/params.go b/libs/wx/params.go index 4d9c324..115ea01 100644 --- a/libs/wx/params.go +++ b/libs/wx/params.go @@ -6,17 +6,17 @@ import ( "hudongzhuanjia/utils/define" ) -var ( - WxCertPath = `./cacert/apiclient_cert.pem` - WxKeyPath = `./cacert/apiclient_key.pem` - WxCaPath = `./cacert/rootca.pem` - Appid = "wx7b0bcf476552c5e9" - Secret = "f6aabdd40ea25272f4442603a7dc8028" - Mchid = `1394404502` - ApiKey = `2c82c64ceec6ba89ffc9f593c671a12f` - mainHost = `https://api.mch.weixin.qq.com` - backHost = `https://api2.mch.weixin.qq.com` -) +//var ( +// WxCertPath = `./cacert/apiclient_cert.pem` +// WxKeyPath = `./cacert/apiclient_key.pem` +// WxCaPath = `./cacert/rootca.pem` +// Appid = "wx7b0bcf476552c5e9" +// Secret = "f6aabdd40ea25272f4442603a7dc8028" +// Mchid = `1394404502` +// ApiKey = `2c82c64ceec6ba89ffc9f593c671a12f` +// mainHost = `https://api.mch.weixin.qq.com` +// backHost = `https://api2.mch.weixin.qq.com` +//) var ( RedirectUri = "http://api.hudongzhuanjia.com/" @@ -31,17 +31,17 @@ var ( ) var ( - NotifyURL = fmt.Sprintf("%s/wechat/callback", define.HOST) // 微信回调通知 - UnifiedOrderURL = fmt.Sprintf("%s/pay/unifiedorder", mainHost) // 统一下单url - QueryOrderURL = fmt.Sprintf("%s/pay/orderquery", mainHost) // 微信查询订单 - CloseOrderURL = fmt.Sprintf("%s/pay/closeorder", mainHost) // 微信关闭订单 - RefundURL = fmt.Sprintf("%s/secapi/pay/refund", mainHost) // 微信退款 - RefundQueryURL = fmt.Sprintf("%s/pay/refundquery", mainHost) // 微信查询退款 - DownloadBillURL = fmt.Sprintf("%s/pay/downloadbill", mainHost) // 微信下载账单 - DownloadFundFlowURL = fmt.Sprintf("%s/pay/downloadfundflow", mainHost) - TransfersURL = fmt.Sprintf("%s/mmpaymkttransfers/promotion/transfers", mainHost) - SendRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/sendredpack", mainHost) - QueryRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/gethbinfo", mainHost) + NotifyURL = fmt.Sprintf("%s/wechat/callback", define.HOST) // 微信回调通知 + UnifiedOrderURL = fmt.Sprintf("%s/pay/unifiedorder", define.WxHost) // 统一下单url + QueryOrderURL = fmt.Sprintf("%s/pay/orderquery", define.WxHost) // 微信查询订单 + CloseOrderURL = fmt.Sprintf("%s/pay/closeorder", define.WxHost) // 微信关闭订单 + RefundURL = fmt.Sprintf("%s/secapi/pay/refund", define.WxHost) // 微信退款 + RefundQueryURL = fmt.Sprintf("%s/pay/refundquery", define.WxHost) // 微信查询退款 + DownloadBillURL = fmt.Sprintf("%s/pay/downloadbill", define.WxHost) // 微信下载账单 + DownloadFundFlowURL = fmt.Sprintf("%s/pay/downloadfundflow", define.WxHost) + TransfersURL = fmt.Sprintf("%s/mmpaymkttransfers/promotion/transfers", define.WxHost) + SendRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/sendredpack", define.WxHost) + QueryRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/gethbinfo", define.WxHost) ) type CommonReturn struct { diff --git a/libs/wx/pay.go b/libs/wx/pay.go index 8079ab9..fa503a6 100644 --- a/libs/wx/pay.go +++ b/libs/wx/pay.go @@ -3,9 +3,9 @@ package wx import ( "bytes" "crypto/tls" - "crypto/x509" "encoding/xml" "fmt" + "hudongzhuanjia/utils/define" "io/ioutil" "net/http" ) @@ -22,28 +22,28 @@ var _tlsConfig *tls.Config //var WxClient = NewClient() -func getTLSConfig() (*tls.Config, error) { - if _tlsConfig != nil { - return _tlsConfig, nil - } - // load cert - cert, err := tls.LoadX509KeyPair(WxCertPath, WxKeyPath) - if err != nil { - return nil, err - } - // load root ca - caData, err := ioutil.ReadFile(WxCaPath) - if err != nil { - return nil, err - } - pool := x509.NewCertPool() - pool.AppendCertsFromPEM(caData) - _tlsConfig = &tls.Config{ - Certificates: []tls.Certificate{cert}, - RootCAs: pool, - } - return _tlsConfig, nil -} +//func getTLSConfig() (*tls.Config, error) { +// if _tlsConfig != nil { +// return _tlsConfig, nil +// } +// // load cert +// cert, err := tls.LoadX509KeyPair(WxCertPath, WxKeyPath) +// if err != nil { +// return nil, err +// } +// // load root ca +// caData, err := ioutil.ReadFile(WxCaPath) +// if err != nil { +// return nil, err +// } +// pool := x509.NewCertPool() +// pool.AppendCertsFromPEM(caData) +// _tlsConfig = &tls.Config{ +// Certificates: []tls.Certificate{cert}, +// RootCAs: pool, +// } +// return _tlsConfig, nil +//} type Client struct { AppId string @@ -82,10 +82,10 @@ func (w *Client) UnifiedOrder(param *UnifiedOrderParam) (*UnifiedOrderResult, er if err != nil { return nil, err } - if res.ReturnCode != CODE_SUCCESS { + if res.ReturnCode != define.CODE_SUCCESS { return res, fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) } - if res.ResultCode != CODE_SUCCESS { + if res.ResultCode != define.CODE_SUCCESS { return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) } @@ -113,10 +113,10 @@ func (w *Client) QueryOrder(param *QueryOrderParam) (*QueryOrderResult, error) { if err != nil { return nil, err } - if res.ReturnCode != CODE_SUCCESS { + if res.ReturnCode != define.CODE_SUCCESS { return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) } - if res.ResultCode != CODE_SUCCESS { + if res.ResultCode != define.CODE_SUCCESS { return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) } return res, nil @@ -143,10 +143,10 @@ func (w *Client) CloseOrder(param *CloseOrderParam) (*CloseOrderResult, error) { if err != nil { return nil, err } - if res.ReturnCode != CODE_SUCCESS { + if res.ReturnCode != define.CODE_SUCCESS { return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) } - if res.ResultCode != CODE_SUCCESS { + if res.ResultCode != define.CODE_SUCCESS { return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) } @@ -174,10 +174,10 @@ func (w *Client) Refund(param *RefundParam) (*RefundResult, error) { if err != nil { return nil, err } - if res.ReturnCode != CODE_SUCCESS { + if res.ReturnCode != define.CODE_SUCCESS { return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) } - if res.ResultCode != CODE_SUCCESS { + if res.ResultCode != define.CODE_SUCCESS { return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) } @@ -205,10 +205,10 @@ func (w *Client) RefundQuery(param *RefundQueryParam) (*RefundQueryResult, error if err != nil { return nil, err } - if res.ReturnCode != CODE_SUCCESS { + if res.ReturnCode != define.CODE_SUCCESS { return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) } - if res.ResultCode != CODE_SUCCESS { + if res.ResultCode != define.CODE_SUCCESS { return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) } return res, nil @@ -239,10 +239,10 @@ func (w *Client) SendRedPack(param *RedPackParam) (*RedPackResult, error) { if err != nil { return nil, err } - if res.ReturnCode != CODE_SUCCESS { + if res.ReturnCode != define.CODE_SUCCESS { return res, fmt.Errorf("network error, return_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) } - if res.ResultCode != CODE_SUCCESS { + if res.ResultCode != define.CODE_SUCCESS { return res, fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) } return res, nil diff --git a/libs/wx/wx.go b/libs/wx/wx.go index b1ae601..549e8c5 100644 --- a/libs/wx/wx.go +++ b/libs/wx/wx.go @@ -4,20 +4,21 @@ import ( "fmt" "github.com/kirinlabs/HttpRequest" "github.com/ouxuanserver/osmanthuswine/src/helper" + "hudongzhuanjia/utils/define" "net/url" ) func GetCodeUrl() string { uid := helper.CreateUUID() - return fmt.Sprintf(CodeUrl, Appid, url.PathEscape(RedirectUri), uid) + return fmt.Sprintf(CodeUrl, define.AppId, url.PathEscape(RedirectUri), uid) } func GetAccessTokenUrl(code string) string { - return fmt.Sprintf(AccessTokenUrl, Appid, Secret, code) + return fmt.Sprintf(AccessTokenUrl, define.AppId, define.Secret, code) } func GetRefreshTokenUrl(refreshToken string) string { - return fmt.Sprintf(RefreshTokenUrl, Appid, refreshToken) + return fmt.Sprintf(RefreshTokenUrl, define.AppId, refreshToken) } func GetAuthUrl(accessToken string, openid string) string { @@ -33,7 +34,7 @@ func GetTicketUrl(ticketToken string) string { } func GetTicketTokenUrl() string { - return fmt.Sprintf(TicketTokenUrl, Appid, Secret) + return fmt.Sprintf(TicketTokenUrl, define.AppId, define.Secret) } /// diff --git a/services/lottery/lottery.go b/services/lottery/lottery.go index 9750a2e..910a40b 100644 --- a/services/lottery/lottery.go +++ b/services/lottery/lottery.go @@ -142,6 +142,20 @@ type LotteryUsersResult struct { Avatar string `json:"avatar"` } +func GetLotteryUsersResultByRollNum(ladderId, rehearsalId interface{}, rollNum int) ([]*LotteryUsersResult, error) { + users := make([]*LotteryUsersResult, 0) + session := core.GetXormAuto().Table(new(models.LotteryDrawRecord)).Alias("r"). + Join("LEFT", new(models.User).Alias("u"), "u.id=r.user_id"). + Where("r.is_delete=0 and r.lottery_draw_rule_ladder_id=? and "+ + "r.rehearsal_id=?", ladderId, rehearsalId) + defer session.Close() + if rollNum > 0 { + session = session.Where("roll_num=?", rollNum) + } + err := session.Find(&users) + return users, err +} + func GetLotteryUsersResult(areaId, activityId, rehearsalId interface{}, ids []int64) ([]*LotteryUsersResult, error) { result := make([]*LotteryUsersResult, 0) session := core.GetXormAuto().Table(new(models.SignHistory)).Alias("h"). @@ -169,7 +183,7 @@ type WinnersResult struct { func GetWinnersResult(ruleId, rehearsalId interface{}) ([]*WinnersResult, error) { result := make([]*WinnersResult, 0) - err := core.GetXormAuto().Table("ox_lottery_draw_record").Alias("record"). + err := core.GetXormAuto().Table(new(models.LotteryDrawRecord)).Alias("record"). Join("LEFT", new(models.User).Alias("user"), "user.id=record.user_id and user.is_delete=0"). Where("record.is_delete=0 and record.lottery_draw_rule_id=? and record.rehearsal_id=?", ruleId, rehearsalId). Find(&result) diff --git a/services/pay/client.go b/services/pay/client.go index 7ccc595..cf433c3 100644 --- a/services/pay/client.go +++ b/services/pay/client.go @@ -5,6 +5,7 @@ import ( "crypto/x509" "fmt" "github.com/chanxuehong/wechat/mch/core" + "hudongzhuanjia/utils/define" "net/http" ) @@ -44,5 +45,5 @@ func Client() (*core.Client, error) { }, } - return core.NewClient(Appid, Mchid, ApiKey, httpClient), nil + return core.NewSubMchClient(define.AppId, define.MchId, define.ApiKey, "", define.SubMchId, httpClient), nil } diff --git a/services/pay/const.go b/services/pay/const.go index 6f0a461..6e86dfd 100644 --- a/services/pay/const.go +++ b/services/pay/const.go @@ -1,78 +1,79 @@ package pay_service -import ( - "fmt" - "hudongzhuanjia/utils/define" -) +import () -var ( - WxCertPath = `./cacert/apiclient_cert.pem` - WxKeyPath = `./cacert/apiclient_key.pem` - WxCaPath = `./cacert/rootca.pem` - Appid = "wx7b0bcf476552c5e9" - Secret = "f6aabdd40ea25272f4442603a7dc8028" - Mchid = `1394404502` - ApiKey = `2c82c64ceec6ba89ffc9f593c671a12f` - ClientIp = `123.207.246.51` - mainHost = `https://api.mch.weixin.qq.com` - backHost = `https://api2.mch.weixin.qq.com` -) +//var ( +// WxCertPath = `./cacert/apiclient_cert.pem` +// WxKeyPath = `./cacert/apiclient_key.pem` +// WxCaPath = `./cacert/rootca.pem` +// //MchId = `1394404502` +// //AppId = "wx7b0bcf476552c5e9" +// Secret = "f6aabdd40ea25272f4442603a7dc8028" +// AppId = `wx662a1633304bfd42` +// MchId = `1441266702` +// SubMchId = `1594049151` +// ApiKey = `5x201c8zn43cg675204594cab5423320` +// //ApiKey = `2c82c64ceec6ba89ffc9f593c671a12f` +// ClientIp = `123.207.246.51` +// mainHost = `https://api.mch.weixin.qq.com` +// backHost = `https://api2.mch.weixin.qq.com` +//) -var ( - NotifyURL = fmt.Sprintf("%s/wechat/callback", define.HOST) // 微信回调通知 - UnifiedOrderURL = fmt.Sprintf("%s/pay/unifiedorder", mainHost) // 统一下单url - QueryOrderURL = fmt.Sprintf("%s/pay/orderquery", mainHost) // 微信查询订单 - CloseOrderURL = fmt.Sprintf("%s/pay/closeorder", mainHost) // 微信关闭订单 - RefundURL = fmt.Sprintf("%s/secapi/pay/refund", mainHost) // 微信退款 - RefundQueryURL = fmt.Sprintf("%s/pay/refundquery", mainHost) // 微信查询退款 - DownloadBillURL = fmt.Sprintf("%s/pay/downloadbill", mainHost) // 微信下载账单 - DownloadFundFlowURL = fmt.Sprintf("%s/pay/downloadfundflow", mainHost) - TransfersURL = fmt.Sprintf("%s/mmpaymkttransfers/promotion/transfers", mainHost) - SendRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/sendredpack", mainHost) - QueryRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/gethbinfo", mainHost) -) +//var ( +// NotifyURL = fmt.Sprintf("%s/wechat/callback", define.HOST) // 微信回调通知 +// UnifiedOrderURL = fmt.Sprintf("%s/pay/unifiedorder", mainHost) // 统一下单url +// QueryOrderURL = fmt.Sprintf("%s/pay/orderquery", mainHost) // 微信查询订单 +// CloseOrderURL = fmt.Sprintf("%s/pay/closeorder", mainHost) // 微信关闭订单 +// RefundURL = fmt.Sprintf("%s/secapi/pay/refund", mainHost) // 微信退款 +// RefundQueryURL = fmt.Sprintf("%s/pay/refundquery", mainHost) // 微信查询退款 +// DownloadBillURL = fmt.Sprintf("%s/pay/downloadbill", mainHost) // 微信下载账单 +// DownloadFundFlowURL = fmt.Sprintf("%s/pay/downloadfundflow", mainHost) +// TransfersURL = fmt.Sprintf("%s/mmpaymkttransfers/promotion/transfers", mainHost) +// SendRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/sendredpack", mainHost) +// QueryRedPackURL = fmt.Sprintf("%s/mmpaymkttransfers/gethbinfo", mainHost) +//) -const ( - CODE_SUCCESS = "SUCCESS" // 成功 - CODE_FAIL = "FAIL" // 失败 - CODE_NOTPAY = "NOTPAY" // 未支付 - CODE_CHANGE = "CHANGE" // 退款异常 - CODE_REFUNDCLOSE = "REFUNDCLOSE" // 退款关闭 - CODE_ERROR = "ERROR" // 业务错误 - CODE_INVALID_REQUEST = "INVALID_REQUEST" // 无效请求 - CODE_NOAUTH = "NOAUTH" // 异常IP请求不予受理 - CODE_NOTENOUGH = "NOTENOUGH" // 余额不足 - CODE_ORDERPAID = "ORDERPAID" // 订单已支付 - CODE_ORDERCLOSED = "ORDERCLOSED" // 订单已关闭 - CODE_SYSTEMERROR = "SYSTEMERROR" // 系统错误 - CODE_APPID_NOT_EXIST = "APPID_NOT_EXIST" // APPID不存在 - CODE_MCHID_NOT_EXIST = "MCHID_NOT_EXIST" // MCHID不存在 - CODE_APPID_MCHID_NOT_MATCH = "APPID_MCHID_NOT_MATCH" // APPID MCHID 不匹配 - CODE_LACK_PARAMS = "LACK_PARAMS" // 缺少参数 - CODE_OUT_TRADE_NO_USED = "OUT_TRADE_NO_USED" // 商户订单号重复 - CODE_SIGNERROR = "SIGNERROR" // 签名错误 - CODE_XML_FORMAT_ERROR = "XML_FORMAT_ERROR" // xml格式错误 - CODE_REQUIRE_POST_METHOD = "REQUIRE_POST_METHOD" // 请使用post请求方法 - CODE_POST_DATA_EMPTY = "POST_DATA_EMPTY" // post数据为空 - CODE_NOT_UTF8 = "NOT_UTF8" // 编码错误 - CODE_ORDERNOTEXIST = "ORDERNOTEXIST" // 交易订单号不存在 - CODE_BIZERR_NEED_RETRY = "BIZERR_NEED_RETRY" // 退款业务流程错误,需要商户触发重试来解决 - CODE_TRADE_OVERDUE = "TRADE_OVERDUE" // 订单已经超过退款期限 - CODE_USER_ACCOUNT_ABNORMAL = "USER_ACCOUNT_ABNORMAL" // 退款请求失败用户帐号注销 - CODE_INVALID_REQ_TOO_MUCH = "INVALID_REQ_TOO_MUCH" // 无效请求过多 - CODE_INVALID_TRANSACTIONID = "INVALID_TRANSACTIONID" // 无效transaction_id - CODE_PARAM_ERROR = "PARAM_ERROR" // 参数错误 - CODE_FREQUENCY_LIMITED = "FREQUENCY_LIMITED" // 请求频率限制 - CODE_TRADE_SUCCESS = "SUCCESS" // 交易成功 - CODE_TRADE_REFUND = "REFUND" // 转入退款 - CODE_TRADE_NOTPAY = "NOTPAY" // 尚未支付 - CODE_TRADE_CLOSED = "CLOSED" // 已关闭 - CODE_TRADE_REVOKED = "REVOKED" // 已撤销 - CODE_TRADE_USERPAYING = "USERPAYING" // 用户支付中 - CODE_TRADE_PAYERROR = "PAYERROR" // 支付失败 - CODE_TRANSFER_PROCESSING = "PROCESSING" // 转账处理中 - CODE_TRANSFER_NOT_FOUND = "NOT_FOUND" // 账单不见了 -) +//const ( +// CODE_SUCCESS = "SUCCESS" // 成功 +// CODE_FAIL = "FAIL" // 失败 +// CODE_NOTPAY = "NOTPAY" // 未支付 +// CODE_CHANGE = "CHANGE" // 退款异常 +// CODE_REFUNDCLOSE = "REFUNDCLOSE" // 退款关闭 +// CODE_ERROR = "ERROR" // 业务错误 +// CODE_INVALID_REQUEST = "INVALID_REQUEST" // 无效请求 +// CODE_NOAUTH = "NOAUTH" // 异常IP请求不予受理 +// CODE_NOTENOUGH = "NOTENOUGH" // 余额不足 +// CODE_ORDERPAID = "ORDERPAID" // 订单已支付 +// CODE_ORDERCLOSED = "ORDERCLOSED" // 订单已关闭 +// CODE_SYSTEMERROR = "SYSTEMERROR" // 系统错误 +// CODE_APPID_NOT_EXIST = "APPID_NOT_EXIST" // APPID不存在 +// CODE_MCHID_NOT_EXIST = "MCHID_NOT_EXIST" // MCHID不存在 +// CODE_APPID_MCHID_NOT_MATCH = "APPID_MCHID_NOT_MATCH" // APPID MCHID 不匹配 +// CODE_LACK_PARAMS = "LACK_PARAMS" // 缺少参数 +// CODE_OUT_TRADE_NO_USED = "OUT_TRADE_NO_USED" // 商户订单号重复 +// CODE_SIGNERROR = "SIGNERROR" // 签名错误 +// CODE_XML_FORMAT_ERROR = "XML_FORMAT_ERROR" // xml格式错误 +// CODE_REQUIRE_POST_METHOD = "REQUIRE_POST_METHOD" // 请使用post请求方法 +// CODE_POST_DATA_EMPTY = "POST_DATA_EMPTY" // post数据为空 +// CODE_NOT_UTF8 = "NOT_UTF8" // 编码错误 +// CODE_ORDERNOTEXIST = "ORDERNOTEXIST" // 交易订单号不存在 +// CODE_BIZERR_NEED_RETRY = "BIZERR_NEED_RETRY" // 退款业务流程错误,需要商户触发重试来解决 +// CODE_TRADE_OVERDUE = "TRADE_OVERDUE" // 订单已经超过退款期限 +// CODE_USER_ACCOUNT_ABNORMAL = "USER_ACCOUNT_ABNORMAL" // 退款请求失败用户帐号注销 +// CODE_INVALID_REQ_TOO_MUCH = "INVALID_REQ_TOO_MUCH" // 无效请求过多 +// CODE_INVALID_TRANSACTIONID = "INVALID_TRANSACTIONID" // 无效transaction_id +// CODE_PARAM_ERROR = "PARAM_ERROR" // 参数错误 +// CODE_FREQUENCY_LIMITED = "FREQUENCY_LIMITED" // 请求频率限制 +// CODE_TRADE_SUCCESS = "SUCCESS" // 交易成功 +// CODE_TRADE_REFUND = "REFUND" // 转入退款 +// CODE_TRADE_NOTPAY = "NOTPAY" // 尚未支付 +// CODE_TRADE_CLOSED = "CLOSED" // 已关闭 +// CODE_TRADE_REVOKED = "REVOKED" // 已撤销 +// CODE_TRADE_USERPAYING = "USERPAYING" // 用户支付中 +// CODE_TRADE_PAYERROR = "PAYERROR" // 支付失败 +// CODE_TRANSFER_PROCESSING = "PROCESSING" // 转账处理中 +// CODE_TRANSFER_NOT_FOUND = "NOT_FOUND" // 账单不见了 +//) type CommonReturn struct { ReturnCode string `xml:"return_code,omitempty" json:"return_code,omitempty"` diff --git a/services/pay/handle.go b/services/pay/handle.go index 3ddeba4..71223a3 100644 --- a/services/pay/handle.go +++ b/services/pay/handle.go @@ -6,12 +6,95 @@ import ( "hudongzhuanjia/logger" "hudongzhuanjia/models" im_service "hudongzhuanjia/services/im" + "hudongzhuanjia/utils/define" + "math" "time" ) -//处理支付成功之后的回调问题 +func init() { + go loopUnifiedOrder() +} + +var orderDelayQueue = make(chan *models.UserOrder, math.MaxInt8) + +func PutOrderDelayQueue(order *models.UserOrder) { + orderDelayQueue <- order +} + +func loopUnifiedOrder() { + orders, err := models.GetUserOrdersByStatus(0, 3) + if err != nil { + panic(err) + } + + for _, order := range orders { + PutOrderDelayQueue(order) + } + + defer func() { + if err := recover(); err != nil { + logger.Error("订单轮询查询: panic 恢复错误", err) + } + // 重启 + time.Sleep(5 * time.Second) + loopUnifiedOrder() + }() + for { + select { + case order, ok := <-orderDelayQueue: + if !ok { + panic("通道异常关闭") + } + if order.ExpireAt <= time.Now().Unix() { // 订单超时 + if order.Status == 0 { + err = Close(order.OutTradeNo) // 超时关闭订单 + if err != nil { + logger.Error("订单关闭出现错误: 错误原因->", err) + } + order.Status = 5 + go HandleFailed(order) + } + continue + } -// 直播红包 + if order.Status == 0 { + res, err := OrderQuery(order.OutTradeNo) + if err != nil { + logger.Error("查询订单出现错误: 错误原因-->", err.Error(), "交易订单号-->", order.OutTradeNo) + orderDelayQueue <- order // 重新进入队列 + continue + } + + if res["trade_state"] == define.CODE_TRADE_SUCCESS { + go HandleSuccess(order) + } else if res["trade_state"] == define.CODE_TRADE_REFUND { + order.Status = 3 + orderDelayQueue <- order + continue + } else { + orderDelayQueue <- order + continue + } + } else if order.Status == 3 { + res, err := QueryRefund(order.OutTradeNo) + if err != nil { + logger.Error("退款订单查询错误: 错误原因-->", err.Error(), "交易订单号-->", order.OutTradeNo) + continue + } + order.RefundAccount = res.RefundList[0].RefundAccount + order.RefundRecvAccount = res.RefundList[0].RefundRecvAccout + order.Status = 4 + _, err = models.Update(order.Id, order, "refund_account", "refund_recv_account", "status") + if err != nil { + logger.Error("退款状态改变错误: 错误原因-->", err, "交易订单号-->", order.OutTradeNo) + continue + } + } + } + } +} + +//处理支付成功之后的回调问题 func HandleSuccess(order *models.UserOrder) error { if order.GoodType == 4 { // 直播商品 customerOrder := new(models.CustomerOrder) @@ -186,3 +269,21 @@ func HandleFailed(order *models.UserOrder) error { } return nil } + +// 定时任务 +// 1个小时查询一次 +func HandleTicker() { + defer func() { + if err := recover(); err != nil { + logger.Error("定时任务错误原因", err) + } + HandleTicker() + }() + ticker := time.NewTicker(1 * time.Hour) + for { + select { + case <-ticker.C: + + } + } +} diff --git a/services/pay/order.go b/services/pay/order.go index bf2d782..0bc1295 100644 --- a/services/pay/order.go +++ b/services/pay/order.go @@ -8,96 +8,13 @@ import ( "hudongzhuanjia/logger" "hudongzhuanjia/models" "hudongzhuanjia/utils" + "hudongzhuanjia/utils/define" "io" "io/ioutil" - "math" "strconv" "time" ) -func init() { - go loopUnifiedOrder() -} - -var orderDelayQueue = make(chan *models.UserOrder, math.MaxInt8) - -func PutOrderDelayQueue(order *models.UserOrder) { - orderDelayQueue <- order -} - -func loopUnifiedOrder() { - orders, err := models.GetUserOrdersByStatus(0, 3) - if err != nil { - panic(err) - } - - for _, order := range orders { - PutOrderDelayQueue(order) - } - - defer func() { - if err := recover(); err != nil { - logger.Error("订单轮询查询: panic 恢复错误", err) - } - // 重启 - time.Sleep(5 * time.Second) - loopUnifiedOrder() - }() - for { - select { - case order, ok := <-orderDelayQueue: - if !ok { - panic("通道异常关闭") - } - if order.ExpireAt <= time.Now().Unix() { // 订单超时 - if order.Status == 0 { - err = Close(order.OutTradeNo) // 超时关闭订单 - if err != nil { - logger.Error("订单关闭出现错误: 错误原因->", err) - } - order.Status = 5 - go HandleFailed(order) - } - continue - } - - if order.Status == 0 { - res, err := OrderQuery(order.OutTradeNo) - if err != nil { - logger.Error("查询订单出现错误: 错误原因-->", err.Error(), "交易订单号-->", order.OutTradeNo) - orderDelayQueue <- order // 重新进入队列 - continue - } - - if res["trade_state"] == CODE_TRADE_SUCCESS { - go HandleSuccess(order) - } else if res["trade_state"] == CODE_TRADE_REFUND { - order.Status = 3 - orderDelayQueue <- order - continue - } else { - orderDelayQueue <- order - continue - } - } else if order.Status == 3 { - res, err := QueryRefund(order.OutTradeNo) - if err != nil { - logger.Error("退款订单查询错误: 错误原因-->", err.Error(), "交易订单号-->", order.OutTradeNo) - continue - } - order.RefundAccount = res.RefundList[0].RefundAccount - order.RefundRecvAccount = res.RefundList[0].RefundRecvAccout - order.Status = 4 - _, err = models.Update(order.Id, order, "refund_account", "refund_recv_account", "status") - if err != nil { - logger.Error("退款状态改变错误: 错误原因-->", err, "交易订单号-->", order.OutTradeNo) - continue - } - } - } - } -} - const CallbackOrderUrl = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackOrder" func UnifiedOrder(content, openId string, fee, goodType, userId, activityId, expireAt int64) (map[string]interface{}, error) { @@ -114,10 +31,9 @@ func UnifiedOrder(content, openId string, fee, goodType, userId, activityId, exp body["total_fee"] = fmt.Sprint(fee) body["notify_url"] = CallbackOrderUrl body["trade_type"] = "JSAPI" - body["device_info"] = "WEB" body["nonce_str"] = nonceStr body["sign_type"] = pay_core.SignType_MD5 - body["open_id"] = openId + body["openid"] = openId body["time_expire"] = pay_core.FormatTime(time.Unix(expireAt, 0)) resp, err := pay.UnifiedOrder(client, body) @@ -127,7 +43,6 @@ func UnifiedOrder(content, openId string, fee, goodType, userId, activityId, exp // 记录这次订单 userOrder := new(models.UserOrder) - userOrder.DeviceInfo = "WEB" userOrder.Body = content userOrder.UserId = userId userOrder.ActivityId = activityId @@ -147,11 +62,11 @@ func UnifiedOrder(content, openId string, fee, goodType, userId, activityId, exp //获取H5支付需要的paySign timestamp := strconv.FormatInt(time.Now().Unix(), 10) pac := "prepay_id=" + resp["prepay_id"] - paySign := pay_core.JsapiSign(client.AppId(), timestamp, nonceStr, pac, pay_core.SignType_MD5, ApiKey) + paySign := pay_core.JsapiSign(client.AppId(), timestamp, nonceStr, pac, pay_core.SignType_MD5, define.ApiKey) go PutOrderDelayQueue(userOrder) return map[string]interface{}{ - "appid": Appid, + "appid": client.AppId(), "timestamp": timestamp, "nonce_str": nonceStr, "package": pac, @@ -176,10 +91,10 @@ func ReOrder(outTradeNo string) (map[string]interface{}, error) { nonceStr := utils.RandomStr(32) //获取H5支付需要的paySign pac := "prepay_id=" + userOrder.PrepayId - paySign := pay_core.JsapiSign(Appid, timestamp, nonceStr, pac, pay_core.SignType_MD5, ApiKey) + paySign := pay_core.JsapiSign(define.AppId, timestamp, nonceStr, pac, pay_core.SignType_MD5, define.ApiKey) go PutOrderDelayQueue(userOrder) return map[string]interface{}{ - "appid": Appid, + "appid": define.AppId, "timestamp": timestamp, "nonce_str": nonceStr, "package": pac, @@ -241,11 +156,11 @@ func NotifyOrder(w io.Reader) (order *models.UserOrder, err error) { return } - if res.ReturnCode != CODE_SUCCESS { + if res.ReturnCode != define.CODE_SUCCESS { return nil, fmt.Errorf("network error, retrun_code: %+v and return_msg: %+v", res.ReturnCode, res.ReturnMsg) } - if res.ResultCode == CODE_SUCCESS && res.TradeType == CODE_TRADE_SUCCESS { + if res.ResultCode == define.CODE_SUCCESS && res.TradeType == define.CODE_TRADE_SUCCESS { userOrder := new(models.UserOrder) userOrder.TransactionId = res.TransactionId userOrder.Status = 1 diff --git a/services/pay/order_test.go b/services/pay/order_test.go new file mode 100644 index 0000000..5b92104 --- /dev/null +++ b/services/pay/order_test.go @@ -0,0 +1,16 @@ +package pay_service + +import ( + "fmt" + "testing" + "time" +) + +func TestUnifiedOrder(t *testing.T) { + res, err := UnifiedOrder("欧轩互动测试", "o9XM41s_NN8Y0QK6_MbM-aYMV3TE", + 2, 1, 1, 101, time.Now().Add(1*time.Hour).Unix()) + if err != nil { + t.Error(err) + } + fmt.Println(res) +} diff --git a/services/pay/transfer.go b/services/pay/transfer.go index 6f927ea..b6c135c 100644 --- a/services/pay/transfer.go +++ b/services/pay/transfer.go @@ -8,6 +8,7 @@ import ( "hudongzhuanjia/logger" "hudongzhuanjia/models" "hudongzhuanjia/utils" + "hudongzhuanjia/utils/define" "math" "strconv" "time" @@ -89,9 +90,9 @@ func loopTransfer() { continue } - if res.Status == CODE_SUCCESS { + if res.Status == define.CODE_SUCCESS { continue - } else if res.Status == CODE_TRANSFER_PROCESSING { + } else if res.Status == define.CODE_TRANSFER_PROCESSING { transferDelayQueue <- param continue } else { @@ -150,8 +151,8 @@ func Transfer(desc, openId, partnerTradeNo string, amount int) (*TransferRespons body["check_name"] = "NO_CHECK" // NO_CHECK:不校验真实姓名 , FORCE_CHECK:强校验真实姓名 body["amount"] = fmt.Sprintf("%d", amount) // 企业付款金额,单位为分 body["desc"] = desc // 企业付款备注,必填。注意:备注中的敏感词会被转成字符* - body["mchid"] = Mchid - body["mch_appid"] = Appid + body["mchid"] = define.MchId + body["mch_appid"] = define.AppId client, err := Client() m, err := promotion.Transfers(client, body) @@ -240,11 +241,11 @@ func TransferInfo(partnerTradeNo string) (*TransferInfoResponse, error) { ErrCode: m["err_code"], } transfer := new(models.UserTransfer) - if res.Status == CODE_SUCCESS { + if res.Status == define.CODE_SUCCESS { transfer.Status = 2 - } else if res.Status == CODE_TRANSFER_PROCESSING { + } else if res.Status == define.CODE_TRANSFER_PROCESSING { transfer.Status = 1 - } else if res.Status == CODE_FAIL { + } else if res.Status == define.CODE_FAIL { transfer.Status = 3 } transfer.Reason = res.Reason @@ -285,7 +286,7 @@ func SendRedPack(sendName, openId, wishing, actName, remark string, totalAmount, body["total_amount"] = fmt.Sprintf("%d", totalAmount) body["total_num"] = fmt.Sprintf("%d", totalNum) body["wishing"] = wishing - body["client_ip"] = ClientIp + body["client_ip"] = define.ClientIp body["act_name"] = actName body["remark"] = remark body["scene_id"] = fmt.Sprintf("PRODUCT_%d", scene) diff --git a/test/pay_test.go b/test/pay_test.go index a76fb6f..997ce65 100644 --- a/test/pay_test.go +++ b/test/pay_test.go @@ -34,7 +34,7 @@ func TestQueryOrder(t *testing.T) { outTradeNo := "6PM9n5WDSX47frNfQ9OxWEKe8u6ChBos" res, err := pay_service.OrderQuery(outTradeNo) fmt.Println(err) - fmt.Printf("%+v\n", res.Query) + fmt.Printf("%+v\n", res) } func TestClose(t *testing.T) { diff --git a/utils/define/define.go b/utils/define/define.go index bc0610f..0372360 100644 --- a/utils/define/define.go +++ b/utils/define/define.go @@ -1,7 +1,5 @@ package define -import "time" - const TimeFormat = "2006-01-01 15:04:05" const ( @@ -86,5 +84,68 @@ const ( TYPE_ENTRYPEOPLE = "entry_people" ) -var DefaultTime = time.Date(1970, 1, 1, 8, 0, 0, 0, time.Local) +// 固定长度 var DefaultOrderNo = 10000000000 + +// 微信常量 +const ( + // 欧轩互动 -> 普通商户 + ApiKey = `2c82c64ceec6ba89ffc9f593c671a12f` + AppId = "wx7b0bcf476552c5e9" + Secret = `f6aabdd40ea25272f4442603a7dc8028` + MchId = `1394404502` + SubMchId = `` + + // 欧轩 -> 服务商 + //ApiKey = `5x201c8zn43cg675204594cab5423320` + //AppId = `wx662a1633304bfd42` + //Secret = `90df40859d20c95fbb047d48ccbe0a30` + //MchId = `1441266702` + //SubMchId = `1594049151` + + WxHost = `https://api.mch.weixin.qq.com` + WxBack = `https://api2.mch.weixin.qq.com` + ClientIp = `123.207.246.51` +) + +const ( + CODE_SUCCESS = "SUCCESS" // 成功 + CODE_FAIL = "FAIL" // 失败 + CODE_NOTPAY = "NOTPAY" // 未支付 + CODE_CHANGE = "CHANGE" // 退款异常 + CODE_REFUNDCLOSE = "REFUNDCLOSE" // 退款关闭 + CODE_ERROR = "ERROR" // 业务错误 + CODE_INVALID_REQUEST = "INVALID_REQUEST" // 无效请求 + CODE_NOAUTH = "NOAUTH" // 异常IP请求不予受理 + CODE_NOTENOUGH = "NOTENOUGH" // 余额不足 + CODE_ORDERPAID = "ORDERPAID" // 订单已支付 + CODE_ORDERCLOSED = "ORDERCLOSED" // 订单已关闭 + CODE_SYSTEMERROR = "SYSTEMERROR" // 系统错误 + CODE_APPID_NOT_EXIST = "APPID_NOT_EXIST" // APPID不存在 + CODE_MCHID_NOT_EXIST = "MCHID_NOT_EXIST" // MCHID不存在 + CODE_APPID_MCHID_NOT_MATCH = "APPID_MCHID_NOT_MATCH" // APPID MCHID 不匹配 + CODE_LACK_PARAMS = "LACK_PARAMS" // 缺少参数 + CODE_OUT_TRADE_NO_USED = "OUT_TRADE_NO_USED" // 商户订单号重复 + CODE_SIGNERROR = "SIGNERROR" // 签名错误 + CODE_XML_FORMAT_ERROR = "XML_FORMAT_ERROR" // xml格式错误 + CODE_REQUIRE_POST_METHOD = "REQUIRE_POST_METHOD" // 请使用post请求方法 + CODE_POST_DATA_EMPTY = "POST_DATA_EMPTY" // post数据为空 + CODE_NOT_UTF8 = "NOT_UTF8" // 编码错误 + CODE_ORDERNOTEXIST = "ORDERNOTEXIST" // 交易订单号不存在 + CODE_BIZERR_NEED_RETRY = "BIZERR_NEED_RETRY" // 退款业务流程错误,需要商户触发重试来解决 + CODE_TRADE_OVERDUE = "TRADE_OVERDUE" // 订单已经超过退款期限 + CODE_USER_ACCOUNT_ABNORMAL = "USER_ACCOUNT_ABNORMAL" // 退款请求失败用户帐号注销 + CODE_INVALID_REQ_TOO_MUCH = "INVALID_REQ_TOO_MUCH" // 无效请求过多 + CODE_INVALID_TRANSACTIONID = "INVALID_TRANSACTIONID" // 无效transaction_id + CODE_PARAM_ERROR = "PARAM_ERROR" // 参数错误 + CODE_FREQUENCY_LIMITED = "FREQUENCY_LIMITED" // 请求频率限制 + CODE_TRADE_SUCCESS = "SUCCESS" // 交易成功 + CODE_TRADE_REFUND = "REFUND" // 转入退款 + CODE_TRADE_NOTPAY = "NOTPAY" // 尚未支付 + CODE_TRADE_CLOSED = "CLOSED" // 已关闭 + CODE_TRADE_REVOKED = "REVOKED" // 已撤销 + CODE_TRADE_USERPAYING = "USERPAYING" // 用户支付中 + CODE_TRADE_PAYERROR = "PAYERROR" // 支付失败 + CODE_TRANSFER_PROCESSING = "PROCESSING" // 转账处理中 + CODE_TRANSFER_NOT_FOUND = "NOT_FOUND" // 账单不见了 +)