后台服务
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

341 行
11 KiB

  1. package com.iformall.pay;
  2. import java.security.cert.X509Certificate;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import javax.crypto.IllegalBlockSizeException;
  7. import com.alibaba.fastjson.JSON;
  8. import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils;
  9. import com.github.binarywang.wxpay.config.WxPayConfig;
  10. import com.github.binarywang.wxpay.exception.WxPayException;
  11. import com.github.binarywang.wxpay.service.WxPayService;
  12. import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
  13. import com.iformall.domain.po.WxPayAccount;
  14. import com.iformall.utils.HttpUtil;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. public class WxPay {
  18. protected static Logger log = LoggerFactory.getLogger(WxPay.class);
  19. // 统一下单接口
  20. private static final String UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  21. // 订单查询
  22. private static final String ORDERQUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
  23. // 关闭订单
  24. private static final String CLOSEORDER_URL = "https://api.mch.weixin.qq.com/pay/closeorder";
  25. // 撤销订单
  26. private static final String REVERSE_URL = "https://api.mch.weixin.qq.com/secapi/pay/reverse";
  27. // 申请退款
  28. private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
  29. // 查询退款
  30. private static final String REFUNDQUERY_URL = "https://api.mch.weixin.qq.com/pay/refundquery";
  31. // 下载对账单
  32. private static final String DOWNLOADBILLY_URL = "https://api.mch.weixin.qq.com/pay/downloadbill";
  33. // 交易保障
  34. private static final String REPORT_URL = "https://api.mch.weixin.qq.com/payitil/report";
  35. // 转换短链接
  36. private static final String SHORT_URL = "https://api.mch.weixin.qq.com/tools/shorturl";
  37. // 授权码查询openId接口
  38. private static final String AUTHCODETOOPENID_URL = "https://api.mch.weixin.qq.com/tools/authcodetoopenid";
  39. // 刷卡支付
  40. private static final String MICROPAY_URL = "https://api.mch.weixin.qq.com/pay/micropay";
  41. // 企业付款
  42. private static final String TRANSFERS_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
  43. // 查询企业付款
  44. private static final String GETTRANSFERINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo";
  45. // 查询代金券批次
  46. private static final String GETCOUPONSTOCK_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/query_coupon_stock";
  47. // 查询代金券信息
  48. private static final String GETCOUPONINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/querycouponsinfo";
  49. // 沙箱
  50. private static final String SANDBOX_GETSIGNKEY_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey";
  51. private WxPay() {
  52. }
  53. /**
  54. * 交易类型枚举
  55. *
  56. * @author Javen 2017年4月15日
  57. * JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里
  58. * MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口
  59. */
  60. public static enum TradeType {
  61. JSAPI, NATIVE, APP, WAP, MICROPAY
  62. }
  63. /**
  64. * 统一下单
  65. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_1
  66. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
  67. *
  68. * @param params
  69. * @return
  70. */
  71. public static String pushOrder(Map<String, String> params) {
  72. return doPost(UNIFIEDORDER_URL, params);
  73. }
  74. /**
  75. * 订单查询
  76. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_2
  77. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2
  78. *
  79. * @param params
  80. * 请求参数
  81. * @return
  82. */
  83. public static String orderQuery(Map<String, String> params) {
  84. return doPost(ORDERQUERY_URL, params);
  85. }
  86. /**
  87. * 关闭订单
  88. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_3
  89. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
  90. *
  91. * @param params
  92. * @return
  93. */
  94. public static String closeOrder(Map<String, String> params) {
  95. return doPost(CLOSEORDER_URL, params);
  96. }
  97. /**
  98. * 撤销订单
  99. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_11&index=3
  100. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3
  101. *
  102. * @param params
  103. * 请求参数
  104. * @param certPath
  105. * 证书文件目录
  106. * @param certPass
  107. * 证书密码
  108. * @return
  109. */
  110. public static String orderReverse(Map<String, String> params, String certPath, String certPass) {
  111. return doPostSSL(REVERSE_URL, params, certPath, certPass);
  112. }
  113. /**
  114. * 申请退款
  115. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_4
  116. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4
  117. *
  118. * @param params
  119. * 请求参数
  120. * @param certPath
  121. * 证书文件目录
  122. * @param certPass
  123. * 证书密码
  124. * @return
  125. */
  126. public static String orderRefund(Map<String, String> params, String certPath, String certPass) {
  127. return doPostSSL(REFUND_URL, params, certPath, certPass);
  128. }
  129. /**
  130. * 查询退款
  131. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_5
  132. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5
  133. *
  134. * @param params
  135. * 请求参数
  136. * @return
  137. */
  138. public static String orderRefundQuery(Map<String, String> params) {
  139. return doPost(REFUNDQUERY_URL, params);
  140. }
  141. /**
  142. * 下载对账单
  143. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_6
  144. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_6
  145. *
  146. * @param params
  147. * 请求参数
  148. * @return
  149. */
  150. public static String downloadBill(Map<String, String> params) {
  151. return doPost(DOWNLOADBILLY_URL, params);
  152. }
  153. /**
  154. * 交易保障
  155. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_14&index=7
  156. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_14&index=7
  157. *
  158. * @param params
  159. * 请求参数
  160. * @return
  161. */
  162. public static String orderReport(Map<String, String> params) {
  163. return doPost(REPORT_URL, params);
  164. }
  165. /**
  166. * 转换短链接
  167. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_9&index=8
  168. * 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_9&index=8
  169. *
  170. * @param params
  171. * 请求参数
  172. * @return
  173. */
  174. public static String toShortUrl(Map<String, String> params) {
  175. return doPost(SHORT_URL, params);
  176. }
  177. /**
  178. * 授权码查询openId
  179. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_12&index=9
  180. * 商户模式接入文档:
  181. * https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9
  182. *
  183. * @param params
  184. * 请求参数
  185. * @return
  186. */
  187. public static String authCodeToOpenid(Map<String, String> params) {
  188. return doPost(AUTHCODETOOPENID_URL, params);
  189. }
  190. /**
  191. * 刷卡支付
  192. * 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_10&index=1
  193. * 商户模式接入文档:
  194. * https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
  195. *
  196. * @param params
  197. * 请求参数
  198. * @return
  199. */
  200. public static String micropay(Map<String, String> params) {
  201. return WxPay.doPost(MICROPAY_URL, params);
  202. }
  203. /**
  204. *企业付款到零钱:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2,
  205. *微信后来改为 商家转账到零钱 产品
  206. * @param params
  207. * 请求参数
  208. * @param certPath
  209. * 证书文件目录
  210. * @param certPassword
  211. * 证书密码
  212. * @return {String}
  213. */
  214. public static String transfers(Map<String, String> params, String certPath, String certPassword) {
  215. return WxPay.doPostSSL(TRANSFERS_URL, params, certPath, certPassword);
  216. }
  217. /**
  218. * 查询企业付款
  219. * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
  220. * @param params
  221. * 请求参数
  222. * @param certPath
  223. * 证书文件目录
  224. * @param certPassword
  225. * 证书密码
  226. * @return {String}
  227. */
  228. public static String getTransferInfo(Map<String, String> params, String certPath, String certPassword) {
  229. return WxPay.doPostSSL(GETTRANSFERINFO_URL, params, certPath, certPassword);
  230. }
  231. /**
  232. * 商户模式下 扫码模式一之生成二维码
  233. *
  234. * @param appid
  235. * @param mch_id
  236. * @param product_id
  237. * @param partnerKey
  238. * @param isToShortUrl
  239. * 是否转化为短连接
  240. * @return
  241. */
  242. public static String getCodeUrl(String appid, String mch_id, String product_id, String partnerKey,
  243. boolean isToShortUrl) {
  244. String url = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXX&time_stamp=XXXXX&nonce_str=XXXXX";
  245. String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
  246. String nonceStr = Long.toString(System.currentTimeMillis());
  247. Map<String, String> packageParams = new HashMap<String, String>();
  248. packageParams.put("appid", appid);
  249. packageParams.put("mch_id", mch_id);
  250. packageParams.put("product_id", product_id);
  251. packageParams.put("time_stamp", timeStamp);
  252. packageParams.put("nonce_str", nonceStr);
  253. String packageSign = WxPayment.createSign(packageParams, partnerKey);
  254. String qrCodeUrl = WxPayment.replace(url, "XXXXX", packageSign, appid, mch_id, product_id, timeStamp,
  255. nonceStr);
  256. if (isToShortUrl) {
  257. String shortResult = WxPay
  258. .toShortUrl(WxPayment.buildShortUrlParasMap(appid, null, mch_id, null, qrCodeUrl, partnerKey));
  259. if (log.isDebugEnabled()) {
  260. log.info(shortResult);
  261. }
  262. Map<String, String> shortMap = WxPayment.xmlToMap(shortResult);
  263. String return_code = shortMap.get("return_code");
  264. if (WxPayment.codeIsOK(return_code)) {
  265. String result_code = shortMap.get("result_code");
  266. if (WxPayment.codeIsOK(result_code)) {
  267. qrCodeUrl = shortMap.get("short_url");
  268. }
  269. }
  270. }
  271. return qrCodeUrl;
  272. }
  273. /**
  274. * 查询代金券批次
  275. * https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_4&index=5
  276. *
  277. * @param params
  278. * @return
  279. */
  280. public static String getCouponStock(Map<String, String> params) {
  281. return doPost(GETCOUPONSTOCK_URL, params);
  282. }
  283. /**
  284. * 查询代金券信息
  285. * https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_5&index=6
  286. *
  287. * @param params
  288. * @return
  289. */
  290. public static String getCouponInfo(Map<String, String> params) {
  291. return doPost(GETCOUPONINFO_URL, params);
  292. }
  293. /**
  294. * 获取验签秘钥API
  295. * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_1
  296. *
  297. * @param params
  298. * @return
  299. */
  300. public static String sanboxSignGet(Map<String, String> params) {
  301. return doPost(SANDBOX_GETSIGNKEY_URL, params);
  302. }
  303. public static String doPost(String url, Map<String, String> params) {
  304. return HttpUtil.payPost(url, WxPayment.toXml(params));
  305. }
  306. public static String doPostSSL(String url, Map<String, String> params, String certPath, String certPass) {
  307. return HttpUtil.payPostSSL(url, WxPayment.toXml(params), certPath, certPass);
  308. }
  309. }