package com.izouma.nineth.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.request.AlipayTradeWapPayRequest; import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; import com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult; import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; import com.github.binarywang.wxpay.constant.WxPayConstants; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.izouma.nineth.config.AlipayProperties; import com.izouma.nineth.config.WxPayProperties; import com.izouma.nineth.domain.*; import com.izouma.nineth.dto.NFTAccount; import com.izouma.nineth.dto.PageQuery; import com.izouma.nineth.enums.OrderStatus; import com.izouma.nineth.enums.PayMethod; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.CollectionRepo; import com.izouma.nineth.repo.OrderRepo; import com.izouma.nineth.repo.UserAddressRepo; import com.izouma.nineth.repo.UserRepo; import com.izouma.nineth.utils.JpaUtils; import com.izouma.nineth.utils.JsonUtils; import com.izouma.nineth.utils.SecurityUtils; import com.izouma.nineth.utils.SnowflakeIdWorker; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.EncoderException; import org.apache.commons.codec.net.URLCodec; import org.apache.commons.collections.MapUtils; import org.apache.http.client.utils.URLEncodedUtils; import org.springframework.core.env.Environment; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.ui.Model; import javax.transaction.Transactional; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Arrays; import java.util.Map; import java.util.Optional; import java.util.UUID; @Service @AllArgsConstructor @Slf4j public class OrderService { private OrderRepo orderRepo; private CollectionRepo collectionRepo; private UserAddressRepo userAddressRepo; private UserRepo userRepo; private Environment env; private AlipayClient alipayClient; private AlipayProperties alipayProperties; private WxPayService wxPayService; private WxPayProperties wxPayProperties; private AssetService assetService; public Page all(PageQuery pageQuery) { return orderRepo.findAll(JpaUtils.toSpecification(pageQuery, Order.class), JpaUtils.toPageRequest(pageQuery)); } @Transactional public Order create(Long userId, Long collectionId, int qty, Long addressId) { if (qty <= 0) throw new BusinessException("数量必须大于0"); User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("用户不存在")); Collection collection = collectionRepo.findById(collectionId).orElseThrow(new BusinessException("藏品不存在")); User minter = userRepo.findById(collection.getMinterId()).orElseThrow(new BusinessException("铸造者不存在")); if (!collection.isOnShelf()) { throw new BusinessException("藏品已下架"); } if (qty > collection.getStock()) { throw new BusinessException("库存不足"); } UserAddress userAddress = null; if (addressId != null) { userAddress = userAddressRepo.findById(addressId).orElseThrow(new BusinessException("地址信息不存在")); } collection.setStock(collection.getStock() - qty); collection.setSale(collection.getSale() + qty); collectionRepo.save(collection); minter.setSales(minter.getSales() + 1); Order order = Order.builder() .userId(userId) .collectionId(collectionId) .name(collection.getName()) .pic(collection.getPics()) .properties(collection.getProperties()) .type(collection.getType()) .minter(minter.getNickname()) .minterAvatar(minter.getAvatar()) .qty(qty) .price(collection.getPrice()) .gasPrice(BigDecimal.valueOf(1)) .totalPrice(collection.getPrice().multiply(BigDecimal.valueOf(qty)).add(BigDecimal.valueOf(1))) .contactName(Optional.ofNullable(userAddress).map(UserAddress::getName).orElse(null)) .contactPhone(Optional.ofNullable(userAddress).map(UserAddress::getPhone).orElse(null)) .address(Optional.ofNullable(userAddress).map(u -> u.getProvinceId() + " " + u.getCityId() + " " + u.getDistrictId() + " " + u.getAddress()) .orElse(null)) .status(OrderStatus.NOT_PAID) .build(); return orderRepo.save(order); } public void payOrderAlipay(Long id, Model model) { try { Order order = orderRepo.findByIdAndDelFalse(id).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } JSONObject bizContent = new JSONObject(); bizContent.put("notifyUrl", alipayProperties.getNotifyUrl()); bizContent.put("returnUrl", alipayProperties.getReturnUrl()); bizContent.put("out_trade_no", String.valueOf(new SnowflakeIdWorker(0, 0).nextId())); bizContent.put("total_amount", order.getTotalPrice().stripTrailingZeros().toPlainString()); bizContent.put("disable_pay_channels", "pcredit,creditCard"); if (Arrays.stream(env.getActiveProfiles()).noneMatch(s -> s.equals("prod"))) { // 测试环境设为1分 bizContent.put("total_amount", "0.01"); } bizContent.put("subject", order.getName()); bizContent.put("product_code", "QUICK_WAP_PAY"); JSONObject body = new JSONObject(); body.put("action", "payOrder"); body.put("userId", order.getUserId()); body.put("orderId", order.getId()); bizContent.put("body", body.toJSONString()); AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest(); alipayRequest.setReturnUrl(alipayProperties.getReturnUrl()); alipayRequest.setNotifyUrl(alipayProperties.getNotifyUrl()); alipayRequest.setBizContent(JSON.toJSONString(bizContent)); String form = alipayClient.pageExecute(alipayRequest).getBody(); model.addAttribute("form", form); } catch (BusinessException err) { model.addAttribute("errMsg", err.getError()); } catch (Exception e) { model.addAttribute("errMsg", e.getMessage()); } } public String payOrderWeixinH5(Long id) throws WxPayException, EncoderException { Order order = orderRepo.findByIdAndDelFalse(id).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest(); request.setBody(order.getName()); request.setOutTradeNo(String.valueOf(new SnowflakeIdWorker(1, 1).nextId())); request.setTotalFee(order.getTotalPrice().multiply(BigDecimal.valueOf(100)).intValue()); if (Arrays.stream(env.getActiveProfiles()).noneMatch(s -> s.equals("prod"))) { // 测试环境设为1分 // request.setTotalFee(1); } request.setSpbillCreateIp("180.102.110.170"); request.setNotifyUrl(wxPayProperties.getNotifyUrl()); request.setTradeType(WxPayConstants.TradeType.MWEB); request.setSignType("MD5"); JSONObject body = new JSONObject(); body.put("action", "payOrder"); body.put("userId", order.getUserId()); body.put("orderId", order.getId()); request.setAttach(body.toJSONString()); WxPayMwebOrderResult result = wxPayService. createOrder(request); return result.getMwebUrl() + "&redirect_url=" + new URLCodec().encode(wxPayProperties.getReturnUrl()); } public Object payOrderWeixin(Long id) throws WxPayException { Order order = orderRepo.findByIdAndDelFalse(id).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest(); request.setBody(order.getName()); request.setOutTradeNo(String.valueOf(new SnowflakeIdWorker(1, 1).nextId())); request.setTotalFee(order.getTotalPrice().multiply(BigDecimal.valueOf(100)).intValue()); if (Arrays.stream(env.getActiveProfiles()).noneMatch(s -> s.equals("prod"))) { // 测试环境设为1分 // request.setTotalFee(1); } request.setSpbillCreateIp("180.102.110.170"); request.setNotifyUrl(wxPayProperties.getNotifyUrl()); request.setTradeType(WxPayConstants.TradeType.JSAPI); request.setOpenid(SecurityUtils.getAuthenticatedUser().getOpenId()); request.setSignType("MD5"); JSONObject body = new JSONObject(); body.put("action", "payOrder"); body.put("userId", order.getUserId()); body.put("orderId", order.getId()); request.setAttach(body.toJSONString()); return wxPayService.createOrder(request); } public void notifyAlipay(Long orderId, Map params) { Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() == OrderStatus.NOT_PAID) { Asset asset = null; try { asset = assetService.createAsset(order); order.setStatus(OrderStatus.PROCESSING); order.setPayTime(LocalDateTime.now()); order.setTransactionId(MapUtils.getString(params, "trade_no")); order.setPayMethod(PayMethod.ALIPAY); orderRepo.save(order); if (asset != null) { order.setTxHash(asset.getTxHash()); order.setGasUsed(asset.getGasUsed()); order.setBlockNumber(asset.getBlockNumber()); order.setStatus(OrderStatus.FINISH); orderRepo.save(order); } } catch (Exception e) { log.error("支付宝回调出错", e); } } } }