目录
org.springframework.boot spring-boot-starter-web com.fasterxml.jackson.core jackson-databind 2.11.0 com.fasterxml.jackson.datatype jackson-datatype-jsr310 2.9.3 org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-configuration-processor true com.google.zxing core 3.2.1 com.google.zxing javase 3.2.0 com.github.wxpay wxpay-sdk 0.0.3 org.apache.httpcomponents httpclient com.github.xiaoymin swagger-bootstrap-ui 1.9.6 com.spring4all swagger-spring-boot-starter 1.9.1.RELEASE
- public class HttpUtil {
- private String url;
- private Map
param; - private int statusCode;//状态码
- private String content;//主体部分
- private String xmlParam;//生成的xml
- private boolean isHttps;
-
- public boolean isHttps() {
- return isHttps;
- }
-
- public void setHttps(boolean isHttps) {
- this.isHttps = isHttps;
- }
-
- public String getXmlParam() {
- return xmlParam;
- }
-
- public void setXmlParam(String xmlParam) {
- this.xmlParam = xmlParam;
- }
-
- public HttpUtil(String url, Map
param) { - this.url = url;
- this.param = param;
- }
-
- public HttpUtil(String url) {
- this.url = url;
- }
-
- public void setParameter(Map
map) { - param = map;
- }
-
- public void addParameter(String key, String value) {
- if (param == null)
- param = new HashMap
(); - 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("?");
- else
- url.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
nvps = new LinkedList(); - 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) {
- 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;
- }
- }
可以根据上下文获取Reques和Response对象
- public class WebServletUtil {
- private static ServletRequestAttributes servletRequestAttributes;
-
- static {
- servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
- }
-
- public static HttpServletRequest getRequest(){
- return servletRequestAttributes.getRequest();
- }
-
- public static HttpServletResponse getResponse(){
- return servletRequestAttributes.getResponse();
- }
- }
为了更方便测试接口集成了swagger文档
- @Configuration
- @EnableSwagger2//开启swagger
- public class Swagger2Conf {
-
- @Bean
- public Docket webApiConfig(){
-
- return new Docket(DocumentationType.SWAGGER_2)
- .groupName("webApi")
- .apiInfo(webApiInfo())
- .select()
- .apis(RequestHandlerSelectors.basePackage("com.gzh.weixinpay.controller"))
- //过滤掉所有error或error.*页面
- .paths(Predicates.not(PathSelectors.regex("/error.*")))
- .build();
- }
- private ApiInfo webApiInfo(){
-
- return new ApiInfoBuilder()
- .title("权限管理API文档")
- .description("本文档描述了权限管理接口定义")
- .version("1.0")
- .contact(new Contact("gzh", "http://taobao.com", "1984274233@qq.com"))
- .build();
- }
- }
- package com.gzh.weixinpay.conf;
-
- import com.fasterxml.jackson.core.JsonProcessingException;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.github.wxpay.sdk.WXPayUtil;
- import com.google.zxing.BarcodeFormat;
- import com.google.zxing.EncodeHintType;
- import com.google.zxing.MultiFormatWriter;
- import com.google.zxing.client.j2se.MatrixToImageWriter;
- import com.google.zxing.common.BitMatrix;
- import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
- import com.gzh.weixinpay.util.HttpUtil;
- import com.gzh.weixinpay.util.WebServletUtil;
- import lombok.Data;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.context.annotation.PropertySource;
- import org.springframework.stereotype.Component;
-
- import java.io.OutputStream;
- import java.io.Serializable;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
-
- /**
- * TODO
- *
- * @author DELL
- * @version 1.0
- * @since 2022-08-12 21:00:56
- */
- @Data
- @Component("config")
- @ConfigurationProperties(prefix = "weixin")//让配置参数能分离出来
- @PropertySource("classpath:payconfig.properties")
- public class WxConfig implements Serializable {
-
- @Value("${APPID}")
- private String APPID;
-
- @Value("${MCH_ID}")
- private String MCH_ID;
-
- @Value("${KEY}")
- private String KEY;
-
- @Value("${SPBILL_CREATE_IP}")
- private String SPBILL_CREATE_IP;
-
- @Value("${NOTIFY_URL}")
- private String NOTIFY_URL;
-
- @Value("${TRADE_TYPE}")
- private String TRADE_TYPE;
-
- @Value("${PLACEANORDER_URL}")
- private String PAY_URL;
-
- @Value("${QUERY_URL}")
- private String QRY_URL;
-
- /**
- *
- * @param out_trade_no 订单编号
- * @param total_fee 总金额
- * @param expireTimeMin 失效时间
- * @return
- */
- public Map createNative(String out_trade_no, int total_fee , Integer expireTimeMin) throws JsonProcessingException {
- Map
param = new HashMap(); - param.put("appid", APPID);
- param.put("mch_id", MCH_ID);
- param.put("nonce_str", WXPayUtil.generateNonceStr());
- param.put("body", "测试支付功能"); //定义订单内容
- param.put("out_trade_no", out_trade_no); //商户订单编号
- param.put("fee_type", "CNY");
- param.put("total_fee", new ObjectMapper().writeValueAsString(total_fee)); //总金额
- param.put("spbill_create_ip", SPBILL_CREATE_IP);
- param.put("notify_url", NOTIFY_URL); //回调地址
- param.put("trade_type", "NATIVE");
- Date date = new Date();
- long time = date.getTime();
- SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
- String timeStart = simpleDateFormat.format(time);
- String timeEnd = simpleDateFormat.format(time + expireTimeMin * 60000);
- param.put("time_start", timeStart); //订单创建时间
- param.put("time_expire", timeEnd); //定义失效时间
- try {
-
-
- String xmlParam = WXPayUtil.generateSignedXml(param, KEY); //参数转换
- HttpUtil client = new HttpUtil(PAY_URL);
- client.setHttps(true);
- client.setXmlParam(xmlParam);
- client.post();
- String result = client.getContent();
- Map
resultMap = WXPayUtil.xmlToMap(result); -
- if (resultMap.get("err_code") != null && resultMap.get("err_code").equals("ORDERPAID")) {
- System.out.println("<--"+out_trade_no+"--> :订单已经支付!");
-
- }
-
- Map
map = new HashMap<>(); - String code_url = resultMap.get("code_url");
-
- map.put("code_url", code_url);
- map.put("total_fee", String.valueOf(total_fee));
- map.put("out_trade_no", out_trade_no);
-
- return map;
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- /**
- * @param out_trade_no 订单id
- * @return
- */
- public Map queryPayStatus(String out_trade_no) {
-
- Map param = new HashMap();
- param.put("appid", APPID);
- param.put("mch_id", MCH_ID);
- param.put("out_trade_no", out_trade_no);
- param.put("nonce_str", WXPayUtil.generateNonceStr());
- try {
- String xmlParam = WXPayUtil.generateSignedXml(param, KEY);
- HttpUtil client = new HttpUtil(QRY_URL);
- client.setHttps(true);
- client.setXmlParam(xmlParam);
- client.post();
- String result = client.getContent();
- Map
map = WXPayUtil.xmlToMap(result); -
- if (map.get("err_code") != null && map.get("err_code").equals("ORDERNOTEXIST")) {
- System.out.println("订单不存在!");
- }
- if (map.get("trade_state").equals("SUCCESS")) {
- //支付成功,未支付为:NOTPAY
- }
-
- return map;
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
- }
- @RestController
- @CrossOrigin
- @RequestMapping("/order")
- public class PayController {
-
- @Resource
- WxConfig config;
-
- @PostMapping("/createPay")
- public BusiResult createPayOrder(@RequestBody PayVo payVo) throws JsonProcessingException {
- //向微信发起调用生成预付链接
- Map res = config.createNative(payVo.getOrderId(),
- payVo.getFee(),
- payVo.getExpirTime());
- System.out.println(res);
- return BusiResult.success(res);
- }
- //生成二维码图片
- @GetMapping("getImg")
- public void getImg(String code_url){
- if(code_url == null) throw new NullPointerException();
-
- try {
- //生成二维码配置
- Map
hints = new HashMap<>(); - // 设置纠错等级
- hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
- // 编码类型
- hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
-
- BitMatrix bitMatrix = new MultiFormatWriter().encode(code_url, BarcodeFormat.QR_CODE, 400, 400, hints);
- OutputStream outputStream = WebServletUtil.getResponse().getOutputStream();
-
- MatrixToImageWriter.writeToStream(bitMatrix, "png", outputStream);
-
- } catch (Exception e){
- e.printStackTrace();
- }
- }
-
- @PostMapping("/queryPayStatus")
- public BusiResult queryPayStatus(@RequestBody PayVo payVo){
- //向微信发起调用生成预付链接
- Map res = config.queryPayStatus(payVo.getOrderId());
- System.out.println(res);
- return BusiResult.success(res);
- }
- }
#公众号appleId APPID=? #商户号 MCH_ID=? #商户密钥 KEY=? #APP和网页支付提交用户端ip, Native支付填调用微信支付API的机器IP, 即:服务器ip地址 SPBILL_CREATE_IP=127.0.0.1 #接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。(需要配置) NOTIFY_URL=http://225m5x.natappfree.cc/page/notify #支付方式,取值如下:JSAPI,NATIVE,APP TRADE_TYPE=NATIVE # 微信支付 - 统一下单地址 PLACEANORDER_URL=https://api.mch.weixin.qq.com/pay/unifiedorder QUERY_URL=https://api.mch.weixin.qq.com/pay/orderquery

