mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 20:49:00 +08:00
✨ Introducing new features. 新增yungouos支付渠道
This commit is contained in:
1 parent
dbbba889c0
commit
511e56d0dd
11 files changed
+326
-18
No files matched your search
@@ -94,6 +94,11 @@
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>weixin-java-mp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.yungouos.pay</groupId>
|
||||
<artifactId>yungouos-pay-sdk</artifactId>
|
||||
<version>2.0.4</version>
|
||||
</dependency>
|
||||
<!--web 模块-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.pig4cloud.pigx.pay.config;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2021/1/4
|
||||
* <p>
|
||||
* 聚合支付
|
||||
*/
|
||||
@Data
|
||||
public class MergePayConfig {
|
||||
/**
|
||||
* 前端回调地址
|
||||
*/
|
||||
private String returnUrl;
|
||||
|
||||
/**
|
||||
* 服务端回调地址
|
||||
*/
|
||||
private String notifyUrl;
|
||||
}
|
||||
+4
@@ -25,4 +25,8 @@ public class PayCommonProperties {
|
||||
*/
|
||||
private WxPayConfig wxPayConfig;
|
||||
|
||||
/**
|
||||
* 聚合支付参数
|
||||
*/
|
||||
private MergePayConfig mergePayConfig;
|
||||
}
|
||||
+30
-9
@@ -17,8 +17,10 @@
|
||||
|
||||
package com.pig4cloud.pigx.pay.controller;
|
||||
|
||||
import cn.hutool.http.ContentType;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ijpay.wxpay.WxPayApiConfigKit;
|
||||
import com.pig4cloud.pigx.common.core.util.R;
|
||||
import com.pig4cloud.pigx.common.log.annotation.SysLog;
|
||||
@@ -41,6 +43,7 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 商品
|
||||
@@ -56,18 +59,30 @@ public class PayGoodsOrderController {
|
||||
|
||||
private final PayGoodsOrderService payGoodsOrderService;
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
|
||||
/**
|
||||
* 商品订单
|
||||
* @param goods 商品
|
||||
*
|
||||
* @param goods 商品
|
||||
* @param response
|
||||
* @return R
|
||||
*/
|
||||
@SneakyThrows
|
||||
@Inner(false)
|
||||
@GetMapping("/buy")
|
||||
@GetMapping(value = {"/buy", "/merge/buy"})
|
||||
@SysLog("购买商品")
|
||||
public void buy(PayGoodsOrder goods, HttpServletRequest request, HttpServletResponse response) {
|
||||
String ua = request.getHeader(HttpHeaders.USER_AGENT);
|
||||
|
||||
//服务商 模式
|
||||
if ("/goods/merge/buy".equals(request.getRequestURI())) {
|
||||
Map<String, Object> result = payGoodsOrderService.buy(goods, true);
|
||||
response.setContentType(ContentType.JSON.getValue());
|
||||
response.getWriter().print(objectMapper.writeValueAsString(result));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ua.contains(PayConstants.MICRO_MESSENGER)) {
|
||||
String appId = WxPayApiConfigKit.getWxPayApiConfig().getAppId();
|
||||
String wxUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s"
|
||||
@@ -78,16 +93,17 @@ public class PayGoodsOrderController {
|
||||
}
|
||||
|
||||
if (ua.contains(PayConstants.ALIPAY)) {
|
||||
payGoodsOrderService.buy(goods);
|
||||
payGoodsOrderService.buy(goods, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* oauth
|
||||
* @param goods 商品信息
|
||||
* @param state appid
|
||||
* @param code 回调code
|
||||
*
|
||||
* @param goods 商品信息
|
||||
* @param state appid
|
||||
* @param code 回调code
|
||||
* @param modelAndView
|
||||
* @return
|
||||
* @throws WxErrorException
|
||||
@@ -101,13 +117,14 @@ public class PayGoodsOrderController {
|
||||
goods.setUserId(wxMpOAuth2AccessToken.getOpenId());
|
||||
goods.setAmount(goods.getAmount());
|
||||
modelAndView.setViewName("pay");
|
||||
modelAndView.addAllObjects(payGoodsOrderService.buy(goods));
|
||||
modelAndView.addAllObjects(payGoodsOrderService.buy(goods, false));
|
||||
return modelAndView;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param page 分页对象
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param payGoodsOrder 商品订单表
|
||||
* @return
|
||||
*/
|
||||
@@ -119,6 +136,7 @@ public class PayGoodsOrderController {
|
||||
|
||||
/**
|
||||
* 通过id查询商品订单表
|
||||
*
|
||||
* @param goodsOrderId id
|
||||
* @return R
|
||||
*/
|
||||
@@ -130,6 +148,7 @@ public class PayGoodsOrderController {
|
||||
|
||||
/**
|
||||
* 新增商品订单表
|
||||
*
|
||||
* @param payGoodsOrder 商品订单表
|
||||
* @return R
|
||||
*/
|
||||
@@ -143,6 +162,7 @@ public class PayGoodsOrderController {
|
||||
|
||||
/**
|
||||
* 修改商品订单表
|
||||
*
|
||||
* @param payGoodsOrder 商品订单表
|
||||
* @return R
|
||||
*/
|
||||
@@ -156,6 +176,7 @@ public class PayGoodsOrderController {
|
||||
|
||||
/**
|
||||
* 通过id删除商品订单表
|
||||
*
|
||||
* @param goodsOrderId id
|
||||
* @return R
|
||||
*/
|
||||
|
||||
+17
@@ -59,6 +59,8 @@ public class PayNotifyRecordController {
|
||||
|
||||
private final PayNotifyCallbakHandler weChatCallback;
|
||||
|
||||
private final PayNotifyCallbakHandler mergePayCallback;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param page 分页对象
|
||||
@@ -148,4 +150,19 @@ public class PayNotifyRecordController {
|
||||
return weChatCallback.handle(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 聚合渠道异步回调
|
||||
* @param request 渠道请求
|
||||
* @return
|
||||
*/
|
||||
@Inner(false)
|
||||
@SneakyThrows
|
||||
@XssCleanIgnore
|
||||
@PostMapping("/merge/callbak")
|
||||
public void mergeCallbak(HttpServletRequest request, HttpServletResponse response) {
|
||||
// 解析回调信息
|
||||
Map<String, String> params = AliPayApi.toMap(request);
|
||||
response.getWriter().print(mergePayCallback.handle(params));
|
||||
}
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package com.pig4cloud.pigx.pay.handler.impl;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
|
||||
import com.pig4cloud.pigx.pay.entity.PayNotifyRecord;
|
||||
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
|
||||
import com.pig4cloud.pigx.pay.handler.MessageDuplicateCheckerHandler;
|
||||
import com.pig4cloud.pigx.pay.service.PayGoodsOrderService;
|
||||
import com.pig4cloud.pigx.pay.service.PayNotifyRecordService;
|
||||
import com.pig4cloud.pigx.pay.service.PayTradeOrderService;
|
||||
import com.pig4cloud.pigx.pay.utils.OrderStatusEnum;
|
||||
import com.pig4cloud.pigx.pay.utils.PayConstants;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2021/1/4
|
||||
* <p>
|
||||
* 聚合支付回调处理
|
||||
*/
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@Service("mergePayCallback")
|
||||
public class YungouosMergePayNotifyCallbakHandler extends AbstractPayNotifyCallbakHandler {
|
||||
|
||||
private final MessageDuplicateCheckerHandler duplicateCheckerHandler;
|
||||
|
||||
private final PayNotifyRecordService recordService;
|
||||
|
||||
private final PayTradeOrderService tradeOrderService;
|
||||
|
||||
private final PayGoodsOrderService goodsOrderService;
|
||||
|
||||
/**
|
||||
* 初始化执行
|
||||
*
|
||||
* @param params
|
||||
*/
|
||||
@Override
|
||||
public void before(Map<String, String> params) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 去重处理
|
||||
*
|
||||
* @param params 回调报文
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Boolean duplicateChecker(Map<String, String> params) {
|
||||
// 判断10秒内是否已经回调处理
|
||||
if (duplicateCheckerHandler.isDuplicate(params.get(PayConstants.MERGE_OUT_TRADE_NO))) {
|
||||
log.info("聚合支付订单重复回调 {} 不做处理", params);
|
||||
this.saveNotifyRecord(params, "重复回调");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验签逻辑
|
||||
*
|
||||
* @param params 回调报文
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Boolean verifyNotify(Map<String, String> params) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析报文
|
||||
*
|
||||
* @param params
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String parse(Map<String, String> params) {
|
||||
String mergeCode = params.get(PayConstants.MERGE_CODE);
|
||||
String orderNo = params.get(PayConstants.MERGE_OUT_TRADE_NO);
|
||||
PayGoodsOrder goodsOrder = goodsOrderService
|
||||
.getOne(Wrappers.<PayGoodsOrder>lambdaQuery().eq(PayGoodsOrder::getPayOrderId, orderNo));
|
||||
PayTradeOrder tradeOrder = tradeOrderService
|
||||
.getOne(Wrappers.<PayTradeOrder>lambdaQuery().eq(PayTradeOrder::getOrderId, orderNo));
|
||||
|
||||
if (OrderStatusEnum.SUCCESS.getStatus().equals(mergeCode)) {
|
||||
goodsOrder.setStatus(OrderStatusEnum.SUCCESS.getStatus());
|
||||
tradeOrder.setStatus(OrderStatusEnum.SUCCESS.getStatus());
|
||||
} else {
|
||||
goodsOrder.setStatus(OrderStatusEnum.FAIL.getStatus());
|
||||
tradeOrder.setStatus(OrderStatusEnum.FAIL.getStatus());
|
||||
}
|
||||
|
||||
goodsOrderService.updateById(goodsOrder);
|
||||
|
||||
String succTime = MapUtil.getStr(params, "time");
|
||||
tradeOrder.setPaySuccTime(DateUtil.parse(succTime, DatePattern.NORM_DATETIME_FORMAT).getTime());
|
||||
tradeOrder.setChannelOrderNo(params.get("orderNo"));
|
||||
tradeOrderService.updateById(tradeOrder);
|
||||
return "SUCCESS";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存回调记录
|
||||
*
|
||||
* @param params 回调报文
|
||||
* @param result 处理结果
|
||||
*/
|
||||
@Override
|
||||
public void saveNotifyRecord(Map<String, String> params, String result) {
|
||||
PayNotifyRecord record = new PayNotifyRecord();
|
||||
String notifyId = RandomUtil.randomNumbers(12);
|
||||
MapUtil.renameKey(params, PayConstants.MERGE_OUT_TRADE_NO, PayConstants.OUT_TRADE_NO);
|
||||
saveRecord(params, result, record, notifyId, recordService);
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package com.pig4cloud.pigx.pay.handler.impl;
|
||||
|
||||
import cn.hutool.core.util.NumberUtil;
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import com.ijpay.wxpay.WxPayApiConfigKit;
|
||||
import com.pig4cloud.pigx.pay.config.PayCommonProperties;
|
||||
import com.pig4cloud.pigx.pay.entity.PayGoodsOrder;
|
||||
import com.pig4cloud.pigx.pay.entity.PayTradeOrder;
|
||||
import com.pig4cloud.pigx.pay.mapper.PayGoodsOrderMapper;
|
||||
import com.pig4cloud.pigx.pay.mapper.PayTradeOrderMapper;
|
||||
import com.pig4cloud.pigx.pay.utils.OrderStatusEnum;
|
||||
import com.pig4cloud.pigx.pay.utils.PayChannelNameEnum;
|
||||
import com.yungouos.pay.merge.MergePay;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2021/1/4
|
||||
* <p>
|
||||
* https://open.pay.yungouos.com/#/api/api/pay/merge/nativePay
|
||||
* 服务商聚合支付模式
|
||||
*/
|
||||
@Slf4j
|
||||
@Service("MERGE_PAY")
|
||||
@RequiredArgsConstructor
|
||||
public class YungouosMergePayOrderHandler extends AbstractPayOrderHandler {
|
||||
|
||||
private final PayCommonProperties commonProperties;
|
||||
|
||||
private final PayTradeOrderMapper tradeOrderMapper;
|
||||
|
||||
private final PayGoodsOrderMapper goodsOrderMapper;
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
/**
|
||||
* 创建交易订单
|
||||
*
|
||||
* @param goodsOrder 商品订单
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public PayTradeOrder createTradeOrder(PayGoodsOrder goodsOrder) {
|
||||
PayTradeOrder tradeOrder = new PayTradeOrder();
|
||||
tradeOrder.setOrderId(goodsOrder.getPayOrderId());
|
||||
tradeOrder.setAmount(goodsOrder.getAmount());
|
||||
tradeOrder.setChannelId(PayChannelNameEnum.MERGE_PAY.getName());
|
||||
tradeOrder.setChannelMchId(WxPayApiConfigKit.getWxPayApiConfig().getMchId());
|
||||
tradeOrder.setClientIp(ServletUtil.getClientIP(request));
|
||||
tradeOrder.setCurrency("CNY");
|
||||
tradeOrder.setStatus(OrderStatusEnum.INIT.getStatus());
|
||||
tradeOrder.setBody(goodsOrder.getGoodsName());
|
||||
tradeOrderMapper.insert(tradeOrder);
|
||||
return tradeOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调起渠道支付
|
||||
*
|
||||
* @param goodsOrder 商品订单
|
||||
* @param tradeOrder 交易订单
|
||||
* @return obj
|
||||
*/
|
||||
@Override
|
||||
public Object pay(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder) {
|
||||
String money = NumberUtil.div(tradeOrder.getAmount(), "100", 2).toString();
|
||||
return MergePay.nativePay(tradeOrder.getOrderId(), money, "100106279016"
|
||||
, tradeOrder.getBody()
|
||||
, "1"
|
||||
, tradeOrder.getBody()
|
||||
, commonProperties.getMergePayConfig().getNotifyUrl()
|
||||
, commonProperties.getMergePayConfig().getReturnUrl()
|
||||
, ""
|
||||
, ""
|
||||
, ""
|
||||
, "759492493EBC43B498955E261E1A494F");
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新订单信息
|
||||
*
|
||||
* @param goodsOrder 商品订单
|
||||
* @param tradeOrder 交易订单
|
||||
*/
|
||||
@Override
|
||||
public void updateOrder(PayGoodsOrder goodsOrder, PayTradeOrder tradeOrder) {
|
||||
tradeOrderMapper.updateById(tradeOrder);
|
||||
goodsOrderMapper.updateById(goodsOrder);
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -33,8 +33,9 @@ public interface PayGoodsOrderService extends IService<PayGoodsOrder> {
|
||||
/**
|
||||
* 购买商品
|
||||
* @param goodsOrder goods
|
||||
* @param isMerge 是否是服务商
|
||||
* @return
|
||||
*/
|
||||
Map<String, Object> buy(PayGoodsOrder goodsOrder);
|
||||
Map<String, Object> buy(PayGoodsOrder goodsOrder, boolean isMerge);
|
||||
|
||||
}
|
||||
+6
-2
@@ -50,13 +50,17 @@ public class PayGoodsOrderServiceImpl extends ServiceImpl<PayGoodsOrderMapper, P
|
||||
|
||||
/**
|
||||
* 下单购买
|
||||
*
|
||||
* @param goodsOrder
|
||||
* @param isMerge
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, Object> buy(PayGoodsOrder goodsOrder) {
|
||||
String ua = request.getHeader(HttpHeaders.USER_AGENT);
|
||||
public Map<String, Object> buy(PayGoodsOrder goodsOrder, boolean isMerge) {
|
||||
// 是否聚合支付
|
||||
String ua = isMerge ? "MERGE_PAY" : request.getHeader(HttpHeaders.USER_AGENT);
|
||||
|
||||
Enum channel = PayChannelNameEnum.getChannel(ua);
|
||||
PayOrderHandler orderHandler = orderHandlerMap.get(channel.name());
|
||||
goodsOrder.setGoodsName("测试产品");
|
||||
|
||||
+10
-6
@@ -25,7 +25,12 @@ public enum PayChannelNameEnum {
|
||||
/**
|
||||
* 微信公众号支付
|
||||
*/
|
||||
WEIXIN_MP("WEIXIN_MP", "微信公众号支付");
|
||||
WEIXIN_MP("WEIXIN_MP", "微信公众号支付"),
|
||||
|
||||
/**
|
||||
* 聚合支付
|
||||
*/
|
||||
MERGE_PAY("MERGE_PAY", "yungouos 一码付");
|
||||
|
||||
/**
|
||||
* 名称
|
||||
@@ -40,18 +45,17 @@ public enum PayChannelNameEnum {
|
||||
|
||||
/**
|
||||
* 通过ua 判断所属渠道
|
||||
*
|
||||
* @param ua 浏览器类型
|
||||
* @return
|
||||
*/
|
||||
public static Enum getChannel(String ua) {
|
||||
if (ua.contains(PayConstants.ALIPAY)) {
|
||||
return PayChannelNameEnum.ALIPAY_WAP;
|
||||
}
|
||||
else if (ua.contains(PayConstants.MICRO_MESSENGER)) {
|
||||
} else if (ua.contains(PayConstants.MICRO_MESSENGER)) {
|
||||
return PayChannelNameEnum.WEIXIN_MP;
|
||||
}
|
||||
else {
|
||||
return PayChannelNameEnum.WEIXIN_WAP;
|
||||
} else {
|
||||
return PayChannelNameEnum.MERGE_PAY;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
@@ -33,4 +33,14 @@ public interface PayConstants {
|
||||
*/
|
||||
String TRADE_STATUS = "trade_status";
|
||||
|
||||
/**
|
||||
* 聚合支付返回 Code
|
||||
*/
|
||||
String MERGE_CODE = "code";
|
||||
|
||||
/**
|
||||
* 聚合支付订单号
|
||||
*/
|
||||
String MERGE_OUT_TRADE_NO = "outTradeNo";
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user