feat(payment): 支付功能调整和订单状态查询

master
yang 2025-02-10 18:44:44 +08:00
parent 13d4e21691
commit da69a15cb9
7 changed files with 135 additions and 30 deletions

View File

@ -74,13 +74,13 @@ public class AliPayController extends BaseController {
String appId = "2021005114616085"; String appId = "2021005114616085";
String state = ShareCodeUtils.idToCode(SecurityUtils.getUserId()); // 防止CSRF攻击 String state = ShareCodeUtils.idToCode(SecurityUtils.getUserId()); // 防止CSRF攻击
String encodedRedirectUri = URLEncoder.encode("https://3195d9a3.r27.cpolar.top/ali/pay/callback", "UTF-8"); String encodedRedirectUri = URLEncoder.encode("https://4b0ca615.r27.cpolar.top/ali/pay/callback", "UTF-8");
String authUrl = String.format( String authUrl = String.format(
"https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=%s&scope=%s&redirect_uri=%s&state=%s", "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=%s&scope=%s&redirect_uri=%s&state=%s",
appId, scope, encodedRedirectUri, state appId, scope, encodedRedirectUri, state
); );
QrCodeUtil.generate(authUrl, 300, 300, "png", response.getOutputStream()); // QrCodeUtil.generate(authUrl, 300, 300, "png", response.getOutputStream());
return AjaxResult.success("成功", authUrl); return AjaxResult.success("成功", authUrl);
} }
@ -136,8 +136,10 @@ public class AliPayController extends BaseController {
return AjaxResult.error("商品id不能为空"); return AjaxResult.error("商品id不能为空");
} }
payVo = aliPayService.memberPay(orderTradeDto); payVo = aliPayService.memberPay(orderTradeDto);
// QrCodeUtil.generate(payVo.getUrl(), 300, 300, "png", response.getOutputStream());
} else if ("points".equalsIgnoreCase(type)) { } else if ("points".equalsIgnoreCase(type)) {
payVo = aliPayService.pointsPay(orderTradeDto.getPaymentAmount()); payVo = aliPayService.pointsPay(orderTradeDto.getAmount());
// QrCodeUtil.generate(payVo.getUrl(), 300, 300, "png", response.getOutputStream());
} }
return AjaxResult.success(payVo); return AjaxResult.success(payVo);
@ -198,10 +200,15 @@ public class AliPayController extends BaseController {
// 验签通过 // 验签通过
String code = params.get("out_trade_no"); // 商户订单号 String code = params.get("out_trade_no"); // 商户订单号
OrderTrade orderTrade = orderTradeService.lambdaQuery()
.eq(OrderTrade::getCode, code)
.one();
if (orderTrade == null) {
redisCache.deleteObject(code);
return "failure";
}
// 获取订单后缀 // 获取订单后缀
String suffix = code.substring(code.lastIndexOf("_") + 1); String suffix = code.substring(code.lastIndexOf("_") + 1);
String orderTradeJson = redisCache.getCacheObject(code);
OrderTrade orderTrade = JSONUtil.toBean(orderTradeJson, OrderTrade.class);
orderTradeService.orderHandler(orderTrade, suffix, params); orderTradeService.orderHandler(orderTrade, suffix, params);

View File

@ -5,6 +5,7 @@ import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.qrcode.QrCodeUtil; import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.json.JSON; import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayApiException;
import com.alipay.api.request.AlipaySystemOauthTokenRequest; import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.easysdk.base.oauth.models.AlipaySystemOauthTokenResponse; import com.alipay.easysdk.base.oauth.models.AlipaySystemOauthTokenResponse;
@ -36,10 +37,8 @@ import javax.validation.constraints.NotBlank;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.*;
import java.util.List; import java.util.concurrent.TimeUnit;
import java.util.Map;
import java.util.Random;
/** /**
* @AuthorChenYan * @AuthorChenYan
@ -62,6 +61,12 @@ public class OrderTradeController extends BaseController {
@Autowired @Autowired
private OrderTradeService orderTradeService; private OrderTradeService orderTradeService;
@Autowired
private AliPayService aliPayService;
@Autowired
private RedisCache redisCache;
/** /**
* *
*/ */
@ -121,7 +126,14 @@ public class OrderTradeController extends BaseController {
*/ */
@GetMapping("/queryTradeStatus") @GetMapping("/queryTradeStatus")
@ApiOperation(value = "查询交易状态") @ApiOperation(value = "查询交易状态")
public Object queryTradeStatus(@Valid @NotBlank(message = "订单号不能为空") String outTradeNo) throws Exception { public AjaxResult queryTradeStatus(@Valid @NotBlank(message = "订单号不能为空") String outTradeNo) throws Exception {
return aliPayService.queryTradeStatus(outTradeNo);
}
@GetMapping("/getTradStatus")
public Object getTradStatus(String outTradeNo) throws Exception {
Factory.setOptions(config); Factory.setOptions(config);
AlipayTradeQueryResponse query = Factory.Payment.Common().query(outTradeNo); AlipayTradeQueryResponse query = Factory.Payment.Common().query(outTradeNo);
Map<String, Object> map = JSONUtils.jsonToMap(query.getHttpBody()); Map<String, Object> map = JSONUtils.jsonToMap(query.getHttpBody());
@ -132,7 +144,6 @@ public class OrderTradeController extends BaseController {
// TRADE_CLOSED未付款交易超时关闭或支付完成后全额退款 // TRADE_CLOSED未付款交易超时关闭或支付完成后全额退款
// TRADE_SUCCESS交易支付成功 // TRADE_SUCCESS交易支付成功
// TRADE_FINISHED交易结束不可退款 // TRADE_FINISHED交易结束不可退款
// 当 trade_status 等于 TRADE_SUCCESS 或 TRADE_FINISHED 时, 表示支付成功
return map.get("alipay_trade_query_response"); return map.get("alipay_trade_query_response");
} }

View File

@ -128,7 +128,7 @@ mall:
privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyhwMKnP7oBQ9qKhxke9AXN7ZNcniMnJFcWWFPfs3W6QqKBGFGFYQFyqfmnf2gM4nYtEbvit0CcmSrdniR3aZVb6s0A/KWqD5ejf+zjdnn5XH4GYsm/DXZoBqdAMWQUaQcVB1lC9az1rn13n9UHBJ+s+UAWtFjXMDd78dsE7enU3RjBffyvl/A+r6c0jnSHDNttSXyamxGX8ng8hK5XdCAusOfYpWnLY90sjlyz98snIfVPqAfD3KTP88gRF1KfWZniwMCR/OjCp6jm5d5dvOj8xyk7R1LfZ0CH/fXOcvpCe9JISS9DyzEzW5XpsnO5p8Mo8wFL6TKVBng+Ss0Tr0NAgMBAAECggEAPnaCl+oKPf/XPtvxBy9SxWzWug49I2V8boVPSNMjDfiHmXai2jSY9rXLPSM2JCEkL9ATqag6X6rKkjtnQBH/KpFho1dmP1QqTkb8mkQdY8ehsp6tUzyXUsdzyE8G0NHfy5Gan0ofGtkcQ2xPvIv95JromtErxcokKQLGEYhsj3xL+KVsUh5YedX/6sAiJ1KS5Zs82eh6bbCvUzuSPc4hjyfLSux5AnGBPnwEzWWJiA5z9zK17i8Cb7FnEeRmNvJw7VsXaCMFquZ6+bzlKdSuUqzqNhHMX8AivePTjj7pPHFW3FTh64E20yzl7CIwkScToXT3H7oaHRA1xGySmGNBuQKBgQDXFcg0b8L0A/Zril+4IwfckH1gpUbqlplzfozM/a/0rojQEdS+X7g4ypdPc47cwoLJx08/84L8ZPj49CImoGNdj5K9B2fY/E10SIJJqN5lb9NI4KINvGGM58NDSAl+GjT5mljkPI8jzQ1ACcy9DGV/KVScGHUWUpeLOK22AEcfWwKBgQDUfPFBHc2Bkuv3bRoNT+fnChMw5CI65wD74vR5GKyurh50DB3RZXwhRsAFd9NowINm9B2KAR0IrB+vh3EwfJaWDauh3ykZZtrAphSa11dJXvtathHTuQmXalZv5brh5mHie87yoxMn7vqDi0bwkNlb/b1wwokwc0oc3NSoNsFptwKBgCJhjPs00kkHSSCvodVhZCRRxHjqcoeVQzo/BGrQMow+SghYkVVNH7mUSNOeeTu4rAdtILHsTwfhbBr/i2X5RWjzRlWJFYSN8COiY5E6uTIlyfRgVAc2EbHgakoa/cl2jvlHPuZc99SVNoUCDAQ8Mw08ohXBoxXKZgcPLFVnffb5AoGBAJW5cDmk6WCrCRAwVVIaAtsek0U5CxGcImpakk8d3te7IwQ8YWph6yR7eOSheVrvg+ewjXvnqvCocC877brvnyAeg9isqYYXnn5uyEgPApdVkSFq94bLdIG30S5JnvR8ZG61NK5t0BqsXuL/6b2rIy2Zzrm8qfR02D0cMdBRvNljAoGBAMJG7/TqodrYPYyOZ4/IbbhAitBHWpHYJHSENnuxbQGAQuCt52Jp3eULR2r7uk3dUDuE8mB2QAEStuV/orfdxxRxJIYbEynJFGCa9O5LTevbM4MoNRfLCPPmFK5PJivlJcdrCyQKEmGSLLrVdb3H/Wzu0/4K/ZhwyrtBz4MRkuwD privateKey: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCyhwMKnP7oBQ9qKhxke9AXN7ZNcniMnJFcWWFPfs3W6QqKBGFGFYQFyqfmnf2gM4nYtEbvit0CcmSrdniR3aZVb6s0A/KWqD5ejf+zjdnn5XH4GYsm/DXZoBqdAMWQUaQcVB1lC9az1rn13n9UHBJ+s+UAWtFjXMDd78dsE7enU3RjBffyvl/A+r6c0jnSHDNttSXyamxGX8ng8hK5XdCAusOfYpWnLY90sjlyz98snIfVPqAfD3KTP88gRF1KfWZniwMCR/OjCp6jm5d5dvOj8xyk7R1LfZ0CH/fXOcvpCe9JISS9DyzEzW5XpsnO5p8Mo8wFL6TKVBng+Ss0Tr0NAgMBAAECggEAPnaCl+oKPf/XPtvxBy9SxWzWug49I2V8boVPSNMjDfiHmXai2jSY9rXLPSM2JCEkL9ATqag6X6rKkjtnQBH/KpFho1dmP1QqTkb8mkQdY8ehsp6tUzyXUsdzyE8G0NHfy5Gan0ofGtkcQ2xPvIv95JromtErxcokKQLGEYhsj3xL+KVsUh5YedX/6sAiJ1KS5Zs82eh6bbCvUzuSPc4hjyfLSux5AnGBPnwEzWWJiA5z9zK17i8Cb7FnEeRmNvJw7VsXaCMFquZ6+bzlKdSuUqzqNhHMX8AivePTjj7pPHFW3FTh64E20yzl7CIwkScToXT3H7oaHRA1xGySmGNBuQKBgQDXFcg0b8L0A/Zril+4IwfckH1gpUbqlplzfozM/a/0rojQEdS+X7g4ypdPc47cwoLJx08/84L8ZPj49CImoGNdj5K9B2fY/E10SIJJqN5lb9NI4KINvGGM58NDSAl+GjT5mljkPI8jzQ1ACcy9DGV/KVScGHUWUpeLOK22AEcfWwKBgQDUfPFBHc2Bkuv3bRoNT+fnChMw5CI65wD74vR5GKyurh50DB3RZXwhRsAFd9NowINm9B2KAR0IrB+vh3EwfJaWDauh3ykZZtrAphSa11dJXvtathHTuQmXalZv5brh5mHie87yoxMn7vqDi0bwkNlb/b1wwokwc0oc3NSoNsFptwKBgCJhjPs00kkHSSCvodVhZCRRxHjqcoeVQzo/BGrQMow+SghYkVVNH7mUSNOeeTu4rAdtILHsTwfhbBr/i2X5RWjzRlWJFYSN8COiY5E6uTIlyfRgVAc2EbHgakoa/cl2jvlHPuZc99SVNoUCDAQ8Mw08ohXBoxXKZgcPLFVnffb5AoGBAJW5cDmk6WCrCRAwVVIaAtsek0U5CxGcImpakk8d3te7IwQ8YWph6yR7eOSheVrvg+ewjXvnqvCocC877brvnyAeg9isqYYXnn5uyEgPApdVkSFq94bLdIG30S5JnvR8ZG61NK5t0BqsXuL/6b2rIy2Zzrm8qfR02D0cMdBRvNljAoGBAMJG7/TqodrYPYyOZ4/IbbhAitBHWpHYJHSENnuxbQGAQuCt52Jp3eULR2r7uk3dUDuE8mB2QAEStuV/orfdxxRxJIYbEynJFGCa9O5LTevbM4MoNRfLCPPmFK5PJivlJcdrCyQKEmGSLLrVdb3H/Wzu0/4K/ZhwyrtBz4MRkuwD
# 沙箱支付宝公钥 # 沙箱支付宝公钥
publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgfv3CE8I87I5HHcMtK1RrPQZzLqYlXxRa96lIYkEyFsxdMcMSwnNJJf/mceZhMQnXQDkuEYTZPO/DJbmiZkBWbRZNfIJur5Af/wKZEmHahtEWlrdJdJ6fh7j11eeqbXBfo55H1dxPEQA/obfe85WrqoE0fa06XElgq5/RwsSKjZpnorbO8mMnDaRwxIOoRVHQlHgfkMtTHfP+Zw8Kv0tyJdWLxVDgtg0OoO8VnrDNGBwsxJDOvLjZBbp9NX3wiWQpfh4OBkN1KKfIA9yfBhS6N0bnWfr428Boz/qNhycdrG/MYGQDiG8hVt177fKvTVXRf/kdSIz3izN1GnzOUkadQIDAQAB publicKey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgfv3CE8I87I5HHcMtK1RrPQZzLqYlXxRa96lIYkEyFsxdMcMSwnNJJf/mceZhMQnXQDkuEYTZPO/DJbmiZkBWbRZNfIJur5Af/wKZEmHahtEWlrdJdJ6fh7j11eeqbXBfo55H1dxPEQA/obfe85WrqoE0fa06XElgq5/RwsSKjZpnorbO8mMnDaRwxIOoRVHQlHgfkMtTHfP+Zw8Kv0tyJdWLxVDgtg0OoO8VnrDNGBwsxJDOvLjZBbp9NX3wiWQpfh4OBkN1KKfIA9yfBhS6N0bnWfr428Boz/qNhycdrG/MYGQDiG8hVt177fKvTVXRf/kdSIz3izN1GnzOUkadQIDAQAB
notifyUrl: https://253d7236.r27.cpolar.top/ali/pay/notify notifyUrl: https://4b0ca615.r27.cpolar.top/ali/pay/notify
# 沙箱支付宝网关 # 沙箱支付宝网关
gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do gatewayUrl: https://openapi-sandbox.dl.alipaydev.com/gateway.do

View File

@ -22,7 +22,7 @@ public class OrderTradeDto {
*/ */
@ApiModelProperty(value = "支付金额", required = true) @ApiModelProperty(value = "支付金额", required = true)
@NotNull(message = "支付金额不能为空") @NotNull(message = "支付金额不能为空")
private Double paymentAmount; private Double amount;
/** /**
* member points * member points

View File

@ -14,5 +14,8 @@ public interface AliPayService {
AjaxResult fetch(String outBizNo, String amount) throws AlipayApiException; AjaxResult fetch(String outBizNo, String amount) throws AlipayApiException;
// 查询订单状态
AjaxResult queryTradeStatus(String outTradeNo) throws Exception;
String balance() throws AlipayApiException; String balance() throws AlipayApiException;
} }

View File

@ -2,6 +2,8 @@ package com.mcwl.pay.service.impl;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID; import cn.hutool.core.lang.UUID;
import cn.hutool.extra.mail.MailUtil; import cn.hutool.extra.mail.MailUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
@ -21,13 +23,17 @@ import com.alipay.api.response.AlipayFundAccountQueryResponse;
import com.alipay.api.response.AlipayFundTransUniTransferResponse; import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.easysdk.factory.Factory; import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config; import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.common.models.AlipayTradeCloseResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse; import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
import com.mcwl.common.JSONUtils;
import com.mcwl.common.core.domain.AjaxResult; import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.core.domain.entity.SysUser; import com.mcwl.common.core.domain.entity.SysUser;
import com.mcwl.common.core.redis.RedisCache; import com.mcwl.common.core.redis.RedisCache;
import com.mcwl.common.exception.ServiceException; import com.mcwl.common.exception.ServiceException;
import com.mcwl.common.utils.SecurityUtils; import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.common.utils.ShareCodeUtils; import com.mcwl.common.utils.ShareCodeUtils;
import com.mcwl.common.utils.StringUtils;
import com.mcwl.memberCenter.domain.MemberLevel; import com.mcwl.memberCenter.domain.MemberLevel;
import com.mcwl.memberCenter.service.MemberLevelService; import com.mcwl.memberCenter.service.MemberLevelService;
import com.mcwl.pay.config.AliConfig; import com.mcwl.pay.config.AliConfig;
@ -47,10 +53,7 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList; import java.util.*;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@ -60,6 +63,9 @@ import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
public class AliPayServiceImpl implements AliPayService { public class AliPayServiceImpl implements AliPayService {
@Autowired
private Config config;
@Autowired @Autowired
private RedisCache redisCache; private RedisCache redisCache;
@ -156,25 +162,24 @@ public class AliPayServiceImpl implements AliPayService {
// 设置orderTrade信息 // 设置orderTrade信息
OrderTrade tradeEntity = new OrderTrade(); OrderTrade tradeEntity = new OrderTrade();
BeanUtil.copyProperties(orderTradeDto, tradeEntity); BeanUtil.copyProperties(orderTradeDto, tradeEntity);
tradeEntity.setCode(UUID.randomUUID().toString(true).substring(0, 30)); tradeEntity.setCode(UUID.randomUUID().toString(true).substring(0, 30) + "_member");
tradeEntity.setUserId(SecurityUtils.getUserId()); tradeEntity.setUserId(SecurityUtils.getUserId());
tradeEntity.setUserName(SecurityUtils.getUsername()); tradeEntity.setUserName(SecurityUtils.getUsername());
tradeEntity.setProductId(productId); tradeEntity.setProductId(productId);
tradeEntity.setProductName(memberLevel.getMemberName()); tradeEntity.setProductName(memberLevel.getMemberName());
tradeEntity.setTotalAmount(orderTradeDto.getPaymentAmount()); tradeEntity.setTotalAmount(orderTradeDto.getAmount());
tradeEntity.setOrderStatus(3); tradeEntity.setOrderStatus(1);
tradeEntity.setPayStatus(2); tradeEntity.setPayStatus(1);
orderTradeService.save(tradeEntity); orderTradeService.save(tradeEntity);
//调用支付宝的接口 //调用支付宝的接口
AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace() AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace()
// 设置过期时 // 设置过期时
.preCreate(memberLevel.getMemberName(), .preCreate(memberLevel.getMemberName(),
tradeEntity.getCode() + "_member", tradeEntity.getCode(),
orderTradeDto.getPaymentAmount().toString()); orderTradeDto.getAmount().toString());
// 缓存到redis // 缓存到redis
redisCache.setCacheObject(tradeEntity.getCode() + "_member", JSONUtil.toJsonStr(tradeEntity), 3, TimeUnit.MINUTES); redisCache.setCacheObject(tradeEntity.getCode() + "_promotionId", orderTradeDto.getPromotionId());
redisCache.setCacheObject(tradeEntity.getCode() + "_member" + "_promotionId", orderTradeDto.getPromotionId(), 3, TimeUnit.MINUTES);
// AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace().preCreate("订单主题Mac笔记本", "LS123qwe123", "19999"); // AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace().preCreate("订单主题Mac笔记本", "LS123qwe123", "19999");
//参照官方文档响应示例,解析返回结果 //参照官方文档响应示例,解析返回结果
String httpBodyStr = payResponse.getHttpBody(); String httpBodyStr = payResponse.getHttpBody();
@ -198,7 +203,7 @@ public class AliPayServiceImpl implements AliPayService {
public PayVo pointsPay(Double paymentAmount) throws Exception { public PayVo pointsPay(Double paymentAmount) throws Exception {
// 设置orderTrade信息 // 设置orderTrade信息
OrderTrade tradeEntity = new OrderTrade(); OrderTrade tradeEntity = new OrderTrade();
tradeEntity.setCode(UUID.randomUUID().toString(true).substring(0, 30)); tradeEntity.setCode(UUID.randomUUID().toString(true).substring(0, 30) + "_points");
tradeEntity.setUserId(SecurityUtils.getUserId()); tradeEntity.setUserId(SecurityUtils.getUserId());
tradeEntity.setProductId(-1); tradeEntity.setProductId(-1);
tradeEntity.setProductName("积分充值"); tradeEntity.setProductName("积分充值");
@ -206,14 +211,14 @@ public class AliPayServiceImpl implements AliPayService {
tradeEntity.setTotalAmount(paymentAmount); tradeEntity.setTotalAmount(paymentAmount);
tradeEntity.setOrderStatus(1); tradeEntity.setOrderStatus(1);
tradeEntity.setPayStatus(1); tradeEntity.setPayStatus(1);
orderTradeService.save(tradeEntity);
//调用支付宝的接口 //调用支付宝的接口
AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace() AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace()
.preCreate(tradeEntity.getProductName(), .preCreate(tradeEntity.getProductName(),
tradeEntity.getCode() + "_points", tradeEntity.getCode(),
tradeEntity.getPaymentAmount().toString()); tradeEntity.getPaymentAmount().toString());
// 缓存到redis // 缓存到redis
redisCache.setCacheObject(tradeEntity.getCode() + "_points", JSONUtil.toJsonStr(tradeEntity), 3, TimeUnit.MINUTES); redisCache.setCacheObject(tradeEntity.getCode(), JSONUtil.toJsonStr(tradeEntity), 30, TimeUnit.SECONDS);
//参照官方文档响应示例,解析返回结果 //参照官方文档响应示例,解析返回结果
String httpBodyStr = payResponse.getHttpBody(); String httpBodyStr = payResponse.getHttpBody();
JSONObject jsonObject = JSONObject.parseObject(httpBodyStr); JSONObject jsonObject = JSONObject.parseObject(httpBodyStr);
@ -310,6 +315,67 @@ public class AliPayServiceImpl implements AliPayService {
throw new ServiceException("转账失败:" + response.getSubMsg()); throw new ServiceException("转账失败:" + response.getSubMsg());
} }
@Override
public AjaxResult queryTradeStatus(String outTradeNo) throws Exception {
// 查询redis中订单信息
String orderTradeJson = redisCache.getCacheObject(outTradeNo);
OrderTrade orderTrade = JSONUtil.toBean(orderTradeJson, OrderTrade.class);
// 如果redis中存在该订单, 则直接返回该订单的支付状态
if (StringUtils.isNotBlank(orderTradeJson) && Objects.nonNull(orderTrade)) {
return AjaxResult.success("查询成功", orderTrade.getPayStatus());
}
// 查询支付宝订单
orderTrade = orderTradeService.lambdaQuery()
.eq(OrderTrade::getCode, outTradeNo)
.one();
// 如果数据库中不存在该订单, 则返回订单不存在
if (Objects.isNull(orderTrade)) {
return AjaxResult.error("订单不存在");
}
if (orderTrade.getPayStatus() == 1) {
// 查询支付宝订单
Object tradStatus = this.getTradStatus(outTradeNo);
String jsonString = JSONObject.toJSONString(tradStatus);
JSONObject jsonObject = JSONObject.parseObject(jsonString);
Object tradeStatus = jsonObject.get("trade_status");
if (tradeStatus != null && tradeStatus.equals("TRADE_SUCCESS")) {
Map<String, String> params = new HashMap<>();
params.put("buyer_pay_amount", jsonObject.get("buyer_pay_amount").toString());
params.put("out_trade_no", jsonObject.get("out_trade_no").toString());
params.put("gmt_payment", jsonObject.get("send_pay_date").toString());
params.put("total_amount", jsonObject.get("total_amount").toString());
params.put("trade_no", jsonObject.get("trade_no").toString());
String code = orderTrade.getCode();
// 获取订单后缀
String suffix = code.substring(code.lastIndexOf("_") + 1);
orderTradeService.orderHandler(orderTrade, suffix, params);
return AjaxResult.success("查询成功", orderTrade.getPayStatus());
}
long expire = redisCache.getExpire(outTradeNo);
// expire 超过15分钟则删除redis中订单信息
if (expire > 900) {
// 关闭交易
AlipayTradeCloseResponse close = Factory.Payment.Common().close(outTradeNo);
if (close.getCode().equals("10000")) {
orderTrade.setOrderStatus(4);
orderTradeService.updateById(orderTrade);
redisCache.deleteObject(outTradeNo + "promotionId");
}
}
return AjaxResult.success("查询成功", orderTrade.getPayStatus());
}
redisCache.setCacheObject(outTradeNo, JSONUtil.toJsonStr(orderTrade), 5, TimeUnit.SECONDS);
return AjaxResult.success("查询成功", orderTrade.getPayStatus());
}
@Override @Override
public String balance() throws AlipayApiException { public String balance() throws AlipayApiException {
// 初始化SDK // 初始化SDK
@ -380,6 +446,20 @@ public class AliPayServiceImpl implements AliPayService {
} }
private Object getTradStatus(String outTradeNo) throws Exception {
Factory.setOptions(config);
AlipayTradeQueryResponse query = Factory.Payment.Common().query(outTradeNo);
Map<String, Object> map = JSONUtils.jsonToMap(query.getHttpBody());
// 返回交易结果, 是否交易成功需要根据该对象中的 trade_status 来确定
// trade_status 的枚举值如下, 请见 https://opendocs.alipay.com/apis/api_1/alipay.trade.query
// WAIT_BUYER_PAY交易创建等待买家付款
// TRADE_CLOSED未付款交易超时关闭或支付完成后全额退款
// TRADE_SUCCESS交易支付成功
// TRADE_FINISHED交易结束不可退款
// 当 trade_status 等于 TRADE_SUCCESS 或 TRADE_FINISHED 时, 表示支付成功
return map.get("alipay_trade_query_response");
}
private void addLogAndUpdateUserWallet(SysUser sysUser, String amount) { private void addLogAndUpdateUserWallet(SysUser sysUser, String amount) {
BigDecimal wallet = new BigDecimal(sysUser.getWallet().toString()); BigDecimal wallet = new BigDecimal(sysUser.getWallet().toString());

View File

@ -133,6 +133,10 @@ public class OrderTradeServiceImpl extends ServiceImpl<OrderTradeMapper, OrderTr
memberHandler(orderTrade, promotionId); memberHandler(orderTrade, promotionId);
} }
// 删除redis缓存
redisCache.deleteObject(orderTrade.getCode());
redisCache.deleteObject(params.get("out_trade_no") + "promotionId");
} }
private void pointsHandler(OrderTrade orderTrade, Map<String, String> params) { private void pointsHandler(OrderTrade orderTrade, Map<String, String> params) {