支付模块
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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