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

api.go 14 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
11 months ago
1 month ago
9 months ago
1 month ago
9 months ago
1 month ago
9 months ago
1 month ago
1 year ago
1 year ago
1 year ago
1 year ago
1 month ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. package local_wxpay
  2. import (
  3. zhios_pay_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/utils"
  4. "code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/utils/logx"
  5. "code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/utils/qrcode"
  6. "fmt"
  7. "github.com/iGoogle-ink/gopay"
  8. "github.com/iGoogle-ink/gopay/pkg/util"
  9. "github.com/iGoogle-ink/gopay/pkg/xlog"
  10. "github.com/iGoogle-ink/gopay/wechat"
  11. v3 "github.com/iGoogle-ink/gopay/wechat/v3"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. func NewClient(appId, mchId, apiKey string, isProd bool) *wechat.Client {
  17. // 初始化微信客户端
  18. // appId:应用ID
  19. // mchId:商户ID
  20. // apiKey:API秘钥值
  21. // isProd:是否是正式环境
  22. client := wechat.NewClient(appId, mchId, apiKey, isProd)
  23. // 打开Debug开关,输出请求日志,默认关闭
  24. client.DebugSwitch = gopay.DebugOn
  25. // 设置国家:不设置默认 中国国内
  26. // wechat.China:中国国内
  27. // wechat.China2:中国国内备用
  28. // wechat.SoutheastAsia:东南亚
  29. // wechat.Other:其他国家
  30. client.SetCountry(wechat.China)
  31. // 添加微信证书 Path 路径
  32. // certFilePath:apiclient_cert.pem 路径
  33. // keyFilePath:apiclient_key.pem 路径
  34. // pkcs12FilePath:apiclient_cert.p12 路径
  35. // 返回err
  36. //client.AddCertFilePath()
  37. // 添加微信证书内容 Content
  38. // certFileContent:apiclient_cert.pem 内容
  39. // keyFileContent:apiclient_key.pem 内容
  40. // pkcs12FileContent:apiclient_cert.p12 内容
  41. // 返回err
  42. //client.AddCertFileContent()
  43. return client
  44. }
  45. func TradeAppRefund(client *wechat.Client, subject, transactionId, outRefundNo, totalFee, amount, p12Path, notifyUrl string) (*wechat.RefundResponse, gopay.BodyMap, error) {
  46. // 初始化 BodyMap
  47. bm := make(gopay.BodyMap)
  48. bm.Set("transaction_id", transactionId).
  49. Set("nonce_str", util.GetRandomString(32)).
  50. Set("sign_type", wechat.SignType_MD5).
  51. Set("out_refund_no", outRefundNo).
  52. Set("total_fee", totalFee).
  53. Set("refund_fee", amount).
  54. Set("refund_desc", subject).
  55. Set("notify_url", notifyUrl)
  56. wxRsp, resBm, err := client.Refund(bm, nil, nil, p12Path)
  57. fmt.Println(wxRsp)
  58. fmt.Println(resBm)
  59. if err != nil {
  60. xlog.Error(err)
  61. fmt.Println(err)
  62. return wxRsp, resBm, err
  63. }
  64. return wxRsp, resBm, nil
  65. }
  66. func TradeAppRefundQuery(client *wechat.Client, transactionId string) (*wechat.QueryRefundResponse, gopay.BodyMap, error) {
  67. // 初始化 BodyMap
  68. bm := make(gopay.BodyMap)
  69. bm.Set("transaction_id", transactionId).
  70. Set("nonce_str", util.GetRandomString(32)).
  71. Set("sign_type", wechat.SignType_MD5)
  72. wxRsp, resBm, err := client.QueryRefund(bm)
  73. fmt.Println(wxRsp)
  74. fmt.Println(resBm)
  75. if err != nil {
  76. xlog.Error(err)
  77. fmt.Println(err)
  78. return wxRsp, resBm, err
  79. }
  80. return wxRsp, resBm, nil
  81. }
  82. func TradeShowQuery(client *wechat.Client, transactionId string) (*wechat.QueryOrderResponse, gopay.BodyMap, error) {
  83. // 初始化 BodyMap
  84. bm := make(gopay.BodyMap)
  85. bm.Set("transaction_id", transactionId).
  86. Set("nonce_str", util.GetRandomString(32)).
  87. Set("sign_type", wechat.SignType_MD5)
  88. wxRsp, resBm, err := client.QueryOrder(bm)
  89. fmt.Println(wxRsp)
  90. fmt.Println(resBm)
  91. if err != nil {
  92. xlog.Error(err)
  93. fmt.Println(err)
  94. return wxRsp, resBm, err
  95. }
  96. return wxRsp, resBm, nil
  97. }
  98. func TradeShowQuery1(client *wechat.Client, transactionId string) (*wechat.QueryOrderResponse, gopay.BodyMap, error) {
  99. // 初始化 BodyMap
  100. bm := make(gopay.BodyMap)
  101. bm.Set("out_trade_no", transactionId).
  102. Set("nonce_str", util.GetRandomString(32)).
  103. Set("sign_type", wechat.SignType_MD5)
  104. wxRsp, resBm, err := client.QueryOrder(bm)
  105. fmt.Println(wxRsp)
  106. fmt.Println(resBm)
  107. if err != nil {
  108. xlog.Error(err)
  109. fmt.Println(err)
  110. return wxRsp, resBm, err
  111. }
  112. return wxRsp, resBm, nil
  113. }
  114. func TradeShowRefundQuery(client *wechat.Client, transactionId string) (*wechat.QueryRefundResponse, gopay.BodyMap, error) {
  115. // 初始化 BodyMap
  116. bm := make(gopay.BodyMap)
  117. bm.Set("transaction_id", transactionId).
  118. Set("nonce_str", util.GetRandomString(32)).
  119. Set("sign_type", wechat.SignType_MD5)
  120. wxRsp, resBm, err := client.QueryRefund(bm)
  121. //fmt.Println(wxRsp)
  122. //fmt.Println(resBm)
  123. if err != nil {
  124. //xlog.Error(err)
  125. //fmt.Println(err)
  126. return wxRsp, resBm, err
  127. }
  128. return wxRsp, resBm, nil
  129. }
  130. // TradeAppPay is 微信APP支付
  131. func TradeAppPay(client *wechat.Client, subject, orderID, amount, notifyUrl string) (map[string]string, error) {
  132. // 初始化 BodyMap
  133. bm := make(gopay.BodyMap)
  134. bm.Set("nonce_str", util.GetRandomString(32)).
  135. Set("body", subject).
  136. Set("out_trade_no", orderID).
  137. Set("total_fee", amount).
  138. Set("spbill_create_ip", "127.0.0.1").
  139. Set("notify_url", notifyUrl).
  140. Set("trade_type", wechat.TradeType_App).
  141. Set("sign_type", wechat.SignType_MD5)
  142. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  143. // 预下单
  144. wxRsp, err := client.UnifiedOrder(bm)
  145. if err != nil {
  146. _ = zhios_pay_logx.Warn(err)
  147. return nil, err
  148. }
  149. _, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  150. if err != nil {
  151. _ = zhios_pay_logx.Warn(err)
  152. return nil, err
  153. }
  154. //if !ok {
  155. // return nil, errors.New("验签失败")
  156. //}
  157. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  158. paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  159. res := map[string]string{
  160. "appid": client.AppId,
  161. "partnerid": client.MchId,
  162. "prepayid": wxRsp.PrepayId,
  163. "sign": paySign,
  164. "package": "Sign=WXPay",
  165. "noncestr": wxRsp.NonceStr,
  166. "timestamp": timeStamp,
  167. }
  168. return res, nil
  169. }
  170. // TradeAppPay is 微信H5支付
  171. func TradeH5Pay(client *wechat.Client, subject, orderID, amount, notifyUrl string) (map[string]string, error) {
  172. // 初始化 BodyMap
  173. bm := make(gopay.BodyMap)
  174. bm.Set("nonce_str", util.GetRandomString(32)).
  175. Set("body", subject).
  176. Set("out_trade_no", orderID).
  177. Set("total_fee", amount).
  178. Set("spbill_create_ip", "121.196.29.49").
  179. Set("notify_url", notifyUrl).
  180. Set("trade_type", wechat.TradeType_H5).
  181. Set("sign_type", wechat.SignType_MD5).
  182. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  183. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  184. bm.Set("type", "Wap")
  185. bm.Set("wap_url", "https://www.fumm.cc")
  186. bm.Set("wap_name", "zyos")
  187. })
  188. })
  189. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  190. // 预下单
  191. wxRsp, err := client.UnifiedOrder(bm)
  192. if err != nil {
  193. _ = zhios_pay_logx.Warn(err)
  194. return nil, err
  195. }
  196. _, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  197. if err != nil {
  198. _ = zhios_pay_logx.Warn(err)
  199. return nil, err
  200. }
  201. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  202. packages := "prepay_id=" + wxRsp.PrepayId
  203. paySign := wechat.GetH5PaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  204. fmt.Println("paySign===", paySign)
  205. r := map[string]string{
  206. "redirect_url": wxRsp.MwebUrl,
  207. }
  208. return r, nil
  209. }
  210. func TradePcPay(client *wechat.Client, subject, orderID, amount, notifyUrl, productId string) (map[string]string, error) {
  211. // 初始化 BodyMap
  212. bm := make(gopay.BodyMap)
  213. bm.Set("nonce_str", util.GetRandomString(32)).
  214. Set("body", subject).
  215. Set("out_trade_no", orderID).
  216. Set("total_fee", amount).
  217. Set("spbill_create_ip", "121.196.29.49").
  218. Set("notify_url", notifyUrl).
  219. Set("product_id", productId).
  220. Set("trade_type", wechat.TradeType_Native).
  221. Set("sign_type", wechat.SignType_MD5)
  222. // 预下单
  223. wxRsp, err := client.UnifiedOrder(bm)
  224. if err != nil {
  225. _ = zhios_pay_logx.Warn(err)
  226. return nil, err
  227. }
  228. QRcode := ""
  229. if wxRsp.CodeUrl != "" {
  230. QRcode = qrcode.GetPNGBase64(wxRsp.CodeUrl)
  231. }
  232. QRcode = strings.ReplaceAll(QRcode, "\u0000", "")
  233. r := map[string]string{
  234. "payQrcode": QRcode,
  235. }
  236. return r, nil
  237. }
  238. // TradeMiniProgPay is 微信小程序支付 ☑️
  239. func TradeMiniProgPay(client *wechat.Client, subject, orderID, amount, notifyUrl, openid string) (map[string]string, error) {
  240. if len(subject) > 127 {
  241. tmpSubject := []rune(subject)
  242. subject = string(tmpSubject[0:44])
  243. }
  244. // 初始化 BodyMap
  245. bm := make(gopay.BodyMap)
  246. bm.Set("nonce_str", util.GetRandomString(32)).
  247. Set("body", subject).
  248. Set("openid", openid).
  249. Set("out_trade_no", orderID).
  250. Set("total_fee", amount).
  251. Set("spbill_create_ip", "127.0.0.1").
  252. Set("notify_url", notifyUrl).
  253. Set("trade_type", wechat.TradeType_Mini).
  254. Set("sign_type", wechat.SignType_MD5)
  255. // 预下单
  256. wxRsp, err := client.UnifiedOrder(bm)
  257. if err != nil {
  258. _ = zhios_pay_logx.Warn(err)
  259. return nil, err
  260. }
  261. fmt.Println(wxRsp)
  262. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  263. packages := "prepay_id=" + wxRsp.PrepayId
  264. paySign := wechat.GetMiniPaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  265. res := map[string]string{
  266. "appId": client.AppId,
  267. "paySign": paySign,
  268. "signType": wechat.SignType_MD5,
  269. "package": packages,
  270. "nonceStr": wxRsp.NonceStr,
  271. "timeStamp": timeStamp,
  272. }
  273. return res, nil
  274. }
  275. // TradeAppPayV3 is 微信APP支付v3
  276. func TradeAppPayV3(client *v3.ClientV3, subject, orderID, amount, notifyUrl string) (map[string]string, error) {
  277. // 初始化 BodyMap
  278. amountNew := zhios_pay_utils.AnyToFloat64(amount) * 100
  279. bm := make(gopay.BodyMap)
  280. bm.Set("nonce_str", util.GetRandomString(32)).
  281. Set("body", subject).
  282. Set("out_trade_no", orderID).
  283. Set("total_fee", amountNew).
  284. Set("spbill_create_ip", "127.0.0.1").
  285. Set("notify_url", notifyUrl).
  286. Set("trade_type", wechat.TradeType_App).
  287. Set("sign_type", wechat.SignType_MD5)
  288. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  289. //// 预下单
  290. //wxRsp, err := v3.UnifiedOrder(bm)
  291. //if err != nil {
  292. // _ = zhios_pay_logx.Warn(err)
  293. // return nil, err
  294. //}
  295. //_, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  296. //if err != nil {
  297. // _ = zhios_pay_logx.Warn(err)
  298. // return nil, err
  299. //}
  300. ////if !ok {
  301. //// return nil, errors.New("验签失败")
  302. ////}
  303. //timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  304. //paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  305. //res := map[string]string{
  306. // "appid": client.AppId,
  307. // "partnerid": client.MchId,
  308. // "prepayid": wxRsp.PrepayId,
  309. // "sign": paySign,
  310. // "package": "Sign=WXPay",
  311. // "noncestr": wxRsp.NonceStr,
  312. // "timestamp": timeStamp,
  313. //}
  314. //return res, nil
  315. return nil, nil
  316. }
  317. // // TradeJSAPIPay is 微信JSAPI支付
  318. func TradeJSAPIPay(client *wechat.Client, subject, orderID, amount, notifyUrl, openid string) (map[string]string, error) {
  319. // 初始化 BodyMap
  320. bm := make(gopay.BodyMap)
  321. bm.Set("nonce_str", util.GetRandomString(32)).
  322. Set("body", subject).
  323. Set("out_trade_no", orderID).
  324. Set("total_fee", amount).
  325. Set("spbill_create_ip", "121.196.29.49").
  326. Set("notify_url", notifyUrl).
  327. Set("trade_type", wechat.TradeType_JsApi).
  328. Set("sign_type", wechat.SignType_MD5).
  329. Set("openid", openid).
  330. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  331. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  332. bm.Set("type", "Wap")
  333. bm.Set("wap_url", "https://www.fumm.cc")
  334. bm.Set("wap_name", "zyos")
  335. })
  336. })
  337. // 预下单
  338. wxRsp, err := client.UnifiedOrder(bm)
  339. if err != nil {
  340. _ = zhios_pay_logx.Warn(err)
  341. return nil, err
  342. }
  343. _, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  344. if err != nil {
  345. _ = zhios_pay_logx.Warn(err)
  346. return nil, err
  347. }
  348. //if !ok {
  349. // return nil, errors.New("验签失败")
  350. //}
  351. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  352. //paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  353. packages := "prepay_id=" + wxRsp.PrepayId
  354. paySign := wechat.GetJsapiPaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  355. zhios_pay_logx.Info("wxRsp.PrepayId:" + wxRsp.PrepayId)
  356. zhios_pay_logx.Info("wxRsp.PrepayId:" + wxRsp.PrepayId)
  357. zhios_pay_logx.Info("wxRsp.PrepayId:" + openid)
  358. res := map[string]string{
  359. "appid": client.AppId,
  360. "partnerid": client.MchId,
  361. "prepayid": wxRsp.PrepayId,
  362. "sign": paySign,
  363. "package": "prepay_id=" + wxRsp.PrepayId,
  364. "noncestr": wxRsp.NonceStr,
  365. "timestamp": timeStamp,
  366. }
  367. return res, nil
  368. }
  369. // TradeH5PayV3 is 微信H5支付v3
  370. func TradeH5PayV3(client *wechat.Client, subject, orderID, amount, notifyUrl string) (string, error) {
  371. // 初始化 BodyMap
  372. bm := make(gopay.BodyMap)
  373. bm.Set("nonce_str", util.GetRandomString(32)).
  374. Set("body", subject).
  375. Set("out_trade_no", orderID).
  376. Set("total_fee", amount).
  377. Set("spbill_create_ip", "127.0.0.1").
  378. Set("notify_url", notifyUrl).
  379. Set("trade_type", wechat.TradeType_App).
  380. Set("device_info", "WEB").
  381. Set("sign_type", wechat.SignType_MD5).
  382. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  383. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  384. bm.Set("type", "Wap")
  385. bm.Set("wap_url", "https://www.fumm.cc")
  386. bm.Set("wap_name", "H5测试支付")
  387. })
  388. }) /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  389. // 预下单
  390. wxRsp, err := client.UnifiedOrder(bm)
  391. if err != nil {
  392. _ = zhios_pay_logx.Warn(err)
  393. return "", err
  394. }
  395. // ====APP支付 paySign====
  396. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  397. // 获取APP支付的 paySign
  398. // 注意:package 参数因为是固定值,无需开发者再传入
  399. // appId:AppID
  400. // partnerid:partnerid
  401. // nonceStr:随机字符串
  402. // prepayId:统一下单成功后得到的值
  403. // signType:签名方式,务必与统一下单时用的签名方式一致
  404. // timeStamp:时间
  405. // apiKey:API秘钥值
  406. paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  407. return paySign, nil
  408. }
  409. // TradeMiniProgPayV3 is 微信小程序支付v3
  410. func TradeMiniProgPayV3(client *v3.ClientV3, subject, orderID, amount, notifyUrl string) (string, error) {
  411. return "", nil
  412. }