pom.xml | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/controller/UnipayController.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/model/UnipayDto.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/service/UnipayService.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/service/impl/UnipayServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/util/HttpRequester.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/pay/util/HttpRespons.java | ●●●●● patch | view | raw | blame | history | |
src/test/java/cc/mrbird/febs/ProfitTest.java | ●●●●● patch | view | raw | blame | history |
pom.xml
@@ -29,6 +29,12 @@ <dependencies> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.0</version> </dependency> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>${aliyun-oss.version}</version> src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallOrderInfoServiceImpl.java
@@ -1,5 +1,6 @@ package cc.mrbird.febs.mall.service.impl; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.common.enumerates.*; import cc.mrbird.febs.common.exception.FebsException; import cc.mrbird.febs.common.utils.AppContants; @@ -16,18 +17,23 @@ import cc.mrbird.febs.mall.vo.OrderDetailVo; import cc.mrbird.febs.mall.vo.OrderListVo; import cc.mrbird.febs.mall.vo.OrderRefundVo; import cc.mrbird.febs.pay.model.UnipayDto; import cc.mrbird.febs.pay.service.IPayService; import cc.mrbird.febs.pay.service.UnipayService; import cc.mrbird.febs.rabbit.producter.AgentProducer; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUnit; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -61,6 +67,7 @@ private final AgentProducer agentProducer; private final IPayService payService; private final IMallAchieveService mallAchieveService; private final UnipayService unipayService; @Override @Transactional(rollbackFor = Exception.class) @@ -198,6 +205,13 @@ this.baseMapper.updateById(orderInfo); } public static void main(String[] args) { String unipayStr = "{\"r1_MerchantNo\":\"888118000001971\",\"rd_Pic\":\"\",\"r6_FrpCode\":\"ALIPAY_H5\",\"r7_TrxNo\":\"100222082332490699\",\"r0_Version\":\"1.0\",\"r3_Amount\":\"0.01\",\"r4_Cur\":\"1\",\"r2_OrderNo\":\"2022082212510288174\",\"rb_CodeMsg\":\"\",\"hmac\":\"1659BB77DEDDF9956EA4D6DF227C3B14\",\"ra_Code\":100,\"rc_Result\":\"<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title></title></head><body><script type='text/javascript'>location.href='https://qr.alipay.com/bax019737vbdwoisxcdp00a2';</script></body></html>\"}"; JSONObject jsonObject = JSONUtil.parseObj(unipayStr); String r7_trxNo = (String) jsonObject.get("r7_TrxNo"); System.out.println(r7_trxNo); } @Override @Transactional(rollbackFor = Exception.class) public Map<String, Object> payOrder(PayOrderDto payOrderDto) { @@ -212,6 +226,7 @@ } String payResultStr = ""; String rcResult = ""; switch (payOrderDto.getType()) { case "1": // orderInfo.setPayOrderNo(payOrderDto.getPayOrderNo()); @@ -220,12 +235,32 @@ agentProducer.sendOrderReturn(orderInfo.getId()); break; case "2": if (StrUtil.isNotBlank(orderInfo.getPayOrderNo())) { payResultStr = orderInfo.getPayOrderNo(); // if (StrUtil.isNotBlank(orderInfo.getPayOrderNo())) { // payResultStr = orderInfo.getPayOrderNo(); // } else { // payResultStr = payService.aliPay(orderInfo); // } UnipayDto unipayDto = new UnipayDto(); // unipayDto.setAmount(new BigDecimal("0.01")); unipayDto.setAmount(orderInfo.getAmount()); unipayDto.setFrpCode("ALIPAY_H5"); unipayDto.setTradeMerchantNo("777180800385820"); unipayDto.setOrderNo(orderInfo.getOrderNo()); List<MallOrderItem> items = orderInfo.getItems(); if(CollUtil.isEmpty(items)){ unipayDto.setProductName("商品"); } else { payResultStr = payService.aliPay(orderInfo); unipayDto.setProductName(items.get(0).getGoodsName()); } String unipayStr = unipayService.unipay(unipayDto); if("fail" == unipayStr){ throw new FebsException("支付失败"); }else{ JSONUtil.parseObj(unipayStr); JSONObject jsonObject = JSONUtil.parseObj(unipayStr); payResultStr = (String) jsonObject.get("r7_TrxNo"); rcResult = (String) jsonObject.get("rc_Result"); } orderInfo.setPayOrderNo(payResultStr); orderInfo.setPayMethod("支付宝支付"); agentProducer.sendOrderReturn(orderInfo.getId()); @@ -303,6 +338,7 @@ map.put("orderInfo", payResultStr); map.put("orderNo", orderInfo.getOrderNo()); map.put("orderId", orderInfo.getId()); map.put("rcResult", rcResult); return map; } src/main/java/cc/mrbird/febs/pay/controller/UnipayController.java
@@ -9,6 +9,7 @@ import cc.mrbird.febs.pay.model.UniPayCallBackDto; import cc.mrbird.febs.rabbit.producter.AgentProducer; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; @@ -51,7 +52,10 @@ log.info("进入汇聚支付回调"+orderNo+";"+orderAmount+";"+payTradeNo+";"+callBackState); if("100".equals(callBackState) && StrUtil.isNotBlank(orderNo)){ MallOrderInfo orderInfo = orderInfoMapper.selectByOrderNo(orderNo); BigDecimal amount = orderInfo.getAmount(); if(ObjectUtil.isNotEmpty(orderInfo)){ Integer status = orderInfo.getStatus(); if(OrderStatusEnum.WAIT_PAY.getValue() == status){ // BigDecimal amount = orderInfo.getAmount(); // if(amount.compareTo(orderAmount) == 0){ MallMember member = memberService.getById(orderInfo.getMemberId()); if (AgentLevelEnum.ZERO_LEVEL.name().equals(member.getLevel())) { @@ -68,6 +72,8 @@ agentProducer.sendAutoLevelUpMsg(orderInfo.getMemberId()); // } } } } return "success"; } src/main/java/cc/mrbird/febs/pay/model/UnipayDto.java
New file @@ -0,0 +1,29 @@ package cc.mrbird.febs.pay.model; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.validation.constraints.NotBlank; import java.math.BigDecimal; @Data @ApiModel(value = "UnipayDto", description = "汇聚支付接收参数类") public class UnipayDto { @ApiModelProperty(value = "订单编号", example = "123") private String orderNo; @ApiModelProperty(value = "订单金额", example = "123") private BigDecimal amount; @ApiModelProperty(value = "商品名称", example = "123") private String productName; @ApiModelProperty(value = "交易类型", example = "123") private String frpCode; @ApiModelProperty(value = "报备商户号", example = "123") private String tradeMerchantNo; } src/main/java/cc/mrbird/febs/pay/service/UnipayService.java
New file @@ -0,0 +1,10 @@ package cc.mrbird.febs.pay.service; import cc.mrbird.febs.pay.model.UnipayDto; import com.sun.org.apache.xpath.internal.operations.Bool; public interface UnipayService { String unipay(UnipayDto unipayDto); } src/main/java/cc/mrbird/febs/pay/service/impl/UnipayServiceImpl.java
New file @@ -0,0 +1,134 @@ package cc.mrbird.febs.pay.service.impl; import cc.mrbird.febs.common.entity.FebsResponse; import cc.mrbird.febs.pay.model.UnipayDto; import cc.mrbird.febs.pay.service.UnipayService; import cc.mrbird.febs.pay.util.HttpRequester; import cc.mrbird.febs.pay.util.HttpRespons; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.util.*; @Slf4j @Service public class UnipayServiceImpl implements UnipayService { public static final String notifyUrl = "http://47.111.90.145:8800/api/unipay/unipayCallBack"; @Override @Transactional public String unipay(UnipayDto unipayDto) { String key = "2e95f6a3e11e47fa8a4386d6aefe1735";/** md5密钥商户后台-商户中心-商户设置-密钥管理获取 必填!*/ Map<String, String> map = new HashMap<String, String>(); map.put("p0_Version", "1.0");/** 版本号 */ map.put("p1_MerchantNo", "888118000001971");/** 商户编号 */ map.put("p2_OrderNo", unipayDto.getOrderNo()); /**商户订单号*/ map.put("p3_Amount", unipayDto.getAmount().toString());/**订单金额*/ map.put("p4_Cur", "1"); /**交易币种 */ map.put("p5_ProductName", unipayDto.getProductName()); /** 商品名称 */ map.put("p9_NotifyUrl", notifyUrl); /** 服务器异步通知地址 */ map.put("q1_FrpCode", unipayDto.getFrpCode()); /** 交易类型*/ map.put("qa_TradeMerchantNo",unipayDto.getTradeMerchantNo()); /** 777开头的报备商户号 必填!*/ map.put("q7_AppId", "wx42ce0fbc27965fe9"); /** 777开头的报备商户号 必填!*/ String Strmap = createLinkStringByGet(map); // 签名 String sign = ""; sign = SignByMD5(Strmap, key); map.put("hmac", sign);/** 签名数据 */ System.out.println("发送:" + JSON.toJSONString(map).toString()); // post请求参数内容 HttpRequester hr = new HttpRequester(); HttpRespons HP = null; try { HP = hr.sendPost("https://www.joinpay.com/trade/uniPayApi.action", map); } catch (IOException e) { e.printStackTrace(); } System.out.println("接收返回参数:" + HP.getContent()); Boolean result = false; try { result = nosign(HP.getContent(), key); } catch (Exception e) { e.printStackTrace(); } if(result){ return HP.getContent(); }else{ return "fail"; } } //参数的拼接整理 private String createLinkStringByGet(Map<String, String> params){ // TODO Auto-generated method stub List<String> keys = new ArrayList<String>(params.keySet()); Collections.sort(keys); String str1 =""; for(int i=0;i<keys.size();i++) { String key = keys.get(i); Object value = params.get(key);//(String) 强制类型转换 if(value instanceof Integer) { value = (Integer)value; } if(i==keys.size()-1) { str1 = str1+value.toString(); }else { str1 = str1+value; } } System.out.println("整理"+str1); return str1; } /** * MD5签名 * * @param requestSign 请求签名串 * @param merchantKey 商户秘钥 */ private String SignByMD5(String requestSign, String merchantKey) { String reqHmac = ""; try { reqHmac = DigestUtils.md5Hex(requestSign + merchantKey).toUpperCase(); } catch (Exception e) {} return reqHmac; } /** * 验证返回参数 * @param hp * @param key * @return * @throws Exception */ private boolean nosign(String hp, String key){ System.out.println("接收到:" + hp); JSONObject myJson = JSONObject.parseObject(hp); Map m = myJson; // 返回hmac String returnHmac = (String) m.remove("hmac"); System.out.println(m.toString()); String Strmap = createLinkStringByGet(m); // 返回参数组装hmac String hmac1 = SignByMD5(Strmap, key); return hmac1.equalsIgnoreCase(returnHmac); } } src/main/java/cc/mrbird/febs/pay/util/HttpRequester.java
New file @@ -0,0 +1,204 @@ package cc.mrbird.febs.pay.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.Charset; import java.util.Map; import java.util.Vector; public class HttpRequester { private String defaultContentEncoding; public HttpRequester() { this.defaultContentEncoding = Charset.defaultCharset().name(); } /** * 发送POST请求 * * @param urlString * URL地址 * @return 响应对象 * @throws IOException */ public HttpRespons sendPost(String urlString) throws IOException { return this.send(urlString, "POST", null, null); } /** * 发送POST请求 * * @param urlString * URL地址 * @param params * 参数集合 * @return 响应对象 * @throws IOException */ public HttpRespons sendPost(String urlString, Map<String, String> params) throws IOException { for(String key : params.keySet()) { if(params.get(key)!=null&&!"".equals(params.get(key))) { params.put(key, (String)URLEncoder.encode(params.get(key),"utf-8")) ;//(String) 强制类型转换 } } return this.send(urlString, "POST", params, null); } /** * 发送POST请求 * * @param urlString * URL地址 * @param params * 参数集合 * @param propertys * 请求属性 * @return 响应对象 * @throws IOException */ public HttpRespons sendPost(String urlString, Map<String, String> params, Map<String, String> propertys) throws IOException { return this.send(urlString, "POST", params, propertys); } /** * 发送HTTP请求 * * @param urlString * @return 响映对象 * @throws IOException */ private HttpRespons send(String urlString, String method, Map<String, String> parameters, Map<String, String> propertys) throws IOException { HttpURLConnection urlConnection = null; if (method.equalsIgnoreCase("GET") && parameters != null) { StringBuffer param = new StringBuffer(); int i = 0; for (String key : parameters.keySet()) { if (i == 0) param.append("?"); else param.append("&"); param.append(key).append("=").append(parameters.get(key)); i++; } urlString += param; } URL url = new URL(urlString); urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestMethod(method); urlConnection.setDoOutput(true); urlConnection.setDoInput(true); urlConnection.setUseCaches(false); if (propertys != null) for (String key : propertys.keySet()) { urlConnection.addRequestProperty(key, propertys.get(key)); } if (method.equalsIgnoreCase("POST") && parameters != null) { StringBuffer param = new StringBuffer(); for (String key : parameters.keySet()) { param.append("&"); param.append(key).append("=").append(parameters.get(key)); } urlConnection.getOutputStream().write(param.toString().getBytes()); urlConnection.getOutputStream().flush(); urlConnection.getOutputStream().close(); } return this.makeContent(urlString, urlConnection); } /** * 得到响应对象 * * @param urlConnection * @return 响应对象 * @throws IOException */ private HttpRespons makeContent(String urlString, HttpURLConnection urlConnection) throws IOException { HttpRespons httpResponser = new HttpRespons(); try { InputStream in = urlConnection.getInputStream(); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(in)); httpResponser.contentCollection = new Vector<String>(); StringBuffer temp = new StringBuffer(); String line = bufferedReader.readLine(); while (line != null) { httpResponser.contentCollection.add(line); temp.append(line).append("\r\n"); line = bufferedReader.readLine(); } bufferedReader.close(); String ecod = urlConnection.getContentEncoding(); if (ecod == null) ecod = this.defaultContentEncoding; httpResponser.urlString = urlString; httpResponser.defaultPort = urlConnection.getURL().getDefaultPort(); httpResponser.file = urlConnection.getURL().getFile(); httpResponser.host = urlConnection.getURL().getHost(); httpResponser.path = urlConnection.getURL().getPath(); httpResponser.port = urlConnection.getURL().getPort(); httpResponser.protocol = urlConnection.getURL().getProtocol(); httpResponser.query = urlConnection.getURL().getQuery(); httpResponser.ref = urlConnection.getURL().getRef(); httpResponser.userInfo = urlConnection.getURL().getUserInfo(); httpResponser.content = new String(temp.toString().getBytes(), ecod); httpResponser.contentEncoding = ecod; httpResponser.code = urlConnection.getResponseCode(); httpResponser.message = urlConnection.getResponseMessage(); httpResponser.contentType = urlConnection.getContentType(); httpResponser.method = urlConnection.getRequestMethod(); httpResponser.connectTimeout = urlConnection.getConnectTimeout(); httpResponser.readTimeout = urlConnection.getReadTimeout(); return httpResponser; } catch (IOException e) { throw e; } finally { if (urlConnection != null) urlConnection.disconnect(); } } /** * 默认的响应字符集 */ public String getDefaultContentEncoding() { return this.defaultContentEncoding; } /** * 设置默认的响应字符集 */ public void setDefaultContentEncoding(String defaultContentEncoding) { this.defaultContentEncoding = defaultContentEncoding; } } src/main/java/cc/mrbird/febs/pay/util/HttpRespons.java
New file @@ -0,0 +1,181 @@ package cc.mrbird.febs.pay.util; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.InputStreamRequestEntity; import org.apache.commons.httpclient.methods.PostMethod; import org.apache.commons.httpclient.methods.RequestEntity; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Vector; public class HttpRespons { String urlString; int defaultPort; String file; String host; String path; int port; String protocol; String query; String ref; String userInfo; String contentEncoding; String content; String contentType; int code; String message; String method; int connectTimeout; int readTimeout; Vector<String> contentCollection; public String getContent() { return content; } public String getContentType() { return contentType; } public int getCode() { return code; } public String getMessage() { return message; } public Vector<String> getContentCollection() { return contentCollection; } public String getContentEncoding() { return contentEncoding; } public String getMethod() { return method; } public int getConnectTimeout() { return connectTimeout; } public int getReadTimeout() { return readTimeout; } public String getUrlString() { return urlString; } public int getDefaultPort() { return defaultPort; } public String getFile() { return file; } public String getHost() { return host; } public String getPath() { return path; } public int getPort() { return port; } public String getProtocol() { return protocol; } public String getQuery() { return query; } public String getRef() { return ref; } public String getUserInfo() { return userInfo; } public static String post(String params,String requestUrl) throws IOException { // TODO Auto-generated method stub // try { //HttpRequester request = new HttpRequester(); // request.setDefaultContentEncoding("utf-8"); byte[] requestBytes = params.getBytes("utf-8"); // 将参数转为二进制流 HttpClient httpClient = new HttpClient(); // 客户端实例化 PostMethod postMethod = new PostMethod(requestUrl); //设置请求头Authorization // postMethod.setRequestHeader("Authorization", "Basic " + authorization); // 设置请求头 Content-Type postMethod.setRequestHeader("Content-Type", "application/json"); InputStream inputStream = new ByteArrayInputStream(requestBytes, 0,requestBytes.length); RequestEntity requestEntity = new InputStreamRequestEntity(inputStream, requestBytes.length, "application/json; charset=utf-8"); // 请求体 postMethod.setRequestEntity(requestEntity); httpClient.executeMethod(postMethod);// 执行请求 InputStream soapResponseStream = postMethod.getResponseBodyAsStream();// 获取返回的流 byte[] datas = null; try { datas = readInputStream(soapResponseStream);// 从输入流中读取数据 } catch (Exception e) { e.printStackTrace(); } String result = new String(datas, "UTF-8");// 将二进制流转为String // 打印返回结果 // System.out.println(result); return result; } /** * 从输入流中读取数据 * * @param inStream * @return * @throws Exception */ public static byte[] readInputStream(InputStream inStream) throws Exception { ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } byte[] data = outStream.toByteArray(); outStream.close(); inStream.close(); return data; } } src/test/java/cc/mrbird/febs/ProfitTest.java
@@ -7,6 +7,8 @@ import cc.mrbird.febs.mall.service.IAgentService; import cc.mrbird.febs.mall.service.IMallAchieveService; import cc.mrbird.febs.mall.service.IMemberProfitService; import cc.mrbird.febs.pay.model.UnipayDto; import cc.mrbird.febs.pay.service.UnipayService; import cc.mrbird.febs.rabbit.consumer.AgentConsumer; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -113,4 +115,19 @@ mallAchieveService.add(83L); } @Autowired private UnipayService unipayService; @Test public void unipay(){ UnipayDto unipayDto = new UnipayDto(); unipayDto.setAmount(new BigDecimal("0.01")); unipayDto.setFrpCode("ALIPAY_H5"); unipayDto.setTradeMerchantNo("777180800385820"); // unipayDto.setFrpCode("WEIXIN_APP3"); unipayDto.setOrderNo("2022082316415386395"); unipayDto.setProductName("洗护套装"); unipayService.unipay(unipayDto); } }