Skip to content

Commit

Permalink
add url path
Browse files Browse the repository at this point in the history
  • Loading branch information
iGoogle-ink committed Jan 4, 2021
1 parent 1232446 commit be393c5
Show file tree
Hide file tree
Showing 3 changed files with 280 additions and 3 deletions.
77 changes: 74 additions & 3 deletions wechat/v3/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,39 @@ const (
v3CombineQuery = "/v3/combine-transactions/out-trade-no/%s"
v3CombineClose = "/v3/combine-transactions/out-trade-no/%s/close"

// 微信支付分
v3ScorePermission = "/v3/payscore/permissions" // 商户预授权 POST
v3ScorePermissionAuthorizationQuery = "/v3/payscore/permissions/authorization-code/%s" // authorization_code 查询用户授权记录(授权协议号) GET
v3ScorePermissionAuthorizationTerminate = "/v3/payscore/permissions/authorization-code/%s/terminate" // authorization_code 解除用户授权关系(授权协议号) POST
v3ScorePermissionOpenidQuery = "/v3/payscore/permissions/openid/%s" // openid 查询用户授权记录(openid) GET
v3ScorePermissionOpenidTerminate = "/v3/payscore/permissions/openid/%s/terminate" // openid 解除用户授权记录(openid) POST
v3ScoreOrderDirectComplete = "/payscore/serviceorder/direct-complete" // 创单结单合并 POST
v3ScoreOrder = "/v3/payscore/serviceorder" // 创建支付分订单 POST
v3ScoreOrderQuery = "/v3/payscore/serviceorder" // 查询支付分订单 GET
v3ScoreOrderCancel = "/v3/payscore/serviceorder/%s/cancel" // out_trade_no 取消支付分订单 POST
v3ScoreOrderModify = "/v3/payscore/serviceorder/%s/modify" // out_trade_no 修改订单金额 POST
v3ScoreOrderComplete = "/v3/payscore/serviceorder/%s/complete" // out_trade_no 完结支付分订单 POST
v3ScoreOrderPay = "/v3/payscore/serviceorder/%s/pay" // out_trade_no 商户发起催收扣款 POST
v3ScoreOrderSync = "/v3/payscore/serviceorder/%s/sync" // out_trade_no 同步服务订单信息 POST

// 微信先享卡
v3CardPre = "/v3/discount-card/cards" // 预受理领卡请求 POST
v3CardAddUser = "/v3/discount-card/cards/%s/add-user-records" // out_card_code 增加用户记录 POST
v3CardQuery = "/v3/discount-card/cards/%s" // out_card_code 查询先享卡订单 GET

// 支付即服务
v3GuideRegister = "/v3/smartguide/guides" // 服务人员注册 POST
v3GuideAssign = "/v3/smartguide/guides/%s/assign" // guide_id 服务人员分配 POST
v3GuideQuery = "/v3/smartguide/guides" // 服务人员查询 GET
v3GuideUpdate = "/v3/smartguide/guides/%s" // guide_id 服务人员信息更新 PATCH

// 点金计划
v3GoldPlanManage = "/v3/goldplan/merchants/changegoldplanstatus" // 点金计划管理 POST
v3GoldPlanBillManage = "/v3/goldplan/merchants/changecustompagestatus" // 商家小票管理 POST
v3GoldPlanFilterManage = "/v3/goldplan/merchants/set-advertising-industry-filter" // 同业过滤标签管理 POST
v3GoldPlanOpenAdShow = "/v3/goldplan/merchants/open-advertising-show" // 开通广告展示 PATCH
v3GoldPlanCloseAdShow = "/v3/goldplan/merchants/close-advertising-show" // 关闭广告展示 PATCH

// 订单号类型,1-微信订单号,2-商户订单号
TransactionId OrderNoType = 1
OutTradeNo OrderNoType = 2
Expand Down Expand Up @@ -116,6 +149,14 @@ type Level2FundFlowBillRsp struct {
Error string `json:"-"`
}

// 查询订单 Rsp
type CombineQueryOrderRsp struct {
Code int `json:"-"`
SignInfo *SignInfo `json:"-"`
Response *CombineQueryOrder `json:"response,omitempty"`
Error string `json:"-"`
}

// ==================================分割==================================

type JSAPIPayParams struct {
Expand Down Expand Up @@ -204,6 +245,13 @@ type Amount struct {
PayerCurrency string `json:"payer_currency,omitempty"` // 用户支付币种
}

type CombineAmount struct {
TotalAmount int `json:"total_amount,omitempty"` // 订单总金额,单位为分
Currency string `json:"currency,omitempty"` // 标价币种:符合ISO 4217标准的三位字母代码,人民币:CNY
PayerAmount int `json:"payer_amount"` // 订单现金支付金额
PayerCurrency string `json:"payer_currency,omitempty"` // 现金支付币种:符合ISO 4217标准的三位字母代码,默认人民币:CNY
}

type SceneInfo struct {
DeviceId string `json:"device_id,omitempty"` // 商户端设备号(发起扣款请求的商户服务器设备号)
}
Expand Down Expand Up @@ -234,19 +282,42 @@ type QueryOrder struct {
Appid string `json:"appid"` // 直连商户申请的公众号或移动应用appid
Mchid string `json:"mchid"` // 直连商户的商户号,由微信支付生成并下发
OutTradeNo string `json:"out_trade_no"` // 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
TransactionId string `json:"transaction_id,omitempty"` // 微信支付系统生成的订单号
TradeType string `json:"trade_type,omitempty"` // 交易类型,枚举值:JSAPI:公众号支付, NATIVE:扫码支付, APP:APP支付, MICROPAY:付款码支付, MWEB:H5支付, FACEPAY:刷脸支付
TransactionId string `json:"transaction_id"` // 微信支付系统生成的订单号
TradeType string `json:"trade_type"` // 交易类型,枚举值:JSAPI:公众号支付, NATIVE:扫码支付, APP:APP支付, MICROPAY:付款码支付, MWEB:H5支付, FACEPAY:刷脸支付
TradeState string `json:"trade_state"` // 交易状态,枚举值:SUCCESS:支付成功, REFUND:转入退款, NOTPAY:未支付, CLOSED:已关闭, REVOKED:已撤销(付款码支付), USERPAYING:用户支付中(付款码支付), PAYERROR:支付失败(其他原因,如银行返回失败)
TradeStateDesc string `json:"trade_state_desc"` // 交易状态描述
BankType string `json:"bank_type,omitempty"` // 银行类型,采用字符串类型的银行标识
Attach string `json:"attach,omitempty"` // 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
Attach string `json:"attach"` // 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
SuccessTime string `json:"success_time,omitempty"` // 支付完成时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日 13点29分35秒
Payer *Payer `json:"payer"` // 支付者信息
Amount *Amount `json:"amount,omitempty"` // 订单金额信息,当支付成功时返回该字段
SceneInfo *SceneInfo `json:"scene_info,omitempty"` // 支付场景描述
PromotionDetail []*PromotionDetail `json:"promotion_detail,omitempty"` // 优惠功能,享受优惠时返回该字段
}

type SubOrders struct {
Mchid string `json:"mchid"` // 子单发起方商户号,必须与发起方Appid有绑定关系
TradeType string `json:"trade_type"` // 交易类型,枚举值:NATIVE:扫码支付,JSAPI:公众号支付,APP:APP支付,MWEB:H5支付
TradeState string `json:"trade_state"` // 交易状态,枚举值:SUCCESS:支付成功, REFUND:转入退款, NOTPAY:未支付, CLOSED:已关闭, REVOKED:已撤销(付款码支付), USERPAYING:用户支付中(付款码支付), PAYERROR:支付失败(其他原因,如银行返回失败)
BankType string `json:"bank_type,omitempty"` // 银行类型,采用字符串类型的银行标识
Attach string `json:"attach"` // 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
SuccessTime string `json:"success_time"` // 支付完成时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35+08:00表示,北京时间2015年5月20日 13点29分35秒
TransactionId string `json:"transaction_id"` // 微信支付系统生成的订单号
OutTradeNo string `json:"out_trade_no"` // 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一
SubMchid string `json:"sub_mchid"` // 二级商户商户号,由微信支付生成并下发。服务商子商户的商户号,被合单方。直连商户不用传二级商户号
Amount *CombineAmount `json:"amount"` // 订单金额信息,当支付成功时返回该字段

}

type CombineQueryOrder struct {
CombineAppid string `json:"combine_appid"` // 合单发起方的appid
CombineMchid string `json:"combine_mchid"` // 合单发起方商户号
CombineOutTradeNo string `json:"combine_out_trade_no"` // 合单支付总订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一
SceneInfo *SceneInfo `json:"scene_info,omitempty"` // 支付场景描述
SubOrders []*SubOrders `json:"sub_orders"` // 最多支持子单条数:50
Payer *Payer `json:"combine_payer_info"` // 支付者信息
}

type TradeBill struct {
HashType string `json:"hash_type"`
HashValue string `json:"hash_value"`
Expand Down
205 changes: 205 additions & 0 deletions wechat/v3/pay_public_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,208 @@ func (c *ClientV3) V3BillDownLoadBill(downloadUrl string) (fileBytes []byte, err
}
return bs, nil
}

// 合单APP下单API
// Code = 0 is success
// 文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_1.shtml
func (c *ClientV3) V3CombineTransactionApp(bm gopay.BodyMap) (wxRsp *PrepayRsp, err error) {
ts := time.Now().Unix()
nonceStr := gotil.GetRandomString(32)
if bm != nil {
if bm.Get("combine_appid") == gotil.NULL {
bm.Set("combine_appid", c.Appid)
}
if bm.Get("combine_mchid") == gotil.NULL {
bm.Set("combine_mchid", c.Mchid)
}
}
authorization, err := c.authorization(MethodPost, v3CombinePayApp, nonceStr, ts, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(bm, v3CombinePayApp, authorization)
if err != nil {
return nil, err
}
wxRsp = &PrepayRsp{Code: Success, SignInfo: si}
wxRsp.Response = new(Prepay)
if err = json.Unmarshal(bs, wxRsp.Response); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s):%w", string(bs), err)
}
if res.StatusCode != http.StatusOK {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 合单H5下单API
// Code = 0 is success
// 文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_2.shtml
func (c *ClientV3) V3CombineTransactionH5(bm gopay.BodyMap) (wxRsp *H5Rsp, err error) {
ts := time.Now().Unix()
nonceStr := gotil.GetRandomString(32)
if bm != nil {
if bm.Get("combine_appid") == gotil.NULL {
bm.Set("combine_appid", c.Appid)
}
if bm.Get("combine_mchid") == gotil.NULL {
bm.Set("combine_mchid", c.Mchid)
}
}
authorization, err := c.authorization(MethodPost, v3CombinePayH5, nonceStr, ts, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(bm, v3CombinePayH5, authorization)
if err != nil {
return nil, err
}
wxRsp = &H5Rsp{Code: Success, SignInfo: si}
wxRsp.Response = new(H5Url)
if err = json.Unmarshal(bs, wxRsp.Response); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s):%w", string(bs), err)
}
if res.StatusCode != http.StatusOK {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 合单JSAPI/小程序下单API
// Code = 0 is success
// 文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_3.shtml
// 文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_4.shtml
func (c *ClientV3) V3CombineTransactionJsapi(bm gopay.BodyMap) (wxRsp *PrepayRsp, err error) {
ts := time.Now().Unix()
nonceStr := gotil.GetRandomString(32)
if bm != nil {
if bm.Get("combine_appid") == gotil.NULL {
bm.Set("combine_appid", c.Appid)
}
if bm.Get("combine_mchid") == gotil.NULL {
bm.Set("combine_mchid", c.Mchid)
}
}
authorization, err := c.authorization(MethodPost, v3CombinePayJsapi, nonceStr, ts, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(bm, v3CombinePayJsapi, authorization)
if err != nil {
return nil, err
}
wxRsp = &PrepayRsp{Code: Success, SignInfo: si}
wxRsp.Response = new(Prepay)
if err = json.Unmarshal(bs, wxRsp.Response); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s):%w", string(bs), err)
}
if res.StatusCode != http.StatusOK {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 合单Native下单API
// Code = 0 is success
// 文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_5.shtml
func (c *ClientV3) V3CombineTransactionNative(bm gopay.BodyMap) (wxRsp *NativeRsp, err error) {
ts := time.Now().Unix()
nonceStr := gotil.GetRandomString(32)
if bm != nil {
if bm.Get("combine_appid") == gotil.NULL {
bm.Set("combine_appid", c.Appid)
}
if bm.Get("combine_mchid") == gotil.NULL {
bm.Set("combine_mchid", c.Mchid)
}
}
authorization, err := c.authorization(MethodPost, v3CombineNative, nonceStr, ts, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(bm, v3CombineNative, authorization)
if err != nil {
return nil, err
}
wxRsp = &NativeRsp{Code: Success, SignInfo: si}
wxRsp.Response = new(Native)
if err = json.Unmarshal(bs, wxRsp.Response); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s):%w", string(bs), err)
}
if res.StatusCode != http.StatusOK {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 合单查询订单API
// Code = 0 is success
// 文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_11.shtml
func (c *ClientV3) V3CombineTransactionQueryOrder(traderNo string) (wxRsp *CombineQueryOrderRsp, err error) {
var (
ts = time.Now().Unix()
nonceStr = gotil.GetRandomString(32)
uri string
)
uri = fmt.Sprintf(v3CombineQuery, traderNo)
authorization, err := c.authorization(MethodGet, uri, nonceStr, ts, nil)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdGet(uri, authorization)
if err != nil {
return nil, err
}

wxRsp = &CombineQueryOrderRsp{Code: Success, SignInfo: si}
wxRsp.Response = new(CombineQueryOrder)
if err = json.Unmarshal(bs, wxRsp.Response); err != nil {
return nil, fmt.Errorf("json.Unmarshal(%s):%w", string(bs), err)
}
if res.StatusCode != http.StatusOK {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}

// 合单关闭订单API
// Code = 0 is success
// 文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter5_1_12.shtml
func (c *ClientV3) V3CombineTransactionCloseOrder(tradeNo string, bm gopay.BodyMap) (wxRsp *CloseOrderRsp, err error) {
var (
ts = time.Now().Unix()
nonceStr = gotil.GetRandomString(32)
url = fmt.Sprintf(v3CombineClose, tradeNo)
)
if bm != nil {
if bm.Get("combine_appid") == gotil.NULL {
bm.Set("combine_appid", c.Appid)
}
}
authorization, err := c.authorization(MethodPost, url, nonceStr, ts, bm)
if err != nil {
return nil, err
}
res, si, bs, err := c.doProdPost(bm, url, authorization)
if err != nil {
return nil, err
}

wxRsp = &CloseOrderRsp{Code: Success, SignInfo: si}
if res.StatusCode != http.StatusNoContent {
wxRsp.Code = res.StatusCode
wxRsp.Error = string(bs)
return wxRsp, nil
}
return wxRsp, c.verifySyncSign(si)
}
1 change: 1 addition & 0 deletions wechat/v3/score.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package wechat

0 comments on commit be393c5

Please sign in to comment.