支付模块
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 13 KiB

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
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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  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("credit_biz_order_id", args["credit_biz_order_id"])
  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. //扣款
  212. func AlipayTradePay(args map[string]string) (*md.AlipayTradePay, error) {
  213. client := Comm(args)
  214. if args["notify_url"] != "" {
  215. client.NotifyUrl = args["notify_url"]
  216. }
  217. if client == nil {
  218. return nil, errors.New("获取失败")
  219. }
  220. //请求参数
  221. bm := make(gopay.BodyMap)
  222. // biz_content
  223. extendParams := map[string]string{
  224. "creditTradeScene": args["creditTradeScene"],
  225. }
  226. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  227. bz.Set("out_trade_no", args["out_trade_no"])
  228. bz.Set("is_async_pay", args["is_async_pay"])
  229. bz.Set("total_amount", args["total_amount"])
  230. bz.Set("auth_code", args["auth_code"])
  231. bz.Set("product_code", args["product_code"])
  232. bz.Set("scene", args["scene"])
  233. bz.Set("subject", args["subject"])
  234. bz.Set("extend_params", extendParams)
  235. })
  236. var aliPsp md.AlipayTradePay
  237. v2, err := PostAliPayAPISelfV2(client, bm, "alipay.trade.pay", &aliPsp)
  238. if err != nil {
  239. xlog.Error(err)
  240. return nil, err
  241. }
  242. res := v2.(*md.AlipayTradePay)
  243. return res, nil
  244. }
  245. func AlipayTradeQuery(args map[string]string) (*md.AlipayFundTransUniTransfer, error) {
  246. client := Comm(args)
  247. if client == nil {
  248. return nil, errors.New("获取失败")
  249. }
  250. //请求参数
  251. bm := make(gopay.BodyMap)
  252. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  253. bz.Set("out_trade_no", args["out_trade_no"])
  254. })
  255. var aliPsp md.AlipayFundTransUniTransfer
  256. bs, err := PostAliPayAPISelfV2(client, bm, "alipay.trade.query", &aliPsp)
  257. if err != nil {
  258. xlog.Error(err)
  259. return nil, err
  260. }
  261. res := bs.(*md.AlipayFundTransUniTransfer)
  262. return res, nil
  263. }
  264. //结束信用服务订单
  265. func CreditagreementOrderFinish(args map[string]string) (*md.ZhimaCreditPayafteruseCreditbizorderFinish, error) {
  266. client := Comm(args)
  267. client.AppAuthToken = args["app_auth_token"]
  268. if client == nil {
  269. return nil, errors.New("获取失败")
  270. }
  271. //请求参数
  272. bm := make(gopay.BodyMap)
  273. // biz_content
  274. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  275. bz.Set("out_request_no", args["out_request_no"])
  276. bz.Set("credit_biz_order_id", args["credit_biz_order_id"])
  277. bz.Set("is_fulfilled", args["is_fulfilled"])
  278. bz.Set("remark", args["remark"])
  279. })
  280. var aliPsp md.ZhimaCreditPayafteruseCreditbizorderFinish
  281. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditbizorder.finish", &aliPsp)
  282. if err != nil {
  283. xlog.Error(err)
  284. return nil, err
  285. }
  286. res := bs.(*md.ZhimaCreditPayafteruseCreditbizorderFinish)
  287. return res, nil
  288. }
  289. func PostAliPayAPISelfV2(a *alipay.Client, bm gopay.BodyMap, method string, aliRsp interface{}) (aliRsps interface{}, err error) {
  290. var (
  291. bs, bodyBs []byte
  292. )
  293. // check if there is biz_content
  294. bz := bm.GetInterface("biz_content")
  295. if bzBody, ok := bz.(gopay.BodyMap); ok {
  296. if bodyBs, err = json.Marshal(bzBody); err != nil {
  297. return aliRsp, fmt.Errorf("json.Marshal(%v):%w", bzBody, err)
  298. }
  299. bm.Set("biz_content", string(bodyBs))
  300. }
  301. if bs, err = doAliPaySelf(a, bm, method); err != nil {
  302. return aliRsp, err
  303. }
  304. switch method {
  305. case "alipay.trade.app.pay":
  306. return string(bs), nil
  307. case "alipay.trade.wap.pay", "alipay.trade.page.pay", "alipay.user.certify.open.certify", "zhima.credit.payafteruse.creditagreement.sign":
  308. return string(bs), nil
  309. default:
  310. if err = json.Unmarshal(bs, aliRsp); err != nil {
  311. return aliRsp, err
  312. }
  313. return aliRsp, nil
  314. }
  315. }
  316. // 向支付宝发送自定义请求
  317. func doAliPaySelf(a *alipay.Client, bm gopay.BodyMap, method string) (bs []byte, err error) {
  318. var (
  319. url, sign string
  320. )
  321. bm.Set("method", method)
  322. // check public parameter
  323. checkPublicParam(a, bm)
  324. // check sign
  325. if bm.GetString("sign") == "" {
  326. sign, err = alipay.GetRsaSign(bm, bm.GetString("sign_type"), a.PrivateKeyType, a.PrivateKey)
  327. if err != nil {
  328. return nil, fmt.Errorf("GetRsaSign Error: %v", err)
  329. }
  330. bm.Set("sign", sign)
  331. }
  332. if a.DebugSwitch == gopay.DebugOn {
  333. req, _ := json.Marshal(bm)
  334. xlog.Debugf("Alipay_Request: %s", req)
  335. }
  336. param := alipay.FormatURLParam(bm)
  337. switch method {
  338. case "alipay.trade.app.pay":
  339. return []byte(param), nil
  340. case "alipay.trade.wap.pay", "alipay.trade.page.pay", "alipay.user.certify.open.certify", "zhima.credit.payafteruse.creditagreement.sign":
  341. return []byte(baseUrl + "?" + param), nil
  342. default:
  343. httpClient := xhttp.NewClient()
  344. url = baseUrlUtf8
  345. res, bs, errs := httpClient.Type(xhttp.TypeForm).Post(url).SendString(param).EndBytes()
  346. if len(errs) > 0 {
  347. return nil, errs[0]
  348. }
  349. if a.DebugSwitch == gopay.DebugOn {
  350. xlog.Debugf("Alipay_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
  351. }
  352. if res.StatusCode != 200 {
  353. return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
  354. }
  355. return bs, nil
  356. }
  357. }
  358. func checkPublicParam(a *alipay.Client, bm gopay.BodyMap) {
  359. bm.Set("format", "JSON")
  360. if bm.GetString("app_id") == "" && a.AppId != util.NULL {
  361. bm.Set("app_id", a.AppId)
  362. }
  363. if bm.GetString("app_cert_sn") == "" && a.AppCertSN != util.NULL {
  364. bm.Set("app_cert_sn", a.AppCertSN)
  365. }
  366. if bm.GetString("alipay_root_cert_sn") == "" && a.AliPayRootCertSN != util.NULL {
  367. bm.Set("alipay_root_cert_sn", a.AliPayRootCertSN)
  368. }
  369. if bm.GetString("return_url") == "" && a.ReturnUrl != util.NULL {
  370. bm.Set("return_url", a.ReturnUrl)
  371. }
  372. bm.Set("charset", "utf-8")
  373. if bm.GetString("charset") == "" && a.Charset != util.NULL {
  374. bm.Set("charset", a.Charset)
  375. }
  376. bm.Set("sign_type", alipay.RSA2)
  377. if bm.GetString("sign_type") == "" && a.SignType != util.NULL {
  378. bm.Set("sign_type", a.SignType)
  379. }
  380. bm.Set("timestamp", time.Now().Format(util.TimeLayout))
  381. bm.Set("version", "1.0")
  382. if bm.GetString("notify_url") == "" && a.NotifyUrl != util.NULL {
  383. bm.Set("notify_url", a.NotifyUrl)
  384. }
  385. if bm.GetString("app_auth_token") == "" && a.AppAuthToken != util.NULL {
  386. bm.Set("app_auth_token", a.AppAuthToken)
  387. }
  388. if bm.GetString("auth_token") == "" && a.AuthToken != util.NULL {
  389. bm.Set("auth_token", a.AuthToken)
  390. }
  391. }
  392. //原路退回
  393. func AlipayTradeRefund(args map[string]string) (*md.AlipayTradeRefund, error) {
  394. client := Comm(args)
  395. if client == nil {
  396. return nil, errors.New("获取失败")
  397. }
  398. //请求参数
  399. bm := make(gopay.BodyMap)
  400. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  401. bz.Set("trade_no", args["trade_no"])
  402. bz.Set("refund_amount", args["refund_amount"])
  403. bz.Set("refund_reason", args["refund_reason"])
  404. bz.Set("out_request_no", args["out_request_no"])
  405. })
  406. var aliPsp md.AlipayTradeRefund
  407. v2, err := PostAliPayAPISelfV2(client, bm, "alipay.trade.refund", &aliPsp)
  408. if err != nil {
  409. xlog.Error(err)
  410. return nil, err
  411. }
  412. res := v2.(*md.AlipayTradeRefund)
  413. return res, nil
  414. }