下单支付

pull/1/head
czc 2 years ago
parent 147587700b
commit ed90bb1f6c

@ -4,6 +4,8 @@ import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.cyl.h5.pojo.dto.OrderCreateDTO;
import com.cyl.h5.pojo.request.CancelOrderRequest;
import com.cyl.h5.pojo.request.OrderPayRequest;
import com.cyl.h5.pojo.response.OrderPayResponse;
import com.cyl.h5.pojo.vo.CountOrderVO;
import com.cyl.h5.pojo.vo.H5OrderVO;
import com.cyl.h5.pojo.vo.OrderCalcVO;
@ -131,4 +133,28 @@ public class H5OrderController {
}
}
}
@ApiOperation("订单支付")
@PostMapping("/orderPay")
public ResponseEntity<OrderPayResponse> orderPay(@RequestBody OrderPayRequest req){
log.info("订单支付","提交的数据:"+JSONObject.toJSONString(req));
String redisKey = "h5_oms_order_pay_"+req.getPayId();
String redisValue = req.getPayId()+"_"+System.currentTimeMillis();
try {
redisService.lock(redisKey, redisValue, 60);
Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
Long memberId = member.getId();
req.setMemberId(memberId);
return ResponseEntity.ok(service.orderPay(req));
}catch (Exception e){
log.error("支付方法异常", e);
throw new RuntimeException("支付失败");
}finally {
try{
redisService.unLock(redisKey,redisValue);
}catch (Exception e){
log.error("",e);
}
}
}
}

@ -0,0 +1,18 @@
package com.cyl.h5.pojo.request;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel("订单支付请求体")
public class OrderPayRequest {
@ApiModelProperty(value = "支付id", required = true)
private Long payId;
@ApiModelProperty(value = "支付方式: 1-支付宝 2-微信(默认)", required = true)
private Integer type;
@ApiModelProperty(value = "用户id", hidden = true)
private Long memberId;
}

@ -0,0 +1,33 @@
package com.cyl.h5.pojo.response;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author 86199
*/
@Data
@ApiModel("支付响应")
public class OrderPayResponse {
@ApiModelProperty(value = "支付方式1-支付宝2-微信(默认)", dataType = "Integer")
private Integer payType;
@ApiModelProperty("appId")
private String appId;
@ApiModelProperty("timeStamp")
private String timeStamp;
@ApiModelProperty("signType")
private String signType;
@ApiModelProperty("package")
private String package_;
@ApiModelProperty("nonceStr")
private String nonceStr;
@ApiModelProperty("签名")
private String paySign;
}

@ -212,6 +212,10 @@ public class H5MemberService {
MemberVO memberVO = new MemberVO();
BeanUtils.copyProperties(member, memberVO);
memberVO.setPhone(AesCryptoUtils.decrypt(aesKey, member.getPhoneEncrypted()));
QueryWrapper<MemberWechat> qw = new QueryWrapper<>();
qw.eq("member_id", member.getId());
MemberWechat memberWechat = memberWechatMapper.selectOne(qw);
memberVO.setOpenId(memberWechat.getOpenid());
return memberVO;
}
}

