SpringBoot中对接微信支付接口
1.微信支付开发文档
https://pay.weixin.qq.com/wiki/doc/api/index.html
1.准备工作:
在微信上申请服务号类型的公众号,从公众号获取以下数据
-
appid:微信公众账号或开放平台APP的唯一标识
-
mch_id:商户号 (配置文件中的partner)
-
partnerkey:商户密钥
2.根据项目需求选择适合的支付方式,本例使用Native支付方式
点击查看文档->API列表
开发步骤
引入依赖
<dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version>
</dependency>
修改application.proerties配置文件
#关联的公众号appid #商户号 #商户key
weixin.appid=wx34bb2aa123de3dcd
weixin.partner=1611167878
weixin.partnerkey=4ca478a4580794e2f7cf67881cb21dd4b1
参数注入:
@Component
public class PropertiesUtils implements InitializingBean {@Value("${weixin.appid}")private String appid;@Value("${weixin.partner}")private String partner;@Value("${weixin.partnerkey}")private String partnerkey;public static String APPID;public static String PARTNER;public static String PARTNERKEY;@Overridepublic void afterPropertiesSet() throws Exception {APPID = appid;PARTNER = partner;PARTNERKEY = partnerkey;}
}
HttpClient工具类:
用于发送http请求,可直接复制
/*** http请求客户端*/
public class HttpClient {private String url;private Map<String, String> param;private int statusCode;private String content;private String xmlParam;private boolean isHttps;private boolean isCert = false;//证书密码 微信商户号(mch_id)private String certPassword;public boolean isHttps() {return isHttps;}public void setHttps(boolean isHttps) {this.isHttps = isHttps;}public boolean isCert() {return isCert;}public void setCert(boolean cert) {isCert = cert;}public String getXmlParam() {return xmlParam;}public void setXmlParam(String xmlParam) {this.xmlParam = xmlParam;}public HttpClient(String url, Map<String, String> param) {this.url = url;this.param = param;}public HttpClient(String url) {this.url = url;}public String getCertPassword() {return certPassword;}public void setCertPassword(String certPassword) {this.certPassword = certPassword;}public void setParameter(Map<String, String> map) {param = map;}public void addParameter(String key, String value) {if (param == null)param = new HashMap<String, String>();param.put(key, value);}public void post() throws ClientProtocolException, IOException {HttpPost http = new HttpPost(url);setEntity(http);execute(http);}public void put() throws ClientProtocolException, IOException {HttpPut http = new HttpPut(url);setEntity(http);execute(http);}public void get() throws ClientProtocolException, IOException {if (param != null) {StringBuilder url = new StringBuilder(this.url);boolean isFirst = true;for (String key : param.keySet()) {if (isFirst)url.append("?");elseurl.append("&");url.append(key).append("=").append(param.get(key));}this.url = url.toString();}HttpGet http = new HttpGet(url);execute(http);}/*** set http post,put param*/private void setEntity(HttpEntityEnclosingRequestBase http) {if (param != null) {List<NameValuePair> nvps = new LinkedList<NameValuePair>();for (String key : param.keySet())nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数}if (xmlParam != null) {http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));}}private void execute(HttpUriRequest http) throws ClientProtocolException,IOException {CloseableHttpClient httpClient = null;try {if (isHttps) {if(isCert) {FileInputStream inputStream = new FileInputStream(new File(ConstantPropertiesUtils.CERT));KeyStore keystore = KeyStore.getInstance("PKCS12");char[] partnerId2charArray = certPassword.toCharArray();keystore.load(inputStream, partnerId2charArray);SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keystore, partnerId2charArray).build();SSLConnectionSocketFactory sslsf =new SSLConnectionSocketFactory(sslContext,new String[] { "TLSv1" },null,SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();} else {SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {// 信任所有public boolean isTrusted(X509Certificate[] chain,String authType)throws CertificateException {return true;}}).build();SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();}} else {httpClient = HttpClients.createDefault();}CloseableHttpResponse response = httpClient.execute(http);try {if (response != null) {if (response.getStatusLine() != null)statusCode = response.getStatusLine().getStatusCode();HttpEntity entity = response.getEntity();// 响应内容content = EntityUtils.toString(entity, Consts.UTF_8);}} finally {response.close();}} catch (Exception e) {e.printStackTrace();} finally {httpClient.close();}}public int getStatusCode() {return statusCode;}public String getContent() throws ParseException, IOException {return content;}
}
到此准备工作结束,剩下的就是参考微信支付开发文档,提供微信支付接口所需参数和获取请求结果,从结果中取出我们所需的数据
准备微信支付所需参数
//对接微信支付//组装数据Map<String, String> paramMap = new HashedMap<>();paramMap.put("appid", PropertiesUtils.APPID); //公众号appidparamMap.put("mch_id",PropertiesUtils.PARTNER); //商户号paramMap.put("out_trade_no",orderInfo.getOutTradeNo()); //商户订单号paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); //随机字符串String object = orderInfo.getReserveDate()+"就诊"+ orderInfo.getDepname();paramMap.put("body",object); //商品描述//paramMap.put("total_fee", order.getAmount().multiply(new BigDecimal("100")).longValue()+"");paramMap.put("total_fee","1"); //支付金额paramMap.put("spbill_create_ip","127.0.0.1"); //用户的客户端IPparamMap.put("notify_url", "https://2495161sb6.goho.co/api/order/weixinPay/weixinNotify");//微信支付结果通知的回调地址paramMap.put("trade_type", "NATIVE"); //交易类型
注: total_fee 属性为支付金额,单位是分
微信支付接口地址: https://api.mch.weixin.qq.com/pay/unifiedorder
调用接口,发送Http请求
//对接微信支付
HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");httpClient.setXmlParam(WXPayUtil.generateSignedXml(paramMap,ConstantPropertiesUtils.PARTNERKEY));
//微信接口为https请求,告诉httpClient改请求为https
httpClient.setHttps(true);
httpClient.post();
接收返回值,获取所需数据
//获取响应数据String content = httpClient.getContent();Map<String, String> resultMap = WXPayUtil.xmlToMap(content);//以下字段在return_code和result_code都为SUCCESS的时候有返回if(resultMap.get("return_code").equals("SUCCESS")&&resultMap.get("result_code").equals("SUCCESS")) {map = new HashMap<>();map.put("orderId", orderId); //订单idmap.put("totalFee", orderInfo.getAmount()); map.put("resultCode", resultMap.get("result_code"));map.put("codeUrl", resultMap.get("code_url")); //二维码链接}
查询订单退款等操作参考下单即可
map = new HashMap<>();
map.put(“orderId”, orderId); //订单id
map.put(“totalFee”, orderInfo.getAmount());
map.put(“resultCode”, resultMap.get(“result_code”));
map.put(“codeUrl”, resultMap.get(“code_url”)); //二维码链接
}
查询订单退款等操作参考下单即可