微信支付CreateUnifiedOrder
微信API,入统一为struct,出统一用mxj再转struct
This commit is contained in:
@@ -9,9 +9,9 @@ import (
|
|||||||
"git.rosy.net.cn/baseapi/utils"
|
"git.rosy.net.cn/baseapi/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CDData string
|
type CData string
|
||||||
|
|
||||||
func (c CDData) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
func (c CData) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||||
return e.EncodeElement(struct {
|
return e.EncodeElement(struct {
|
||||||
string `xml:",cdata"`
|
string `xml:",cdata"`
|
||||||
}{string(c)}, start)
|
}{string(c)}, start)
|
||||||
@@ -21,7 +21,7 @@ type CallbackResponse struct {
|
|||||||
XMLName xml.Name `json:"-" xml:"xml"`
|
XMLName xml.Name `json:"-" xml:"xml"`
|
||||||
|
|
||||||
ReturnCode string `json:"return_code" xml:"return_code"`
|
ReturnCode string `json:"return_code" xml:"return_code"`
|
||||||
ReturnMsg CDData `json:"return_msg" xml:"return_msg"`
|
ReturnMsg CData `json:"return_msg" xml:"return_msg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -41,7 +41,7 @@ func Err2CallbackResponse(err error, data string) *CallbackResponse {
|
|||||||
}
|
}
|
||||||
return &CallbackResponse{
|
return &CallbackResponse{
|
||||||
ReturnCode: ResponseCodeFail,
|
ReturnCode: ResponseCodeFail,
|
||||||
ReturnMsg: CDData(returnMsg),
|
ReturnMsg: CData(returnMsg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,33 +28,81 @@ const (
|
|||||||
sigType = "MD5"
|
sigType = "MD5"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
FeeTypeCNY = "CNY"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TradeTypeJSAPI = "JSAPI" // JSAPI支付(或小程序支付)
|
||||||
|
TradeTypeNative = "NATIVE"
|
||||||
|
TradeTypeAPP = "APP"
|
||||||
|
TradeTypeMicroPay = "MICROPAY"
|
||||||
|
)
|
||||||
|
|
||||||
|
type API struct {
|
||||||
|
appID string
|
||||||
|
appKey string
|
||||||
|
mchID string
|
||||||
|
client *http.Client
|
||||||
|
config *platformapi.APIConfig
|
||||||
|
}
|
||||||
|
|
||||||
type RequestBase struct {
|
type RequestBase struct {
|
||||||
XMLName xml.Name `json:"-" xml:"xml"`
|
XMLName xml.Name `json:"-" xml:"xml"`
|
||||||
|
|
||||||
AppID string `json:"appid" xml:"appid"`
|
AppID string `json:"appid" xml:"appid"`
|
||||||
MchID string `json:"mch_id" xml:"mch_id"`
|
DeviceInfo string `json:"device_info,omitempty" xml:"device_info,omitempty"`
|
||||||
NonceStr string `json:"nonce_str" xml:"nonce_str"`
|
MchID string `json:"mch_id" xml:"mch_id"`
|
||||||
Sign string `json:"sign" xml:"sign"`
|
NonceStr string `json:"nonce_str" xml:"nonce_str"`
|
||||||
SignType string `json:"sign_type,omitempty" xml:"sign_type,omitempty"`
|
Sign string `json:"sign" xml:"sign"`
|
||||||
|
SignType string `json:"sign_type,omitempty" xml:"sign_type,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type IRequestBase interface {
|
||||||
|
SetAppID(appID string)
|
||||||
|
SetMchID(mchID string)
|
||||||
|
SetNonceStr(nonceStr string)
|
||||||
|
SetSign(sign string)
|
||||||
|
SetSignType(signType string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RequestBase) SetAppID(appID string) {
|
||||||
|
r.AppID = appID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RequestBase) SetMchID(mchID string) {
|
||||||
|
r.MchID = mchID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RequestBase) SetNonceStr(nonceStr string) {
|
||||||
|
r.NonceStr = nonceStr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RequestBase) SetSign(sign string) {
|
||||||
|
r.Sign = sign
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RequestBase) SetSignType(signType string) {
|
||||||
|
r.SignType = signType
|
||||||
}
|
}
|
||||||
|
|
||||||
type ResponseResult struct {
|
type ResponseResult struct {
|
||||||
XMLName xml.Name `json:"-" xml:"xml"`
|
// XMLName xml.Name `json:"-" xml:"xml"`
|
||||||
|
|
||||||
ReturnCode string `json:"return_code" xml:"return_code"`
|
ReturnCode string `json:"return_code" xml:"return_code"`
|
||||||
ReturnMsg string `json:"return_msg" xml:"return_msg"`
|
ReturnMsg string `json:"return_msg" xml:"return_msg"`
|
||||||
|
|
||||||
AppID string `json:"appid" xml:"appid"`
|
AppID string `json:"appid" xml:"appid"`
|
||||||
|
DeviceInfo string `json:"device_info,omitempty" xml:"device_info,omitempty"`
|
||||||
MchID string `json:"mch_id" xml:"mch_id"`
|
MchID string `json:"mch_id" xml:"mch_id"`
|
||||||
NonceStr string `json:"nonce_str" xml:"nonce_str"`
|
NonceStr string `json:"nonce_str" xml:"nonce_str"`
|
||||||
Sign string `json:"sign" xml:"sign"`
|
Sign string `json:"sign" xml:"sign"`
|
||||||
SignType string `json:"sign_type,omitempty" xml:"sign_type,omitempty"`
|
|
||||||
ResultCode string `json:"result_code" xml:"result_code"`
|
ResultCode string `json:"result_code" xml:"result_code"`
|
||||||
ErrCode string `json:"err_code,omitempty" xml:"err_code,omitempty"`
|
ErrCode string `json:"err_code,omitempty" xml:"err_code,omitempty"`
|
||||||
ErrCodeDes string `json:"err_code_des,omitempty" xml:"err_code_des,omitempty"`
|
ErrCodeDes string `json:"err_code_des,omitempty" xml:"err_code_des,omitempty"`
|
||||||
|
|
||||||
DeviceInfo string `json:"device_info,omitempty" xml:"device_info,omitempty"`
|
SignType string `json:"sign_type,omitempty" xml:"sign_type,omitempty"`
|
||||||
OpenID string `json:"openid,omitempty" xml:"openid,omitempty"`
|
OpenID string `json:"openid,omitempty" xml:"openid,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderQueryParam struct {
|
type OrderQueryParam struct {
|
||||||
@@ -63,12 +111,80 @@ type OrderQueryParam struct {
|
|||||||
OutTradeNo string `json:"out_trade_no" xml:"out_trade_no"`
|
OutTradeNo string `json:"out_trade_no" xml:"out_trade_no"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type API struct {
|
type OrderInfo struct {
|
||||||
appID string
|
ReturnCode string `json:"return_code" xml:"return_code"`
|
||||||
appKey string
|
ReturnMsg string `json:"return_msg" xml:"return_msg"`
|
||||||
mchID string
|
|
||||||
client *http.Client
|
AppID string `json:"appid" xml:"appid"`
|
||||||
config *platformapi.APIConfig
|
DeviceInfo string `json:"device_info,omitempty" xml:"device_info,omitempty"`
|
||||||
|
MchID string `json:"mch_id" xml:"mch_id"`
|
||||||
|
NonceStr string `json:"nonce_str" xml:"nonce_str"`
|
||||||
|
Sign string `json:"sign" xml:"sign"`
|
||||||
|
ResultCode string `json:"result_code" xml:"result_code"`
|
||||||
|
ErrCode string `json:"err_code,omitempty" xml:"err_code,omitempty"`
|
||||||
|
ErrCodeDes string `json:"err_code_des,omitempty" xml:"err_code_des,omitempty"`
|
||||||
|
|
||||||
|
Attach string `json:"attach"`
|
||||||
|
BankType string `json:"bank_type"`
|
||||||
|
CashFee string `json:"cash_fee"`
|
||||||
|
CashFeeType string `json:"cash_fee_type"`
|
||||||
|
FeeType string `json:"fee_type"`
|
||||||
|
IsSubscribe string `json:"is_subscribe"`
|
||||||
|
OpenID string `json:"openid"`
|
||||||
|
OutTradeNo string `json:"out_trade_no"`
|
||||||
|
TimeEnd string `json:"time_end"`
|
||||||
|
TotalFee string `json:"total_fee"`
|
||||||
|
TradeState string `json:"trade_state"`
|
||||||
|
TradeStateDesc string `json:"trade_state_desc"`
|
||||||
|
TradeType string `json:"trade_type"`
|
||||||
|
TransactionID string `json:"transaction_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateOrderSceneInfo struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
AreaCode string `json:"area_code"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateOrderParam struct {
|
||||||
|
RequestBase
|
||||||
|
Body string `json:"body" xml:"body"`
|
||||||
|
NotifyURL string `json:"notify_url" xml:"notify_url"`
|
||||||
|
OutTradeNo string `json:"out_trade_no" xml:"out_trade_no"`
|
||||||
|
SpbillCreateIP string `json:"spbill_create_ip" xml:"spbill_create_ip"`
|
||||||
|
TradeType string `json:"trade_type" xml:"trade_type"`
|
||||||
|
TotalFee int `json:"total_fee" xml:"total_fee"`
|
||||||
|
|
||||||
|
Detail CData `json:"detail.omitempty" xml:"detail,omitempty"`
|
||||||
|
Attach string `json:"attach,omitempty" xml:"attach,omitempty"`
|
||||||
|
FeeType string `json:"fee_type,omitempty" xml:"fee_type,omitempty"`
|
||||||
|
TimeStart string `json:"time_start,omitempty" xml:"time_start,omitempty"`
|
||||||
|
TimeExpire string `json:"time_expire,omitempty" xml:"time_expire,omitempty"`
|
||||||
|
GoodsTag string `json:"goods_tag,omitempty" xml:"goods_tag,omitempty"`
|
||||||
|
ProductID string `json:"product_id,omitempty" xml:"product_id,omitempty"`
|
||||||
|
LimitPay string `json:"limit_pay,omitempty" xml:"limit_pay,omitempty"`
|
||||||
|
OpenID string `json:"openid,omitempty" xml:"openid,omitempty"`
|
||||||
|
Receipt string `json:"receipt,omitempty" xml:"receipt,omitempty"`
|
||||||
|
SceneInfo string `json:"scene_info,omitempty" xml:"scene_info,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateOrderResult struct {
|
||||||
|
ReturnCode string `json:"return_code" xml:"return_code"`
|
||||||
|
ReturnMsg string `json:"return_msg" xml:"return_msg"`
|
||||||
|
|
||||||
|
AppID string `json:"appid" xml:"appid"`
|
||||||
|
DeviceInfo string `json:"device_info,omitempty" xml:"device_info,omitempty"`
|
||||||
|
MchID string `json:"mch_id" xml:"mch_id"`
|
||||||
|
NonceStr string `json:"nonce_str" xml:"nonce_str"`
|
||||||
|
Sign string `json:"sign" xml:"sign"`
|
||||||
|
ResultCode string `json:"result_code" xml:"result_code"`
|
||||||
|
ErrCode string `json:"err_code,omitempty" xml:"err_code,omitempty"`
|
||||||
|
ErrCodeDes string `json:"err_code_des,omitempty" xml:"err_code_des,omitempty"`
|
||||||
|
|
||||||
|
TradeType string `json:"trade_type"`
|
||||||
|
PrepayID string `json:"prepay_id"`
|
||||||
|
CodeURL string `json:"code_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(appID, appKey, mchID string, config ...*platformapi.APIConfig) *API {
|
func New(appID, appKey, mchID string, config ...*platformapi.APIConfig) *API {
|
||||||
@@ -109,10 +225,10 @@ func (a *API) signParam(params map[string]interface{}) (sig string) {
|
|||||||
return sig
|
return sig
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalXML(data []byte, result interface{}) error {
|
// func unmarshalXML(data []byte, result interface{}) error {
|
||||||
d := xml.NewDecoder(bytes.NewReader(data))
|
// d := xml.NewDecoder(bytes.NewReader(data))
|
||||||
return d.Decode(result)
|
// return d.Decode(result)
|
||||||
}
|
// }
|
||||||
|
|
||||||
func mustMarshalXML(obj interface{}) []byte {
|
func mustMarshalXML(obj interface{}) []byte {
|
||||||
byteArr, err := xml.Marshal(obj)
|
byteArr, err := xml.Marshal(obj)
|
||||||
@@ -122,69 +238,18 @@ func mustMarshalXML(obj interface{}) []byte {
|
|||||||
return byteArr
|
return byteArr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *API) AccessAPI(action string, params interface{}, baseParam *RequestBase) (retVal *ResponseResult, err error) {
|
func (a *API) AccessAPI(action string, requestParam IRequestBase) (retVal map[string]interface{}, err error) {
|
||||||
baseParam.AppID = a.appID
|
requestParam.SetAppID(a.appID)
|
||||||
baseParam.MchID = a.mchID
|
requestParam.SetMchID(a.mchID)
|
||||||
baseParam.NonceStr = utils.GetUUID()
|
requestParam.SetNonceStr(utils.GetUUID())
|
||||||
baseParam.SignType = sigType
|
requestParam.SetSignType(sigType)
|
||||||
baseParam.Sign = a.signParam(utils.Struct2FlatMap(params))
|
requestParam.SetSign(a.signParam(utils.Struct2FlatMap(requestParam)))
|
||||||
|
|
||||||
fullURL := utils.GenerateGetURL(prodURL, action, nil)
|
fullURL := utils.GenerateGetURL(prodURL, action, nil)
|
||||||
|
|
||||||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||||||
func() *http.Request {
|
func() *http.Request {
|
||||||
request, _ := http.NewRequest(http.MethodPost, fullURL, bytes.NewReader(mustMarshalXML(params)))
|
request, _ := http.NewRequest(http.MethodPost, fullURL, bytes.NewReader(mustMarshalXML(requestParam)))
|
||||||
return request
|
|
||||||
},
|
|
||||||
a.config,
|
|
||||||
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
|
|
||||||
if jsonResult1 == nil {
|
|
||||||
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
|
|
||||||
}
|
|
||||||
retVal, errLevel, err = a.checkResult(jsonResult1[platformapi.KeyData].(string))
|
|
||||||
return errLevel, err
|
|
||||||
})
|
|
||||||
return retVal, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *API) checkResult(xmlStr string) (result *ResponseResult, errLevel string, err error) {
|
|
||||||
err = unmarshalXML([]byte(xmlStr), &result)
|
|
||||||
if err != nil {
|
|
||||||
errLevel = platformapi.ErrLevelGeneralFail
|
|
||||||
} else {
|
|
||||||
if result.ReturnCode != ResponseCodeSuccess {
|
|
||||||
errLevel = platformapi.ErrLevelGeneralFail
|
|
||||||
err = utils.NewErrorCode(result.ReturnMsg, result.ReturnCode)
|
|
||||||
result = nil
|
|
||||||
} else {
|
|
||||||
// if result.ResultCode != ResponseCodeSuccess {
|
|
||||||
// errLevel = platformapi.ErrLevelGeneralFail
|
|
||||||
// err = utils.NewErrorCode(result.ErrCodeDes, result.ErrCode)
|
|
||||||
// result = nil
|
|
||||||
// } else {
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result, errLevel, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *API) AccessAPIByMap(action string, params map[string]interface{}) (retVal map[string]interface{}, err error) {
|
|
||||||
params2 := utils.MergeMaps(params, map[string]interface{}{
|
|
||||||
"appid": a.appID,
|
|
||||||
"mch_id": a.mchID,
|
|
||||||
"nonce_str": utils.GetUUID(),
|
|
||||||
"sign_type": sigType,
|
|
||||||
})
|
|
||||||
params2[sigKey] = a.signParam(params2)
|
|
||||||
|
|
||||||
fullURL := utils.GenerateGetURL(prodURL, action, nil)
|
|
||||||
xmlBytes, err := mxj.Map(params2).Xml("xml")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
|
||||||
func() *http.Request {
|
|
||||||
request, _ := http.NewRequest(http.MethodPost, fullURL, bytes.NewReader(xmlBytes))
|
|
||||||
return request
|
return request
|
||||||
},
|
},
|
||||||
a.config,
|
a.config,
|
||||||
@@ -198,6 +263,57 @@ func (a *API) AccessAPIByMap(action string, params map[string]interface{}) (retV
|
|||||||
return retVal, err
|
return retVal, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// func (a *API) checkResult(xmlStr string) (result *ResponseResult, errLevel string, err error) {
|
||||||
|
// err = unmarshalXML([]byte(xmlStr), &result)
|
||||||
|
// if err != nil {
|
||||||
|
// errLevel = platformapi.ErrLevelGeneralFail
|
||||||
|
// } else {
|
||||||
|
// if result.ReturnCode != ResponseCodeSuccess {
|
||||||
|
// errLevel = platformapi.ErrLevelGeneralFail
|
||||||
|
// err = utils.NewErrorCode(result.ReturnMsg, result.ReturnCode)
|
||||||
|
// result = nil
|
||||||
|
// } else {
|
||||||
|
// // if result.ResultCode != ResponseCodeSuccess {
|
||||||
|
// // errLevel = platformapi.ErrLevelGeneralFail
|
||||||
|
// // err = utils.NewErrorCode(result.ErrCodeDes, result.ErrCode)
|
||||||
|
// // result = nil
|
||||||
|
// // } else {
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return result, errLevel, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// func (a *API) AccessAPIByMap(action string, params map[string]interface{}) (retVal map[string]interface{}, err error) {
|
||||||
|
// params2 := utils.MergeMaps(params, map[string]interface{}{
|
||||||
|
// "appid": a.appID,
|
||||||
|
// "mch_id": a.mchID,
|
||||||
|
// "nonce_str": utils.GetUUID(),
|
||||||
|
// "sign_type": sigType,
|
||||||
|
// })
|
||||||
|
// params2[sigKey] = a.signParam(params2)
|
||||||
|
|
||||||
|
// fullURL := utils.GenerateGetURL(prodURL, action, nil)
|
||||||
|
// xmlBytes, err := mxj.Map(params2).Xml("xml")
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
// err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
||||||
|
// func() *http.Request {
|
||||||
|
// request, _ := http.NewRequest(http.MethodPost, fullURL, bytes.NewReader(xmlBytes))
|
||||||
|
// return request
|
||||||
|
// },
|
||||||
|
// a.config,
|
||||||
|
// func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
|
||||||
|
// if jsonResult1 == nil {
|
||||||
|
// return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
|
||||||
|
// }
|
||||||
|
// retVal, errLevel, err = a.checkResultAsMap(jsonResult1[platformapi.KeyData].(string))
|
||||||
|
// return errLevel, err
|
||||||
|
// })
|
||||||
|
// return retVal, err
|
||||||
|
// }
|
||||||
|
|
||||||
func (a *API) checkResultAsMap(xmlStr string) (result map[string]interface{}, errLevel string, err error) {
|
func (a *API) checkResultAsMap(xmlStr string) (result map[string]interface{}, errLevel string, err error) {
|
||||||
mv, err := mxj.NewMapXml([]byte(xmlStr))
|
mv, err := mxj.NewMapXml([]byte(xmlStr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -221,18 +337,26 @@ func (a *API) checkResultAsMap(xmlStr string) (result map[string]interface{}, er
|
|||||||
return result, errLevel, err
|
return result, errLevel, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *API) OrderQuery(transactionID, outTradeNo string) (retVal map[string]interface{}, err error) {
|
func SceneInfoList2String(sceneList []*CreateOrderSceneInfo) (str string) {
|
||||||
// param := &OrderQueryParam{
|
return string(utils.MustMarshal(sceneList))
|
||||||
// TransactionID: transactionID,
|
}
|
||||||
// OutTradeNo: outTradeNo,
|
|
||||||
// }
|
func (a *API) OrderQuery(transactionID, outTradeNo string) (orderInfo *OrderInfo, err error) {
|
||||||
// retVal, err = a.AccessAPI("orderquery", param, ¶m.RequestBase)
|
param := &OrderQueryParam{
|
||||||
param := map[string]interface{}{}
|
TransactionID: transactionID,
|
||||||
if transactionID != "" {
|
OutTradeNo: outTradeNo,
|
||||||
param["transaction_id"] = transactionID
|
}
|
||||||
} else {
|
retVal, err := a.AccessAPI("orderquery", param)
|
||||||
param["out_trade_no"] = outTradeNo
|
if err == nil {
|
||||||
}
|
err = utils.Map2StructByJson(retVal, &orderInfo, false)
|
||||||
retVal, err = a.AccessAPIByMap("orderquery", param)
|
}
|
||||||
return retVal, err
|
return orderInfo, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *API) CreateUnifiedOrder(param *CreateOrderParam) (createOrderResult *CreateOrderResult, err error) {
|
||||||
|
retVal, err := a.AccessAPI("unifiedorder", param)
|
||||||
|
if err == nil {
|
||||||
|
err = utils.Map2StructByJson(retVal, &createOrderResult, false)
|
||||||
|
}
|
||||||
|
return createOrderResult, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,3 +29,18 @@ func TestOrderQuery(t *testing.T) {
|
|||||||
}
|
}
|
||||||
t.Log(utils.Format4Output(result, false))
|
t.Log(utils.Format4Output(result, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreateUnifiedOrder(t *testing.T) {
|
||||||
|
result, err := api.CreateUnifiedOrder(&CreateOrderParam{
|
||||||
|
Body: "这里一个测试商品",
|
||||||
|
NotifyURL: "http://callback.test.jxc4.com/wxpay/msg/",
|
||||||
|
OutTradeNo: utils.GetUUID(),
|
||||||
|
SpbillCreateIP: "114.114.114.114",
|
||||||
|
TradeType: TradeTypeNative,
|
||||||
|
TotalFee: 1,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(utils.Format4Output(result, false))
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user