package com.xzx.gc.pay.controller;
|
|
import cn.hutool.core.lang.Snowflake;
|
import cn.hutool.core.util.IdUtil;
|
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.MultiFormatWriter;
|
import com.google.zxing.WriterException;
|
import com.google.zxing.common.BitMatrix;
|
import com.xzx.gc.common.constant.Constants;
|
import com.xzx.gc.common.request.BaseController;
|
import com.xzx.gc.model.admin.PayInfoModel;
|
import com.xzx.gc.model.admin.WeChatParams;
|
import com.xzx.gc.pay.service.PayService;
|
import com.xzx.gc.util.HttpUtil;
|
import com.xzx.gc.util.PayForUtil;
|
import com.xzx.gc.util.WeChatConfig;
|
import com.xzx.gc.util.XMLUtil;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.web.bind.annotation.*;
|
|
import javax.imageio.ImageIO;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.awt.image.BufferedImage;
|
import java.io.*;
|
import java.math.BigDecimal;
|
import java.net.URLEncoder;
|
import java.util.*;
|
|
@RestController
|
@Api(tags = "微信充值接口类")
|
@Slf4j
|
public class WeixinPayController extends BaseController {
|
|
|
@Autowired
|
private PayService payService;
|
/**
|
* 获取微信支付的二维码地址
|
* @return
|
* @author chenp
|
* @throws Exception
|
*/
|
public static String getCodeUrl(WeChatParams ps) throws Exception {
|
/**
|
* 账号信息
|
*/
|
String appid = WeChatConfig.APPID;//微信服务号的appid
|
String mch_id = WeChatConfig.MCHID; //微信支付商户号
|
String key = WeChatConfig.APIKEY; // 微信支付的API密钥
|
String notify_url = WeChatConfig.WECHAT_NOTIFY_URL_PC;//回调地址【注意,这里必须要使用外网的地址】
|
String ufdoder_url=WeChatConfig.UFDODER_URL;//微信下单API地址
|
String trade_type = "NATIVE"; //类型【网页扫码支付】
|
|
/**
|
* 时间字符串
|
*/
|
String currTime = PayForUtil.getCurrTime();
|
String strTime = currTime.substring(8, currTime.length());
|
String strRandom = PayForUtil.buildRandom(4) + "";
|
String nonce_str = strTime + strRandom;
|
|
/**
|
* 参数封装
|
*/
|
SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
|
packageParams.put("appid", appid);
|
packageParams.put("mch_id", mch_id);
|
packageParams.put("nonce_str", nonce_str);//随机字符串
|
packageParams.put("body", ps.body);//支付的商品名称
|
packageParams.put("out_trade_no", ps.out_trade_no+nonce_str);//商户订单号【备注:每次发起请求都需要随机的字符串,否则失败。】
|
packageParams.put("total_fee", ps.total_fee);//支付金额
|
packageParams.put("spbill_create_ip", PayForUtil.localIp());//客户端主机
|
packageParams.put("notify_url", notify_url);
|
packageParams.put("trade_type", trade_type);
|
packageParams.put("attach", ps.attach);//额外的参数【业务类型+会员ID+支付类型】
|
|
|
String sign = PayForUtil.createSign("UTF-8", packageParams,key); //获取签名
|
packageParams.put("sign", sign);
|
|
String requestXML = PayForUtil.getRequestXml(packageParams);//将请求参数转换成String类型
|
log.info("微信支付请求参数的报文"+requestXML);
|
String resXml = HttpUtil.postData(ufdoder_url,requestXML); //解析请求之后的xml参数并且转换成String类型
|
Map map = XMLUtil.doXMLParse(resXml);
|
log.info("微信支付响应参数的报文"+resXml);
|
String urlCode = (String) map.get("code_url");
|
|
return urlCode;
|
}
|
|
|
|
//微信支付接口
|
@PostMapping(Constants.ADMIN_VIEW_PREFIX + "/weixinPay/wxPay.json")
|
@ResponseBody
|
@ApiOperation(value="获取微信付款地址(该地址用于生成微信付款二维码)", notes="test: 仅0有正确返回")
|
public String wxPay(@RequestBody WeChatParams ps) throws Exception {
|
Snowflake snowflake = IdUtil.getSnowflake(0, 3);
|
String payOrderId = "ZF"+snowflake.nextIdStr();
|
ps.setOut_trade_no(payOrderId);
|
ps.setTotal_fee(new BigDecimal(ps.getTotal_fee()).multiply(new BigDecimal("100")).toString());
|
String urlCode =getCodeUrl(ps);
|
System.out.println(urlCode);
|
|
PayInfoModel model = new PayInfoModel();
|
model.setPayOrderId(payOrderId);
|
model.setMoney(ps.getTotal_fee());
|
int num =payService.addPayInfo(model);
|
return urlCode;
|
}
|
|
/**
|
* pc端微信支付之后的回调方法
|
* @param request
|
* @param response
|
* @throws Exception
|
*/
|
@RequestMapping(value="wechat_notify_url_pc",method= RequestMethod.POST)
|
public void wechat_notify_url_pc(HttpServletRequest request, HttpServletResponse response) throws Exception{
|
|
//读取参数
|
InputStream inputStream ;
|
StringBuffer sb = new StringBuffer();
|
inputStream = request.getInputStream();
|
String s ;
|
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
|
while ((s = in.readLine()) != null){
|
sb.append(s);
|
}
|
in.close();
|
inputStream.close();
|
|
//解析xml成map
|
Map<String, String> m = new HashMap<String, String>();
|
m = XMLUtil.doXMLParse(sb.toString());
|
|
//过滤空 设置 TreeMap
|
SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
|
Iterator<String> it = m.keySet().iterator();
|
while (it.hasNext()) {
|
String parameter = it.next();
|
String parameterValue = m.get(parameter);
|
|
String v = "";
|
if(null != parameterValue) {
|
v = parameterValue.trim();
|
}
|
packageParams.put(parameter, v);
|
}
|
// 微信支付的API密钥
|
String key = WeChatConfig.APIKEY; // key
|
log.info("微信支付返回回来的参数:"+packageParams);
|
//判断签名是否正确
|
if(PayForUtil.isTenpaySign("UTF-8", packageParams,key)) {
|
//------------------------------
|
//处理业务开始
|
//------------------------------
|
String resXml = "";
|
if("SUCCESS".equals((String)packageParams.get("result_code"))){
|
// 这里是支付成功
|
|
//执行自己的业务逻辑开始
|
String app_id = (String)packageParams.get("appid");
|
String mch_id = (String)packageParams.get("mch_id");
|
String openid = (String)packageParams.get("openid");
|
String is_subscribe = (String)packageParams.get("is_subscribe");//是否关注公众号
|
|
//附加参数【商标申请_0bda32824db44d6f9611f1047829fa3b_15460】--【业务类型_会员ID_订单号】
|
String attach = (String)packageParams.get("attach");
|
//商户订单号
|
String out_trade_no = (String)packageParams.get("out_trade_no");
|
//付款金额【以分为单位】
|
String total_fee = (String)packageParams.get("total_fee");
|
//微信生成的交易订单号
|
String transaction_id = (String)packageParams.get("transaction_id");//微信支付订单号
|
//支付完成时间
|
String time_end=(String)packageParams.get("time_end");
|
|
//out_trade_no
|
|
log.info("app_id:"+app_id);
|
log.info("mch_id:"+mch_id);
|
log.info("openid:"+openid);
|
log.info("is_subscribe:"+is_subscribe);
|
log.info("out_trade_no:"+out_trade_no);
|
log.info("total_fee:"+total_fee);
|
log.info("额外参数_attach:"+attach);
|
log.info("time_end:"+time_end);
|
|
//执行自己的业务逻辑结束
|
log.info("支付成功");
|
//通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
|
resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
|
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
|
|
} else {
|
log.info("支付失败,错误信息:" + packageParams.get("err_code"));
|
resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
|
+ "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
|
}
|
//------------------------------
|
//处理业务完毕
|
//------------------------------
|
BufferedOutputStream out = new BufferedOutputStream(
|
response.getOutputStream());
|
out.write(resXml.getBytes());
|
out.flush();
|
out.close();
|
} else{
|
log.info("通知签名验证失败");
|
}
|
|
}
|
}
|