new-dev
parent
7c837c272e
commit
88cd132792
File diff suppressed because one or more lines are too long
@ -0,0 +1,81 @@ |
|||||||
|
package com.web.controller.notify; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.hai.entity.HighOrder; |
||||||
|
import com.hai.order.service.OrderPaySuccessService; |
||||||
|
import com.hai.order.service.OrderService; |
||||||
|
import com.hai.order.type.OrderPayType; |
||||||
|
import com.hai.order.type.OrderStatus; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.stereotype.Controller; |
||||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||||
|
import org.springframework.web.bind.annotation.RequestMethod; |
||||||
|
import org.springframework.web.bind.annotation.ResponseBody; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import javax.servlet.http.HttpServletResponse; |
||||||
|
import java.io.PrintWriter; |
||||||
|
import java.math.BigDecimal; |
||||||
|
|
||||||
|
@Controller |
||||||
|
@RequestMapping(value = "/huiPayNotify") |
||||||
|
@Api(value = "惠支付业务通知") |
||||||
|
public class HuiPayNotifyController { |
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(HuiPayNotifyController.class); |
||||||
|
|
||||||
|
@Resource |
||||||
|
private OrderService orderService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private OrderPaySuccessService paySuccessService; |
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping(value = "/huiPayCallback", method = RequestMethod.POST) |
||||||
|
@ApiOperation(value = "惠支付回调") |
||||||
|
@ResponseBody |
||||||
|
public void huiPayCallback(@RequestBody String reqBodyStr, HttpServletResponse response) { |
||||||
|
try { |
||||||
|
log.info("===============惠支付回调start=================="); |
||||||
|
JSONObject dataObject = JSONObject.parseObject(reqBodyStr, JSONObject.class); |
||||||
|
// 处理业务
|
||||||
|
log.info("开始处理业务"); |
||||||
|
log.info("惠支付-回调参数: " + dataObject); |
||||||
|
|
||||||
|
// 查询交易订单
|
||||||
|
HighOrder order = orderService.getOrderDetailByNo(dataObject.getString("outTradeNo")); |
||||||
|
if (order != null && order.getOrderStatus().equals(OrderStatus.STATUS1.getNumber())) { |
||||||
|
// 处理订单业务
|
||||||
|
paySuccessService.orderPaySuccessHandle(dataObject.getString("outTradeNo"), |
||||||
|
OrderPayType.PAY_TYPE2, |
||||||
|
dataObject.getString("accTradeNo"), |
||||||
|
dataObject.getBigDecimal("tradeAmount"), |
||||||
|
null); |
||||||
|
} |
||||||
|
log.info("处理业务完成"); |
||||||
|
log.info("============回调任务End============="); |
||||||
|
|
||||||
|
|
||||||
|
response.setCharacterEncoding("UTF-8"); |
||||||
|
response.setContentType("text/html;charset=utf-8"); |
||||||
|
PrintWriter writer= response.getWriter(); |
||||||
|
|
||||||
|
JSONObject postJson = new JSONObject(); |
||||||
|
postJson.put("code" ,"SUCCESS"); |
||||||
|
postJson.put("message" ,"执行成功"); |
||||||
|
writer.write(postJson.toJSONString()); |
||||||
|
writer.flush(); |
||||||
|
writer.close(); |
||||||
|
|
||||||
|
} catch (Exception e) { |
||||||
|
log.error("订单处理异常", e); |
||||||
|
} finally { |
||||||
|
log.info("===============微信支付回调end=================="); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package com.hai.pay.channel.huipay; |
||||||
|
|
||||||
|
public class TradeService { |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,117 @@ |
|||||||
|
package com.hai.pay.channel.huipay.config; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import com.hai.common.exception.ErrorCode; |
||||||
|
import com.hai.common.exception.ErrorHelp; |
||||||
|
import com.hai.common.exception.SysCode; |
||||||
|
import com.hai.common.pay.WechatPayUtil; |
||||||
|
import com.hai.common.utils.HttpsUtils; |
||||||
|
import com.hai.config.CommonSysConst; |
||||||
|
import com.hai.dao.HighPayRecordMapper; |
||||||
|
import com.hai.entity.HighOrder; |
||||||
|
import com.hai.entity.HighPayRecord; |
||||||
|
import com.hai.order.utils.OrderUtil; |
||||||
|
import com.hai.pay.channel.huipay.utils.SignatureUtil; |
||||||
|
import com.hai.service.HighOrderService; |
||||||
|
import com.hai.service.pay.PayRecordService; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
import org.springframework.stereotype.Component; |
||||||
|
|
||||||
|
import javax.annotation.Resource; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.math.BigDecimal; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.SortedMap; |
||||||
|
import java.util.TreeMap; |
||||||
|
|
||||||
|
@Component |
||||||
|
public class HuiConfig { |
||||||
|
|
||||||
|
@Resource |
||||||
|
private PayRecordService payRecordService; |
||||||
|
|
||||||
|
@Resource |
||||||
|
private HighOrderService highOrderService; |
||||||
|
|
||||||
|
private static Logger log = LoggerFactory.getLogger(HuiConfig.class); |
||||||
|
|
||||||
|
// 请求地址
|
||||||
|
public final static String postUrl = "https://pay.dctpay.com/openApi/v1/"; |
||||||
|
|
||||||
|
// 渝北区浩联物资经营部
|
||||||
|
public final static String hlMerNo = "2023090816465844909"; |
||||||
|
|
||||||
|
// 渝北区浩联物资经营部
|
||||||
|
public final static String hlKey = "ZatCMLMSZxnkc2rk7dtpTORMLcKetcKt"; |
||||||
|
|
||||||
|
public final static String hlSubAppid = "wx8d49e2f83025229d"; |
||||||
|
|
||||||
|
/** |
||||||
|
* @Author Sum1Dream |
||||||
|
* @Name preorder |
||||||
|
* @Description // 发起支付
|
||||||
|
* @Date 16:35 2023/9/13 |
||||||
|
* @Param object |
||||||
|
* @return java.util.SortedMap<java.lang.Object,java.lang.Object> |
||||||
|
*/ |
||||||
|
public SortedMap<Object,Object> preorder(JSONObject object) throws Exception { |
||||||
|
object.put("merchantNo" , hlMerNo); |
||||||
|
object.put("subAppid" , hlSubAppid); |
||||||
|
object.put("sign" , SignatureUtil.createSign(object , hlKey)); |
||||||
|
|
||||||
|
JSONObject jsonObject = HttpsUtils.doPost(postUrl + "trade/preorder", object, new HashMap<>()); |
||||||
|
// 签名校验
|
||||||
|
SortedMap<Object,Object> sortedMap = null; |
||||||
|
if (jsonObject.getString("return_code").equals("000000")) { |
||||||
|
|
||||||
|
JSONObject payParam = jsonObject.getJSONObject("return_data").getJSONObject("payParam"); |
||||||
|
sortedMap = new TreeMap<>(); |
||||||
|
sortedMap.put("appId", payParam.get("app_id")); |
||||||
|
sortedMap.put("nonceStr", payParam.get("nonce_str")); |
||||||
|
sortedMap.put("timeStamp", payParam.get("time_stamp")); |
||||||
|
sortedMap.put("signType", "MD5"); |
||||||
|
sortedMap.put("package", payParam.get("package")); |
||||||
|
sortedMap.put("sign", payParam.get("pay_sign")); |
||||||
|
|
||||||
|
// 将支付请求存入支付纪录
|
||||||
|
HighPayRecord payRecord = new HighPayRecord(); |
||||||
|
payRecord.setBodyInfo(String.valueOf(payParam)); |
||||||
|
payRecord.setResType(1); |
||||||
|
payRecord.setPayType(2); |
||||||
|
payRecord.setPayMoney(object.getBigDecimal("totalAmount")); |
||||||
|
payRecordService.addPayRecord(payRecord); |
||||||
|
|
||||||
|
} else { |
||||||
|
log.error("微信支付 -> 组装支付参数:支付信息错误"); |
||||||
|
log.error("错误信息:" + jsonObject.getString("return_msg")); |
||||||
|
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法支付,请稍后重新提交订单支付!"); |
||||||
|
} |
||||||
|
|
||||||
|
return sortedMap; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @Author Sum1Dream |
||||||
|
* @Name refund |
||||||
|
* @Description // 发起退款
|
||||||
|
* @Date 16:35 2023/9/13 |
||||||
|
* @Param orderNo |
||||||
|
* @return com.alibaba.fastjson.JSONObject |
||||||
|
*/ |
||||||
|
public JSONObject refund(HighOrder order) throws Exception { |
||||||
|
|
||||||
|
JSONObject object = new JSONObject(); |
||||||
|
object.put("merchantNo" , hlMerNo); |
||||||
|
object.put("outTradeNo" , order.getOrderNo()); |
||||||
|
object.put("refundTradeNo" , OrderUtil.generateRefundOrderNo()); |
||||||
|
object.put("refundAmount" , order.getPayRealPrice()); |
||||||
|
object.put("sign" , SignatureUtil.createSign(object , hlKey)); |
||||||
|
|
||||||
|
return HttpsUtils.doPost(postUrl + "trade/refund", object, new HashMap<>()); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,99 @@ |
|||||||
|
package com.hai.pay.channel.huipay.utils; |
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject; |
||||||
|
import org.apache.commons.lang3.StringUtils; |
||||||
|
|
||||||
|
import javax.xml.bind.annotation.adapters.HexBinaryAdapter; |
||||||
|
import java.security.MessageDigest; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Set; |
||||||
|
import java.util.concurrent.ExecutorService; |
||||||
|
import java.util.concurrent.Executors; |
||||||
|
|
||||||
|
/** |
||||||
|
* 签名工具类 |
||||||
|
*/ |
||||||
|
public class SignatureUtil { |
||||||
|
|
||||||
|
/** |
||||||
|
* 参数签名 |
||||||
|
* @param param 参数 |
||||||
|
* @param key 秘钥 |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static String createSign(Object param, String key) throws Exception { |
||||||
|
Map map = JSONObject.parseObject(JSONObject.toJSONString(param), Map.class); |
||||||
|
return md5Encode(paramSort(map, key).getBytes()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 验证签名 |
||||||
|
* @param checkSign 需验证的签名字符串 |
||||||
|
* @param param 参数 |
||||||
|
* @param key 秘钥 |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static Boolean checkSign(String checkSign,Object param, String key) throws Exception { |
||||||
|
Map map = JSONObject.parseObject(JSONObject.toJSONString(param), Map.class); |
||||||
|
// 去除签名
|
||||||
|
map.remove("sign"); |
||||||
|
if (checkSign.equals(createSign(map, key))) { |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 参数排序 |
||||||
|
* @param param |
||||||
|
* @return |
||||||
|
*/ |
||||||
|
public static String paramSort(final Map<String, Object> param, String key) { |
||||||
|
Set<String> keySet = param.keySet(); |
||||||
|
String[] keyArray = keySet.toArray(new String[keySet.size()]); |
||||||
|
Arrays.sort(keyArray); |
||||||
|
StringBuilder sb = new StringBuilder(); |
||||||
|
for (String k : keyArray) { |
||||||
|
if (StringUtils.isBlank(sb.toString())) { |
||||||
|
sb.append(k).append("=").append(param.get(k)); |
||||||
|
} else { |
||||||
|
sb.append("&").append(k).append("=").append(param.get(k)); |
||||||
|
} |
||||||
|
} |
||||||
|
sb.append("&key=").append(key); |
||||||
|
return sb.toString(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* MD5加密 |
||||||
|
* @param data |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public static String md5Encode(byte[] data) throws Exception { |
||||||
|
// 初始化MessageDigest
|
||||||
|
MessageDigest md = MessageDigest.getInstance("MD5"); |
||||||
|
// 执行摘要信息
|
||||||
|
byte[] digest = md.digest(data); |
||||||
|
// 将摘要信息转换为32位的十六进制字符串
|
||||||
|
return new String(new HexBinaryAdapter().marshal(digest)); |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception { |
||||||
|
String paramStr = "{\n" + |
||||||
|
" \"merchantNo\": \"2023090816465844909\",\n" + |
||||||
|
" \"outTradeNo\": \"ZF1130202305051459532538973458\",\n" + |
||||||
|
" \"payMode\": \"WECHAT\",\n" + |
||||||
|
" \"totalAmount\": 0.01,\n" + |
||||||
|
" \"transType\": \"JSAPI\",\n" + |
||||||
|
" \"profitSharing\": 0,\n" + |
||||||
|
" \"specialField\": \"测试\"" + |
||||||
|
"}"; |
||||||
|
String sign = createSign(JSONObject.parseObject(paramStr), "ZatCMLMSZxnkc2rk7dtpTORMLcKetcKt"); |
||||||
|
System.out.println(sign); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue