alipay_client.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. package gopay
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. "time"
  8. "github.com/parnurzeal/gorequest"
  9. )
  10. type AliPayClient struct {
  11. AppId string
  12. PrivateKey string
  13. AlipayRootCertSN string
  14. AppCertSN string
  15. ReturnUrl string
  16. NotifyUrl string
  17. Charset string
  18. SignType string
  19. AppAuthToken string
  20. AuthToken string
  21. IsProd bool
  22. }
  23. //初始化支付宝客户端
  24. // 注意:如果使用支付宝公钥证书验签,请设置 支付宝根证书SN(client.SetAlipayRootCertSN())、应用公钥证书SN(client.SetAppCertSN())
  25. // appId:应用ID
  26. // PrivateKey:应用私钥
  27. // IsProd:是否是正式环境
  28. func NewAliPayClient(appId, privateKey string, isProd bool) (client *AliPayClient) {
  29. return &AliPayClient{
  30. AppId: appId,
  31. PrivateKey: privateKey,
  32. IsProd: isProd,
  33. }
  34. }
  35. //alipay.trade.fastpay.refund.query(统一收单交易退款查询)
  36. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.fastpay.refund.query
  37. func (a *AliPayClient) AliPayTradeFastPayRefundQuery(body BodyMap) (aliRsp *AliPayTradeFastpayRefundQueryResponse, err error) {
  38. var (
  39. p1, p2 string
  40. bs []byte
  41. )
  42. p1 = body.Get("out_trade_no")
  43. p2 = body.Get("trade_no")
  44. if p1 == null && p2 == null {
  45. return nil, errors.New("out_trade_no and trade_no are not allowed to be null at the same time")
  46. }
  47. if bs, err = a.doAliPay(body, "alipay.trade.fastpay.refund.query"); err != nil {
  48. return
  49. }
  50. aliRsp = new(AliPayTradeFastpayRefundQueryResponse)
  51. if err = json.Unmarshal(bs, aliRsp); err != nil {
  52. return nil, err
  53. }
  54. if aliRsp.AliPayTradeFastpayRefundQueryResponse.Code != "10000" {
  55. info := aliRsp.AliPayTradeFastpayRefundQueryResponse
  56. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  57. }
  58. aliRsp.SignData = getSignData(bs)
  59. return
  60. }
  61. //alipay.trade.order.settle(统一收单交易结算接口)
  62. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.order.settle
  63. func (a *AliPayClient) AliPayTradeOrderSettle(body BodyMap) (aliRsp *AliPayTradeOrderSettleResponse, err error) {
  64. var (
  65. p1, p2 string
  66. bs []byte
  67. )
  68. p1 = body.Get("out_request_no")
  69. p2 = body.Get("trade_no")
  70. if p1 == null || p2 == null {
  71. return nil, errors.New("out_request_no or trade_no are not allowed to be null")
  72. }
  73. if bs, err = a.doAliPay(body, "alipay.trade.order.settle"); err != nil {
  74. return
  75. }
  76. aliRsp = new(AliPayTradeOrderSettleResponse)
  77. if err = json.Unmarshal(bs, aliRsp); err != nil {
  78. return nil, err
  79. }
  80. if aliRsp.AliPayTradeOrderSettleResponse.Code != "10000" {
  81. info := aliRsp.AliPayTradeOrderSettleResponse
  82. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  83. }
  84. aliRsp.SignData = getSignData(bs)
  85. return
  86. }
  87. //alipay.trade.create(统一收单交易创建接口)
  88. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.create
  89. func (a *AliPayClient) AliPayTradeCreate(body BodyMap) (aliRsp *AliPayTradeCreateResponse, err error) {
  90. var (
  91. p1, p2 string
  92. bs []byte
  93. )
  94. p1 = body.Get("out_trade_no")
  95. p2 = body.Get("buyer_id")
  96. if p1 == null && p2 == null {
  97. return nil, errors.New("out_trade_no and buyer_id are not allowed to be null at the same time")
  98. }
  99. if bs, err = a.doAliPay(body, "alipay.trade.create"); err != nil {
  100. return
  101. }
  102. aliRsp = new(AliPayTradeCreateResponse)
  103. if err = json.Unmarshal(bs, aliRsp); err != nil {
  104. return nil, err
  105. }
  106. if aliRsp.AliPayTradeCreateResponse.Code != "10000" {
  107. info := aliRsp.AliPayTradeCreateResponse
  108. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  109. }
  110. aliRsp.SignData = getSignData(bs)
  111. return
  112. }
  113. //alipay.trade.close(统一收单交易关闭接口)
  114. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.close
  115. func (a *AliPayClient) AliPayTradeClose(body BodyMap) (aliRsp *AliPayTradeCloseResponse, err error) {
  116. var (
  117. p1, p2 string
  118. bs []byte
  119. )
  120. p1 = body.Get("out_trade_no")
  121. p2 = body.Get("trade_no")
  122. if p1 == null && p2 == null {
  123. return nil, errors.New("out_trade_no and trade_no are not allowed to be null at the same time")
  124. }
  125. if bs, err = a.doAliPay(body, "alipay.trade.close"); err != nil {
  126. return
  127. }
  128. aliRsp = new(AliPayTradeCloseResponse)
  129. if err = json.Unmarshal(bs, aliRsp); err != nil {
  130. return nil, err
  131. }
  132. if aliRsp.AliPayTradeCloseResponse.Code != "10000" {
  133. info := aliRsp.AliPayTradeCloseResponse
  134. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  135. }
  136. aliRsp.SignData = getSignData(bs)
  137. return
  138. }
  139. //alipay.trade.cancel(统一收单交易撤销接口)
  140. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.cancel
  141. func (a *AliPayClient) AliPayTradeCancel(body BodyMap) (aliRsp *AliPayTradeCancelResponse, err error) {
  142. var (
  143. p1, p2 string
  144. bs []byte
  145. )
  146. p1 = body.Get("out_trade_no")
  147. p2 = body.Get("trade_no")
  148. if p1 == null && p2 == null {
  149. return nil, errors.New("out_trade_no and trade_no are not allowed to be null at the same time")
  150. }
  151. if bs, err = a.doAliPay(body, "alipay.trade.cancel"); err != nil {
  152. return
  153. }
  154. aliRsp = new(AliPayTradeCancelResponse)
  155. if err = json.Unmarshal(bs, aliRsp); err != nil {
  156. return nil, err
  157. }
  158. if aliRsp.AliPayTradeCancelResponse.Code != "10000" {
  159. info := aliRsp.AliPayTradeCancelResponse
  160. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  161. }
  162. aliRsp.SignData = getSignData(bs)
  163. return
  164. }
  165. //alipay.trade.refund(统一收单交易退款接口)
  166. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.refund
  167. func (a *AliPayClient) AliPayTradeRefund(body BodyMap) (aliRsp *AliPayTradeRefundResponse, err error) {
  168. var (
  169. p1, p2 string
  170. bs []byte
  171. )
  172. p1 = body.Get("out_trade_no")
  173. p2 = body.Get("trade_no")
  174. if p1 == null && p2 == null {
  175. return nil, errors.New("out_trade_no and trade_no are not allowed to be null at the same time")
  176. }
  177. if bs, err = a.doAliPay(body, "alipay.trade.refund"); err != nil {
  178. return nil, err
  179. }
  180. aliRsp = new(AliPayTradeRefundResponse)
  181. if err = json.Unmarshal(bs, aliRsp); err != nil {
  182. return nil, err
  183. }
  184. if aliRsp.AlipayTradeRefundResponse.Code != "10000" {
  185. info := aliRsp.AlipayTradeRefundResponse
  186. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  187. }
  188. aliRsp.SignData = getSignData(bs)
  189. return
  190. }
  191. //alipay.trade.refund(统一收单退款页面接口)
  192. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.page.refund
  193. func (a *AliPayClient) AliPayTradePageRefund(body BodyMap) (aliRsp *AliPayTradePageRefundResponse, err error) {
  194. var (
  195. p1, p2 string
  196. bs []byte
  197. )
  198. p1 = body.Get("out_trade_no")
  199. p2 = body.Get("trade_no")
  200. if p1 == null && p2 == null {
  201. return nil, errors.New("out_trade_no and trade_no are not allowed to be null at the same time")
  202. }
  203. if bs, err = a.doAliPay(body, " alipay.trade.page.refund"); err != nil {
  204. return
  205. }
  206. aliRsp = new(AliPayTradePageRefundResponse)
  207. if err = json.Unmarshal(bs, aliRsp); err != nil {
  208. return nil, err
  209. }
  210. if aliRsp.AliPayTradePageRefundResponse.Code != "10000" {
  211. info := aliRsp.AliPayTradePageRefundResponse
  212. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  213. }
  214. aliRsp.SignData = getSignData(bs)
  215. return
  216. }
  217. //alipay.trade.precreate(统一收单线下交易预创建)
  218. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.precreate
  219. func (a *AliPayClient) AliPayTradePrecreate(body BodyMap) (aliRsp *AlipayTradePrecreateResponse, err error) {
  220. var bs []byte
  221. p := body.Get("out_trade_no")
  222. if p == null {
  223. return nil, errors.New("out_trade_no is not allowed to be null")
  224. }
  225. if bs, err = a.doAliPay(body, "alipay.trade.precreate"); err != nil {
  226. return
  227. }
  228. aliRsp = new(AlipayTradePrecreateResponse)
  229. if err = json.Unmarshal(bs, aliRsp); err != nil {
  230. return nil, err
  231. }
  232. if aliRsp.AlipayTradePrecreateResponse.Code != "10000" {
  233. info := aliRsp.AlipayTradePrecreateResponse
  234. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  235. }
  236. aliRsp.SignData = getSignData(bs)
  237. return
  238. }
  239. //alipay.trade.pay(统一收单交易支付接口)
  240. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.pay
  241. func (a *AliPayClient) AliPayTradePay(body BodyMap) (aliRsp *AliPayTradePayResponse, err error) {
  242. var bs []byte
  243. p := body.Get("out_trade_no")
  244. if p == null {
  245. return nil, errors.New("out_trade_no is not allowed to be null")
  246. }
  247. if bs, err = a.doAliPay(body, "alipay.trade.pay"); err != nil {
  248. return
  249. }
  250. aliRsp = new(AliPayTradePayResponse)
  251. if err = json.Unmarshal(bs, aliRsp); err != nil {
  252. return nil, err
  253. }
  254. if aliRsp.AliPayTradePayResponse.Code != "10000" {
  255. info := aliRsp.AliPayTradePayResponse
  256. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  257. }
  258. aliRsp.SignData = getSignData(bs)
  259. return
  260. }
  261. //alipay.trade.query(统一收单线下交易查询)
  262. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.query
  263. func (a *AliPayClient) AliPayTradeQuery(body BodyMap) (aliRsp *AliPayTradeQueryResponse, err error) {
  264. var (
  265. p1, p2 string
  266. bs []byte
  267. )
  268. p1 = body.Get("out_trade_no")
  269. p2 = body.Get("trade_no")
  270. if p1 == null && p2 == null {
  271. return nil, errors.New("out_trade_no and trade_no are not allowed to be null at the same time")
  272. }
  273. if bs, err = a.doAliPay(body, "alipay.trade.query"); err != nil {
  274. return
  275. }
  276. aliRsp = new(AliPayTradeQueryResponse)
  277. if err = json.Unmarshal(bs, aliRsp); err != nil {
  278. return nil, err
  279. }
  280. if aliRsp.AliPayTradeQueryResponse.Code != "10000" {
  281. info := aliRsp.AliPayTradeQueryResponse
  282. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  283. }
  284. aliRsp.SignData = getSignData(bs)
  285. return
  286. }
  287. //alipay.trade.app.pay(app支付接口2.0)
  288. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.app.pay
  289. func (a *AliPayClient) AliPayTradeAppPay(body BodyMap) (payParam string, err error) {
  290. var bs []byte
  291. trade := body.Get("out_trade_no")
  292. if trade == null {
  293. return null, errors.New("out_trade_no is not allowed to be null")
  294. }
  295. if bs, err = a.doAliPay(body, "alipay.trade.app.pay"); err != nil {
  296. return null, err
  297. }
  298. payParam = string(bs)
  299. return
  300. }
  301. //alipay.trade.wap.pay(手机网站支付接口2.0)
  302. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.wap.pay
  303. func (a *AliPayClient) AliPayTradeWapPay(body BodyMap) (payUrl string, err error) {
  304. var bs []byte
  305. trade := body.Get("out_trade_no")
  306. if trade == null {
  307. return null, errors.New("out_trade_no is not allowed to be null")
  308. }
  309. body.Set("product_code", "QUICK_WAP_WAY")
  310. if bs, err = a.doAliPay(body, "alipay.trade.wap.pay"); err != nil {
  311. return null, err
  312. }
  313. payUrl = string(bs)
  314. return
  315. }
  316. //alipay.trade.page.pay(统一收单下单并支付页面接口)
  317. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.page.pay
  318. func (a *AliPayClient) AliPayTradePagePay(body BodyMap) (payUrl string, err error) {
  319. var bs []byte
  320. trade := body.Get("out_trade_no")
  321. if trade == null {
  322. return null, errors.New("out_trade_no is not allowed to be null")
  323. }
  324. body.Set("product_code", "FAST_INSTANT_TRADE_PAY")
  325. if bs, err = a.doAliPay(body, "alipay.trade.page.pay"); err != nil {
  326. return null, err
  327. }
  328. payUrl = string(bs)
  329. return
  330. }
  331. //alipay.fund.trans.toaccount.transfer(单笔转账到支付宝账户接口)
  332. // 文档地址:https://docs.open.alipay.com/api_28/alipay.fund.trans.toaccount.transfer
  333. func (a *AliPayClient) AlipayFundTransToaccountTransfer(body BodyMap) (aliRsp *AlipayFundTransToaccountTransferResponse, err error) {
  334. var bs []byte
  335. trade1 := body.Get("out_biz_no")
  336. if trade1 == null {
  337. return nil, errors.New("out_biz_no is not allowed to be null")
  338. }
  339. if bs, err = a.doAliPay(body, "alipay.fund.trans.toaccount.transfer"); err != nil {
  340. return
  341. }
  342. aliRsp = new(AlipayFundTransToaccountTransferResponse)
  343. if err = json.Unmarshal(bs, aliRsp); err != nil {
  344. return nil, err
  345. }
  346. if aliRsp.AlipayFundTransToaccountTransferResponse.Code != "10000" {
  347. info := aliRsp.AlipayFundTransToaccountTransferResponse
  348. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  349. }
  350. aliRsp.SignData = getSignData(bs)
  351. return
  352. }
  353. //alipay.trade.orderinfo.sync(支付宝订单信息同步接口)
  354. // 文档地址:https://docs.open.alipay.com/api_1/alipay.trade.orderinfo.sync
  355. func (a *AliPayClient) AliPayTradeOrderinfoSync(body BodyMap) {
  356. }
  357. //alipay.system.oauth.token(换取授权访问令牌)
  358. // 文档地址:https://docs.open.alipay.com/api_9/alipay.system.oauth.token
  359. func (a *AliPayClient) AliPaySystemOauthToken(body BodyMap) (aliRsp *AliPaySystemOauthTokenResponse, err error) {
  360. var bs []byte
  361. grantType := body.Get("grant_type")
  362. if grantType == null {
  363. return nil, errors.New("grant_type is not allowed to be null")
  364. }
  365. code := body.Get("code")
  366. refreshToken := body.Get("refresh_token")
  367. if code == null && refreshToken == null {
  368. return nil, errors.New("code and refresh_token are not allowed to be null at the same time")
  369. }
  370. if bs, err = aliPaySystemOauthToken(a.AppId, a.PrivateKey, body, "alipay.system.oauth.token", a.IsProd); err != nil {
  371. return
  372. }
  373. aliRsp = new(AliPaySystemOauthTokenResponse)
  374. if err = json.Unmarshal(bs, aliRsp); err != nil {
  375. return nil, err
  376. }
  377. if aliRsp.AliPaySystemOauthTokenResponse.AccessToken == null {
  378. info := aliRsp.ErrorResponse
  379. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  380. }
  381. aliRsp.SignData = getSignData(bs)
  382. return
  383. }
  384. //alipay.user.info.share(支付宝会员授权信息查询接口)
  385. // body:此接口无需body参数
  386. // 文档地址:https://docs.open.alipay.com/api_2/alipay.user.info.share
  387. func (a *AliPayClient) AlipayUserInfoShare() (aliRsp *AlipayUserInfoShareResponse, err error) {
  388. var bs []byte
  389. if bs, err = a.doAliPay(nil, "alipay.user.info.share"); err != nil {
  390. return nil, err
  391. }
  392. aliRsp = new(AlipayUserInfoShareResponse)
  393. if err = json.Unmarshal(bs, aliRsp); err != nil {
  394. return nil, err
  395. }
  396. if aliRsp.AlipayUserInfoShareResponse.Code != "10000" {
  397. info := aliRsp.AlipayUserInfoShareResponse
  398. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  399. }
  400. aliRsp.SignData = getSignData(bs)
  401. return
  402. }
  403. //alipay.open.auth.token.app(换取应用授权令牌)
  404. // 文档地址:https://docs.open.alipay.com/api_9/alipay.open.auth.token.app
  405. func (a *AliPayClient) AlipayOpenAuthTokenApp(body BodyMap) (aliRsp *AlipayOpenAuthTokenAppResponse, err error) {
  406. var bs []byte
  407. grantType := body.Get("grant_type")
  408. if grantType == null {
  409. return nil, errors.New("grant_type is not allowed to be null")
  410. }
  411. code := body.Get("code")
  412. refreshToken := body.Get("refresh_token")
  413. if code == null && refreshToken == null {
  414. return nil, errors.New("code and refresh_token are not allowed to be null at the same time")
  415. }
  416. if bs, err = a.doAliPay(body, "alipay.open.auth.token.app"); err != nil {
  417. return
  418. }
  419. aliRsp = new(AlipayOpenAuthTokenAppResponse)
  420. if err = json.Unmarshal(bs, aliRsp); err != nil {
  421. return nil, err
  422. }
  423. if aliRsp.AlipayOpenAuthTokenAppResponse.Code != "10000" {
  424. info := aliRsp.AlipayOpenAuthTokenAppResponse
  425. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  426. }
  427. aliRsp.SignData = getSignData(bs)
  428. return
  429. }
  430. //zhima.credit.score.get(芝麻分)
  431. // 文档地址:https://docs.open.alipay.com/api_8/zhima.credit.score.get
  432. func (a *AliPayClient) ZhimaCreditScoreGet(body BodyMap) (aliRsp *ZhimaCreditScoreGetResponse, err error) {
  433. var (
  434. p1, p2 string
  435. bs []byte
  436. )
  437. if p1 = body.Get("product_code"); p1 == null {
  438. body.Set("product_code", "w1010100100000000001")
  439. }
  440. if p2 = body.Get("transaction_id"); p2 == null {
  441. return nil, errors.New("transaction_id is not allowed to be null")
  442. }
  443. if bs, err = a.doAliPay(body, "zhima.credit.score.get"); err != nil {
  444. return
  445. }
  446. aliRsp = new(ZhimaCreditScoreGetResponse)
  447. if err = json.Unmarshal(bs, aliRsp); err != nil {
  448. return nil, err
  449. }
  450. if aliRsp.ZhimaCreditScoreGetResponse.Code != "10000" {
  451. info := aliRsp.ZhimaCreditScoreGetResponse
  452. return nil, fmt.Errorf(`{"code":"%v","msg":"%v","sub_code":"%v","sub_msg":"%v"}`, info.Code, info.Msg, info.SubCode, info.SubMsg)
  453. }
  454. aliRsp.SignData = getSignData(bs)
  455. return
  456. }
  457. //向支付宝发送请求
  458. func (a *AliPayClient) doAliPay(body BodyMap, method string) (bytes []byte, err error) {
  459. var (
  460. bodyStr, sign, url, urlParam string
  461. bodyBs []byte
  462. res gorequest.Response
  463. errs []error
  464. )
  465. if body != nil {
  466. if bodyBs, err = json.Marshal(body); err != nil {
  467. return nil, fmt.Errorf("json.Marshal:%v", err.Error())
  468. }
  469. bodyStr = string(bodyBs)
  470. }
  471. pubBody := make(BodyMap)
  472. pubBody.Set("app_id", a.AppId)
  473. pubBody.Set("method", method)
  474. pubBody.Set("format", "JSON")
  475. if a.AppCertSN != null {
  476. pubBody.Set("app_cert_sn", a.AppCertSN)
  477. }
  478. if a.AlipayRootCertSN != null {
  479. pubBody.Set("alipay_root_cert_sn", a.AlipayRootCertSN)
  480. }
  481. if a.ReturnUrl != null {
  482. pubBody.Set("return_url", a.ReturnUrl)
  483. }
  484. if a.Charset == null {
  485. pubBody.Set("charset", "utf-8")
  486. } else {
  487. pubBody.Set("charset", a.Charset)
  488. }
  489. if a.SignType == null {
  490. pubBody.Set("sign_type", "RSA2")
  491. } else {
  492. pubBody.Set("sign_type", a.SignType)
  493. }
  494. pubBody.Set("timestamp", time.Now().Format(TimeLayout))
  495. pubBody.Set("version", "1.0")
  496. if a.NotifyUrl != null {
  497. pubBody.Set("notify_url", a.NotifyUrl)
  498. }
  499. if a.AppAuthToken != null {
  500. pubBody.Set("app_auth_token", a.AppAuthToken)
  501. }
  502. if a.AuthToken != null {
  503. pubBody.Set("auth_token", a.AuthToken)
  504. }
  505. if bodyStr != null {
  506. pubBody.Set("biz_content", bodyStr)
  507. }
  508. if sign, err = getRsaSign(pubBody, pubBody.Get("sign_type"), FormatPrivateKey(a.PrivateKey)); err != nil {
  509. return
  510. }
  511. pubBody.Set("sign", sign)
  512. urlParam = FormatAliPayURLParam(pubBody)
  513. if method == "alipay.trade.app.pay" {
  514. return []byte(urlParam), nil
  515. }
  516. if method == "alipay.trade.page.pay" {
  517. if !a.IsProd {
  518. return []byte(zfbSandboxBaseUrl + "?" + urlParam), nil
  519. } else {
  520. return []byte(zfbBaseUrl + "?" + urlParam), nil
  521. }
  522. }
  523. agent := HttpAgent()
  524. if !a.IsProd {
  525. url = zfbSandboxBaseUrlUtf8
  526. } else {
  527. url = zfbBaseUrlUtf8
  528. }
  529. if res, bytes, errs = agent.Post(url).Type("form-data").SendString(urlParam).EndBytes(); len(errs) > 0 {
  530. return nil, errs[0]
  531. }
  532. if res.StatusCode != 200 {
  533. return nil, fmt.Errorf("HTTP Request Error, StatusCode = %v", res.StatusCode)
  534. }
  535. if method == "alipay.trade.wap.pay" {
  536. if res.Request.URL.String() == zfbSandboxBaseUrl || res.Request.URL.String() == zfbBaseUrl {
  537. return nil, errors.New("alipay.trade.wap.pay error,please check the parameters")
  538. }
  539. return []byte(res.Request.URL.String()), nil
  540. }
  541. return
  542. }
  543. func getSignData(bs []byte) (signData string) {
  544. str := string(bs)
  545. indexStart := strings.Index(str, `":`)
  546. indexEnd := strings.Index(str, `,"sign"`)
  547. signData = str[indexStart+2 : indexEnd]
  548. return
  549. }