package com.example.demo.pay.service.Impl;
import com.example.demo.common.constants.Message;
import com.example.demo.common.enums.ResponseEnum;
import com.example.demo.common.utils.*;
import com.example.demo.pay.service.WeChatService;
import org.apache.commons.lang3.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.*;
@Service
public class WeChatServiceImpl implements WeChatService {
private final static Logger logger = LoggerFactory.getLogger(WeChatServiceImpl.class);
private static String API_KEY = "xxxxxxx";
private static String APP_ID="xxxxxxx";
private static String MCH_ID="xxxxxxxxx";
private static String NOTIFY_URL="http://xxxxxxxx/wx/callBlack";
private static String REDIRECT_URL="http://xxxxxxxxxxxc/REDIRECT_URL.html?orderNo=";
private static String SPBILL_CREATE_IP="xxx.xxx.xx.xx";
private final static String WX_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
public final static String WX_CHECK_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
@Override
public Message wxpay(HttpServletRequest request,String orderNo) {
String nonce_str = generateNonceStr();
int total_fee = 1;
double money=total_fee;
String body = "购买xxxxxxxxxx" + (money / 100) + "元";
String out_trade_no = orderNo;
String spbill_create_ip = SPBILL_CREATE_IP;
String trade_type = "MWEB";
String scene_info = "{'h5_info': {'type':'Wap','wap_url': 'https://pay.qq.com','wap_name': '产品购买'}}";
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
packageParams.put("appid", APP_ID);
packageParams.put("mch_id", MCH_ID);
packageParams.put("nonce_str", nonce_str);
packageParams.put("body", body);
packageParams.put("out_trade_no", out_trade_no);
packageParams.put("total_fee", total_fee);
packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("notify_url", NOTIFY_URL);
packageParams.put("trade_type", trade_type);
packageParams.put("scene_info", scene_info);
String sign = PayCommonUtil.createSign("UTF-8", packageParams, API_KEY);
packageParams.put("sign", sign);
String mweb_url = "";
Map<String,Object> data=new HashMap<>();
try {
String requestXML = PayCommonUtil.getRequestXml(packageParams);
String resXml = HttpRequest.postData(WX_PAY_URL, requestXML);
Map map = XMLUtil.doXMLParse(resXml);
logger.info("map:{}"+map);
String returnCode = (String) map.get("return_code");
if ("SUCCESS".equals(returnCode)) {
String resultCode = (String) map.get("result_code");
if ("SUCCESS".equals(resultCode)) {
logger.info("订单号:{}发起H5支付成功", out_trade_no);
mweb_url = (String) map.get("mweb_url");
} else {
String errCodeDes = (String) map.get("err_code_des");
logger.info("订单号:{}发起H5支付(系统)失败:{}", out_trade_no, errCodeDes);
}
} else {
String returnMsg = (String) map.get("return_msg");
logger.info("(订单号:{}发起H5支付(通信)失败:{}", out_trade_no, map);
}
} catch (Exception e) {
logger.error("订单号:{}发起H5支付失败(系统异常))", out_trade_no, e);
}
try {
String url = URLEncoder.encode(REDIRECT_URL+out_trade_no, "utf-8");
mweb_url=mweb_url+"&redirect_url="+url;
}catch (Exception e){
logger.error("URl进行Encode异常:{}", e);
}
data.put("url",mweb_url);
data.put("orderNo",out_trade_no);
return new Message(ResponseEnum.SUCCESS, data);
}
@Override
public void weixinCallback(HttpServletRequest request, HttpServletResponse response) {
try {
InputStream inputStream = request.getInputStream();
StringBuffer sb = new StringBuffer();
String s;
BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((s = in.readLine()) != null) {
sb.append(s);
}
in.close();
inputStream.close();
Map<String, String> m = new HashMap<String, String>();
m = XMLUtil.doXMLParse(sb.toString());
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
Iterator it = m.keySet().iterator();
while (it.hasNext()) {
String parameter =String.valueOf( it.next());
String parameterValue = m.get(parameter);
String v = "";
if (null != parameterValue) {
v = parameterValue.trim();
}
packageParams.put(parameter, v);
}
logger.info("回调参数 map:{}"+packageParams);
String key = API_KEY;
if (PayCommonUtil.isTenpaySign("UTF-8", packageParams, key)) {
logger.info("微信支付成功回调");
String resXml = "";
if ("SUCCESS".equals(String.valueOf(packageParams.get("result_code")))) {
String orderNo = String.valueOf(packageParams.get("out_trade_no"));
logger.info("付款成功,微信订单号:{}", orderNo);
resXml = "<xml>"
+ "<return_code><![CDATA[SUCCESS]]></return_code>"
+ "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
} else {
logger.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 {
logger.info("通知签名验证失败");
}
} catch (Exception e) {
logger.error("微信H5支付回调异常{}:", e.toString(), e);
}
}
@Override
public Message weChatQuery(HttpServletRequest request, String out_trade_no) {
String nonce_str = generateNonceStr();
SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
packageParams.put("appid", APP_ID);
packageParams.put("mch_id", MCH_ID);
packageParams.put("nonce_str", nonce_str);
packageParams.put("out_trade_no",out_trade_no);
String sign = PayCommonUtil.createSign("UTF-8", packageParams, API_KEY);
packageParams.put("sign", sign);
Map<String,Object> data=new HashMap<>();
data.put("pay_success_url",PAY_SUCCESS_URL);
data.put("pay_error_url",PAY_ERROR_URL);
try {
String requestXML = PayCommonUtil.getRequestXml(packageParams);
String resXml = HttpRequest.postData(WX_CHECK_ORDER_URL, requestXML);
Map map = XMLUtil.doXMLParse(resXml);
logger.info("map:{}"+map);
String returnCode = (String) map.get("return_code");
if ("SUCCESS".equals(returnCode)) {
String resultCode = (String) map.get("result_code");
if ("SUCCESS".equals(resultCode)) {
String tradeState = (String) map.get("trade_state");
logger.info("tradeState:{}" + tradeState);
logger.info("订单号:{}", out_trade_no);
data.put("orders",map);
boolean paySuccess=paySuccess(tradeState);
if (paySuccess == true)
return new Message(ResponseEnum.SUCCESS, data);
} else {
String errCodeDes = (String) map.get("err_code_des");
logger.info("订单号:{}订单查询失败(系统)失败:{}", out_trade_no, errCodeDes);
}
} else {
String returnMsg = (String) map.get("return_msg");
logger.info("(订单号:{}订单查询失败:{}", out_trade_no, returnMsg);
}
} catch (Exception e) {
logger.error("订单号:{}订单查询失败(系统异常))", out_trade_no, e);
}
return new Message(ResponseEnum.FALL,data);
}
public static String generateNonceStr() {
String noncestr = RandomStringUtils.randomAlphanumeric(16);
return noncestr;
}
public static String create_timestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
public static boolean paySuccess(String tradeState){
if("SUCCESS".equalsIgnoreCase(tradeState)){
return true;
}
return false;
}
}