支付模块
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

376 líneas
12 KiB

  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. // TradeAppPay is 微信APP支付
  83. func TradeAppPay(client *wechat.Client, subject, orderID, amount, notifyUrl string) (map[string]string, error) {
  84. // 初始化 BodyMap
  85. bm := make(gopay.BodyMap)
  86. bm.Set("nonce_str", util.GetRandomString(32)).
  87. Set("body", subject).
  88. Set("out_trade_no", orderID).
  89. Set("total_fee", amount).
  90. Set("spbill_create_ip", "127.0.0.1").
  91. Set("notify_url", notifyUrl).
  92. Set("trade_type", wechat.TradeType_App).
  93. Set("sign_type", wechat.SignType_MD5)
  94. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  95. // 预下单
  96. wxRsp, err := client.UnifiedOrder(bm)
  97. if err != nil {
  98. _ = zhios_pay_logx.Warn(err)
  99. return nil, err
  100. }
  101. _, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  102. if err != nil {
  103. _ = zhios_pay_logx.Warn(err)
  104. return nil, err
  105. }
  106. //if !ok {
  107. // return nil, errors.New("验签失败")
  108. //}
  109. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  110. paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  111. res := map[string]string{
  112. "appid": client.AppId,
  113. "partnerid": client.MchId,
  114. "prepayid": wxRsp.PrepayId,
  115. "sign": paySign,
  116. "package": "Sign=WXPay",
  117. "noncestr": wxRsp.NonceStr,
  118. "timestamp": timeStamp,
  119. }
  120. return res, nil
  121. }
  122. // TradeAppPay is 微信H5支付
  123. func TradeH5Pay(client *wechat.Client, subject, orderID, amount, notifyUrl string) (map[string]string, error) {
  124. // 初始化 BodyMap
  125. bm := make(gopay.BodyMap)
  126. bm.Set("nonce_str", util.GetRandomString(32)).
  127. Set("body", subject).
  128. Set("out_trade_no", orderID).
  129. Set("total_fee", amount).
  130. Set("spbill_create_ip", "121.196.29.49").
  131. Set("notify_url", notifyUrl).
  132. Set("trade_type", wechat.TradeType_H5).
  133. Set("sign_type", wechat.SignType_MD5).
  134. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  135. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  136. bm.Set("type", "Wap")
  137. bm.Set("wap_url", "https://www.fumm.cc")
  138. bm.Set("wap_name", "zyos")
  139. })
  140. })
  141. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  142. // 预下单
  143. wxRsp, err := client.UnifiedOrder(bm)
  144. if err != nil {
  145. _ = zhios_pay_logx.Warn(err)
  146. return nil, err
  147. }
  148. _, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  149. if err != nil {
  150. _ = zhios_pay_logx.Warn(err)
  151. return nil, err
  152. }
  153. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  154. packages := "prepay_id=" + wxRsp.PrepayId
  155. paySign := wechat.GetH5PaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  156. fmt.Println("paySign===", paySign)
  157. r := map[string]string{
  158. "redirect_url": wxRsp.MwebUrl,
  159. }
  160. return r, nil
  161. }
  162. func TradePcPay(client *wechat.Client, subject, orderID, amount, notifyUrl, productId string) (map[string]string, error) {
  163. // 初始化 BodyMap
  164. bm := make(gopay.BodyMap)
  165. bm.Set("nonce_str", util.GetRandomString(32)).
  166. Set("body", subject).
  167. Set("out_trade_no", orderID).
  168. Set("total_fee", amount).
  169. Set("spbill_create_ip", "121.196.29.49").
  170. Set("notify_url", notifyUrl).
  171. Set("product_id", productId).
  172. Set("trade_type", wechat.TradeType_Native).
  173. Set("sign_type", wechat.SignType_MD5)
  174. // 预下单
  175. wxRsp, err := client.UnifiedOrder(bm)
  176. if err != nil {
  177. _ = zhios_pay_logx.Warn(err)
  178. return nil, err
  179. }
  180. QRcode := ""
  181. if wxRsp.CodeUrl != "" {
  182. QRcode = qrcode.GetPNGBase64(wxRsp.CodeUrl)
  183. }
  184. QRcode = strings.ReplaceAll(QRcode, "\u0000", "")
  185. r := map[string]string{
  186. "payQrcode": QRcode,
  187. }
  188. return r, nil
  189. }
  190. // TradeMiniProgPay is 微信小程序支付 ☑️
  191. func TradeMiniProgPay(client *wechat.Client, subject, orderID, amount, notifyUrl, openid string) (map[string]string, error) {
  192. if len(subject) > 127 {
  193. tmpSubject := []rune(subject)
  194. subject = string(tmpSubject[0:44])
  195. }
  196. // 初始化 BodyMap
  197. bm := make(gopay.BodyMap)
  198. bm.Set("nonce_str", util.GetRandomString(32)).
  199. Set("body", subject).
  200. Set("openid", openid).
  201. Set("out_trade_no", orderID).
  202. Set("total_fee", amount).
  203. Set("spbill_create_ip", "127.0.0.1").
  204. Set("notify_url", notifyUrl).
  205. Set("trade_type", wechat.TradeType_Mini).
  206. Set("sign_type", wechat.SignType_MD5)
  207. // 预下单
  208. wxRsp, err := client.UnifiedOrder(bm)
  209. if err != nil {
  210. _ = zhios_pay_logx.Warn(err)
  211. return nil, err
  212. }
  213. fmt.Println(wxRsp)
  214. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  215. packages := "prepay_id=" + wxRsp.PrepayId
  216. paySign := wechat.GetMiniPaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  217. res := map[string]string{
  218. "appId": client.AppId,
  219. "paySign": paySign,
  220. "signType": wechat.SignType_MD5,
  221. "package": packages,
  222. "nonceStr": wxRsp.NonceStr,
  223. "timeStamp": timeStamp,
  224. }
  225. return res, nil
  226. }
  227. // TradeAppPayV3 is 微信APP支付v3
  228. func TradeAppPayV3(client *v3.ClientV3, subject, orderID, amount, notifyUrl string) (map[string]string, error) {
  229. // 初始化 BodyMap
  230. amountNew := zhios_pay_utils.AnyToFloat64(amount) * 100
  231. bm := make(gopay.BodyMap)
  232. bm.Set("nonce_str", util.GetRandomString(32)).
  233. Set("body", subject).
  234. Set("out_trade_no", orderID).
  235. Set("total_fee", amountNew).
  236. Set("spbill_create_ip", "127.0.0.1").
  237. Set("notify_url", notifyUrl).
  238. Set("trade_type", wechat.TradeType_App).
  239. Set("sign_type", wechat.SignType_MD5)
  240. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  241. //// 预下单
  242. //wxRsp, err := v3.UnifiedOrder(bm)
  243. //if err != nil {
  244. // _ = zhios_pay_logx.Warn(err)
  245. // return nil, err
  246. //}
  247. //_, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  248. //if err != nil {
  249. // _ = zhios_pay_logx.Warn(err)
  250. // return nil, err
  251. //}
  252. ////if !ok {
  253. //// return nil, errors.New("验签失败")
  254. ////}
  255. //timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  256. //paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  257. //res := map[string]string{
  258. // "appid": client.AppId,
  259. // "partnerid": client.MchId,
  260. // "prepayid": wxRsp.PrepayId,
  261. // "sign": paySign,
  262. // "package": "Sign=WXPay",
  263. // "noncestr": wxRsp.NonceStr,
  264. // "timestamp": timeStamp,
  265. //}
  266. //return res, nil
  267. return nil, nil
  268. }
  269. //// TradeJSAPIPay is 微信JSAPI支付
  270. func TradeJSAPIPay(client *wechat.Client, subject, orderID, amount, notifyUrl, openid string) (map[string]string, error) {
  271. // 初始化 BodyMap
  272. bm := make(gopay.BodyMap)
  273. bm.Set("nonce_str", util.GetRandomString(32)).
  274. Set("body", subject).
  275. Set("out_trade_no", orderID).
  276. Set("total_fee", amount).
  277. Set("spbill_create_ip", "121.196.29.49").
  278. Set("notify_url", notifyUrl).
  279. Set("trade_type", wechat.TradeType_JsApi).
  280. Set("sign_type", wechat.SignType_MD5).
  281. Set("openid", openid).
  282. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  283. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  284. bm.Set("type", "Wap")
  285. bm.Set("wap_url", "https://www.fumm.cc")
  286. bm.Set("wap_name", "zyos")
  287. })
  288. })
  289. // 预下单
  290. wxRsp, err := client.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. packages := "prepay_id=" + wxRsp.PrepayId
  306. paySign := wechat.GetJsapiPaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  307. zhios_pay_logx.Info("wxRsp.PrepayId:" + wxRsp.PrepayId)
  308. zhios_pay_logx.Info("wxRsp.PrepayId:" + wxRsp.PrepayId)
  309. zhios_pay_logx.Info("wxRsp.PrepayId:" + openid)
  310. res := map[string]string{
  311. "appid": client.AppId,
  312. "partnerid": client.MchId,
  313. "prepayid": wxRsp.PrepayId,
  314. "sign": paySign,
  315. "package": "prepay_id=" + wxRsp.PrepayId,
  316. "noncestr": wxRsp.NonceStr,
  317. "timestamp": timeStamp,
  318. }
  319. return res, nil
  320. }
  321. // TradeH5PayV3 is 微信H5支付v3
  322. func TradeH5PayV3(client *wechat.Client, subject, orderID, amount, notifyUrl string) (string, error) {
  323. // 初始化 BodyMap
  324. bm := make(gopay.BodyMap)
  325. bm.Set("nonce_str", util.GetRandomString(32)).
  326. Set("body", subject).
  327. Set("out_trade_no", orderID).
  328. Set("total_fee", amount).
  329. Set("spbill_create_ip", "127.0.0.1").
  330. Set("notify_url", notifyUrl).
  331. Set("trade_type", wechat.TradeType_App).
  332. Set("device_info", "WEB").
  333. Set("sign_type", wechat.SignType_MD5).
  334. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  335. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  336. bm.Set("type", "Wap")
  337. bm.Set("wap_url", "https://www.fumm.cc")
  338. bm.Set("wap_name", "H5测试支付")
  339. })
  340. }) /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  341. // 预下单
  342. wxRsp, err := client.UnifiedOrder(bm)
  343. if err != nil {
  344. _ = zhios_pay_logx.Warn(err)
  345. return "", err
  346. }
  347. // ====APP支付 paySign====
  348. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  349. // 获取APP支付的 paySign
  350. // 注意:package 参数因为是固定值,无需开发者再传入
  351. // appId:AppID
  352. // partnerid:partnerid
  353. // nonceStr:随机字符串
  354. // prepayId:统一下单成功后得到的值
  355. // signType:签名方式,务必与统一下单时用的签名方式一致
  356. // timeStamp:时间
  357. // apiKey:API秘钥值
  358. paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  359. return paySign, nil
  360. }
  361. // TradeMiniProgPayV3 is 微信小程序支付v3
  362. func TradeMiniProgPayV3(client *v3.ClientV3, subject, orderID, amount, notifyUrl string) (string, error) {
  363. return "", nil
  364. }