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

417 line
12 KiB

  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. })
  101. aliPsp := ""
  102. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditagreement.sign", &aliPsp)
  103. if err != nil {
  104. xlog.Error(err)
  105. return "", err
  106. }
  107. return zhios_pay_utils.AnyToString(bs), nil
  108. }
  109. func CreditagreementQuery(args map[string]string) (*md.ZhimaCreditPayafteruseCreditagreementQuery, error) {
  110. client := Comm(args)
  111. client.AppAuthToken = args["app_auth_token"]
  112. if client == nil {
  113. return nil, errors.New("获取失败")
  114. }
  115. //请求参数
  116. bm := make(gopay.BodyMap)
  117. // biz_content
  118. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  119. bz.Set("out_agreement_no", args["out_agreement_no"])
  120. })
  121. var aliPsp md.ZhimaCreditPayafteruseCreditagreementQuery
  122. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditagreement.query", &aliPsp)
  123. if err != nil {
  124. xlog.Error(err)
  125. return nil, err
  126. }
  127. res := bs.(*md.ZhimaCreditPayafteruseCreditagreementQuery)
  128. return res, nil
  129. }
  130. //信用下单
  131. func CreditagreementOrder(args map[string]string) (*md.ZhimaCreditPayafteruseCreditbizorderOrder, error) {
  132. client := Comm(args)
  133. client.AppAuthToken = args["app_auth_token"]
  134. if client == nil {
  135. return nil, errors.New("获取失败")
  136. }
  137. //请求参数
  138. bm := make(gopay.BodyMap)
  139. // biz_content
  140. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  141. bz.Set("out_order_no", args["out_order_no"])
  142. bz.Set("credit_agreement_id", args["credit_agreement_id"])
  143. bz.Set("category_id", args["category_id"])
  144. bz.Set("order_amount", args["order_amount"])
  145. bz.Set("amount_type", args["amount_type"])
  146. bz.Set("subject", args["subject"])
  147. })
  148. var aliPsp md.ZhimaCreditPayafteruseCreditbizorderOrder
  149. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditbizorder.order", &aliPsp)
  150. if err != nil {
  151. xlog.Error(err)
  152. return nil, err
  153. }
  154. res := bs.(*md.ZhimaCreditPayafteruseCreditbizorderOrder)
  155. return res, nil
  156. }
  157. //查询信用订单
  158. func CreditagreementOrderQuery(args map[string]string) (*md.ZhimaCreditPayafteruseCreditbizorderQuery, error) {
  159. client := Comm(args)
  160. client.AppAuthToken = args["app_auth_token"]
  161. if client == nil {
  162. return nil, errors.New("获取失败")
  163. }
  164. //请求参数
  165. bm := make(gopay.BodyMap)
  166. // biz_content
  167. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  168. bz.Set("credit_biz_order_id", args["credit_biz_order_id"])
  169. })
  170. var aliPsp md.ZhimaCreditPayafteruseCreditbizorderQuery
  171. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditbizorder.query", &aliPsp)
  172. if err != nil {
  173. xlog.Error(err)
  174. return nil, err
  175. }
  176. res := bs.(*md.ZhimaCreditPayafteruseCreditbizorderQuery)
  177. return res, nil
  178. }
  179. //转账
  180. func AlipayFundTransUniTransfer(args map[string]string) (*md.AlipayFundTransUniTransfer, error) {
  181. client := Comm(args)
  182. if client == nil {
  183. return nil, errors.New("获取失败")
  184. }
  185. //请求参数
  186. bm := make(gopay.BodyMap)
  187. // biz_content
  188. payeeInfo := map[string]string{
  189. "identity": args["identity"],
  190. "identity_type": args["identity_type"],
  191. "name": args["name"],
  192. }
  193. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  194. bz.Set("out_biz_no", args["out_biz_no"])
  195. bz.Set("trans_amount", args["trans_amount"])
  196. bz.Set("product_code", args["product_code"])
  197. bz.Set("biz_scene", args["biz_scene"])
  198. bz.Set("order_title", args["order_title"])
  199. bz.Set("payee_info", payeeInfo)
  200. })
  201. var aliPsp md.AlipayFundTransUniTransfer
  202. bs, err := PostAliPayAPISelfV2(client, bm, "alipay.fund.trans.uni.transfer", &aliPsp)
  203. if err != nil {
  204. xlog.Error(err)
  205. return nil, err
  206. }
  207. res := bs.(*md.AlipayFundTransUniTransfer)
  208. return res, nil
  209. }
  210. //扣款
  211. func AlipayTradePay(args map[string]string) (*md.AlipayTradePay, error) {
  212. client := Comm(args)
  213. if args["notify_url"] != "" {
  214. client.NotifyUrl = args["notify_url"]
  215. }
  216. if client == nil {
  217. return nil, errors.New("获取失败")
  218. }
  219. //请求参数
  220. bm := make(gopay.BodyMap)
  221. // biz_content
  222. extendParams := map[string]string{
  223. "creditTradeScene": args["creditTradeScene"],
  224. }
  225. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  226. bz.Set("out_trade_no", args["out_trade_no"])
  227. bz.Set("is_async_pay", args["is_async_pay"])
  228. bz.Set("total_amount", args["total_amount"])
  229. bz.Set("auth_code", args["auth_code"])
  230. bz.Set("product_code", args["product_code"])
  231. bz.Set("scene", args["scene"])
  232. bz.Set("subject", args["subject"])
  233. bz.Set("extend_params", extendParams)
  234. })
  235. var aliPsp md.AlipayTradePay
  236. v2, err := PostAliPayAPISelfV2(client, bm, "alipay.trade.pay", &aliPsp)
  237. if err != nil {
  238. xlog.Error(err)
  239. return nil, err
  240. }
  241. res := v2.(*md.AlipayTradePay)
  242. return res, nil
  243. }
  244. func AlipayTradeQuery(args map[string]string) (*md.AlipayFundTransUniTransfer, error) {
  245. client := Comm(args)
  246. if client == nil {
  247. return nil, errors.New("获取失败")
  248. }
  249. //请求参数
  250. bm := make(gopay.BodyMap)
  251. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  252. bz.Set("out_trade_no", args["out_trade_no"])
  253. })
  254. var aliPsp md.AlipayFundTransUniTransfer
  255. bs, err := PostAliPayAPISelfV2(client, bm, "alipay.trade.query", &aliPsp)
  256. if err != nil {
  257. xlog.Error(err)
  258. return nil, err
  259. }
  260. res := bs.(*md.AlipayFundTransUniTransfer)
  261. return res, nil
  262. }
  263. //结束信用服务订单
  264. func CreditagreementOrderFinish(args map[string]string) (*md.ZhimaCreditPayafteruseCreditbizorderFinish, error) {
  265. client := Comm(args)
  266. client.AppAuthToken = args["app_auth_token"]
  267. if client == nil {
  268. return nil, errors.New("获取失败")
  269. }
  270. //请求参数
  271. bm := make(gopay.BodyMap)
  272. // biz_content
  273. bm.SetBodyMap("biz_content", func(bz gopay.BodyMap) {
  274. bz.Set("out_request_no", args["out_request_no"])
  275. bz.Set("credit_biz_order_id", args["credit_biz_order_id"])
  276. bz.Set("is_fulfilled", args["is_fulfilled"])
  277. bz.Set("remark", args["remark"])
  278. })
  279. var aliPsp md.ZhimaCreditPayafteruseCreditbizorderFinish
  280. bs, err := PostAliPayAPISelfV2(client, bm, "zhima.credit.payafteruse.creditbizorder.finish", &aliPsp)
  281. if err != nil {
  282. xlog.Error(err)
  283. return nil, err
  284. }
  285. res := bs.(*md.ZhimaCreditPayafteruseCreditbizorderFinish)
  286. return res, nil
  287. }
  288. func PostAliPayAPISelfV2(a *alipay.Client, bm gopay.BodyMap, method string, aliRsp interface{}) (aliRsps interface{}, err error) {
  289. var (
  290. bs, bodyBs []byte
  291. )
  292. // check if there is biz_content
  293. bz := bm.GetInterface("biz_content")
  294. if bzBody, ok := bz.(gopay.BodyMap); ok {
  295. if bodyBs, err = json.Marshal(bzBody); err != nil {
  296. return aliRsp, fmt.Errorf("json.Marshal(%v):%w", bzBody, err)
  297. }
  298. bm.Set("biz_content", string(bodyBs))
  299. }
  300. if bs, err = doAliPaySelf(a, bm, method); err != nil {
  301. return aliRsp, err
  302. }
  303. switch method {
  304. case "alipay.trade.app.pay":
  305. return string(bs), nil
  306. case "alipay.trade.wap.pay", "alipay.trade.page.pay", "alipay.user.certify.open.certify", "zhima.credit.payafteruse.creditagreement.sign":
  307. return string(bs), nil
  308. default:
  309. if err = json.Unmarshal(bs, aliRsp); err != nil {
  310. return aliRsp, err
  311. }
  312. return aliRsp, nil
  313. }
  314. }
  315. // 向支付宝发送自定义请求
  316. func doAliPaySelf(a *alipay.Client, bm gopay.BodyMap, method string) (bs []byte, err error) {
  317. var (
  318. url, sign string
  319. )
  320. bm.Set("method", method)
  321. // check public parameter
  322. checkPublicParam(a, bm)
  323. // check sign
  324. if bm.GetString("sign") == "" {
  325. sign, err = alipay.GetRsaSign(bm, bm.GetString("sign_type"), a.PrivateKeyType, a.PrivateKey)
  326. if err != nil {
  327. return nil, fmt.Errorf("GetRsaSign Error: %v", err)
  328. }
  329. bm.Set("sign", sign)
  330. }
  331. if a.DebugSwitch == gopay.DebugOn {
  332. req, _ := json.Marshal(bm)
  333. xlog.Debugf("Alipay_Request: %s", req)
  334. }
  335. param := alipay.FormatURLParam(bm)
  336. switch method {
  337. case "alipay.trade.app.pay":
  338. return []byte(param), nil
  339. case "alipay.trade.wap.pay", "alipay.trade.page.pay", "alipay.user.certify.open.certify", "zhima.credit.payafteruse.creditagreement.sign":
  340. return []byte(baseUrl + "?" + param), nil
  341. default:
  342. httpClient := xhttp.NewClient()
  343. url = baseUrlUtf8
  344. res, bs, errs := httpClient.Type(xhttp.TypeForm).Post(url).SendString(param).EndBytes()
  345. if len(errs) > 0 {
  346. return nil, errs[0]
  347. }
  348. if a.DebugSwitch == gopay.DebugOn {
  349. xlog.Debugf("Alipay_Response: %s%d %s%s", xlog.Red, res.StatusCode, xlog.Reset, string(bs))
  350. }
  351. if res.StatusCode != 200 {
  352. return nil, fmt.Errorf("HTTP Request Error, StatusCode = %d", res.StatusCode)
  353. }
  354. return bs, nil
  355. }
  356. }
  357. func checkPublicParam(a *alipay.Client, bm gopay.BodyMap) {
  358. bm.Set("format", "JSON")
  359. if bm.GetString("app_id") == "" && a.AppId != util.NULL {
  360. bm.Set("app_id", a.AppId)
  361. }
  362. if bm.GetString("app_cert_sn") == "" && a.AppCertSN != util.NULL {
  363. bm.Set("app_cert_sn", a.AppCertSN)
  364. }
  365. if bm.GetString("alipay_root_cert_sn") == "" && a.AliPayRootCertSN != util.NULL {
  366. bm.Set("alipay_root_cert_sn", a.AliPayRootCertSN)
  367. }
  368. if bm.GetString("return_url") == "" && a.ReturnUrl != util.NULL {
  369. bm.Set("return_url", a.ReturnUrl)
  370. }
  371. bm.Set("charset", "utf-8")
  372. if bm.GetString("charset") == "" && a.Charset != util.NULL {
  373. bm.Set("charset", a.Charset)
  374. }
  375. bm.Set("sign_type", alipay.RSA2)
  376. if bm.GetString("sign_type") == "" && a.SignType != util.NULL {
  377. bm.Set("sign_type", a.SignType)
  378. }
  379. bm.Set("timestamp", time.Now().Format(util.TimeLayout))
  380. bm.Set("version", "1.0")
  381. if bm.GetString("notify_url") == "" && a.NotifyUrl != util.NULL {
  382. bm.Set("notify_url", a.NotifyUrl)
  383. }
  384. if bm.GetString("app_auth_token") == "" && a.AppAuthToken != util.NULL {
  385. bm.Set("app_auth_token", a.AppAuthToken)
  386. }
  387. if bm.GetString("auth_token") == "" && a.AuthToken != util.NULL {
  388. bm.Set("auth_token", a.AuthToken)
  389. }
  390. }