package com.swpu.uchain.takeawayapplet.service.impl;
import com.swpu.uchain.takeawayapplet.VO.ResultVO;
import com.swpu.uchain.takeawayapplet.config.UrlProperties;
import com.swpu.uchain.takeawayapplet.config.WeChatProperties;
import com.swpu.uchain.takeawayapplet.dto.OrderDTO;
import com.swpu.uchain.takeawayapplet.enums.ResultEnum;
import com.swpu.uchain.takeawayapplet.exception.GlobalException;
import com.swpu.uchain.takeawayapplet.form.PayForm;
import com.swpu.uchain.takeawayapplet.form.RefundForm;
import com.swpu.uchain.takeawayapplet.service.MessageService;
import com.swpu.uchain.takeawayapplet.service.OrderService;
import com.swpu.uchain.takeawayapplet.service.PayService;
import com.swpu.uchain.takeawayapplet.util.GetOpenIdUtil;
import com.swpu.uchain.takeawayapplet.util.PayUtil;
import com.swpu.uchain.takeawayapplet.util.RandomUtil;
import com.swpu.uchain.takeawayapplet.util.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
//import com.swpu.uchain.takeawayapplet.service.MessageService;
/**
* @ClassName PayServiceImpl
* @Author hobo
* @Date 19-3-21 下午8:11
* @Description
**/
@Service
@Slf4j
public class PayServiceImpl implements PayService {
@Autowired
private WeChatProperties weChatProperties;
@Autowired
private UrlProperties urlProperties;
@Autowired
private OrderService orderService;
@Autowired
private MessageService messageService;
/**
* @return void
* @Author hobo
* @Description : 创建预支付请求
* @Param [orderDTO]
**/
@Override
public ResultVO creat(PayForm payForm, String code, HttpServletRequest request) {
try {
//生成随机字符串
String nonceStr = RandomUtil.getRandomStringByLength(32);
//商品简介
String body = new String(weChatProperties.getTitle().getBytes("ISO-8859-1"), "UTF-8");
//获得本机的ip地址
String spbillCreatIp = PayUtil.getIpAddr(request);
String ordNo = payForm.getId() + "";
//支付金额 单位:分 转为元
String totalFee = payForm.getOrderAmount().multiply(new BigDecimal(100)) + "";
String openId = GetOpenIdUtil.getOpenId(code);
//生成预支付订单
Map<String, String> packageParams = new HashMap<String, String>();
packageParams.put("appid", weChatProperties.getAppid());
packageParams.put("mch_id", weChatProperties.getMchId());
packageParams.put("nonce_str", nonceStr);
packageParams.put("body", body);
packageParams.put("out_trade_no", ordNo);
packageParams.put("totalFee", totalFee);
packageParams.put("spbill_create_ip", spbillCreatIp);
packageParams.put("notify_url", weChatProperties.getNotifyUrl());
packageParams.put("trade_type", weChatProperties.getTradeType());
packageParams.put("open_id", openId);
//除去数组中的空值和签名参数
packageParams = PayUtil.paraFileter(packageParams);
String preStr = PayUtil.createLinkString(packageParams);
//MD5运算生成签名,第一次签名 调用统一下单接口
String mySign = PayUtil.sign(preStr, weChatProperties.getMchKey(), "utf-8").toUpperCase();
log.info("====================第一次签名" + mySign + "====================");
//连同生成的签名一起拼接成xml数据
String xml = "</xml version='1.0' encoding='gdk'>"
+ "<appid>" + weChatProperties.getAppid() + "</appid>"
+ "<body><![CDATA]" + body + "]]></body>"
+ "<mch_id>" + weChatProperties.getMchId() + "</mch_id>"
+ "<nonce_str>" + nonceStr + "</nonce_str>"
+ "<openid>" + openId + "</openid>"
+ "<out_trade_no>" + ordNo + "<out_trade_no>"
+ "<spbill_create_ip>" + spbillCreatIp + "</spbill_create_ip>"
+ "<total_fee>" + totalFee + "</total_fee>"
+ "<trade_type>" + weChatProperties.getTradeType() + "</trade_type>"
+ "<sign>" + mySign + "</sign>"
+ "</xml>";
log.info("====================调试请求XML数据====================");
System.out.println(xml);
//调用统一下单接口
String result = PayUtil.httpRequest(urlProperties.getPayUrl(), "POST", xml);
log.info("====================调试返回XML数据====================");
System.out.println(result);
// 将解析结果放入HashMap中
Map map = PayUtil.doXMLParse(result);
String return_code = (String) map.get("return_code");
//返回移动端需要的参数
Map<String, Object> response = new HashMap<String, Object>();
//return_code 为成功 return_msg 为失败
if ("SUCCESS".equals(return_code)) {
//业务结果
String prepay_id = (String) map.get("prepay_id");
response.put("nonceStr", nonceStr);
response.put("package", "prepay_id" + prepay_id);
Long timeStamp = System.currentTimeMillis() / 1000;
//时间 类型转换为微信官方要求的String
response.put("time_stamp", timeStamp + "");
String stringSignTemp = "appId=" + weChatProperties.getAppid() + "&nonceStr=" + nonceStr
+ "&package=prepay_id" + prepay_id + "&signType=MD5" + "&timeStamp=" + timeStamp;
//再次签名 用于小程序端调用wx.requestPayment方法
String paySign = PayUtil.sign(stringSignTemp, weChatProperties.getMchKey(), "utf-8").toUpperCase();
log.info("===================第二次签名:" + paySign + "====================");
response.put("paySign", paySign);
}
response.put("appid", weChatProperties.getAppid());
return ResultUtil.success(response);
} catch (Exception e) {
e.printStackTrace();
return ResultUtil.error(ResultEnum.PAY_REQUEST_FAIL);
}
}
/**
* @return void
* @Author hobo
* @Description : 异步通知判断签名
* @Param [notifyData]
**/
@Override
public ResultVO notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
String line = null;
StringBuffer sb = new StringBuffer();
while ((line = br.readLine()) != null) {
sb.append(line);
}
br.close();
String notifyXml = sb.toString();
String resXml = "";
log.info("接收到的报文 notifyXml={}", notifyXml);
Map map = PayUtil.doXMLParse(notifyXml);
//从报文中获取值
String returnCode = (String) map.get("return_code");
String outTradeNo = (String) map.get("out_trade_no");
String totalFee = (String) map.get("total_fee");
Long orderId = Long.parseLong(outTradeNo);
OrderDTO orderDTO = orderService.findOrder(orderId);
if (!(orderDTO.getOrderAmount() + "").equals(totalFee)) {
throw new GlobalException(ResultEnum.AMOUNT_ERROR);
}
if ("SUCCESS".equals(returnCode)) {
//验证签名是�
![avatar](https://profile-avatar.csdnimg.cn/2b17cb8b32224168bb8ed166a94dd8f6_weixin_56154577.jpg!1)
JJJ69
- 粉丝: 6381
- 资源: 5917
最新资源
- Golang_Puzzlers-春节主题资源
- AndBase-javaEE框架项目资源
- 智慧园区管理系统-活动资源
- XLang-汇编语言资源
- 基于数据预处理与PSO-SVM优化的风功率预测及其聚类分析-一种提高预测准确性的方法,基于数据预处理与PSO-SVM优化的风功率预测及聚类分析-一种提高可再生能源预测准确性的方法,基于数据预处理和
- 风光储系统并网Simulink仿真建模深度分析:从原理到实践的应用研究,风光储系统并网技术:基于Simulink仿真建模的深度分析与研究,风光储系统并网simulink仿真建模分析 ,风光储系统; 并
- 基于自抗扰控制的幅频特性曲线研究:传函推导与PID等效在跟踪和抗扰曲线上的应用分析,基于自抗扰控制的幅频特性曲线研究:PID等效性及其在跟踪和抗扰曲线上的应用分析,自抗扰控制,幅频特性曲线,传函推导
- 小程序商城源码-Java-C语言资源
- 基于FPGA的高效OFDM调制解调技术实现,Verilog代码编写及FFT与IFFT的双重验证:包括详细的testbench操作流程及程序录像,基于FPGA的OFDM调制解调Verilog实现:包含I
- 基于FPGA的256点FFT算法Verilog实现与程序操作指南,包含Testbench及无IP核应用案例的演示录像,基于FPGA实现的256点FFT傅里叶变换算法与Verilog代码优化方案含测试与
- 基于两阶段鲁棒优化的微电网经济调度策略:应对分布式电源与负荷不确定性的高效调度方案,基于分布式电源与负荷不确定性的微电网两阶段鲁棒优化经济调度策略,微电网两阶段鲁棒优化经济调度方法 参考文献:微电网两
- 通过场分布分析光子晶体的色散特性研究,光子晶体色散研究:场分布与光子能量关系解析,通过场分布得到光子晶体的色散 ,场分布; 光子晶体; 色散,光子晶体色散分析:场分布的揭示与应用
- 小程序商城源码-Java-C++资源
- IOTGate-Java资源
- Aestate-Python资源
- nats.swift-Swift资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback-tip](https://img-home.csdnimg.cn/images/20220527035111.png)