[关闭]
@kangwg 2017-04-09T14:38:31.000000Z 字数 7452 阅读 1053

layout: post
title: "微信支付"
subtitle: "微信app支付,微信公众号支付,微信扫码支付"
date: 2017-04-09 12:00:00
author: "kangwg"
header-img: "img/post-bg-2015.jpg"
catalog: true

- 微信

先导入微信的第三方依赖

    <dependency>
        <groupId>me.hao0</groupId>
        <artifactId>wepay-core</artifactId>
        <version>1.1.2</version>
    </dependency>

先建微信支付的基类,然后各种支付类型的实现继承它

  1. import java.math.BigDecimal;
  2. import java.text.SimpleDateFormat;
  3. import java.util.Map;
  4. import org.slf4j.*;
  5. import com.google.common.base.Strings;
  6. import cn.swao.baselib.util.*;
  7. import me.hao0.wepay.core.*;
  8. import me.hao0.wepay.exception.WepayException;
  9. import me.hao0.wepay.model.order.WePayOrder;
  10. import me.hao0.wepay.model.refund.*;
  11. public class WxPayService {
  12. private static Logger log = LoggerFactory.getLogger(WxPayService.class);
  13. public Wepay wepay = null;
  14. public final static SimpleDateFormat wxTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
  15. public String merchant = null;
  16. public void setMerchant(String merchant) {
  17. this.merchant = merchant;
  18. }
  19. public Wepay initWepay(String certPath, String appId, String payKey, String payMerchant, String certPasswd) {
  20. if (Strings.isNullOrEmpty(certPath)) {
  21. log.info("WxPay : no init.");
  22. } else {
  23. log.info("WxPay : init. " + certPath);
  24. byte[] data = FsUtils.readBinaryFile(certPath);//读取证书
  25. if (data == null)
  26. log.error("WxPay : read cert error. " + certPath);
  27. else
  28. this.wepay = WepayBuilder.newBuilder(appId, payKey, payMerchant).certPasswd(certPasswd).certs(data).build();
  29. }
  30. return this.wepay;
  31. }
  32. public Notifies getNotifies() {
  33. return this.wepay.notifies();
  34. }
  35. // 异步通知检验
  36. public boolean notifyVerify(Map<String, ?> map) {
  37. return getNotifies().verifySign(map);
  38. }
  39. // 订单查询
  40. public WePayOrder getOrder(String outTradeNo) {
  41. try {
  42. return this.wepay.order().queryByOutTradeNo(outTradeNo);
  43. } catch (WepayException e) {
  44. log.error("WxPay getOrder", e);
  45. return null;
  46. }
  47. }
  48. // 退款
  49. public RefundApplyResponse refund(String outTradeNo, BigDecimal fee) {
  50. try {
  51. log.info(LogUtils.gen("WxPay refund", "out_trade_no", outTradeNo));
  52. Integer totalFee = fee.multiply(new BigDecimal(100)).intValue();
  53. RefundApplyRequest req = new RefundApplyRequest();
  54. req.setOutTradeNo(outTradeNo);
  55. req.setOutRefundNo(outTradeNo);
  56. req.setTotalFee(totalFee);
  57. req.setRefundFee(totalFee);
  58. req.setOpUserId(this.merchant);
  59. RefundApplyResponse result = this.wepay.refund().apply(req);
  60. log.info(LogUtils.gen("WxPay sucess", "RefundApplyResponse", result.toString()));
  61. return result;
  62. } catch (WepayException e) {
  63. log.error("WxPay refund", e);
  64. return null;
  65. }
  66. }
  67. // 退款查询
  68. public RefundQueryResponse getRefund(String outTradeNo) {
  69. try {
  70. return wepay.refund().queryByOutTradeNo(outTradeNo);
  71. } catch (WepayException e) {
  72. log.error("WxPay getRefund", e);
  73. return null;
  74. }
  75. }
  76. }

initWepay是对微信支付client对象初始化,其中还有通用的退款、查询、异步通知校验的方法。

