| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522 |
- package com.kede.wxsdk.service;
- import java.io.BufferedReader;
- import java.io.ByteArrayInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.math.BigDecimal;
- import java.net.InetAddress;
- import java.nio.charset.Charset;
- import java.security.AlgorithmParameters;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
- import java.util.UUID;
- import javax.crypto.Cipher;
- import javax.crypto.spec.IvParameterSpec;
- import javax.crypto.spec.SecretKeySpec;
- import javax.servlet.http.HttpServletRequest;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import org.apache.commons.codec.binary.Base64;
- import org.apache.commons.collections4.map.HashedMap;
- import org.apache.http.HttpResponse;
- import org.apache.http.HttpStatus;
- import org.apache.http.ParseException;
- import org.apache.http.client.ClientProtocolException;
- import org.apache.http.client.HttpClient;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.client.methods.HttpPost;
- import org.apache.http.entity.StringEntity;
- import org.apache.http.impl.client.HttpClientBuilder;
- import org.apache.http.util.EntityUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.kede.common.dao.OrderMapper;
- import com.kede.common.dao.UserMapper;
- import com.kede.common.error.BusinessException;
- import com.kede.common.model.Order;
- import com.kede.common.model.Project;
- import com.kede.common.model.User;
- import com.kede.common.utils.LoggerUtils;
- import com.kede.common.utils.StringUtils;
- import com.kede.core.mybatis.JDBCIdGenerator;
- import com.kede.core.mybatis.page.Pagination;
- import com.kede.core.shiro.token.TokenManager;
- import com.kede.order.service.impl.OrderService;
- import com.kede.wxsdk.WXPayConstants;
- import com.kede.wxsdk.WXPayUtil;
- /**
- * 小程序
- * @author Administrator
- *
- */
- @Service
- public class WxService {
-
- @Value(value = "${wx.appId}")
- private String appId;
- @Value(value = "${wx.appSecret}")
- private String appSecret;
- @Value(value = "${wx.mchId}")
- private String mchId;
- @Value(value = "${wx.apiKiy}")
- private String apiKiy;
- @Value(value = "${wx.notifyUrl}")
- private String notifyUrl;
- @Value(value = "${wx.apiv3}")
- private String apiv3;
- @Value(value = "${wx.certPath}")
- private String certPath;
-
-
- @Autowired
- private JDBCIdGenerator idGenerator;
- @Autowired
- private OrderService orderService;
-
- @Autowired
- private UserMapper userMapper;
- @Autowired
- private OrderMapper orderMapper;
-
-
-
- /**
- * 小程序下单
- * @param p
- * @return
- */
- public Map<String , String > pushUnifiedOrder(Project p){
- WXPay wxpay = null;
- Map<String, String> map=new HashMap<>();
- try {
- IWxPayConfig iWxPayConfig=new IWxPayConfig(appId,mchId,apiKiy,certPath);
- wxpay = new WXPay(iWxPayConfig); // *** 注入自己实现的微信配置类, 创建WXPay核心类, WXPay 包括统一下单接口
- InetAddress addr = InetAddress.getLocalHost();
- String ip = addr.getHostAddress();
- Map<String, String> data = new HashMap<String, String>();
- data.put("body", p.getName());
- String orderNo=idGenerator.generateId().toString();
- data.put("out_trade_no", orderNo); // 订单唯一编号, 不允许重复
- // 订单金额, 单位分
- String amout=p.getAmount().multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString();
- String openId=(String) TokenManager.getVal2Session("openId");
- // String openId="oGNT65WX5ysEnCUmAvaXOdIrMswA";
- if (StringUtils.isBlank(openId)) {
- throw new BusinessException("无法获取正确的openId");
- }
- Order o=new Order();
- o.setOrderNo(orderNo);
- o.setPayAmount(new BigDecimal(0));
- o.setPayStatus(0);
- o.setProjectAmount(p.getAmount());
- o.setProjectId(p.getId());
- o.setProjectName(p.getName());
- o.setStatus(0);
- o.setUid(TokenManager.getUserId());
- if (p.getAmount().compareTo(new BigDecimal("0.01"))>=0) {
- data.put("total_fee", amout);
- data.put("spbill_create_ip", ip); // 下单ip
- data.put("openid", openId); // 微信公众号统一标示openid
- data.put("notify_url", notifyUrl); // 订单结果通知, 微信主动回调此接口
- data.put("trade_type", "JSAPI"); // 固定填写
- Map<String, String> response = wxpay.unifiedOrder(data); // 微信sdk集成方法, 统一下单接口unifiedOrder, 此处请求 MD5加密 加密方式
- LoggerUtils.debug(getClass(),"微信支付下单成功, 返回值 response=%s", response);
- String prepayId = response.get("prepay_id");
- if (prepayId == null) {
- throw new BusinessException("无法获取正确的prepayId");
- }
- orderService.insert(o);
- // 前端调起微信支付必要参数
- String packages = "prepay_id=" + prepayId;
- Map<String, String> wxPayMap = new HashMap<String, String>();
- String uuid=UUID.randomUUID().toString().replace("-", "").toLowerCase();
- wxPayMap.put("appId", iWxPayConfig.getAppID());
- wxPayMap.put("timeStamp", String.valueOf(new Date().getTime()));
- wxPayMap.put("nonceStr", uuid);
- wxPayMap.put("package", packages);
- wxPayMap.put("signType", "MD5");
- // 加密串中包括 appId timeStamp nonceStr package signType 5个参数, 通过sdk WXPayUtil类加密
- String sign = WXPayUtil.generateSignature(wxPayMap, iWxPayConfig.getKey());
- // 返回给前端调起微信支付的必要参数
- map.put("prepay_id", prepayId);
- map.put("out_trade_no", orderNo);
- map.put("paySign", sign);
- map.putAll(wxPayMap);
- }else {
- LoggerUtils.debug(getClass(),"订单下单成功, 返回值 amount=%s", p.getAmount());
- o.setPayStatus(1);
- orderService.insert(o);
- map.put("out_trade_no", orderNo);
- map.put("amount", "0");
- }
-
-
-
- } catch (Exception e) {
- e.printStackTrace();
- throw new BusinessException("支付异常");
- }
- return map;
- }
-
- /**
- * 订单查询
- * @param orderNo
- * @return
- */
- public Map<String, String> pushOrderQuery(String orderNo){
- // 发起微信支付
- WXPay wxpay = null;
- Map<String, String> map=new HashMap<>();
- try {
- IWxPayConfig iWxPayConfig=new IWxPayConfig(appId,mchId,apiKiy,certPath);
- wxpay = new WXPay(iWxPayConfig); // *** 注入自己实现的微信配置类, 创建WXPay核心类, WXPay 包括统一下单接口
- Map<String, String> data = new HashMap<String, String>();
- data.put("out_trade_no", orderNo);
- data.put("mchid", mchId);
- map = wxpay.orderQuery(data);
- LoggerUtils.debug(getClass(),"微信查询成功, 返回值 response={%s}", map);
- String total_fee=map.get("total_fee");
- String transaction_id=map.get("transaction_id");
- String out_trade_no=map.get("out_trade_no");
- if (map.get("trade_state").equals("SUCCESS")) {
- Order os=orderMapper.selectByPrimaryKey(out_trade_no);
- if (os.getPayStatus()!=1) {
- insertOrder(total_fee, transaction_id, out_trade_no);
- }
- }
- }catch (Exception e) {
- e.printStackTrace();
- throw new BusinessException("查询异常");
- }
- return map;
- }
- private void insertOrder(String total_fee, String transaction_id, String out_trade_no) {
- Order o=new Order();
- o.setOrderNo(out_trade_no);
- o.setPayStatus(1);
- o.setPayAmount(new BigDecimal(total_fee).divide(new BigDecimal(100)));
- o.setWxOrderNo(transaction_id);
- orderMapper.updateByPrimaryKeySelective(o);
- }
-
- /**
- * 微信撤销订单
- * @param o.
- * @return
- */
- public Map<String, String> pushWxClose(Order o){
- // 发起微信支付
- WXPay wxpay = null;
- Map<String, String> map=new HashMap<>();
- try {
- IWxPayConfig iWxPayConfig=new IWxPayConfig(appId,mchId,apiKiy,certPath);
- wxpay = new WXPay(iWxPayConfig); // *** 注入自己实现的微信配置类, 创建WXPay核心类, WXPay 包括统一下单接口
- Map<String, String> data = new HashMap<String, String>();
- data.put("out_trade_no", o.getOrderNo());
- data.put("mchid", mchId);
- map = wxpay.closeOrder(data);
- LoggerUtils.debug(getClass(),"微信撤销成功, 返回值 response={%s}", map);
- if (o.getPayStatus()!=1) {
- Order on=new Order();
- on.setOrderNo(o.getOrderNo());
- on.setPayStatus(2);
- orderMapper.updateByPrimaryKeySelective(on);
- }
- }catch (Exception e) {
- throw new BusinessException("撤销异常");
- }
- return map;
- }
-
- public void wxPayCallBack(HttpServletRequest req) {
- BufferedReader reader;
- try {
- reader = req.getReader();
- String line ;
- StringBuilder sb = new StringBuilder();
- while((line = reader.readLine()) != null) {
- sb.append(line);
- }
- // 2、xml字符串 转换为 map对象
- Map<String, String> map = WXPayUtil.xmlToMap(sb.toString());
- LoggerUtils.debug(getClass(), "获取参数%s",map.toString());
- // 3、尝试从缓存中获取,判断是否已经接收过通知
- if (map.get("result_code").equals(WXPayConstants.SUCCESS)
- && WXPayConstants.SUCCESS.equals(map.get("return_code"))) {
- }
- String out_trade_no=map.get("out_trade_no");
- String transaction_id=map.get("transaction_id");
- String result_code=map.get("result_code");
- String total_fee=map.get("total_fee");
- if (result_code.equals("SUCCESS")) {
- Order os=orderMapper.selectByPrimaryKey(out_trade_no);
- if (os.getPayStatus()!=1) {
- insertOrder(total_fee, transaction_id, out_trade_no);
- }
- }
- LoggerUtils.debug(getClass(),"\n\n\n\n\n>>>>>>>>>>>>>>>>>>>>>>>>微信回调结束>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n\n\n\n");
- } catch ( Exception e) {
- e.printStackTrace();
- throw new BusinessException("回调解析异常");
- }
- }
-
- /**
- * XML格式字符串转换为Map
- *
- * @param strXML XML字符串
- * @return XML数据转换后的Map
- * @throws Exception
- */
- public Map<String, Object> xmlToMap(String strXML) throws Exception {
- Map<String, Object> data = new HashMap<String, Object>();
- DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
- InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
- org.w3c.dom.Document doc = documentBuilder.parse(stream);
- doc.getDocumentElement().normalize();
- NodeList nodeList = doc.getDocumentElement().getChildNodes();
- for (int idx = 0; idx < nodeList.getLength(); ++idx) {
- Node node = nodeList.item(idx);
- if (node.getNodeType() == Node.ELEMENT_NODE) {
- org.w3c.dom.Element element = (org.w3c.dom.Element) node;
- data.put(element.getNodeName(), element.getTextContent());
- }
- }
- try {
- stream.close();
- } catch (Exception ex) {
- }
- return data;
- }
-
- /**
- * IO解析获取微信的数据
- *
- * @param request
- * @return
- */
- public String getXmlString(HttpServletRequest request) {
- BufferedReader reader = null;
- String line = "";
- String xmlString = null;
- try {
- reader = request.getReader();
- StringBuffer inputString = new StringBuffer();
- while ((line = reader.readLine()) != null) {
- inputString.append(line);
- }
- xmlString = inputString.toString();
- } catch (Exception e) {
-
- }
- return xmlString;
- }
- /**
- * 参数解密
- * @param sessionKey
- * @param encryptedData
- * @param iv
- * @return
- * @throws Exception
- */
- public JSONObject pushDecryptData(String sessionKey,String encryptedData, String iv) {
- byte[] dataByte = Base64.decodeBase64(encryptedData);
- // 加密秘钥
- byte[] keyByte = Base64.decodeBase64(sessionKey);
- // 偏移量
- byte[] ivByte = Base64.decodeBase64(iv);
- try {
- // 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
- int base = 16;
- if (keyByte.length % base != 0) {
- int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
- byte[] temp = new byte[groups * base];
- Arrays.fill(temp, (byte) 0);
- System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
- keyByte = temp;
- }
- // 初始化
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
- AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
- parameters.init(new IvParameterSpec(ivByte));
- cipher.init(Cipher.DECRYPT_MODE, spec, parameters);// 初始化
- byte[] resultByte = cipher.doFinal(dataByte);
- if (null != resultByte && resultByte.length > 0) {
- String result = new String(resultByte, "UTF-8");
- JSONObject js=JSONObject.parseObject(result);
- String mobile=(String) js.get("purePhoneNumber");
- User u=new User();
- u.setId(userMapper.selectByOpenId((String)TokenManager.getVal2Session("openId")).getId());
- u.setMobile(mobile);
- userMapper.updateByPrimaryKeySelective(u);
- return js;
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
-
- public Object getliveinfo(Integer pageNo,Integer pageSize){
- String url = String.format("https://api.weixin.qq.com/wxa/business/getliveinfo?access_token=%s", getAccessToken());
- Map<String, Object>map=new HashedMap<String, Object>();
- map.put("start", (pageNo - 1) * pageSize);
- map.put("limit", pageSize);
- map=this.getPostMethod(url, map);
- Pagination<Object> p=new Pagination<Object>(pageNo, pageSize, map.get("total"), map.get("room_info"));
- return p;
- }
-
- public String getAccessToken() {
- String access_token=(String) TokenManager.getVal2Session("access_token");
- String expires_in= (String) TokenManager.getVal2Session("expires_in");
- if (access_token!=null&&expires_in!=null) {
- expires_in=expires_in+7200;
- if (new Date().getTime()<Long.valueOf(expires_in)) {
- return access_token;
- }
- }
- String url = String.format(
- "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId,
- appSecret);
- JSONObject js = this.httpGet(url);
- String errcode =js.getString("errcode");
- if (errcode!=null) {
- throw new BusinessException("获取AccessToekn失败!");
- }
- access_token = js.getString("access_token");
- expires_in = js.getString("expires_in");
- TokenManager.setVal2Session("access_token", access_token);
- TokenManager.setVal2Session("expires_in", expires_in);
- return access_token;
- }
-
-
-
-
- public JSONObject httpGet(String url) {
- JSONObject jsonResult = null;
- try {
- HttpClient client = HttpClientBuilder.create().build();//获取DefaultHttpClient请求
- HttpGet request = new HttpGet(url);
- HttpResponse response = client.execute(request);
- if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
- String strResult = EntityUtils.toString(response.getEntity(),"UTF-8");//此处设定编码格式
- jsonResult = JSON.parseObject(strResult);
- } else {
- LoggerUtils.error(getClass(), "HttpStatus异常");
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return jsonResult;
- }
-
- public JSONObject getPostMethod(String url,Map<String, Object>map){
- HttpClient httpClient = HttpClientBuilder.create().build();
- HttpPost httpPost = new HttpPost(url);
- httpPost.addHeader("Content-type", "application/json");
- httpPost.setHeader("Accept", "application/json");
- httpPost.setEntity(new StringEntity(JSON.toJSONString(map), Charset.forName("UTF-8")));
- HttpResponse response = null;
- try {
- response = httpClient.execute(httpPost);
- if (null == response || response.getStatusLine() == null) {
- throw new Exception("Post Request For Url[{}] is not ok. Response is null");
- } else if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
- throw new Exception("Post Request For Url[{}] is not ok. Response Status Code is {"+response.getStatusLine().getStatusCode()+"}");
- }
- } catch (ClientProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- String resultString=null;
- try {
- resultString = EntityUtils.toString(response.getEntity());
- } catch (ParseException | IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- JSONObject jsonObj = JSONObject.parseObject(resultString);
- return jsonObj;
- }
- public Map<String, String> pushNativePay(Project p,String tradeType) {
- WXPay wxpay = null;
- Map<String, String> map = new HashMap<>();
- try {
- IWxPayConfig iWxPayConfig = new IWxPayConfig(appId, mchId, apiKiy, certPath);
- wxpay = new WXPay(iWxPayConfig); // *** 注入自己实现的微信配置类, 创建WXPay核心类, WXPay 包括统一下单接口
- InetAddress addr = InetAddress.getLocalHost();
- String ip = addr.getHostAddress();
- Map<String, String> data = new HashMap<String, String>();
- data.put("body", p.getName());
- String orderNo = idGenerator.generateId().toString();
- data.put("out_trade_no", orderNo); // 订单唯一编号, 不允许重复
- // 订单金额, 单位分
- String amout = p.getAmount().multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString();
- Order o = new Order();
- o.setOrderNo(orderNo);
- o.setPayAmount(new BigDecimal(0));
- o.setPayStatus(0);
- o.setProjectAmount(p.getAmount());
- o.setProjectId(p.getId());
- o.setProjectName(p.getName());
- o.setStatus(0);
- o.setUid("");
- data.put("total_fee", amout);
- data.put("spbill_create_ip", ip); // 下单ip
- data.put("notify_url", notifyUrl); // 订单结果通知, 微信主动回调此接口
- data.put("trade_type", tradeType); // 固定填写
- Map<String, String> wxPayMap = new HashMap<String, String>();
- // 前端调起微信支付必要参数
- String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
- wxPayMap.put("appId", iWxPayConfig.getAppID());
- wxPayMap.put("timeStamp", String.valueOf(new Date().getTime()));
- wxPayMap.put("nonce_str", uuid);
- String sign = WXPayUtil.generateSignature(wxPayMap, iWxPayConfig.getKey());
- map.put("sign", sign);
- map.put("out_trade_no", orderNo);
- map = wxpay.unifiedOrder(data); // 微信sdk集成方法, 统一下单接口unifiedOrder, 此处请求 MD5加密
- LoggerUtils.debug(getClass(), "微信支付下单成功, 返回值 response=%s", map);
- orderService.insert(o);
- } catch (Exception e) {
- e.printStackTrace();
- throw new BusinessException("支付异常");
- }
- return map;
- }
-
-
- }
|