@kangwg
2017-04-09T06:38:31.000000Z
字数 7452
阅读 1178
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>
先建微信支付的基类,然后各种支付类型的实现继承它
import java.math.BigDecimal;import java.text.SimpleDateFormat;import java.util.Map;import org.slf4j.*;import com.google.common.base.Strings;import cn.swao.baselib.util.*;import me.hao0.wepay.core.*;import me.hao0.wepay.exception.WepayException;import me.hao0.wepay.model.order.WePayOrder;import me.hao0.wepay.model.refund.*;public class WxPayService {private static Logger log = LoggerFactory.getLogger(WxPayService.class);public Wepay wepay = null;public final static SimpleDateFormat wxTimeFormat = new SimpleDateFormat("yyyyMMddHHmmss");public String merchant = null;public void setMerchant(String merchant) {this.merchant = merchant;}public Wepay initWepay(String certPath, String appId, String payKey, String payMerchant, String certPasswd) {if (Strings.isNullOrEmpty(certPath)) {log.info("WxPay : no init.");} else {log.info("WxPay : init. " + certPath);byte[] data = FsUtils.readBinaryFile(certPath);//读取证书if (data == null)log.error("WxPay : read cert error. " + certPath);elsethis.wepay = WepayBuilder.newBuilder(appId, payKey, payMerchant).certPasswd(certPasswd).certs(data).build();}return this.wepay;}public Notifies getNotifies() {return this.wepay.notifies();}// 异步通知检验public boolean notifyVerify(Map<String, ?> map) {return getNotifies().verifySign(map);}// 订单查询public WePayOrder getOrder(String outTradeNo) {try {return this.wepay.order().queryByOutTradeNo(outTradeNo);} catch (WepayException e) {log.error("WxPay getOrder", e);return null;}}// 退款public RefundApplyResponse refund(String outTradeNo, BigDecimal fee) {try {log.info(LogUtils.gen("WxPay refund", "out_trade_no", outTradeNo));Integer totalFee = fee.multiply(new BigDecimal(100)).intValue();RefundApplyRequest req = new RefundApplyRequest();req.setOutTradeNo(outTradeNo);req.setOutRefundNo(outTradeNo);req.setTotalFee(totalFee);req.setRefundFee(totalFee);req.setOpUserId(this.merchant);RefundApplyResponse result = this.wepay.refund().apply(req);log.info(LogUtils.gen("WxPay sucess", "RefundApplyResponse", result.toString()));return result;} catch (WepayException e) {log.error("WxPay refund", e);return null;}}// 退款查询public RefundQueryResponse getRefund(String outTradeNo) {try {return wepay.refund().queryByOutTradeNo(outTradeNo);} catch (WepayException e) {log.error("WxPay getRefund", e);return null;}}}
initWepay是对微信支付client对象初始化,其中还有通用的退款、查询、异步通知校验的方法。
1.app支付
import java.math.BigDecimal;import java.net.*;import java.util.Map;import javax.annotation.PostConstruct;import org.slf4j.*;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import com.google.common.base.Strings;import com.google.common.collect.Maps;import com.google.gson.JsonObject;import cn.swao.baselib.util.*;import me.hao0.wepay.model.pay.*;@Servicepublic class WxAppService extends WxPayService {private static Logger log = LoggerFactory.getLogger(WeixinMpService.class);@Value("${open.appId:}")private String appId = null;@Value("${open.appSecret:}")private String appSecret = null;@Value("${open.pay.Merchant:}")private String payMerchant = null;@Value("${open.pay.Key:}")private String payKey = null;@Value("${open.pay.CertPasswd:}")private String certPasswd = null;@Value("${open.pay.CertPath:}")private String certPath = null;@Value("${open.pay.notifyUrl:}")private String payNotifyUrl = null;@PostConstructprivate void init() {initWepay(certPath, appId, payKey, payMerchant, certPasswd);setMerchant(this.payMerchant);}// app支付public AppPayResponse getAppPay(String outTradeNo, BigDecimal fee, String body, String ip) {log.info(LogUtils.gen("wxapp下单", "out_trade_no", outTradeNo, "body", body, "ip", ip));PayRequest app = new PayRequest();int totalFee = FinanceUtils.toFen(fee);app.setBody(body);app.setNotifyUrl(this.payNotifyUrl);app.setOutTradeNo(outTradeNo);app.setTotalFee(totalFee);if (Strings.isNullOrEmpty(ip)) {try {ip = InetAddress.getLocalHost().getHostAddress();//如果ip为空,那么拿本机ip(防止拿不到ip导致的异常)} catch (UnknownHostException e) {}}app.setClientId(ip);app.setTimeStart(DateUtils.nowString(wxTimeFormat));Map<String, Object> attachMap = Maps.newHashMap();attachMap.put("out_trade_no", outTradeNo);attachMap.put("wxPayWay", "JSAPI");app.setAttach(JSONUtils.toJson(attachMap));try {log.info(LogUtils.gen("app", app.toString()));AppPayResponse appPay = super.wepay.pay().appPay(app);log.info(LogUtils.gen("wxapp下单成功", "appPay", appPay.toString()));return appPay;} catch (Exception e) {log.error("WxAppService getAppPay", e);return null;}}}
其中的方法是app统一支付下单的方法,其他的查询和异步验签只需要用父类的方法。@Value中的参数写在配置文件中,这些参数是app支付必要的一些参数 ,@PostConstruct项目启动后调用,获取微信支付的对象。
2.微信公众号支付和扫码支付
import cn.swao.baselib.model.NotifyTemplates;import cn.swao.baselib.util.*;import com.google.common.base.Strings;import com.google.common.collect.Maps;import com.google.gson.JsonObject;import me.hao0.wepay.exception.WepayException;import me.hao0.wepay.model.pay.JsPayRequest;import me.hao0.wepay.model.pay.JsPayResponse;import me.hao0.wepay.model.pay.QrPayRequest;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;import javax.annotation.PostConstruct;import java.math.BigDecimal;import java.util.*;@Servicepublic class WeixinMpService extends WxPayService {private static Logger log = LoggerFactory.getLogger(WeixinMpService.class);@Value("${mp.appId:}")private String appId = null;@Value("${mp.appSecret:}")private String appSecret = null;@Value("${mp.pay.Merchant:}")private String payMerchant = null;@Value("${mp.pay.Key:}")private String payKey = null;@Value("${mp.pay.CertPasswd:}")private String certPasswd = null;@Value("${mp.pay.CertPath:}")private String certPath = null;@Value("${mp.pay.notifyUrl:}")private String payNotifyUrl = null;@PostConstructprivate void init() {initWepay(this.certPath, this.appId, this.payKey, this.payMerchant, this.certPasswd);setMerchant(this.payMerchant);}// 微信公众号支付public JsPayResponse getJsPay(String outTradeNo, BigDecimal fee, String body, String ip, String openid) {log.info(LogUtils.gen("开始统一下单", "out_trade_no", outTradeNo, "body", body, "ip", ip, "openid", openid));int totalFee = FinanceUtils.toFen(fee);JsPayRequest jpr = new JsPayRequest();jpr.setBody(body);jpr.setNotifyUrl(this.payNotifyUrl);jpr.setOutTradeNo(outTradeNo);jpr.setTotalFee(totalFee);if (Strings.isNullOrEmpty(ip))ip = SysUtils.getIp();jpr.setClientId(ip);jpr.setOpenId(openid);jpr.setTimeStart(DateUtils.nowString(wxTimeFormat));Map<String, Object> attachMap = Maps.newHashMap();attachMap.put("out_trade_no", outTradeNo);attachMap.put("wxPayWay", "JSAPI");jpr.setAttach(JSONUtils.toJson(attachMap));try {log.info(LogUtils.gen("jpr", jpr.toString()));JsPayResponse jsPay = this.wepay.pay().jsPay(jpr);log.info(LogUtils.gen("统一下单成功", "JsPayResponse", jsPay.toString()));return jsPay;} catch (WepayException e) {log.error("WeixinService getJsPay", e);return null;}}//扫码支付public String getQrPay(String outTradeNo, BigDecimal fee, String body, String ip, String productId) {log.info(LogUtils.gen("开始统一下单", "out_trade_no", outTradeNo, "body", body, "ip", ip, "productId", productId));QrPayRequest qr = new QrPayRequest();int totalFee = FinanceUtils.toFen(fee);qr.setBody(body);qr.setNotifyUrl(this.payNotifyUrl);qr.setOutTradeNo(outTradeNo);qr.setTotalFee(totalFee);if (Strings.isNullOrEmpty(ip))ip = SysUtils.getIp();//获取本机地址ipqr.setClientId(ip);qr.setTimeStart(DateUtils.nowString(wxTimeFormat));qr.setProductId(productId);String codeUrl = null;try {codeUrl = this.wepay.pay().qrPay(qr);log.info("扫码支付 codeUrl:{}", codeUrl);} catch (Exception e) {log.error("扫码支付下单失败", e);}return codeUrl;}}