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

新增根据订单号查询支付订单状态
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; package com.mcwl.web.controller.pay;
import com.alipay.easysdk.payment.facetoface.models.AlipayTradePrecreateResponse;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alipay.easysdk.factory.Factory; 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 com.mcwl.pay.domain.OrderTrade;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; 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 { public String pay(OrderTrade tradeEntity) throws Exception {
Factory.setOptions(config); Factory.setOptions(config);
//调用支付宝的接口 //调用支付宝的接口
// AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace() AlipayTradePrecreateResponse payResponse = Factory.Payment.FaceToFace()
// .preCreate(tradeEntity.getUserName(), .preCreate(tradeEntity.getUserName(),
// tradeEntity.getCode(), tradeEntity.getCode(),
// tradeEntity.getPaymentAmount().toString()); tradeEntity.getPaymentAmount().toString());
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();
JSONObject jsonObject = JSONObject.parseObject(httpBodyStr); JSONObject jsonObject = JSONObject.parseObject(httpBodyStr);

View File

@ -1,25 +1,28 @@
package com.mcwl.web.controller.pay; package com.mcwl.web.controller.pay;
import cn.hutool.extra.qrcode.QrCodeUtil; 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.controller.BaseController;
import com.mcwl.common.core.domain.AjaxResult; import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.common.core.page.TableDataInfo; import com.mcwl.common.core.page.TableDataInfo;
import com.mcwl.common.domain.IdsParam; import com.mcwl.common.domain.IdsParam;
import com.mcwl.common.interfaces.NoLogin;
import com.mcwl.common.utils.SecurityUtils; import com.mcwl.common.utils.SecurityUtils;
import com.mcwl.pay.domain.OrderTrade; import com.mcwl.pay.domain.OrderTrade;
import com.mcwl.pay.service.OrderTradeService; 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.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Map;
import static com.mcwl.common.utils.PageUtils.startPage;
/** /**
* @AuthorChenYan * @AuthorChenYan
@ -30,11 +33,15 @@ import static com.mcwl.common.utils.PageUtils.startPage;
* @Date2025/1/3 14:46 * @Date2025/1/3 14:46
*/ */
@Slf4j
@RestController @RestController
@RequestMapping("/web/pay") @RequestMapping("/web/pay")
@Validated @Validated
public class OrderTradeController extends BaseController { public class OrderTradeController extends BaseController {
@Autowired
private Config config;
@Autowired @Autowired
private OrderTradeService orderTradeService; private OrderTradeService orderTradeService;
@ -102,7 +109,7 @@ public class OrderTradeController extends BaseController {
* @param response * @param response
* @throws Exception * @throws Exception
*/ */
@NoLogin @Anonymous
@PostMapping("/doPay") @PostMapping("/doPay")
public void doPay(@RequestBody OrderTrade tradeEntity, HttpServletResponse response) throws Exception { public void doPay(@RequestBody OrderTrade tradeEntity, HttpServletResponse response) throws Exception {
String qrUrl = aliPayIntegration.pay(tradeEntity); 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; //package com.mcwl.memberCenter;
//
import com.mcwl.McWlApplication; //import com.mcwl.McWlApplication;
import com.mcwl.common.core.domain.AjaxResult; //import com.mcwl.common.core.domain.AjaxResult;
import com.mcwl.memberCenter.consumer.EmptyPointsRemindConsumer; //import com.mcwl.memberCenter.consumer.EmptyPointsRemindConsumer;
import com.mcwl.memberCenter.service.MemberLevelService; //import com.mcwl.memberCenter.service.MemberLevelService;
import com.mcwl.memberCenter.service.MemberService; //import com.mcwl.memberCenter.service.MemberService;
import com.mcwl.memberCenter.task.UserMemberTask; //import com.mcwl.memberCenter.task.UserMemberTask;
import com.mcwl.web.controller.memberCenter.MemberController; //import com.mcwl.web.controller.memberCenter.MemberController;
import com.mcwl.web.controller.memberCenter.MemberLevelController; //import com.mcwl.web.controller.memberCenter.MemberLevelController;
import org.junit.Test; //import org.junit.Test;
import org.junit.runner.RunWith; //import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; //import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner; //import org.springframework.test.context.junit4.SpringRunner;
//
@RunWith(SpringRunner.class) //@RunWith(SpringRunner.class)
@SpringBootTest(classes = McWlApplication.class) //@SpringBootTest(classes = McWlApplication.class)
public class MemberCenterTest { //public class MemberCenterTest {
//
//
@Autowired // @Autowired
private MemberLevelService memberLevelService; // private MemberLevelService memberLevelService;
//
@Autowired // @Autowired
private MemberController memberController; // private MemberController memberController;
//
@Autowired // @Autowired
private MemberService memberService; // private MemberService memberService;
//
@Autowired // @Autowired
private UserMemberTask userMemberTask; // private UserMemberTask userMemberTask;
//
@Autowired // @Autowired
private MemberLevelController memberLevelController; // private MemberLevelController memberLevelController;
//
@Autowired // @Autowired
private EmptyPointsRemindConsumer emptyPointsRemindConsumer; // private EmptyPointsRemindConsumer emptyPointsRemindConsumer;
@Test // @Test
public void createUserMember() { // public void createUserMember() {
System.out.println(memberService.createUserMember(1L, 1013L, "wechat",1L)); // System.out.println(memberService.createUserMember(1L, 1013L, "wechat",1L));
} // }
//
@Test // @Test
public void emptyPointsTaskTest() { // public void emptyPointsTaskTest() {
userMemberTask.emptyPointsTsk(); // userMemberTask.emptyPointsTsk();
} // }
//
@Test // @Test
public void updateSubscriptionStatusTaskTest() { // public void updateSubscriptionStatusTaskTest() {
userMemberTask.updateSubscriptionStatusTask(); // userMemberTask.updateSubscriptionStatusTask();
} // }
//
//
@Test // @Test
public void memberServiceTest() { // public void memberServiceTest() {
System.out.println(memberLevelService.list()); // System.out.println(memberLevelService.list());
} // }
//
@Test // @Test
public void getPointsTest() { // public void getPointsTest() {
AjaxResult points = memberController.getPoints(); // AjaxResult points = memberController.getPoints();
System.out.println("points = " + points); // System.out.println("points = " + points);
} // }
//
@Test // @Test
public void getMemberLevelListTest() { // public void getMemberLevelListTest() {
System.out.println("memberLevelController.getMemberBenefitList() = " + memberLevelController.getMemberBenefitList()); // System.out.println("memberLevelController.getMemberBenefitList() = " + memberLevelController.getMemberBenefitList());
} // }
//
} //}

View File

@ -341,6 +341,9 @@
<version>3.5.0</version> <version>3.5.0</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </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) -> { .authorizeHttpRequests((requests) -> {
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll()); permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问 // 对于登录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(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()