1.app支付

  1. import java.math.BigDecimal;
  2. import java.net.*;
  3. import java.util.Map;
  4. import javax.annotation.PostConstruct;
  5. import org.slf4j.*;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import org.springframework.stereotype.Service;
  8. import com.google.common.base.Strings;
  9. import com.google.common.collect.Maps;
  10. import com.google.gson.JsonObject;
  11. import cn.swao.baselib.util.*;
  12. import me.hao0.wepay.model.pay.*;
  13. @Service
  14. public class WxAppService extends WxPayService {
  15. private static Logger log = LoggerFactory.getLogger(WeixinMpService.class);
  16. @Value("${open.appId:}")
  17. private String appId = null;
  18. @Value("${open.appSecret:}")
  19. private String appSecret = null;
  20. @Value("${open.pay.Merchant:}")
  21. private String payMerchant = null;
  22. @Value("${open.pay.Key:}")
  23. private String payKey = null;
  24. @Value("${open.pay.CertPasswd:}")
  25. private String certPasswd = null;
  26. @Value("${open.pay.CertPath:}")
  27. private String certPath = null;
  28. @Value("${open.pay.notifyUrl:}")
  29. private String payNotifyUrl = null;
  30. @PostConstruct
  31. private void init() {
  32. initWepay(certPath, appId, payKey, payMerchant, certPasswd);
  33. setMerchant(this.payMerchant);
  34. }
  35. // app支付
  36. public AppPayResponse getAppPay(String outTradeNo, BigDecimal fee, String body, String ip) {
  37. log.info(LogUtils.gen("wxapp下单", "out_trade_no", outTradeNo, "body", body, "ip", ip));
  38. PayRequest app = new PayRequest();
  39. int totalFee = FinanceUtils.toFen(fee);
  40. app.setBody(body);
  41. app.setNotifyUrl(this.payNotifyUrl);
  42. app.setOutTradeNo(outTradeNo);
  43. app.setTotalFee(totalFee);
  44. if (Strings.isNullOrEmpty(ip)) {
  45. try {
  46. ip = InetAddress.getLocalHost().getHostAddress();//如果ip为空,那么拿本机ip(防止拿不到ip导致的异常)
  47. } catch (UnknownHostException e) {
  48. }
  49. }
  50. app.setClientId(ip);
  51. app.setTimeStart(DateUtils.nowString(wxTimeFormat));
  52. Map<String, Object> attachMap = Maps.newHashMap();
  53. attachMap.put("out_trade_no", outTradeNo);
  54. attachMap.put("wxPayWay", "JSAPI");
  55. app.setAttach(JSONUtils.toJson(attachMap));
  56. try {
  57. log.info(LogUtils.gen("app", app.toString()));
  58. AppPayResponse appPay = super.wepay.pay().appPay(app);
  59. log.info(LogUtils.gen("wxapp下单成功", "appPay", appPay.toString()));
  60. return appPay;
  61. } catch (Exception e) {
  62. log.error("WxAppService getAppPay", e);
  63. return null;
  64. }
  65. }
  66. }

