新增支付宝扫码支付回调接口

新增根据订单号查询支付订单状态
feature/comment
Diyu0904 2025-01-06 15:27:41 +08:00
parent a98d3bea72
commit 6cba0a69fe
6 changed files with 178 additions and 86 deletions

View File

@ -1,12 +1,13 @@
package com.mcwl.web.controller.pay;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
import com.alibaba.fastjson.JSONObject;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
import com.mcwl.pay.domain.OrderTrade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alipay.easysdk.kernel.Config;
/**
*
@ -27,11 +28,11 @@ public class AliPayIntegration {
public String pay(OrderTrade tradeEntity) throws Exception {
Factory.setOptions(config);
//调用支付宝的接口
// AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace()
// .preCreate(tradeEntity.getUserName(),
// tradeEntity.getCode(),
// tradeEntity.getPaymentAmount().toString());
AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace().preCreate("订单主题Mac笔记本", "LS123qwe123", "19999");
AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace()
.preCreate(tradeEntity.getUserName(),
tradeEntity.getCode(),
tradeEntity.getPaymentAmount().toString());
// AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace().preCreate("订单主题Mac笔记本", "LS123qwe123", "19999");
//参照官方文档响应示例,解析返回结果
String httpBodyStr = payResponse.getHttpBody();
JSONObject jsonObject = JSONObject.parseObject(httpBodyStr);

View File

@ -1,25 +1,28 @@
package com.mcwl.web.controller.pay;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.mcwl.common.JSONUtils;
import com.mcwl.common.annotation.Anonymous;
import com.mcwl.common.core.controller.BaseController;
import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.core.page.TableDataInfo;
import com.mcwl.common.domain.IdsParam;
import com.mcwl.common.interfaces.NoLogin;
import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.pay.domain.OrderTrade;
import com.mcwl.pay.service.OrderTradeService;
import com.mcwl.resource.domain.MallProduct;
import lombok.extern.slf4j.Slf4j;
import com.alipay.easysdk.kernel.Config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import static com.mcwl.common.utils.PageUtils.startPage;
import java.util.Map;
/**
* @AuthorChenYan
@ -30,11 +33,15 @@ import static com.mcwl.common.utils.PageUtils.startPage;
* @Date2025/1/3 14:46
*/
@Slf4j
@RestController
@RequestMapping("/web/pay")
@Validated
public class OrderTradeController extends BaseController {
@Autowired
private Config config;
@Autowired
private OrderTradeService orderTradeService;
@ -102,7 +109,7 @@ public class OrderTradeController extends BaseController {
* @param response
* @throws Exception
*/
@NoLogin
@Anonymous
@PostMapping("/doPay")
public void doPay(@RequestBody OrderTrade tradeEntity, HttpServletResponse response) throws Exception {
String qrUrl = aliPayIntegration.pay(tradeEntity);
@ -110,4 +117,63 @@ public class OrderTradeController extends BaseController {
}
@GetMapping("/queryTradeStatus")
public Object queryTradeStatus(@RequestParam 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");
}
/**
*
* @param request
* @return
* @throws Exception
*/
@Anonymous
@PostMapping("/notify") // 注意这里必须是POST接口
public String payNotify(HttpServletRequest request) throws Exception {
log.info("已经进入回调接口");
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
// System.out.println(name + " = " + request.getParameter(name));
}
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 支付宝验签
if (Factory.Payment.Common().verifyNotify(params)) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
// 更新订单状态
}
}
return "success";
}
}

View File

