123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
|
package com.shop.service.Impl;import com.github.wxpay.sdk.WXPay;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.common.BitMatrix;import com.shop.constant.WxPayConfig;import com.shop.mapper.*;import com.shop.pojo.IntegralLog;import com.shop.pojo.Orders;import com.shop.pojo.SystemOption;import com.shop.pojo.UserPayList;import com.shop.service.UserPayListService;import com.shop.service.WxPayService;import com.shop.utils.WxPayUtils;import com.shop.utils.XmlUtils;import org.jdom2.JDOMException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Repository;import org.springframework.stereotype.Service;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.*;import java.util.concurrent.TimeUnit;import static com.shop.constant.PayConstant.*;/** * @author 阳十三 * @email wdful165177@gmail.com * @blog http://www.item1024.com * @date 2017/9/12 */@Servicepublic class WxPayServiceImpl implements WxPayService { @Autowired private RedisTemplate<String, String> redisTemplate; @Resource private UserPayListMapper userPayListMapper; private WxPayConfig wxPayConfig; private WXPay wxPay; @Resource private OrdersMapper ordersMapper; @Resource private UserInfoMapper userInfoMapper; @Resource private SystemOptionMapper systemOptionMapper; @Resource private IntegralLogMapper integralLogMapper; /** * @param out_trade_no 商户订单号 * @param total_fee 标价金额 * @param userId 用户id * @param productId 商品id * @return 微信支付所需的二维码生成的 短链接 */ @Override public String wxPayByQrcode(String out_trade_no, String total_fee, String productId, int userId) throws Exception { System.out.println("Wxpay start"); //防止请求二维码的时候订单号会重复 if (redisTemplate.hasKey(out_trade_no)) { System.out.println("Wxpay二维码存在 返回缓存的二维码"); return redisTemplate.opsForValue().get(out_trade_no); } UserPayList userPayList = new UserPayList(); userPayList.setOrderId((out_trade_no)); userPayList.setPayAmount(Double.valueOf(total_fee) / 100); userPayList.setPayType(WEPAY); userPayList.setPayCreatetime(new java.sql.Date(System.currentTimeMillis())); userPayList.setUserId(userId); userPayList.setpStatus(0); String code_url = "订单重复了"; wxPayConfig = new WxPayConfig(); wxPay = new WXPay(wxPayConfig); String currTime = WxPayUtils.getCurrTime(); String strTime = currTime.substring(8, currTime.length()); String strRandom = WxPayUtils.buildRandom(4) + ""; String nonce_str = strTime + strRandom; //设置请求参数 Map<String, String> data = new HashMap<String, String>(); data.put("body", "奥农汇"); data.put("out_trade_no", out_trade_no); data.put("nonce_str", nonce_str); data.put("fee_type", "CNY"); data.put("total_fee", total_fee); data.put("spbill_create_ip", CREATE_IP); data.put("notify_url", NOTIFY_URL); data.put("trade_type", TRADE_TYPE); // 此处指定为扫码支付 data.put("product_id", productId); try { //发起支付 Map<String, String> resp = wxPay.unifiedOrder(data); System.out.println(resp); if (resp.get("result_code").equals("SUCCESS")) { //获取二维码URL code_url = resp.get("code_url"); userPayListMapper.insertSelective(userPayList); //存入redis 防止二次请求重复 redisTemplate.opsForValue().set(out_trade_no, code_url); //设置半个小时二维码过期 redisTemplate.expire(out_trade_no, 15, TimeUnit.MINUTES); } } catch (Exception e) { e.printStackTrace(); } return code_url; } @Override public String wxPayRefund(String out_trade_no, String total_fee, String out_refund_no, String refund_fee) throws Exception { //设置请求参数 String flag = "FAIL"; HashMap<String, String> data = new HashMap<String, String>(); wxPayConfig = new WxPayConfig(); wxPay = new WXPay(wxPayConfig); data.put("out_trade_no", out_trade_no); data.put("out_refund_no", out_refund_no); data.put("total_fee", total_fee); data.put("refund_fee", refund_fee); data.put("refund_fee_type", "CNY"); try { //调用sdk发起退款 Map<String, String> result = wxPay.refund(data); System.out.println(result); if ("SUCCESS".equals(result.get("result_code"))) { //TODO:更新订单 System.out.println("订单" + result.get("out_trade_no") + "微信退款成功"); try { ordersMapper.updateStaByOrderIdAndSta(result.get("out_trade_no"), 8, 6); flag = "SUCCESS"; } catch (Exception e) { e.getStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } return flag; } @Override public void wxPayNotify(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格式数据 String notifyData = sb.toString(); // 转换成map Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData); //支付确认内容 String resXml = ""; wxPayConfig = new WxPayConfig(); wxPay = new WXPay(wxPayConfig); //验证签名 if (wxPay.isPayResultNotifySignatureValid(notifyMap)) { // 签名正确 if (notifyMap.get("out_trade_no") != null) { if ("SUCCESS".equals(notifyMap.get("result_code"))) { //交易成功 // TODO:更新订单 System.out.println("订单" + notifyMap.get("out_trade_no") + "微信支付成功"); try { //更改订单状态 ordersMapper.updateStaByOrderIdAndSta(notifyMap.get("out_trade_no"), 1, 2); //更改支付记录表状态 userPayListMapper.updateStaByOrderIdAndSta(notifyMap.get("out_trade_no"), 0, 1); //增加用户积分 int userid = userPayListMapper.selectUserIdByOrderId(notifyMap.get("out_trade_no")); //获取积分规则 SystemOption systemOption = systemOptionMapper.selectByPrimaryKey(1); Double amount = Double.parseDouble(notifyMap.get("total_fee")) / 100 / systemOption.getIntegralMinusrule(); userInfoMapper.updateAmountByUserIdInc(amount, userid); //积分日志 IntegralLog integralLog = new IntegralLog(); integralLog.setIntegralChangenum(amount); integralLog.setIntegralChangereason("购买商品"); integralLog.setIntegralChangetime(new Date(System.currentTimeMillis())); integralLog.setIntegralChangetype(1); integralLog.setIntegralRestnum(0.00); integralLogMapper.insertSelective(integralLog); //设置成功确认内容 resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> "; } catch (Exception e) { System.out.println("更改订单状态异常"); e.getStackTrace(); } } else { //交易失败 try { ordersMapper.updateStaByOrderIdAndSta(notifyMap.get("out_trade_no"), null, 7); } catch (Exception e) { e.getStackTrace(); } resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg></return_msg>" + "</xml> "; System.out.println("订单" + notifyMap.get("out_trade_no") + "微信支付失败"); } } // 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功 } else { // 签名错误,如果数据里没有sign字段,也认为是签名错误 //设置失败确认内容 resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg></return_msg>" + "</xml> "; System.out.println("订单" + notifyMap.get("out_trade_no") + "微信支付失败"); } //发送通知 response.getWriter().println(resXml); } /** * * @param out_trade_no 订单号 * @return * @throws Exception */ @Override public Map<String, String> wxPayQuery(String out_trade_no) throws Exception { HashMap<String, String> data = new HashMap<String, String>(); Map<String, String> result = new HashMap<>(); wxPayConfig = new WxPayConfig(); wxPay = new WXPay(wxPayConfig); data.put("out_trade_no", out_trade_no); try { //调用sdk发起退款 result = wxPay.orderQuery(data); }catch (Exception e){ e.getStackTrace(); } return result; }}
|
用户点评