其中的方法是app统一支付下单的方法,其他的查询和异步验签只需要用父类的方法。@Value中的参数写在配置文件中,这些参数是app支付必要的一些参数 ,@PostConstruct项目启动后调用,获取微信支付的对象。
2.微信公众号支付和扫码支付

  1. import cn.swao.baselib.model.NotifyTemplates;
  2. import cn.swao.baselib.util.*;
  3. import com.google.common.base.Strings;
  4. import com.google.common.collect.Maps;
  5. import com.google.gson.JsonObject;
  6. import me.hao0.wepay.exception.WepayException;
  7. import me.hao0.wepay.model.pay.JsPayRequest;
  8. import me.hao0.wepay.model.pay.JsPayResponse;
  9. import me.hao0.wepay.model.pay.QrPayRequest;
  10. import org.slf4j.Logger;
  11. import org.slf4j.LoggerFactory;
  12. import org.springframework.beans.factory.annotation.Value;
  13. import org.springframework.stereotype.Service;
  14. import javax.annotation.PostConstruct;
  15. import java.math.BigDecimal;
  16. import java.util.*;
  17. @Service
  18. public class WeixinMpService extends WxPayService {
  19. private static Logger log = LoggerFactory.getLogger(WeixinMpService.class);
  20. @Value("${mp.appId:}")
  21. private String appId = null;
  22. @Value("${mp.appSecret:}")
  23. private String appSecret = null;
  24. @Value("${mp.pay.Merchant:}")
  25. private String payMerchant = null;
  26. @Value("${mp.pay.Key:}")
  27. private String payKey = null;
  28. @Value("${mp.pay.CertPasswd:}")
  29. private String certPasswd = null;
  30. @Value("${mp.pay.CertPath:}")
  31. private String certPath = null;
  32. @Value("${mp.pay.notifyUrl:}")
  33. private String payNotifyUrl = null;
  34. @PostConstruct
  35. private void init() {
  36. initWepay(this.certPath, this.appId, this.payKey, this.payMerchant, this.certPasswd);
  37. setMerchant(this.payMerchant);
  38. }
  39. // 微信公众号支付
  40. public JsPayResponse getJsPay(String outTradeNo, BigDecimal fee, String body, String ip, String openid) {
  41. log.info(LogUtils.gen("开始统一下单", "out_trade_no", outTradeNo, "body", body, "ip", ip, "openid", openid));
  42. int totalFee = FinanceUtils.toFen(fee);
  43. JsPayRequest jpr = new JsPayRequest();
  44. jpr.setBody(body);
  45. jpr.setNotifyUrl(this.payNotifyUrl);
  46. jpr.setOutTradeNo(outTradeNo);
  47. jpr.setTotalFee(totalFee);
  48. if (Strings.isNullOrEmpty(ip))
  49. ip = SysUtils.getIp();
  50. jpr.setClientId(ip);
  51. jpr.setOpenId(openid);
  52. jpr.setTimeStart(DateUtils.nowString(wxTimeFormat));
  53. Map<String, Object> attachMap = Maps.newHashMap();
  54. attachMap.put("out_trade_no", outTradeNo);
  55. attachMap.put("wxPayWay", "JSAPI");
  56. jpr.setAttach(JSONUtils.toJson(attachMap));
  57. try {
  58. log.info(LogUtils.gen("jpr", jpr.toString()));
  59. JsPayResponse jsPay = this.wepay.pay().jsPay(jpr);
  60. log.info(LogUtils.gen("统一下单成功", "JsPayResponse", jsPay.toString()));
  61. return jsPay;
  62. } catch (WepayException e) {
  63. log.error("WeixinService getJsPay", e);
  64. return null;
  65. }
  66. }
  67. //扫码支付
  68. public String getQrPay(String outTradeNo, BigDecimal fee, String body, String ip, String productId) {
  69. log.info(LogUtils.gen("开始统一下单", "out_trade_no", outTradeNo, "body", body, "ip", ip, "productId", productId));
  70. QrPayRequest qr = new QrPayRequest();
  71. int totalFee = FinanceUtils.toFen(fee);
  72. qr.setBody(body);
  73. qr.setNotifyUrl(this.payNotifyUrl);
  74. qr.setOutTradeNo(outTradeNo);
  75. qr.setTotalFee(totalFee);
  76. if (Strings.isNullOrEmpty(ip))
  77. ip = SysUtils.getIp();//获取本机地址ip
  78. qr.setClientId(ip);
  79. qr.setTimeStart(DateUtils.nowString(wxTimeFormat));
  80. qr.setProductId(productId);
  81. String codeUrl = null;
  82. try {
  83. codeUrl = this.wepay.pay().qrPay(qr);
  84. log.info("扫码支付 codeUrl:{}", codeUrl);
  85. } catch (Exception e) {
  86. log.error("扫码支付下单失败", e);
  87. }
  88. return codeUrl;
  89. }
  90. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注