parent
3cfe1aa378
commit
42dc475fb4
@ -1,61 +0,0 @@ |
||||
package com.web.controller; |
||||
|
||||
import com.alibaba.csp.sentinel.Entry; |
||||
import com.alibaba.csp.sentinel.SphU; |
||||
import com.alibaba.csp.sentinel.annotation.SentinelResource; |
||||
import com.alibaba.csp.sentinel.slots.block.BlockException; |
||||
import com.alibaba.csp.sentinel.slots.block.RuleConstant; |
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; |
||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; |
||||
import io.swagger.annotations.Api; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
@Controller |
||||
@RequestMapping(value = "/login") |
||||
@Api(value = "登录") |
||||
public class LoginController { |
||||
|
||||
private static Logger log = LoggerFactory.getLogger(LoginController.class); |
||||
|
||||
@SentinelResource("HelloWorld") |
||||
public void helloWorld() { |
||||
// 资源中的逻辑
|
||||
System.out.println("hello world"); |
||||
} |
||||
|
||||
|
||||
public static void main(String[] args) { |
||||
// 配置规则.
|
||||
initFlowRules(); |
||||
|
||||
int i = 0; |
||||
while (i <= 100) { |
||||
i++; |
||||
// 1.5.0 版本开始可以直接利用 try-with-resources 特性
|
||||
try (Entry entry = SphU.entry("HelloWorld")) { |
||||
// 被保护的逻辑
|
||||
System.out.println("hello world"); |
||||
} catch (BlockException ex) { |
||||
// 处理被流控的逻辑
|
||||
System.out.println("blocked!"); |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static void initFlowRules(){ |
||||
List<FlowRule> rules = new ArrayList<>(); |
||||
FlowRule rule = new FlowRule(); |
||||
rule.setResource("HelloWorld"); |
||||
rule.setGrade(RuleConstant.FLOW_GRADE_QPS); |
||||
// Set limit QPS to 20.
|
||||
rule.setCount(20); |
||||
rules.add(rule); |
||||
FlowRuleManager.loadRules(rules); |
||||
} |
||||
} |
@ -0,0 +1,124 @@ |
||||
package com.web.controller; |
||||
|
||||
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.util.IOUtil; |
||||
import com.hai.common.pay.util.XmlUtil; |
||||
import com.hai.entity.*; |
||||
import com.hai.order.service.OrderPaySuccessService; |
||||
import com.hai.order.service.OrderService; |
||||
import com.hai.order.type.OrderPayType; |
||||
import com.hai.service.pay.NotifyService; |
||||
import io.swagger.annotations.Api; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
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 javax.annotation.Resource; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.BufferedOutputStream; |
||||
import java.math.BigDecimal; |
||||
import java.net.URLDecoder; |
||||
import java.util.SortedMap; |
||||
|
||||
/** |
||||
* @className: OrderPayNotifyController |
||||
* @author: HuRui |
||||
* @date: 2022/9/8 |
||||
**/ |
||||
@Controller |
||||
@RequestMapping("/payNotify") |
||||
@Api(value = "订单支付") |
||||
public class OrderPayNotifyController { |
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderPayNotifyController.class); |
||||
|
||||
@Resource |
||||
private NotifyService notifyService; |
||||
|
||||
@Resource |
||||
private OrderService orderService; |
||||
|
||||
@Resource |
||||
private OrderPaySuccessService paySuccessService; |
||||
|
||||
@RequestMapping(value = "/wechatPay", method = RequestMethod.POST) |
||||
@ApiOperation(value = "微信支付 -> 异步回调") |
||||
public void wechatPay(HttpServletRequest request, HttpServletResponse response) { |
||||
try { |
||||
log.info("===============微信支付回调start=================="); |
||||
String resXml = ""; // 反馈给微信服务器
|
||||
String notifyXml = null; // 微信支付系统发送的数据(<![CDATA[product_001]]>格式)
|
||||
notifyXml = IOUtil.inputStreamToString(request.getInputStream(), "UTF-8"); |
||||
|
||||
log.info("回调参数: " + notifyXml); |
||||
SortedMap<String, String> map = XmlUtil.parseXmlToTreeMap(notifyXml, "UTF-8"); |
||||
log.info("开始处理订单: " + map.get("out_trade_no")); |
||||
|
||||
// 处理业务
|
||||
log.info("开始处理业务"); |
||||
paySuccessService.orderPaySuccessHandle(map.get("out_trade_no"), |
||||
OrderPayType.PAY_TYPE2, map.get("out_trade_no"), |
||||
new BigDecimal(map.get("total_fee")).divide(new BigDecimal("100")), |
||||
null); |
||||
log.info("处理业务完成"); |
||||
|
||||
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream()); |
||||
out.write(resXml.getBytes()); |
||||
out.flush(); |
||||
out.close(); |
||||
} catch (Exception e) { |
||||
log.error("订单处理异常", e); |
||||
} finally { |
||||
log.info("===============微信支付回调end=================="); |
||||
} |
||||
} |
||||
|
||||
@RequestMapping(value = "/unionPay", method = RequestMethod.POST) |
||||
@ApiOperation(value = "银联支付 -> 异步回调") |
||||
public void unionPay(@RequestBody String params, HttpServletRequest request, HttpServletResponse response) { |
||||
try { |
||||
log.info("===============银联支付回调start=================="); |
||||
log.info("回调参数: " + params); |
||||
if (StringUtils.isNotBlank(params)) { |
||||
// 参数解码
|
||||
String paramsStr = URLDecoder.decode(params,"utf-8"); |
||||
JSONObject body = JSONObject.parseObject(paramsStr.substring(0, paramsStr.length() - 1)); |
||||
log.info("开始处理订单: " + body.getString("tradetrace")); |
||||
|
||||
// 查询订单信息
|
||||
HighOrder order = orderService.getOrderDetailByNo(body.getString("tradetrace")); |
||||
if (order == null) { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.NOT_FOUND_ORDER, ""); |
||||
} |
||||
log.info("开始处理业务"); |
||||
// 异步处理业务
|
||||
paySuccessService.orderPaySuccessHandle(order.getOrderNo(), |
||||
OrderPayType.PAY_TYPE5, |
||||
body.getString("wtorderid"), |
||||
order.getPayPrice(), |
||||
null); |
||||
log.info("处理业务完成"); |
||||
} |
||||
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream()); |
||||
JSONObject result = new JSONObject(); |
||||
result.put("resultcode", "00"); |
||||
out.write(result.toJSONString().getBytes()); |
||||
out.flush(); |
||||
out.close(); |
||||
} catch (Exception e) { |
||||
log.error("订单处理异常", e); |
||||
} finally { |
||||
log.info("===============银联支付回调end=================="); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,234 @@ |
||||
package com.web.rocketmq.consumer; |
||||
|
||||
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.util.XmlUtil; |
||||
import com.hai.common.pay.util.sdk.WXPayConstants; |
||||
import com.hai.common.utils.WxUtils; |
||||
import com.hai.entity.*; |
||||
import com.hai.enum_type.GasChannel; |
||||
import com.hai.enum_type.GasChannelPayPlatformType; |
||||
import com.hai.enum_type.MerchantStoreSourceType; |
||||
import com.hai.model.HighMerchantStoreModel; |
||||
import com.hai.model.ResultProfitSharing; |
||||
import com.hai.order.service.OrderService; |
||||
import com.hai.order.type.OrderChildGoodsType; |
||||
import com.hai.order.type.OrderPayType; |
||||
import com.hai.order.type.OrderProductType; |
||||
import com.hai.order.type.OrderStatus; |
||||
import com.hai.service.HighGasChannelConfigService; |
||||
import com.hai.service.HighMerchantStoreService; |
||||
import com.hai.service.HighProfitSharingRecordService; |
||||
import lombok.extern.slf4j.Slf4j; |
||||
import org.apache.http.HttpEntity; |
||||
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
import org.apache.http.client.methods.HttpPost; |
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
||||
import org.apache.http.entity.StringEntity; |
||||
import org.apache.http.impl.client.CloseableHttpClient; |
||||
import org.apache.http.impl.client.HttpClients; |
||||
import org.apache.http.ssl.SSLContexts; |
||||
import org.apache.http.util.EntityUtils; |
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; |
||||
import org.apache.rocketmq.spring.core.RocketMQListener; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.annotation.Resource; |
||||
import javax.net.ssl.SSLContext; |
||||
import java.io.FileInputStream; |
||||
import java.math.BigDecimal; |
||||
import java.security.KeyStore; |
||||
import java.util.*; |
||||
import java.util.stream.Collectors; |
||||
|
||||
@Component |
||||
@Slf4j |
||||
@RocketMQMessageListener(consumerGroup = "order-profit-sharing-group", topic = "order-topic",selectorExpression = "profit-sharing") |
||||
public class OrderProfitSharingConsumer implements RocketMQListener<HighOrder> { |
||||
|
||||
@Resource |
||||
private OrderService orderService; |
||||
|
||||
@Resource |
||||
private HighProfitSharingRecordService profitSharingRecordService; |
||||
|
||||
@Resource |
||||
private HighMerchantStoreService merchantStoreService; |
||||
|
||||
@Resource |
||||
private HighGasChannelConfigService gasChannelConfigService; |
||||
|
||||
@Override |
||||
public void onMessage(HighOrder order) { |
||||
String resultXml = null; |
||||
if (order.getPayType().equals(OrderPayType.PAY_TYPE2.getNumber())) { |
||||
List<HighChildOrder> orderList = order.getHighChildOrderList().stream() |
||||
.filter(o -> o.getGoodsType().equals(OrderChildGoodsType.TYPE3.getNumber())).collect(Collectors.toList()); |
||||
|
||||
if (order.getProductType().equals(OrderProductType.PRODUCT_TYPE6.getNumber())) { |
||||
HighMerchantStore store = merchantStoreService.getDetailById(orderList.get(0).getGoodsId()); |
||||
HighGasChannelConfig gasChannelConfig; |
||||
if (store.getSourceType().equals(MerchantStoreSourceType.type1.getNumber())) { |
||||
gasChannelConfig = gasChannelConfigService.getConfig(GasChannel.type1, GasChannelPayPlatformType.type1); |
||||
|
||||
} else if (store.getSourceType().equals(MerchantStoreSourceType.type2.getNumber())) { |
||||
gasChannelConfig = gasChannelConfigService.getConfig(GasChannel.type2, GasChannelPayPlatformType.type1); |
||||
|
||||
} else if (store.getSourceType().equals(MerchantStoreSourceType.type3.getNumber())) { |
||||
gasChannelConfig = gasChannelConfigService.getConfig(GasChannel.type3, GasChannelPayPlatformType.type1); |
||||
|
||||
} else if (store.getSourceType().equals(MerchantStoreSourceType.type4.getNumber())) { |
||||
gasChannelConfig = gasChannelConfigService.getConfig(GasChannel.type4, GasChannelPayPlatformType.type1); |
||||
|
||||
} else { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未配置分账参数"); |
||||
} |
||||
|
||||
BigDecimal rake = new BigDecimal("0.01"); |
||||
// 计算微信收取的手续费 支付金额 * 0.002 注:如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
|
||||
BigDecimal wxHandlingFee = order.getPayRealPrice().multiply(new BigDecimal("0.002")).setScale(2, BigDecimal.ROUND_HALF_DOWN); |
||||
BigDecimal price = order.getPayRealPrice().subtract(wxHandlingFee); |
||||
// 计算分账金额 手续费后的价格 * 0.01 注:如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
|
||||
BigDecimal profitSharingAmount = price.multiply(rake).setScale(2, BigDecimal.ROUND_DOWN); |
||||
|
||||
resultXml = this.wechatSharingRecord( |
||||
order.getExt1(), |
||||
order.getAccountMerchantNum(), |
||||
gasChannelConfig.getProfitSharingReceiversNo(), |
||||
gasChannelConfig.getProfitSharingReceiversName(), |
||||
order.getPaySerialNo(), |
||||
order.getOrderNo(), |
||||
profitSharingAmount); |
||||
ResultProfitSharing resultProfitSharing = XmlUtil.getObjectFromXML(resultXml, ResultProfitSharing.class); |
||||
HighProfitSharingRecord sharingRecord = new HighProfitSharingRecord(); |
||||
sharingRecord.setOutOrderNo(order.getOrderNo()); |
||||
sharingRecord.setTransactionId(order.getPaySerialNo()); |
||||
sharingRecord.setOrderId(order.getId().toString()); |
||||
sharingRecord.setStatus(resultProfitSharing.getResult_code()); |
||||
sharingRecord.setPrice(profitSharingAmount); |
||||
sharingRecord.setCreateTime(new Date()); |
||||
sharingRecord.setContent(resultXml); |
||||
profitSharingRecordService.insert(sharingRecord); |
||||
|
||||
} else { |
||||
BigDecimal rake = new BigDecimal("0.01"); |
||||
// 计算微信收取的手续费 支付金额 * 0.002 注:如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
|
||||
BigDecimal wxHandlingFee = order.getPayRealPrice().multiply(new BigDecimal("0.002")).setScale(2, BigDecimal.ROUND_HALF_DOWN); |
||||
BigDecimal price = order.getPayRealPrice().subtract(wxHandlingFee); |
||||
// 计算分账金额 手续费后的价格 * 0.01 注:如果与两个相邻数字的距离相等,则为上舍入的舍入模式。
|
||||
BigDecimal profitSharingAmount = price.multiply(rake).setScale(2, BigDecimal.ROUND_DOWN); |
||||
|
||||
resultXml = this.wechatSharingRecord( |
||||
order.getExt1(), |
||||
order.getAccountMerchantNum(), |
||||
"1603942866", |
||||
"惠昕石化", |
||||
order.getPaySerialNo(), |
||||
order.getOrderNo(), |
||||
profitSharingAmount); |
||||
ResultProfitSharing resultProfitSharing = XmlUtil.getObjectFromXML(resultXml, ResultProfitSharing.class); |
||||
HighProfitSharingRecord sharingRecord = new HighProfitSharingRecord(); |
||||
sharingRecord.setOutOrderNo(order.getOrderNo()); |
||||
sharingRecord.setTransactionId(order.getPaySerialNo()); |
||||
sharingRecord.setOrderId(order.getId().toString()); |
||||
sharingRecord.setStatus(resultProfitSharing.getResult_code()); |
||||
sharingRecord.setPrice(profitSharingAmount); |
||||
sharingRecord.setCreateTime(new Date()); |
||||
sharingRecord.setContent(resultXml); |
||||
profitSharingRecordService.insert(sharingRecord); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 【微信】分账 |
||||
* @param appid |
||||
* @param subMchId |
||||
* @param receiversAccount 接收者商户号 |
||||
* @param receiversAccountName 接收者商户名称 |
||||
* @param transaction_id 第三方交易订单号 |
||||
* @param out_order_no 交易订单号 |
||||
* @param amount 分账金额 |
||||
*/ |
||||
public String wechatSharingRecord(String appid, String subMchId, String receiversAccount, String receiversAccountName,String transaction_id,String out_order_no, BigDecimal amount) { |
||||
try { |
||||
Map<String,String> param = new LinkedHashMap<>(); |
||||
param.put("appid", appid); |
||||
param.put("mch_id", "1289663601"); |
||||
param.put("sub_mch_id" , subMchId); |
||||
param.put("transaction_id" , transaction_id); |
||||
param.put("out_order_no" , out_order_no); |
||||
param.put("nonce_str" , WxUtils.makeNonStr()); |
||||
|
||||
List<Map<String,Object>> receiversList = new ArrayList<>(); |
||||
Map<String,Object> receiversMap = new LinkedHashMap<>(); |
||||
receiversMap.put("type", "MERCHANT_ID"); |
||||
receiversMap.put("account", receiversAccount); |
||||
receiversMap.put("amount", amount.multiply(new BigDecimal("100")).intValue()); |
||||
receiversMap.put("description", "分给商户:" + receiversAccountName); |
||||
receiversList.add(receiversMap); |
||||
param.put("receivers" , JSONObject.toJSONString(receiversList)); |
||||
String signStr = WxUtils.generateSignature(param, "Skufk5oi85wDFGl888i6wsRSTkdd5df5" , WXPayConstants.SignType.HMACSHA256); |
||||
param.put("sign" , signStr); |
||||
|
||||
// 请求分账返回的结果
|
||||
return this.wechatRequest(param.get("mch_id"), WxUtils.mapToXml(param)); |
||||
|
||||
|
||||
} catch (Exception e) { |
||||
log.error("CmsContentController --> getCorporateAdvertising() error!", e); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* 【微信】分账请求 |
||||
* @param mchId |
||||
* @param data |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
public String wechatRequest(String mchId, String data) throws Exception { |
||||
/** |
||||
* 注意PKCS12证书 是从微信商户平台-》账户设置-》 API安全 中下载的 |
||||
*/ |
||||
KeyStore keyStore = KeyStore.getInstance("PKCS12"); |
||||
//P12文件目录 证书路径,这里需要你自己修改,linux下还是windows下的根路径
|
||||
FileInputStream instream = new FileInputStream("/home/project/wx_cert/1289663601_apiclient_cert.p12"); |
||||
try { |
||||
keyStore.load(instream, "1289663601".toCharArray());//这里写密码..默认是你的MCHID
|
||||
} finally { |
||||
instream.close(); |
||||
} |
||||
SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, "1289663601".toCharArray()).build();//这里也是写密码的
|
||||
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); |
||||
//小程序退款需要调用双向证书的认证
|
||||
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); |
||||
try { |
||||
HttpPost httpost = new HttpPost("https://api.mch.weixin.qq.com/secapi/pay/profitsharing"); // 设置响应头信息
|
||||
httpost.addHeader("Connection", "keep-alive"); |
||||
httpost.addHeader("Accept", "*/*"); |
||||
httpost.addHeader("Content-Type", "text/xml"); |
||||
httpost.addHeader("Host", "api.mch.weixin.qq.com"); |
||||
httpost.addHeader("X-Requested-With", "XMLHttpRequest"); |
||||
httpost.addHeader("Cache-Control", "max-age=0"); |
||||
httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); |
||||
httpost.setEntity(new StringEntity(data, "UTF-8")); |
||||
CloseableHttpResponse response = httpClient.execute(httpost); |
||||
try { |
||||
HttpEntity entity = response.getEntity(); |
||||
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); |
||||
EntityUtils.consume(entity); |
||||
return jsonStr; |
||||
} finally { |
||||
response.close(); |
||||
} |
||||
} catch (Exception e){ |
||||
throw new RuntimeException(e); |
||||
} finally { |
||||
httpClient.close(); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue