package com.izouma.nineth.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; 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.Asset; import com.izouma.nineth.domain.GiftOrder; import com.izouma.nineth.domain.User; import com.izouma.nineth.enums.AssetStatus; import com.izouma.nineth.enums.OrderStatus; import com.izouma.nineth.enums.PayMethod; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.*; import com.izouma.nineth.utils.SnowflakeIdWorker; import lombok.AllArgsConstructor; import org.apache.commons.codec.EncoderException; import org.apache.commons.codec.net.URLCodec; import org.springframework.context.ApplicationContext; import org.springframework.core.env.Environment; 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; @Service @AllArgsConstructor public class GiftOrderService { private AssetRepo assetRepo; private UserRepo userRepo; private NFTService nftService; private CollectionRepo collectionRepo; private ApplicationContext applicationContext; private OrderRepo orderRepo; private SysConfigService sysConfigService; private GiftOrderRepo giftOrderRepo; private TokenHistoryRepo tokenHistoryRepo; private AlipayProperties alipayProperties; private AlipayClient alipayClient; private WxPayProperties wxPayProperties; private WxPayService wxPayService; private Environment env; private AssetMintService assetMintService; private AssetService assetService; @Transactional public GiftOrder gift(Long userId, Long assetId, Long toUserId) { Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("资产不存在")); if (!(asset.getStatus() == AssetStatus.NORMAL)) { throw new BusinessException("当前状态不可转赠"); } if (asset.isConsignment()) { throw new BusinessException("请先取消寄售"); } if (asset.isPublicShow()) { assetService.cancelPublic(asset); } asset.setStatus(AssetStatus.GIFTING); assetRepo.save(asset); GiftOrder giftOrder = GiftOrder.builder() .userId(userId) .assetId(assetId) .toUserId(toUserId) .gasPrice(sysConfigService.getBigDecimal("gas_fee")) .status(OrderStatus.NOT_PAID) .build(); return giftOrderRepo.save(giftOrder); } @Transactional public void giftNotify(Long orderId, PayMethod payMethod, String transactionId) { GiftOrder giftOrder = giftOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在")); Asset asset = assetRepo.findById(giftOrder.getAssetId()).orElseThrow(new BusinessException("资产不存在")); User newOwner = userRepo.findById(giftOrder.getToUserId()).orElseThrow(new BusinessException("用户不存在")); giftOrder.setPayMethod(payMethod); giftOrder.setStatus(OrderStatus.FINISH); giftOrder.setTransactionId(transactionId); giftOrder.setPayTime(LocalDateTime.now()); giftOrder.setPayMethod(PayMethod.ALIPAY); assetService.transfer(asset, asset.getPrice(), newOwner, "转赠", null); } public void payOrderAlipay(Long id, Model model) { try { GiftOrder order = giftOrderRepo.findById(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.getGasPrice().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", "转赠GAS费"); bizContent.put("product_code", "QUICK_WAP_PAY"); JSONObject body = new JSONObject(); body.put("action", "payGiftOrder"); 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 Object payOrderWeixin(Long id, String tradeType, String openId) throws WxPayException, EncoderException { GiftOrder order = giftOrderRepo.findById(id).orElseThrow(new BusinessException("订单不存在")); if (order.getStatus() != OrderStatus.NOT_PAID) { throw new BusinessException("订单状态错误"); } WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest(); request.setBody("转赠GAS费"); request.setOutTradeNo(String.valueOf(new SnowflakeIdWorker(1, 1).nextId())); request.setTotalFee(order.getGasPrice().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(tradeType); request.setOpenid(openId); request.setSignType("MD5"); JSONObject body = new JSONObject(); body.put("action", "payGiftOrder"); body.put("userId", order.getUserId()); body.put("orderId", order.getId()); request.setAttach(body.toJSONString()); if (WxPayConstants.TradeType.MWEB.equals(tradeType)) { WxPayMwebOrderResult result = wxPayService.createOrder(request); return result.getMwebUrl() + "&redirect_url=" + new URLCodec().encode(wxPayProperties.getReturnUrl()); } else if (WxPayConstants.TradeType.JSAPI.equals(tradeType)) { return wxPayService.createOrder(request); } throw new BusinessException("不支持此付款方式"); } }