@ -1,71 +1,71 @@
package com.mcwl.memberCenter;
import com.mcwl.McWlApplication;
import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.memberCenter.consumer.EmptyPointsRemindConsumer;
import com.mcwl.memberCenter.service.MemberLevelService;
import com.mcwl.memberCenter.service.MemberService;
import com.mcwl.memberCenter.task.UserMemberTask;
import com.mcwl.web.controller.memberCenter.MemberController;
import com.mcwl.web.controller.memberCenter.MemberLevelController;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = McWlApplication.class)
public class MemberCenterTest {
@Autowired
private MemberLevelService memberLevelService;
@Autowired
private MemberController memberController;
@Autowired
private MemberService memberService;
@Autowired
private UserMemberTask userMemberTask;
@Autowired
private MemberLevelController memberLevelController;
@Autowired
private EmptyPointsRemindConsumer emptyPointsRemindConsumer;
@Test
public void createUserMember() {
System.out.println(memberService.createUserMember(1L, 1013L, "wechat",1L));
}
@Test
public void emptyPointsTaskTest() {
userMemberTask.emptyPointsTsk();
}
@Test
public void updateSubscriptionStatusTaskTest() {
userMemberTask.updateSubscriptionStatusTask();
}
@Test
public void memberServiceTest() {
System.out.println(memberLevelService.list());
}
@Test
public void getPointsTest() {
AjaxResult points = memberController.getPoints();
System.out.println("points = " + points);
}
@Test
public void getMemberLevelListTest() {
System.out.println("memberLevelController.getMemberBenefitList() = " + memberLevelController.getMemberBenefitList());
}
}
//package com.mcwl.memberCenter;
//
//import com.mcwl.McWlApplication;
//import com.mcwl.common.core.domain.AjaxResult;
//import com.mcwl.memberCenter.consumer.EmptyPointsRemindConsumer;
//import com.mcwl.memberCenter.service.MemberLevelService;
//import com.mcwl.memberCenter.service.MemberService;
//import com.mcwl.memberCenter.task.UserMemberTask;
//import com.mcwl.web.controller.memberCenter.MemberController;
//import com.mcwl.web.controller.memberCenter.MemberLevelController;
//import org.junit.Test;
//import org.junit.runner.RunWith;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.test.context.junit4.SpringRunner;
//
//@RunWith(SpringRunner.class)
//@SpringBootTest(classes = McWlApplication.class)
//public class MemberCenterTest {
//
//
// @Autowired
// private MemberLevelService memberLevelService;
//
// @Autowired
// private MemberController memberController;
//
// @Autowired
// private MemberService memberService;
//
// @Autowired
// private UserMemberTask userMemberTask;
//
// @Autowired
// private MemberLevelController memberLevelController;
//
// @Autowired
// private EmptyPointsRemindConsumer emptyPointsRemindConsumer;
// @Test
// public void createUserMember() {
// System.out.println(memberService.createUserMember(1L, 1013L, "wechat",1L));
// }
//
// @Test
// public void emptyPointsTaskTest() {
// userMemberTask.emptyPointsTsk();
// }
//
// @Test
// public void updateSubscriptionStatusTaskTest() {
// userMemberTask.updateSubscriptionStatusTask();
// }
//
//
// @Test
// public void memberServiceTest() {
// System.out.println(memberLevelService.list());
// }
//
// @Test
// public void getPointsTest() {
// AjaxResult points = memberController.getPoints();
// System.out.println("points = " + points);
// }
//
// @Test
// public void getMemberLevelListTest() {
// System.out.println("memberLevelController.getMemberBenefitList() = " + memberLevelController.getMemberBenefitList());
// }
//
//}

View File

@ -341,6 +341,9 @@
<version>3.5.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,22 @@
package com.mcwl.common;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
/**
* @author DaiZibo
* @date 2025/1/6
* @apiNote
*/
public class JSONUtils {
private static final ObjectMapper mapper = new ObjectMapper();
public static Map<String, Object> jsonToMap(String jsonStr) throws JsonProcessingException {
Map<String, Object> map = mapper.readValue(jsonStr, Map.class);
return map;
}
}

View File

@ -129,7 +129,7 @@ public class SecurityConfig
.authorizeHttpRequests((requests) -> {
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
requests.antMatchers("/login", "/register", "/captchaImage","/web/pay/doPay","/web/pay/notify").permitAll()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()