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

304 line
10 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. "fmt"
  6. "github.com/iGoogle-ink/gopay"
  7. "github.com/iGoogle-ink/gopay/pkg/util"
  8. "github.com/iGoogle-ink/gopay/wechat"
  9. v3 "github.com/iGoogle-ink/gopay/wechat/v3"
  10. "strconv"
  11. "time"
  12. )
  13. func NewClient(appId, mchId, apiKey string, isProd bool) *wechat.Client {
  14. // 初始化微信客户端
  15. // appId:应用ID
  16. // mchId:商户ID
  17. // apiKey:API秘钥值
  18. // isProd:是否是正式环境
  19. client := wechat.NewClient(appId, mchId, apiKey, isProd)
  20. // 打开Debug开关,输出请求日志,默认关闭
  21. client.DebugSwitch = gopay.DebugOn
  22. // 设置国家:不设置默认 中国国内
  23. // wechat.China:中国国内
  24. // wechat.China2:中国国内备用
  25. // wechat.SoutheastAsia:东南亚
  26. // wechat.Other:其他国家
  27. client.SetCountry(wechat.China)
  28. // 添加微信证书 Path 路径
  29. // certFilePath:apiclient_cert.pem 路径
  30. // keyFilePath:apiclient_key.pem 路径
  31. // pkcs12FilePath:apiclient_cert.p12 路径
  32. // 返回err
  33. //client.AddCertFilePath()
  34. // 添加微信证书内容 Content
  35. // certFileContent:apiclient_cert.pem 内容
  36. // keyFileContent:apiclient_key.pem 内容
  37. // pkcs12FileContent:apiclient_cert.p12 内容
  38. // 返回err
  39. //client.AddCertFileContent()
  40. return client
  41. }
  42. // TradeAppPay is 微信APP支付
  43. func TradeAppPay(client *wechat.Client, subject, orderID, amount, notifyUrl string) (map[string]string, error) {
  44. // 初始化 BodyMap
  45. bm := make(gopay.BodyMap)
  46. bm.Set("nonce_str", util.GetRandomString(32)).
  47. Set("body", subject).
  48. Set("out_trade_no", orderID).
  49. Set("total_fee", amount).
  50. Set("spbill_create_ip", "127.0.0.1").
  51. Set("notify_url", notifyUrl).
  52. Set("trade_type", wechat.TradeType_App).
  53. Set("sign_type", wechat.SignType_MD5)
  54. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  55. // 预下单
  56. wxRsp, err := client.UnifiedOrder(bm)
  57. if err != nil {
  58. _ = zhios_pay_logx.Warn(err)
  59. return nil, err
  60. }
  61. _, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  62. if err != nil {
  63. _ = zhios_pay_logx.Warn(err)
  64. return nil, err
  65. }
  66. //if !ok {
  67. // return nil, errors.New("验签失败")
  68. //}
  69. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  70. paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  71. res := map[string]string{
  72. "appid": client.AppId,
  73. "partnerid": client.MchId,
  74. "prepayid": wxRsp.PrepayId,
  75. "sign": paySign,
  76. "package": "Sign=WXPay",
  77. "noncestr": wxRsp.NonceStr,
  78. "timestamp": timeStamp,
  79. }
  80. return res, nil
  81. }
  82. // TradeAppPay is 微信H5支付
  83. func TradeH5Pay(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", "121.196.29.49").
  91. Set("notify_url", notifyUrl).
  92. Set("trade_type", wechat.TradeType_H5).
  93. Set("sign_type", wechat.SignType_MD5).
  94. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  95. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  96. bm.Set("type", "Wap")
  97. bm.Set("wap_url", "https://www.fumm.cc")
  98. bm.Set("wap_name", "zyos")
  99. })
  100. })
  101. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  102. // 预下单
  103. wxRsp, err := client.UnifiedOrder(bm)
  104. if err != nil {
  105. _ = zhios_pay_logx.Warn(err)
  106. return nil, err
  107. }
  108. _, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  109. if err != nil {
  110. _ = zhios_pay_logx.Warn(err)
  111. return nil, err
  112. }
  113. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  114. packages := "prepay_id=" + wxRsp.PrepayId
  115. paySign := wechat.GetH5PaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  116. fmt.Println("paySign===", paySign)
  117. r := map[string]string{
  118. "redirect_url": wxRsp.MwebUrl,
  119. }
  120. return r, nil
  121. }
  122. // TradeMiniProgPay is 微信小程序支付 ☑️
  123. func TradeMiniProgPay(client *wechat.Client, subject, orderID, amount, notifyUrl, openid 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("openid", openid).
  129. Set("out_trade_no", orderID).
  130. Set("total_fee", amount).
  131. Set("spbill_create_ip", "127.0.0.1").
  132. Set("notify_url", notifyUrl).
  133. Set("trade_type", wechat.TradeType_Mini).
  134. Set("sign_type", wechat.SignType_MD5)
  135. // 预下单
  136. wxRsp, err := client.UnifiedOrder(bm)
  137. if err != nil {
  138. _ = zhios_pay_logx.Warn(err)
  139. return nil, err
  140. }
  141. fmt.Println(wxRsp)
  142. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  143. packages := "prepay_id=" + wxRsp.PrepayId
  144. paySign := wechat.GetMiniPaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  145. res := map[string]string{
  146. "appId": client.AppId,
  147. "paySign": paySign,
  148. "signType": wechat.SignType_MD5,
  149. "package": packages,
  150. "nonceStr": wxRsp.NonceStr,
  151. "timeStamp": timeStamp,
  152. }
  153. return res, nil
  154. }
  155. // TradeAppPayV3 is 微信APP支付v3
  156. func TradeAppPayV3(client *v3.ClientV3, subject, orderID, amount, notifyUrl string) (map[string]string, error) {
  157. // 初始化 BodyMap
  158. amountNew := zhios_pay_utils.AnyToFloat64(amount) * 100
  159. bm := make(gopay.BodyMap)
  160. bm.Set("nonce_str", util.GetRandomString(32)).
  161. Set("body", subject).
  162. Set("out_trade_no", orderID).
  163. Set("total_fee", amountNew).
  164. Set("spbill_create_ip", "127.0.0.1").
  165. Set("notify_url", notifyUrl).
  166. Set("trade_type", wechat.TradeType_App).
  167. Set("sign_type", wechat.SignType_MD5)
  168. /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  169. //// 预下单
  170. //wxRsp, err := v3.UnifiedOrder(bm)
  171. //if err != nil {
  172. // _ = zhios_pay_logx.Warn(err)
  173. // return nil, err
  174. //}
  175. //_, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  176. //if err != nil {
  177. // _ = zhios_pay_logx.Warn(err)
  178. // return nil, err
  179. //}
  180. ////if !ok {
  181. //// return nil, errors.New("验签失败")
  182. ////}
  183. //timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  184. //paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  185. //res := map[string]string{
  186. // "appid": client.AppId,
  187. // "partnerid": client.MchId,
  188. // "prepayid": wxRsp.PrepayId,
  189. // "sign": paySign,
  190. // "package": "Sign=WXPay",
  191. // "noncestr": wxRsp.NonceStr,
  192. // "timestamp": timeStamp,
  193. //}
  194. //return res, nil
  195. return nil, nil
  196. }
  197. //// TradeJSAPIPay is 微信JSAPI支付
  198. func TradeJSAPIPay(client *wechat.Client, subject, orderID, amount, notifyUrl, openid string) (map[string]string, error) {
  199. // 初始化 BodyMap
  200. bm := make(gopay.BodyMap)
  201. bm.Set("nonce_str", util.GetRandomString(32)).
  202. Set("body", subject).
  203. Set("out_trade_no", orderID).
  204. Set("total_fee", amount).
  205. Set("spbill_create_ip", "121.196.29.49").
  206. Set("notify_url", notifyUrl).
  207. Set("trade_type", wechat.TradeType_JsApi).
  208. Set("sign_type", wechat.SignType_MD5).
  209. Set("openid", openid).
  210. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  211. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  212. bm.Set("type", "Wap")
  213. bm.Set("wap_url", "https://www.fumm.cc")
  214. bm.Set("wap_name", "zyos")
  215. })
  216. })
  217. // 预下单
  218. wxRsp, err := client.UnifiedOrder(bm)
  219. if err != nil {
  220. _ = zhios_pay_logx.Warn(err)
  221. return nil, err
  222. }
  223. _, err = wechat.VerifySign(client.ApiKey, wechat.SignType_MD5, wxRsp)
  224. if err != nil {
  225. _ = zhios_pay_logx.Warn(err)
  226. return nil, err
  227. }
  228. //if !ok {
  229. // return nil, errors.New("验签失败")
  230. //}
  231. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  232. //paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  233. packages := "prepay_id=" + wxRsp.PrepayId
  234. paySign := wechat.GetJsapiPaySign(client.AppId, wxRsp.NonceStr, packages, wechat.SignType_MD5, timeStamp, client.ApiKey)
  235. zhios_pay_logx.Info("wxRsp.PrepayId:" + wxRsp.PrepayId)
  236. zhios_pay_logx.Info("wxRsp.PrepayId:" + wxRsp.PrepayId)
  237. zhios_pay_logx.Info("wxRsp.PrepayId:" + openid)
  238. res := map[string]string{
  239. "appid": client.AppId,
  240. "partnerid": client.MchId,
  241. "prepayid": wxRsp.PrepayId,
  242. "sign": paySign,
  243. "package": "prepay_id=" + wxRsp.PrepayId,
  244. "noncestr": wxRsp.NonceStr,
  245. "timestamp": timeStamp,
  246. }
  247. return res, nil
  248. }
  249. // TradeH5PayV3 is 微信H5支付v3
  250. func TradeH5PayV3(client *wechat.Client, subject, orderID, amount, notifyUrl string) (string, error) {
  251. // 初始化 BodyMap
  252. bm := make(gopay.BodyMap)
  253. bm.Set("nonce_str", util.GetRandomString(32)).
  254. Set("body", subject).
  255. Set("out_trade_no", orderID).
  256. Set("total_fee", amount).
  257. Set("spbill_create_ip", "127.0.0.1").
  258. Set("notify_url", notifyUrl).
  259. Set("trade_type", wechat.TradeType_App).
  260. Set("device_info", "WEB").
  261. Set("sign_type", wechat.SignType_MD5).
  262. SetBodyMap("scene_info", func(bm gopay.BodyMap) {
  263. bm.SetBodyMap("h5_info", func(bm gopay.BodyMap) {
  264. bm.Set("type", "Wap")
  265. bm.Set("wap_url", "https://www.fumm.cc")
  266. bm.Set("wap_name", "H5测试支付")
  267. })
  268. }) /*.Set("openid", "o0Df70H2Q0fY8JXh1aFPIRyOBgu8")*/
  269. // 预下单
  270. wxRsp, err := client.UnifiedOrder(bm)
  271. if err != nil {
  272. _ = zhios_pay_logx.Warn(err)
  273. return "", err
  274. }
  275. // ====APP支付 paySign====
  276. timeStamp := strconv.FormatInt(time.Now().Unix(), 10)
  277. // 获取APP支付的 paySign
  278. // 注意:package 参数因为是固定值,无需开发者再传入
  279. // appId:AppID
  280. // partnerid:partnerid
  281. // nonceStr:随机字符串
  282. // prepayId:统一下单成功后得到的值
  283. // signType:签名方式,务必与统一下单时用的签名方式一致
  284. // timeStamp:时间
  285. // apiKey:API秘钥值
  286. paySign := wechat.GetAppPaySign(client.AppId, client.MchId, wxRsp.NonceStr, wxRsp.PrepayId, wechat.SignType_MD5, timeStamp, client.ApiKey)
  287. return paySign, nil
  288. }
  289. // TradeMiniProgPayV3 is 微信小程序支付v3
  290. func TradeMiniProgPayV3(client *v3.ClientV3, subject, orderID, amount, notifyUrl string) (string, error) {
  291. return "", nil
  292. }