package com.cyksj.web.controller.payment; import cn.hutool.core.codec.Base64; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.qrcode.QrCodeUtil; import cn.hutool.extra.qrcode.QrConfig; import cn.hutool.extra.servlet.ServletUtil; import cn.hutool.json.JSONObject; import com.alipay.api.response.AlipayFundTransCommonQueryResponse; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.cyksj.common.constant.Constant; import com.cyksj.common.exception.BusinessRuntimeException; import com.cyksj.common.util.IoKit; import com.cyksj.common.util.Jsons; import com.cyksj.common.util.StringUtil; import com.cyksj.common.util.Xmls; import com.cyksj.config.zfb.BaseZfbConfig; import com.cyksj.config.zfb.ZfbProductCode; import com.cyksj.dto.Result; import com.cyksj.enums.GatewayApiCode; import com.cyksj.enums.GatewayResponse; import com.cyksj.mapper.GoodsDonSkuMapper; import com.cyksj.mapper.OrderDonRenewRecordMapper; import com.cyksj.mapper.OrderDonWaybillMapper; import com.cyksj.mapper.UserMapper; import com.cyksj.mapper.channel.UserPayEquipmentAvailableBenefitsMapper; import com.cyksj.mapper.market.task.UserBindDetailMapper; import com.cyksj.model.dto.AliPayParams; import com.cyksj.model.dto.H5JsPayParams; import com.cyksj.model.entity.*; import com.cyksj.model.manage.views.*; import com.cyksj.model.request.AlipayOrderDonReq; import com.cyksj.model.request.OrderPayRequest; import com.cyksj.model.response.AliPayTradeStatus; import com.cyksj.model.views.GoodsDonSkuView; import com.cyksj.model.views.MidjourneyUserView; import com.cyksj.model.views.OrderCommentView; import com.cyksj.service.midjourney.MidjourneyAccountService; import com.cyksj.service.order.OrderDonService; import com.cyksj.service.paypal.PayPalService; import com.cyksj.service.paypal.PaypalPayConfigService; import com.cyksj.service.stripe.StripePayConfigService; import com.cyksj.service.stripe.StripeService; import com.cyksj.service.user.UserBindRelationService; import com.cyksj.web.util.StpUserUtil; import com.ejlchina.searcher.BeanSearcher; import com.ejlchina.searcher.SearchResult; import com.ejlchina.searcher.param.Operator; import com.ejlchina.searcher.util.MapBuilder; import com.ejlchina.searcher.util.MapUtils; import com.google.gson.JsonSyntaxException; import com.paypal.api.payments.Links; import com.paypal.api.payments.Payment; import com.stripe.exception.SignatureVerificationException; import com.stripe.model.*; import com.stripe.model.checkout.Session; import com.stripe.net.Webhook; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.stream.Collectors; /** * @author chan * @date 2021/10/11 下午3:50 */ @Slf4j @RequestMapping("/applets/order") @RestController public class OrderController { @Autowired private OrderDonService orderDonService; @Resource private BeanSearcher beanSearcher; @Resource private HttpServletRequest request; @Resource private HttpServletResponse response; @Autowired private UserBindDetailMapper userBindDetailMapper; @Autowired private UserMapper userMapper; @Autowired private UserPayEquipmentAvailableBenefitsMapper availableBenefitsMapper; @Autowired private OrderDonWaybillMapper waybillMapper; @Autowired private UserBindRelationService UserBindRelationService; @Autowired private PaypalPayConfigService paypalPayConfigService; @Autowired private PayPalService payPalService; @Autowired private StripePayConfigService stripePayConfigService; @Autowired private StripeService stripeService; @Autowired private MidjourneyAccountService midjourneyAccountService; @Autowired private GoodsDonSkuMapper skuMapper; @Autowired private OrderDonRenewRecordMapper orderDonRenewRecordMapper; /** * 支付 * @author chan * @date 2021-10-11 下午4:56 */ @PostMapping("/post/submit") public Result submit(@Validated @RequestBody OrderPayRequest payRequest, HttpServletResponse response) throws Exception { final String methodName = "吊起微信支付"; Long userId = StpUserUtil.getUserIdAfterLogin(); payRequest.setUserId(userId); log.info("{}[start] params:{}", methodName, payRequest); String ip = ServletUtil.getClientIP(request); String address = StringUtil.getNewInternalAddressByIp(ip); //address.contains("柬埔寨") || if (address.contains("缅甸")) { throw BusinessRuntimeException.getInstance("用户系统异常"); } payRequest.setIp(ip); OrderDon orderDon = orderDonService.submit(payRequest); //无登录订单 预留手机号免登录 if (userId == null && payRequest.getPopularizeId() != null && StrUtil.isNotBlank(payRequest.getPhone())) { User user = userMapper.selectById(orderDon.getUserId()); //写回登陆信息 StpUserUtil.login(user.getId()); response.addHeader("satoken-user", StpUserUtil.getTokenValue()); Cookie cookie = new Cookie("satoken-user", StpUserUtil.getTokenValue()); cookie.setMaxAge(31536000); cookie.setPath("/"); response.addCookie(cookie); JSONObject jsonObject = new JSONObject(); jsonObject.putOpt("showId", user.getShowId()); jsonObject.putOpt("nickName", user.getNickname()); Cookie userInfo = new Cookie("info", Base64.encode(jsonObject.toString())); cookie.setMaxAge(31536000); cookie.setPath("/"); response.addCookie(userInfo); } if (orderDon.getGoodsId() != null && orderDon.getGoodsId() == 26l) { GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId()); orderDon.setIsMirror(sku.getIsMirror()); } return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon); } /** * 套餐提交支付 */ @PostMapping("/post/upgrade/submit") public Result submitUpgrade(@Validated @RequestBody OrderPayRequest payRequest) throws Exception { final String methodName = "套餐吊起支付"; //无需免登录 Long userId = StpUserUtil.getLoginIdAsLong(); payRequest.setUserId(userId); log.info("{}[start] params:{}", methodName, payRequest); String ip = ServletUtil.getClientIP(request); payRequest.setIp(ip); UpgradeOrderDon orderDon = orderDonService.submitUpgrade(payRequest); return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon); } /** * 0元订单确认 */ @PostMapping("/post/order/status/{orderId}") public Result zeroOrderConfirm(@PathVariable Long orderId) { orderDonService.zeroOrderConfirm(orderId); return GatewayResponse.SUCCESS.newBuilder().toResult(); } /** * 套餐0元订单确认 */ @PostMapping("/post/upgrade/order/status/{orderId}") public Result zeroUpgradeOrderConfirm(@PathVariable Long orderId) { orderDonService.zeroUpgradeOrderConfirm(orderId); return GatewayResponse.SUCCESS.newBuilder().toResult(); } /** * 支付 * @author chan * @date 2021-10-11 下午4:56 */ @PostMapping("/post/pay/{orderId}") public Result pay(@PathVariable Long orderId) throws Exception { final String methodName = "吊起微信支付"; log.info("{}[start] orderId:{}",methodName,orderId); H5JsPayParams payParams = orderDonService.pay(orderId, "JSAPI"); return GatewayResponse.SUCCESS.newBuilder().toResult(payParams); } /** * 调用生成订单之后 * 微信网页预下单获取交易链接生成二维码 */ @PostMapping("/get/wx/orderQrCode/{orderId}") public Result createUnifiedOrderQr(@PathVariable Long orderId) throws Exception { //预下单 H5JsPayParams payParams = orderDonService.wxPcWebPay(orderId, "NATIVE"); //获取二维码链接code_url String codeUrl = payParams.getCodeUrl(); QrConfig qrConfig = new QrConfig(300, 300); return GatewayResponse.SUCCESS.newBuilder().toResult(QrCodeUtil.generateAsBase64(codeUrl, qrConfig, "png")); } /** * 微信支付回调 * @author chan * @date 2021-10-11 下午5:42 */ @PostMapping("/prepay/notify") public void prepayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { String xml = IoKit.toString(request.getInputStream()); log.info("=== 微信支付成功的回调: \n {}", xml); // 解析xml Map map = Xmls.toMap(xml); // 支付失败 if (!StringUtils.equals("SUCCESS", map.get("return_code")) || !StringUtils.equals("SUCCESS", map.get("result_code"))) { throw BusinessRuntimeException.getInstance("支付失败."); } orderDonService.prepayNotify(map); String toWeChatXmlResponse = ""; OutputStream out = null; try { out = response.getOutputStream(); IoKit.write(toWeChatXmlResponse, out); } catch (Exception e) { throw BusinessRuntimeException.getInstance(e,e.getMessage()); } finally { IoKit.close(out); } } /** * pc端微信支付回调 * @author chan * @date 2021-10-11 下午5:42 */ @PostMapping("/pc/prepay/notify") public void pcPrepayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { String xml = IoKit.toString(request.getInputStream()); log.info("=== 微信pc端分发支付成功的回调: \n {}", xml); // 解析xml Map map = Xmls.toMap(xml); // 支付失败 if (!StringUtils.equals("SUCCESS", map.get("return_code")) || !StringUtils.equals("SUCCESS", map.get("result_code"))) { throw BusinessRuntimeException.getInstance("支付失败."); } orderDonService.prepayNotify(map); log.info("pc端微信支付回调修改订单状态成功"); String toWeChatXmlResponse = ""; OutputStream out = null; try { out = response.getOutputStream(); IoKit.write(toWeChatXmlResponse, out); } catch (Exception e) { throw BusinessRuntimeException.getInstance(e,e.getMessage()); } finally { IoKit.close(out); } } /** * 支付宝表单支付 * 支付宝调起支付宝表单 * 手机支付 */ @PostMapping("/post/pay/zfb") @Deprecated public Result aliPay(@RequestBody @Validated AlipayOrderDonReq re) throws Exception { AliPayParams aliPayParams = orderDonService.aliPay(re, ZfbProductCode.MOBILE_WEB.getProductCode(), null); // response.setContentType("text/html;charset=" + BaseZfbConfig.charset); //直接将完整的表单html输出到页面 // response.getWriter().write(aliPayParams.getBody()); // response.getWriter().flush(); // response.getWriter().close(); return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody()); } /** * 套餐支付宝支付 */ @PostMapping("/post/pay/upgrade/zfb") @Deprecated public Result aliPayUpgrade(@RequestBody @Validated AlipayOrderDonReq re) throws Exception { AliPayParams aliPayParams = orderDonService.aliPayUpgrade(re, ZfbProductCode.MOBILE_WEB.getProductCode(),null); return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody()); } /** * 支付宝web支付 * pc网页内嵌二维码 */ @PostMapping("/get/zfb/orderQrCode") public Result zfbWebQrCode(@RequestBody @Validated AlipayOrderDonReq re) throws Exception { AliPayParams aliPayParams = orderDonService.aliPay(re, ZfbProductCode.PC_WEB.getProductCode(), BaseZfbConfig.qrPayMode_orderCode); // response.setContentType("text/html;charset=" + BaseZfbConfig.charset); //直接将完整的表单html输出到页面 // response.getWriter().write(aliPayParams.getBody()); // response.getWriter().flush(); // response.getWriter().close(); return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody()); } /** * 支付宝web支付 * pc网页内嵌二维码 */ @PostMapping("/get/zfb/upgrade/orderQrCode") public Result zfbWebQrCodeUpgrade(@RequestBody @Validated AlipayOrderDonReq re) throws Exception { AliPayParams aliPayParams = orderDonService.aliPayUpgrade(re, ZfbProductCode.PC_WEB.getProductCode(), BaseZfbConfig.qrPayMode_orderCode); // response.setContentType("text/html;charset=" + BaseZfbConfig.charset); //直接将完整的表单html输出到页面 // response.getWriter().write(aliPayParams.getBody()); // response.getWriter().flush(); // response.getWriter().close(); return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody()); } /** * 支付宝web支付 * pc网页跳转二维码 */ @PostMapping("/get/zfb/orderRedirect") public Result zfbWebRedirectQrCode(@RequestBody @Validated AlipayOrderDonReq re) throws Exception { AliPayParams aliPayParams = orderDonService.aliPay(re, ZfbProductCode.PC_WEB.getProductCode(), BaseZfbConfig.qrPayMode_redirect); return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody()); } /** * 支付宝回调 */ @PostMapping("/prepay/zfb/notify") public String aliPayNotify(HttpServletRequest request) throws Exception { ////将异步通知中收到的所有参数都存放到map中 Map params = convertRequestParamsToMap(request); String tradeStatus = params.get("trade_status"); String orderNo = params.get("out_trade_no"); if (AliPayTradeStatus.TRADE_SUCCESS.getStatus().equals(tradeStatus) || AliPayTradeStatus.TRADE_FINISHED.getStatus().equals(tradeStatus)) { log.info("支付宝商家订单号orderNo:{},status:{}开始回调", orderNo, tradeStatus); orderDonService.aliPayNotify(params); } else { log.error("支付宝回调 error 状态不符合 成功或完成 status:{} ,orderNo:{}", tradeStatus, orderNo); return "fail"; } return "success"; } /** * 支付宝套餐包回调 */ @PostMapping("/prepay/zfb/upgrade/notify") public String aliPayUpgradeNotify(HttpServletRequest request) throws Exception { ////将异步通知中收到的所有参数都存放到map中 Map params = convertRequestParamsToMap(request); String tradeStatus = params.get("trade_status"); String orderNo = params.get("out_trade_no"); if (AliPayTradeStatus.TRADE_SUCCESS.getStatus().equals(tradeStatus) || AliPayTradeStatus.TRADE_FINISHED.getStatus().equals(tradeStatus)) { log.info("支付宝商家订单号orderNo:{},status:{}开始回调", orderNo, tradeStatus); orderDonService.aliPayUpgradeNotify(params); } else { log.error("支付宝回调 error 状态不符合 成功或完成 status:{} ,orderNo:{}", tradeStatus, orderNo); return "fail"; } return "success"; } /** * 支付宝转账 */ // @PostMapping("/zfb/transfer/accounts") // @NoSubmit // public Result zfbTransferAccounts(@RequestBody @Validated TransferAccountsReq transferAccountsReq) throws Exception { // long userId = StpUserUtil.getLoginIdAsLong(); // transferAccountsReq.setUserId(userId); // orderDonService.transferAccounts(transferAccountsReq); // return GatewayResponse.SUCCESS.newBuilder().toResult("转账成功"); // } /** * 查询支付宝转账状态 */ @GetMapping("/zfb/transfer/status") public Result getTransFerStatusByTid(String translationId) throws Exception { AlipayFundTransCommonQueryResponse response = orderDonService.getTransFerStatusByTid(translationId); if (response.isSuccess()) { if (!Constant.SUCCESS.equals(response.getStatus())) { return GatewayResponse.SUCCESS.newBuilder().toResult(response.getFailReason()); } return GatewayResponse.SUCCESS.newBuilder().toResult("该红包已转账成功"); } return GatewayResponse.SUCCESS.newBuilder().toResult(response.getSubMsg()); } /** * 获取订单列表 */ @GetMapping("/get") public Result> list(String customId){ long userId = StpUserUtil.getLoginIdAsLong(); MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap()); //Long yhsId = yhShopFrontService.getYhsIdByCustomId(customId); List userIds = UserBindRelationService.getRelationUserIdList(userId, null); SearchResult search = beanSearcher.search(OrderDonView.class, builder //.field(OrderDonView::getYhsId, yhsId) .field(OrderDonView::getUserId, userIds).op(Operator.InList) .orderBy(OrderDonView::getId).desc() .build()); search.getDataList().forEach(data->{ Integer count = availableBenefitsMapper.selectCount(Wrappers.lambdaQuery(UserPayEquipmentAvailableBenefits.class) .eq(UserPayEquipmentAvailableBenefits::getRealOrderId, data.getId()) .eq(UserPayEquipmentAvailableBenefits::getDeleted, true)); data.setIsHasBenefits(count > 0 ? true : false); if (data.getIsBenefits() != null && data.getIsBenefits()) { String benefitsList = data.getBenefitsList(); if (StrUtil.isNotBlank(benefitsList)) { try { List skuIds = Jsons.parseList(benefitsList, GoodsDonSku.class).stream().map(GoodsDonSku::getId).collect(Collectors.toList()); data.setBenefitsViews(beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, skuIds).op(Operator.InList).build())); } catch (Exception e) { } } } if (data.getRelationId() == 0) { data.setWaybill(waybillMapper.selectOne(Wrappers.lambdaQuery(OrderDonWaybill.class).eq(OrderDonWaybill::getOrderId, data.getId()).last("limit 1"))); } if (data.getOrderType() == 2) { OrderDonRenewRecord orderDonRenewRecord = orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class) .eq(OrderDonRenewRecord::getOrderId, data.getId()) .last("limit 1")); data.setIsRenewPackage(orderDonRenewRecord != null ? true : false); } }); return GatewayResponse.SUCCESS.newBuilder().toResult(search); } /** * 获取订单详情 */ @GetMapping("/get/{orderId}") public Result detail(@PathVariable Long orderId, Boolean isNoLogin) { Long userId = StpUserUtil.getUserIdAfterLogin(); OrderDetailView detail = orderDonService.getDetail(orderId, userId); return GatewayResponse.SUCCESS.newBuilder().toResult(detail); } /** * 取消订单 */ @GetMapping("/get/close/{orderId}") public Result closeOrder(@PathVariable Long orderId) { long userId = StpUserUtil.getLoginIdAsLong(); orderDonService.closeOrder(orderId, userId); return GatewayResponse.SUCCESS.newBuilder().toResult(); } @GetMapping("/get/order/status/{orderId}") public Result getOrderStatusById(@PathVariable Long orderId) { if (orderId < 1) { throw BusinessRuntimeException.getInstance("订单不存在"); } OrderDonSearchView orderDonView = beanSearcher.searchFirst(OrderDonSearchView.class, MapUtils.builder() .put("orderId", String.format("where id = %s", orderId)) .build()); if (orderDonView == null) { throw BusinessRuntimeException.getInstance("订单不存在"); } if (orderDonView.getIsMirror() && orderDonView.getOrderType() == 2) { Optional.ofNullable(orderDonRenewRecordMapper.selectOne(Wrappers.lambdaQuery(OrderDonRenewRecord.class) .eq(OrderDonRenewRecord::getOrderId, orderId) .last("limit 1"))) .ifPresent(renew -> { GoodsDonSku sku = skuMapper.selectById(renew.getOriSkuId()); orderDonView.setOriSpecVal(sku.getSpecVal()); }); } return GatewayResponse.SUCCESS.newBuilder().toResult(orderDonView); } /** * 查询套餐订单支付状态 */ @GetMapping("/get/upgrade/order/status/{orderId}") public Result getUpgradeOrderStatusById(@PathVariable Long orderId) { if (orderId < 1) { throw BusinessRuntimeException.getInstance("订单不存在"); } UpgradeOrderDonSearchView orderDonView = beanSearcher.searchFirst(UpgradeOrderDonSearchView.class, MapUtils.builder() .put("orderId", String.format("where id = %s", orderId)) .build()); if (orderDonView == null) { throw BusinessRuntimeException.getInstance("订单不存在"); } return GatewayResponse.SUCCESS.newBuilder().toResult(orderDonView); } @PostMapping("/get/noLogin/order") public Result> getSearchResult(@RequestBody List orderIds) { List orderDonViews = beanSearcher.searchAll(OrderDonView.class, MapUtils.builder() .field(OrderDonView::getId, orderIds).op(Operator.InList) .orderBy(OrderDonView::getId).desc().build()); return GatewayResponse.SUCCESS.newBuilder().toResult(orderDonViews); } /** * 平台评论列表 */ @GetMapping("/get/orderComment") public Result> getOrderCommentView() { SearchResult search = beanSearcher.search(OrderCommentView.class, MapUtils.flatBuilder(request.getParameterMap()).build()); return GatewayResponse.SUCCESS.newBuilder().toResult(search); } /** * 电脑端手机号注册 购买车票是否绑定了微信用户 */ @GetMapping("/isBindWx") public Result isBindWx() { Long userId = StpUserUtil.getLoginIdAsLong(); User user = userMapper.selectById(userId); if (user == null) { throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID); } if (StrUtil.isEmpty(user.getLoginPhone())) { return GatewayResponse.SUCCESS.newBuilder().toResult(true); } UserBindDetail userBindDetail = userBindDetailMapper.selectOne(Wrappers.lambdaQuery(UserBindDetail.class) .eq(UserBindDetail::getPhone, user.getLoginPhone())); if (userBindDetail == null || userBindDetail.getUserId() == null) { return GatewayResponse.SUCCESS.newBuilder().toResult(false); } return GatewayResponse.SUCCESS.newBuilder().toResult(true); } /** * 是否绑定了邮箱或手机号 */ @GetMapping("/isBind") public Result isBindPhoneOrEmail(@RequestParam(defaultValue = "1") Boolean fip) { Long userId = StpUserUtil.getLoginIdAsLong(); User user = userMapper.selectById(userId); if (user == null) { throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID); } //手机号注册 无需绑定 if (StrUtil.isNotEmpty(user.getLoginPhone())) { return GatewayResponse.SUCCESS.newBuilder().toResult(true); } //是否绑定了手机号 UserBindDetail userBindDetail = userBindDetailMapper.selectOne(Wrappers.lambdaQuery(UserBindDetail.class) .eq(StrUtil.isNotEmpty(user.getOpenId()), UserBindDetail::getUserId, userId) .eq(StrUtil.isNotEmpty(user.getEmail()), UserBindDetail::getEmailUserId, userId).last("limit 1")); if (fip) { //台湾ip String address = StringUtil.getNewInternalAddressByIp(ServletUtil.getClientIP(request)); if (address.contains("台湾") || !address.contains("中国")) { return GatewayResponse.SUCCESS.newBuilder().toResult(true); } } if (userBindDetail == null || StrUtil.isEmpty(userBindDetail.getPhone())) { return GatewayResponse.SUCCESS.newBuilder().toResult(false); } return GatewayResponse.SUCCESS.newBuilder().toResult(true); } /** * 获取支付宝回调参数 */ private static Map convertRequestParamsToMap(HttpServletRequest request) { Map retMap = new HashMap<>(); Set> entrySet = request.getParameterMap().entrySet(); for (Map.Entry entry : entrySet) { String name = entry.getKey(); String[] values = entry.getValue(); int valLen = values.length; if (valLen == 1) { retMap.put(name, values[0]); } else if (valLen > 1) { StringBuilder sb = new StringBuilder(); for (String val : values) { sb.append(",").append(val); } retMap.put(name, sb.substring(1)); } else { retMap.put(name, ""); } } return retMap; } /** * paypal支付 */ @PostMapping("/paypal/pay/{orderId}") public Result paypalPay(@PathVariable Long orderId,String successUrl) throws Exception { final String methodName = "paypal支付"; log.info("{}[start] orderId:{}",methodName,orderId); Payment payment = payPalService.createPayment(orderId,successUrl); String payUrl = "/"; log.info("paypal links:{}",payment.getLinks()); for(Links links : payment.getLinks()){ if("approval_url".equals(links.getRel())){ // 客户付款登陆地址 String payPalUrl = links.getHref(); log.info("PayPal调起支付成功[end]:{}", orderId); payUrl = payPalUrl; } } log.info("paypal支付成功[end]"); return GatewayResponse.SUCCESS.newBuilder().toResult(payUrl); } /** * stripe支付 */ @PostMapping("/stripe/pay/{orderId}") public Result stripePay(@PathVariable Long orderId,String successUrl) throws Exception { final String methodName = "stripe支付"; log.info("{}[start] orderId:{}",methodName,orderId); String payUrl = stripeService.checkOutStripe(orderId,successUrl); log.info("Stripe支付成功 result:{}[end]",payUrl); return GatewayResponse.SUCCESS.newBuilder().toResult(payUrl); } /** * paypal支付回调 */ @RequestMapping(value = "/paypal/notify") public void successPay(@RequestParam(value = "paymentId") String paymentId, @RequestParam(value = "PayerID") String PayerID) throws Exception { PaypalPayConfig paypalPayConfig = paypalPayConfigService.getById(1); response.sendRedirect(payPalService.successPayment(paymentId,PayerID,paypalPayConfig)); } /** * stripe支付回调 */ @PostMapping("/stripe/notify") @ResponseBody public String webhooks() throws Exception { InputStream inputStream = request.getInputStream(); byte[] bytes = IoKit.toBytes(inputStream); String payload = new String(bytes, StandardCharsets.UTF_8); String sigHeader = request.getHeader("Stripe-Signature"); StripePayConfig stripePayConfig = stripePayConfigService.getById(1); Event event = null; try { event = Webhook.constructEvent( payload, sigHeader, stripePayConfig.getWebhookSecret() ); } catch (JsonSyntaxException | SignatureVerificationException e) { response.setStatus(400); return ""; } // Deserialize the nested object inside the event EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer(); StripeObject stripeObject = null; if (dataObjectDeserializer.getObject().isPresent()) { stripeObject = dataObjectDeserializer.getObject().orElse(null); } else { // Deserialization failed, probably due to an API version mismatch. // Refer to the Javadoc documentation on `EventDataObjectDeserializer` for // instructions on how to handle this case, or return an error here. } // Handle the event switch (event.getType()) { case "payment_intent.succeeded": PaymentIntent paymentIntent = (PaymentIntent) stripeObject; response.setStatus(200); break; case "charge.succeeded": //使用token支付成功回调 Charge charge = (Charge) stripeObject; //TODO 此时根据charge ID 查询出关联的订单并处理支付成功业务代码 response.setStatus(200); break; case "checkout.session.completed": //使用checkout支付成功回调 Session session = (Session) stripeObject; stripeService.fulfillOrder(session); response.setStatus(200); break; default: response.setStatus(400); return ""; } response.setStatus(200); return ""; } /** * 余额明细 */ @GetMapping("/get/balance/detail") public Result> getUserBalanceSourceRecord() { long userId = StpUserUtil.getLoginIdAsLong(); SearchResult search = beanSearcher.search(UserBalanceSourceRecord.class, MapUtils.flatBuilder(request.getParameterMap()) .field(UserBalanceSourceRecord::getUserId, userId) .field(UserBalanceSourceRecord::getDetail).op(Operator.NotNull) .orderBy(UserBalanceSourceRecord::getId).desc() .onlySelect(UserBalanceSourceRecord::getBalance, UserBalanceSourceRecord::getDetail, UserBalanceSourceRecord::getCreatedTime) .build()); return GatewayResponse.SUCCESS.newBuilder().toResult(search); } /** * 获取套餐订单列表 */ @GetMapping("/upgrade/get") public Result> listUpgradeOrder(){ long userId = StpUserUtil.getLoginIdAsLong(); MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap()); List userIds = UserBindRelationService.getRelationUserIdList(userId, null); SearchResult search = beanSearcher.search(UpgradeOrderDonView.class, builder .field(UpgradeOrderDonView::getUserId, userIds).op(Operator.InList) .orderBy(UpgradeOrderDonView::getId).desc() .build()); return GatewayResponse.SUCCESS.newBuilder().toResult(search); } /** * 获取套餐订单详情 */ @GetMapping("/get/upgrade/{orderId}") public Result upgradeOrderDetail(@PathVariable Long orderId) { Long userId = StpUserUtil.getUserIdAfterLogin(); UpgradeOrderDetailView detail = orderDonService.getUpgradeOrderDetail(orderId, userId); return GatewayResponse.SUCCESS.newBuilder().toResult(detail); } /** * 取消套餐订单 */ @GetMapping("/get/close/upgrade/{orderId}") public Result closeUpgradeOrder(@PathVariable Long orderId) { long userId = StpUserUtil.getLoginIdAsLong(); orderDonService.closeUpgradeOrder(orderId, userId); return GatewayResponse.SUCCESS.newBuilder().toResult(); } /** * midjourney查询订单用户账号剩余次数 */ @GetMapping("/get/midjourney/user") public Result getMidjourneyUser(Long relationId) { long userId = StpUserUtil.getLoginIdAsLong(); MidjourneyUserView search = beanSearcher.searchFirst(MidjourneyUserView.class, MapUtils.flatBuilder(request.getParameterMap()) .field(MidjourneyUserView::getUserId, userId).field(MidjourneyUserView::getRelationId, relationId).build()); if (search == null) { MidjourneyUser midjourneyUser = midjourneyAccountService.getMidjourneyUserToken(userId, relationId); search = new MidjourneyUserView(); BeanUtils.copyProperties(midjourneyUser, search); } return GatewayResponse.SUCCESS.newBuilder().toResult(search); } /** * 续费升级提交支付 */ @PostMapping("/post/renew/upgrade/submit") public Result submitRenewUpgrade(@Validated @RequestBody OrderPayRequest payRequest) throws Exception { final String methodName = "续费升级吊起支付"; //无需免登录 Long userId = StpUserUtil.getLoginIdAsLong(); payRequest.setUserId(userId); log.info("{}[start] params:{}", methodName, payRequest); String ip = ServletUtil.getClientIP(request); payRequest.setIp(ip); OrderDon orderDon = orderDonService.submitRenewUpgrade(payRequest); return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon); } /** * 获取续费套餐订单列表 */ @GetMapping("/renew/get") public Result> listRenewOrders(){ long userId = StpUserUtil.getLoginIdAsLong(); MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap()); List userIds = UserBindRelationService.getRelationUserIdList(userId, null); SearchResult search = beanSearcher.search(RenewUpgradeOrderDonView.class, builder .field(UpgradeOrderDonView::getUserId, userIds).op(Operator.InList) .orderBy(UpgradeOrderDonView::getId).desc() .build()); return GatewayResponse.SUCCESS.newBuilder().toResult(search); } }