@ -1,6 +1,7 @@
package com.cyl.h5.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@ -8,6 +9,8 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyl.h5.pojo.dto.OrderCreateDTO;
import com.cyl.h5.pojo.dto.OrderProductListDTO;
import com.cyl.h5.pojo.request.CancelOrderRequest;
import com.cyl.h5.pojo.request.OrderPayRequest;
import com.cyl.h5.pojo.response.OrderPayResponse;
import com.cyl.h5.pojo.vo.CountOrderVO;
import com.cyl.h5.pojo.vo.H5OrderVO;
import com.cyl.h5.pojo.vo.OrderCalcVO;
@ -28,24 +31,37 @@ import com.cyl.manager.pms.mapper.SkuMapper;
import com.cyl.manager.ums.domain.Member;
import com.cyl.manager.ums.domain.MemberAddress;
import com.cyl.manager.ums.domain.MemberCart;
import com.cyl.manager.ums.domain.MemberWechat;
import com.cyl.manager.ums.mapper.MemberAddressMapper;
import com.cyl.manager.ums.mapper.MemberCartMapper;
import com.cyl.manager.ums.mapper.MemberWechatMapper;
import com.cyl.wechat.WechatPayData;
import com.cyl.wechat.WechatPayService;
import com.cyl.wechat.WechatPayUtil;
import com.github.pagehelper.PageHelper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.IDGenerator;
import com.ruoyi.framework.config.LocalDataUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class H5OrderService {
@ -77,6 +93,12 @@ public class H5OrderService {
@Autowired
private OrderOperateHistoryService orderOperateHistoryService;
@Autowired
private WechatPayService wechatPayService;
@Autowired
private MemberWechatMapper memberWechatMapper;
@Transactional
public Long submit(OrderSubmitForm form) {
Member member = (Member) LocalDataUtil.getVar(Constants.MEMBER_INFO);
@ -124,8 +146,11 @@ public class H5OrderService {
//生成一个统一的订单号
Long orderId = IDGenerator.generateId();
//生产一个payId
Long payId = IDGenerator.generateId();
//创建订单
Order order = new Order();
order.setPayId(payId);
order.setId(orderId);
order.setOrderSn(this.getOrderIdPrefix() + orderId);
order.setMemberId(member.getId());
@ -135,8 +160,7 @@ public class H5OrderService {
order.setPurchasePrice(BigDecimal.ZERO);
order.setFreightAmount(BigDecimal.ZERO);
order.setPayAmount(orderTotalAmount);
//暂时为接入支付,直接设置为待发货
order.setStatus(Constants.OrderStatus.SEND);
order.setStatus(Constants.OrderStatus.NOTPAID);
order.setAftersaleStatus(1);
order.setReceiverName(memberAddress.getName());
order.setReceiverPhone(memberAddress.getPhoneHidden());
@ -151,7 +175,7 @@ public class H5OrderService {
order.setNote(form.getNote());
order.setConfirmStatus(0);
order.setDeleteStatus(0);
order.setPaymentTime(optTime);
// order.setPaymentTime(optTime);
order.setCreateTime(optTime);
order.setCreateBy(member.getId());
int rows = orderMapper.insert(order);
@ -164,7 +188,7 @@ public class H5OrderService {
OrderOperateHistory orderOperateHistory = new OrderOperateHistory();
orderOperateHistory.setOrderId(orderId);
orderOperateHistory.setOperateMan(member.getId() + "");
orderOperateHistory.setOrderStatus(Constants.OrderStatus.SEND);
orderOperateHistory.setOrderStatus(Constants.OrderStatus.NOTPAID);
orderOperateHistory.setCreateTime(optTime);
orderOperateHistory.setCreateBy(member.getId());
rows = orderOperateHistoryMapper.insert(orderOperateHistory);
@ -183,7 +207,7 @@ public class H5OrderService {
}
}
//当前订单id接入支付后可返回payId
return orderId;
return payId;
}
public OrderCalcVO addOrderCheck(OrderCreateDTO orderCreateDTO) {
@ -398,4 +422,59 @@ public class H5OrderService {
}
return "取消订单成功";
}
/**
*
* @param req
* @return
*/
public OrderPayResponse orderPay(OrderPayRequest req) {
QueryWrapper<Order> qw = new QueryWrapper<>();
qw.eq("pay_id", req.getPayId());
qw.eq("status", 0);
List<Order> orderList = orderMapper.selectList(qw);
if (CollectionUtil.isEmpty(orderList)){
throw new RuntimeException("没有待支付的订单");
}
QueryWrapper<MemberWechat> memberWechatQw = new QueryWrapper<>();
memberWechatQw.eq("member_id", req.getMemberId());
MemberWechat memberWechat = memberWechatMapper.selectOne(memberWechatQw);
if (memberWechat == null || StrUtil.isBlank(memberWechat.getOpenid())){
throw new RuntimeException("获取用户openId失败");
}
QueryWrapper<OrderItem> orderItemQw = new QueryWrapper<>();
orderItemQw.eq("order_id", orderList.get(0).getId());
List<OrderItem> orderItemList = orderItemMapper.selectList(orderItemQw);
String orderDesc = orderItemList.get(0).getProductName().substring(0, Math.min(40, orderItemList.get(0).getProductName().length()));
String prepayId = wechatPayService.jsapiPay(
String.valueOf(req.getPayId()),
orderDesc,
Integer.valueOf(orderList.stream().map(Order::getPayAmount).
reduce(BigDecimal.ZERO, BigDecimal::add).multiply(new BigDecimal(100)).stripTrailingZeros().toPlainString()),
memberWechat.getOpenid()
);
OrderPayResponse response = new OrderPayResponse();
response.setPayType(2);
String appId = WechatPayData.appId;
String nonceStr = WechatPayUtil.generateNonceStr();
long timeStamp = WechatPayUtil.getCurrentTimestamp();
prepayId = "prepay_id=" + prepayId;
String signType = "RSA";
String paySign = null;
String signatureStr = Stream.of(appId, String.valueOf(timeStamp), nonceStr, prepayId)
.collect(Collectors.joining("\n", "", "\n"));
try {
paySign = WechatPayUtil.getSign(signatureStr, WechatPayData.privateKeyPath);
} catch (Exception e) {
throw new RuntimeException("支付失败");
}
response.setAppId(appId);
response.setTimeStamp(String.valueOf(timeStamp));
response.setNonceStr(nonceStr);
response.setSignType(signType);
response.setPackage_(prepayId);
response.setPaySign(paySign);
return response;
}
}

@ -26,6 +26,9 @@ public class Order extends BaseAudit {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
@ApiModelProperty("支付id")
private Long payId;
@ApiModelProperty("订单编号")
@Excel(name = "订单编号")
private String orderSn;

@ -18,6 +18,8 @@ import lombok.Data;
public class OrderVO extends BaseAudit {
/** 订单id */
private Long id;
/** 支付id */
private Long payId;
/** 订单编号 */
private String orderSn;
/** MEMBER_ID */

@ -64,4 +64,7 @@ public class MemberVO extends BaseAudit {
/** 用户剩余积分 */
@Excel(name = "用户剩余积分")
private BigDecimal integral;
/** openId */
@Excel(name = "openId")
private String openId;
}

@ -0,0 +1,80 @@
package com.cyl.wechat;
import cn.hutool.crypto.PemUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Base64Utils;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.util.*;
public class WechatPayUtil {
private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final Random RANDOM = new SecureRandom();
public static String getSign(String signatureStr,String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException, URISyntaxException {
//replace 根据实际情况,不一定都需要
String replace = privateKey.replace("\\n", "\n");
ClassPathResource classPathResource = new ClassPathResource(privateKey);
InputStream certStream = classPathResource.getInputStream();
PrivateKey merchantPrivateKey = PemUtil.readPemPrivateKey(certStream);
Signature sign = Signature.getInstance("SHA256withRSA");
sign.initSign(merchantPrivateKey);
sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
return Base64Utils.encodeToString(sign.sign());
}
/**
* Nonce Str
*
* @return String
*/
public static String generateNonceStr() {
char[] nonceChars = new char[32];
for (int index = 0; index < nonceChars.length; ++index) {
nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
}
return new String(nonceChars);
}
/**
*
* @return
*/
public static Logger getLogger() {
Logger logger = LoggerFactory.getLogger("wxpay java sdk");
return logger;
}
/**
*
* @return
*/
public static long getCurrentTimestamp() {
return System.currentTimeMillis()/1000;
}
/**
*
* @return
*/
public static long getCurrentTimestampMs() {
return System.currentTimeMillis();
}
}
Loading…
Cancel
Save