支付模块
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

alipay.go 14 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 weeks ago
1 year ago
2 weeks ago
1 year ago
10 months ago
1 year ago
2 weeks ago
1 year ago
9 months ago
1 year ago
2 weeks ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 weeks ago
1 year ago
11 months ago
2 weeks ago
11 months ago
11 months ago
11 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. package pay
  2. import (
  3. "code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/md"
  4. zhios_pay_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/utils"
  5. "encoding/json"
  6. "errors"
  7. "fmt"
  8. "github.com/iGoogle-ink/gopay"
  9. "github.com/iGoogle-ink/gopay/alipay"
  10. "github.com/iGoogle-ink/gopay/pkg/util"
  11. "github.com/iGoogle-ink/gopay/pkg/xhttp"
  12. "github.com/iGoogle-ink/gopay/pkg/xlog"
  13. "time"
  14. )
  15. const (
  16. baseUrl = "https://openapi.alipay.com/gateway.do"
  17. sandboxBaseUrl = "https://openapi.alipaydev.com/gateway.do"
  18. baseUrlUtf8 = "https://openapi.alipay.com/gateway.do?charset=utf-8"
  19. sandboxBaseUrlUtf8 = "https://openapi.alipaydev.com/gateway.do?charset=utf-8"
  20. )
  21. func Comm(args map[string]string) *alipay.Client {
  22. paySet := AlipayCofing(args)
  23. if args["private_key"] == "" || args["app_id"] == "" {
  24. return nil
  25. }
  26. //初始化支付宝客户端
  27. // appID 是在支付宝申请的APPID
  28. // priKey 是支付宝私钥
  29. // code 支付宝授权码
  30. client := alipay.NewClient(args["app_id"], args["private_key"], true)
  31. client.DebugSwitch = gopay.DebugOn
  32. //判断密钥的类型
  33. rsa_type := alipay.RSA2
  34. pkcs_type := alipay.PKCS1
  35. if args["rsa"] == "1" {
  36. rsa_type = alipay.RSA
  37. }
  38. if args["pkcs"] == "1" {
  39. pkcs_type = alipay.PKCS8
  40. }
  41. if paySet.PayAliUseType == "1" {
  42. rsa_type = alipay.RSA2
  43. pkcs_type = alipay.PKCS8
  44. }
  45. //配置公共参数
  46. client.SetCharset("utf-8").
  47. SetSignType(rsa_type).
  48. SetPrivateKeyType(pkcs_type)
  49. //新支付宝支付
  50. if paySet.PayAliUseType == "1" {
  51. client.SetAppCertSN(paySet.PayAppCertSn)
  52. aliPayRootCertSN := "687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6"
  53. client.SetAliPayRootCertSN(aliPayRootCertSN)
  54. client.SetAliPayPublicCertSN(paySet.PayAlipayrsaPublicKey)
  55. }
  56. client.IsProd = true
  57. fmt.Println(client)
  58. return client
  59. }
  60. func OpenAuthTokenApp(args map[string]string) (*alipay.SystemOauthTokenResponse, error) {
  61. client := Comm(args)
  62. if client == nil {
  63. return nil, errors.New("获取失败")
  64. }
  65. //请求参数
  66. body := make(gopay.BodyMap)
  67. body.Set("grant_type", "authorization_code")
  68. body.Set("code", args["code"])
  69. payParam, err := client.SystemOauthToken(body)
  70. if err != nil {
  71. return nil, err
  72. }
  73. return payParam, nil
  74. }
  75. func UserInfoShare(args map[string]string) (*alipay.UserInfoShareResponse, error) {
  76. client := Comm(args)
  77. client.AuthToken = args["auth_token"]
  78. if client == nil {
  79. return nil, errors.New("获取失败")
  80. }
  81. payParam, err := client.UserInfoShare()
  82. if err != nil {
  83. return nil, err
  84. }
  85. return payParam, nil
  86. }
  87. func CreditagreementSign(args map[string]string) (string, error) {
  88. client := Comm(args)
  89. client.AppAuthToken = args["app_auth_token"]
  90. if client == nil {
  91. return "", errors.New("获取失败")
  92. }
  93. //请求参数
  94. bm := make(gopay.BodyMap)
  95. // biz_content
  96. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  97. bz.Set("out_agreement_no", args["out_agreement_no"])
  98. bz.Set("zm_service_id", args["zm_service_id"])
  99. bz.Set("category_id", args["category_id"])
  100. bz.Set("return_back_link", args["return_back_link"])
  101. })
  102. aliPsp := ""
  103. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditagreement.sign", &aliPsp)
  104. if err != nil {
  105. xlog.Error(err)
  106. return "", err
  107. }
  108. return zhios_pay_utils.AnyToString(bs), nil
  109. }
  110. func CreditagreementQuery(args map[string]string) (*md.ZhimaCreditPayafteruseCreditagreementQuery, error) {
  111. client := Comm(args)
  112. client.AppAuthToken = args["app_auth_token"]
  113. if client == nil {
  114. return nil, errors.New("获取失败")
  115. }
  116. //请求参数
  117. bm := make(gopay.BodyMap)
  118. // biz_content
  119. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  120. bz.Set("out_agreement_no", args["out_agreement_no"])
  121. })
  122. var aliPsp md.ZhimaCreditPayafteruseCreditagreementQuery
  123. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditagreement.query", &aliPsp)
  124. if err != nil {
  125. xlog.Error(err)
  126. return nil, err
  127. }
  128. res := bs.(*md.ZhimaCreditPayafteruseCreditagreementQuery)
  129. return res, nil
  130. }
  131. // 信用下单
  132. func CreditagreementOrder(args map[string]string) (*md.ZhimaCreditPayafteruseCreditbizorderOrder, error) {
  133. client := Comm(args)
  134. client.AppAuthToken = args["app_auth_token"]
  135. if client == nil {
  136. return nil, errors.New("获取失败")
  137. }
  138. //请求参数
  139. bm := make(gopay.BodyMap)
  140. // biz_content
  141. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  142. bz.Set("out_order_no", args["out_order_no"])
  143. bz.Set("credit_agreement_id", args["credit_agreement_id"])
  144. bz.Set("category_id", args["category_id"])
  145. bz.Set("order_amount", args["order_amount"])
  146. bz.Set("amount_type", args["amount_type"])
  147. bz.Set("subject", args["subject"])
  148. })
  149. var aliPsp md.ZhimaCreditPayafteruseCreditbizorderOrder
  150. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditbizorder.order", &aliPsp)
  151. if err != nil {
  152. xlog.Error(err)
  153. return nil, err
  154. }
  155. res := bs.(*md.ZhimaCreditPayafteruseCreditbizorderOrder)
  156. return res, nil
  157. }
  158. // 查询信用订单
  159. func CreditagreementOrderQuery(args map[string]string) (*md.ZhimaCreditPayafteruseCreditbizorderQuery, error) {
  160. client := Comm(args)
  161. client.AppAuthToken = args["app_auth_token"]
  162. if client == nil {
  163. return nil, errors.New("获取失败")
  164. }
  165. //请求参数
  166. bm := make(gopay.BodyMap)
  167. // biz_content
  168. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  169. bz.Set("out_order_no", args["out_request_no"])
  170. })
  171. var aliPsp md.ZhimaCreditPayafteruseCreditbizorderQuery
  172. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditbizorder.query", &aliPsp)
  173. if err != nil {
  174. xlog.Error(err)
  175. return nil, err
  176. }
  177. res := bs.(*md.ZhimaCreditPayafteruseCreditbizorderQuery)
  178. return res, nil
  179. }
  180. // 转账
  181. func AlipayFundTransUniTransfer(args map[string]string) (*md.AlipayFundTransUniTransfer, error) {
  182. client := Comm(args)
  183. if client == nil {
  184. return nil, errors.New("获取失败")
  185. }
  186. //请求参数
  187. bm := make(gopay.BodyMap)
  188. // biz_content
  189. payeeInfo := map[string]string{
  190. "identity": args["identity"],
  191. "identity_type": args["identity_type"],
  192. "name": args["name"],
  193. }
  194. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  195. bz.Set("out_biz_no", args["out_biz_no"])
  196. bz.Set("trans_amount", args["trans_amount"])
  197. bz.Set("product_code", args["product_code"])
  198. bz.Set("biz_scene", args["biz_scene"])
  199. bz.Set("order_title", args["order_title"])
  200. bz.Set("payee_info", payeeInfo)
  201. })
  202. var aliPsp md.AlipayFundTransUniTransfer
  203. bs, err := PostAliPayAPISelfV2(client, bm, "alipay.fund.trans.uni.transfer", &aliPsp)
  204. if err != nil {
  205. xlog.Error(err)
  206. return nil, err
  207. }
  208. res := bs.(*md.AlipayFundTransUniTransfer)
  209. return res, nil
  210. }
  211. func AlipayFundTransCommonQuery(args map[string]string) (*md.AlipayFundTransCommonQuery, error) {
  212. client := Comm(args)
  213. if client == nil {
  214. return nil, errors.New("获取失败")
  215. }
  216. //请求参数
  217. bm := make(gopay.BodyMap)
  218. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  219. bz.Set("out_biz_no", args["out_biz_no"])
  220. bz.Set("product_code", args["product_code"])
  221. bz.Set("biz_scene", args["biz_scene"])
  222. })
  223. var aliPsp md.AlipayFundTransCommonQuery
  224. bs, err := PostAliPayAPISelfV2(client, bm, "alipay.fund.trans.common.query", &aliPsp)
  225. if err != nil {
  226. xlog.Error(err)
  227. return nil, err
  228. }
  229. res := bs.(*md.AlipayFundTransCommonQuery)
  230. return res, nil
  231. }
  232. // 扣款
  233. func AlipayTradePay(args map[string]string) (*md.AlipayTradePay, error) {
  234. client := Comm(args)
  235. if args["notify_url"] != "" {
  236. client.NotifyUrl = args["notify_url"]
  237. }
  238. if client == nil {
  239. return nil, errors.New("获取失败")
  240. }
  241. //请求参数
  242. bm := make(gopay.BodyMap)
  243. // biz_content
  244. extendParams := map[string]string{
  245. "creditTradeScene": args["creditTradeScene"],
  246. }
  247. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  248. bz.Set("out_trade_no", args["out_trade_no"])
  249. bz.Set("is_async_pay", args["is_async_pay"])
  250. bz.Set("total_amount", args["total_amount"])
  251. bz.Set("auth_code", args["auth_code"])
  252. bz.Set("product_code", args["product_code"])
  253. bz.Set("scene", args["scene"])
  254. bz.Set("subject", args["subject"])
  255. bz.Set("extend_params", extendParams)
  256. })
  257. var aliPsp md.AlipayTradePay
  258. v2, err := PostAliPayAPISelfV2(client, bm, "alipay.trade.pay", &aliPsp)
  259. if err != nil {
  260. xlog.Error(err)
  261. return nil, err
  262. }
  263. res := v2.(*md.AlipayTradePay)
  264. return res, nil
  265. }
  266. func AlipayTradeQuery(args map[string]string) (*md.AlipayFundTransUniTransfer, error) {
  267. client := Comm(args)
  268. if client == nil {
  269. return nil, errors.New("获取失败")
  270. }
  271. //请求参数
  272. bm := make(gopay.BodyMap)
  273. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  274. bz.Set("out_trade_no", args["out_trade_no"])
  275. })
  276. var aliPsp md.AlipayFundTransUniTransfer
  277. bs, err := PostAliPayAPISelfV2(client, bm, "alipay.trade.query", &aliPsp)
  278. if err != nil {
  279. xlog.Error(err)
  280. return nil, err
  281. }
  282. res := bs.(*md.AlipayFundTransUniTransfer)
  283. return res, nil
  284. }
  285. // 结束信用服务订单
  286. func CreditagreementOrderFinish(args map[string]string) (*md.ZhimaCreditPayafteruseCreditbizorderFinish, error) {
  287. client := Comm(args)
  288. client.AppAuthToken = args["app_auth_token"]
  289. if client == nil {
  290. return nil, errors.New("获取失败")
  291. }
  292. //请求参数
  293. bm := make(gopay.BodyMap)
  294. // biz_content
  295. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  296. bz.Set("out_request_no", args["out_request_no"])
  297. bz.Set("credit_biz_order_id", args["credit_biz_order_id"])
  298. bz.Set("is_fulfilled", args["is_fulfilled"])
  299. bz.Set("remark", args["remark"])
  300. })
  301. var aliPsp md.ZhimaCreditPayafteruseCreditbizorderFinish
  302. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditbizorder.finish", &aliPsp)
  303. if err != nil {
  304. xlog.Error(err)
  305. return nil, err
  306. }
  307. res := bs.(*md.ZhimaCreditPayafteruseCreditbizorderFinish)
  308. return res, nil
  309. }
  310. func PostAliPayAPISelfV2(a *alipay.Client, bm gopay.BodyMap, method string, aliRsp interface{}) (aliRsps interface{}, err error) {
  311. var (
  312. bs, bodyBs []byte
  313. )
  314. // check if there is biz_content
  315. bz := bm.GetInterface("biz_content")
  316. if bzBody, ok := bz.(gopay.BodyMap); ok {
  317. if bodyBs, err = json.Marshal(bzBody); err != nil {
  318. return aliRsp, fmt.Errorf("json.Marshal(%v):%w", bzBody, err)
  319. }
  320. bm.Set("biz_content", string(bodyBs))
  321. }
  322. if bs, err = doAliPaySelf(a, bm, method); err != nil {
  323. return aliRsp, err
  324. }
  325. switch method {
  326. case "alipay.trade.app.pay":
  327. return string(bs), nil
  328. case "alipay.trade.wap.pay", "alipay.trade.page.pay", "alipay.user.certify.open.certify", "zhima.credit.payafteruse.creditagreement.sign":
  329. return string(bs), nil
  330. default:
  331. if err = json.Unmarshal(bs, aliRsp); err != nil {
  332. return aliRsp, err
  333. }
  334. return aliRsp, nil
  335. }
  336. }
  337. // 向支付宝发送自定义请求
  338. func doAliPaySelf(a *alipay.Client, bm gopay.BodyMap, method string) (bs []byte, err error) {
  339. var (
  340. url, sign string
  341. )
  342. bm.Set("method", method)
  343. // check public parameter
  344. checkPublicParam(a, bm)
  345. // check sign
  346. if bm.GetString("sign") == "" {
  347. sign, err = alipay.GetRsaSign(bm, bm.GetString("sign_type"), a.PrivateKeyType, a.PrivateKey)
  348. if err != nil {
  349. return nil, fmt.Errorf("GetRsaSign Error: %v", err)
  350. }
  351. bm.Set("sign", sign)
  352. }
  353. if a.DebugSwitch == gopay.DebugOn {
  354. req, _ := json.Marshal(bm)
  355. xlog.Debugf("Alipay_Request: %s", req)
  356. }
  357. param := alipay.FormatURLParam(bm)
  358. switch method {
  359. case "alipay.trade.app.pay":
  360. return []byte(param), nil
  361. case "alipay.trade.wap.pay", "alipay.trade.page.pay", "alipay.user.certify.open.certify", "zhima.credit.payafteruse.creditagreement.sign":
  362. return []byte(baseUrl + "?" + param), nil
  363. default:
  364. httpClient := xhttp.NewClient()
  365. url = baseUrlUtf8
  366. res, bs, errs := httpClient.Type(xhttp.TypeForm).Post(url).SendString(param).EndBytes()
  367. if len(errs) > 0 {
  368. return nil, errs[0]
  369. }
  370. if a.DebugSwitch == gopay.DebugOn {
  371. xlog.Debugf("Alipay_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
  372. }
  373. if res.StatusCode != 200 {
  374. return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
  375. }
  376. return bs, nil
  377. }
  378. }
  379. func checkPublicParam(a *alipay.Client, bm gopay.BodyMap) {
  380. bm.Set("format", "JSON")
  381. if bm.GetString("app_id") == "" && a.AppId != util.NULL {
  382. bm.Set("app_id", a.AppId)
  383. }
  384. if bm.GetString("app_cert_sn") == "" && a.AppCertSN != util.NULL {
  385. bm.Set("app_cert_sn", a.AppCertSN)
  386. }
  387. if bm.GetString("alipay_root_cert_sn") == "" && a.AliPayRootCertSN != util.NULL {
  388. bm.Set("alipay_root_cert_sn", a.AliPayRootCertSN)
  389. }
  390. if bm.GetString("return_url") == "" && a.ReturnUrl != util.NULL {
  391. bm.Set("return_url", a.ReturnUrl)
  392. }
  393. bm.Set("charset", "utf-8")
  394. if bm.GetString("charset") == "" && a.Charset != util.NULL {
  395. bm.Set("charset", a.Charset)
  396. }
  397. bm.Set("sign_type", alipay.RSA2)
  398. if bm.GetString("sign_type") == "" && a.SignType != util.NULL {
  399. bm.Set("sign_type", a.SignType)
  400. }
  401. bm.Set("timestamp", time.Now().Format(util.TimeLayout))
  402. bm.Set("version", "1.0")
  403. if bm.GetString("notify_url") == "" && a.NotifyUrl != util.NULL {
  404. bm.Set("notify_url", a.NotifyUrl)
  405. }
  406. if bm.GetString("app_auth_token") == "" && a.AppAuthToken != util.NULL {
  407. bm.Set("app_auth_token", a.AppAuthToken)
  408. }
  409. if bm.GetString("auth_token") == "" && a.AuthToken != util.NULL {
  410. bm.Set("auth_token", a.AuthToken)
  411. }
  412. }
  413. // 原路退回
  414. func AlipayTradeRefund(args map[string]string) (*md.AlipayTradeRefund, error) {
  415. client := Comm(args)
  416. if client == nil {
  417. return nil, errors.New("获取失败")
  418. }
  419. //请求参数
  420. bm := make(gopay.BodyMap)
  421. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  422. bz.Set("trade_no", args["trade_no"])
  423. bz.Set("refund_amount", args["refund_amount"])
  424. bz.Set("refund_reason", args["refund_reason"])
  425. bz.Set("out_request_no", args["out_request_no"])
  426. })
  427. var aliPsp md.AlipayTradeRefund
  428. v2, err := PostAliPayAPISelfV2(client, bm, "alipay.trade.refund", &aliPsp)
  429. if err != nil {
  430. xlog.Error(err)
  431. return nil, err
  432. }
  433. res := v2.(*md.AlipayTradeRefund)
  434. return res, nil
  435. }