赞
踩
目录
-
- <!--解决yaml或者properties配置文件注入对象时提示配置,这是官方的配置依赖-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- </dependency>
- <!--完整版的支付jar包 解决subject中文问题-->
- <dependency>
- <groupId>com.alipay.sdk</groupId>
- <artifactId>alipay-sdk-java</artifactId>
- <version>4.22.110.ALL</version>
- </dependency>
-
- <!--糊涂工具转数据格式使用-->
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- <version>5.7.20</version>
- </dependency>
在 登录 - 支付宝申请一个沙箱支付账号,重点一定要私信支付宝客服,开通下商户服务,不然沙箱账号使用不了
#配置沙箱支付 // 商户appid alipay.appId= // 私钥 pkcs8格式的--java应用程序的私钥 都可以再支付宝的平台上申请 alipay.appPrivateKey= // 支付宝公钥---也可以再支付平台申请 alipay.alipayPublicKey= #内网穿透 #natapp地址 #官网:https://natapp.cn/ #先去官网申请免费隧道 并配置要穿透的端口号 #然后复制账号的token值到软件的start.hat里,最后双击修改后的文件 //支付成功后回调的地址---修改订单的状态 alipay.notifyUrl=http://改成自己的项目/alipay/notify // 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址 这里是前端vue服务的跳转地址 alipay.returnUrl=http://localhost:8000/orders
- @Data
- @Component
- @ConfigurationProperties(prefix = "alipay")
- public class AlipayConfig {
- private String appId;
- private String appPrivateKey;
- private String alipayPublicKey;
- private String notifyUrl;
- private String returnUrl;
- }
- @Data
- public class AliPay {
- private String traceNo;
- private double totalAmount;
- private String subject;
- private String alipayTraceNo;
- }
- @RestController
- @RequestMapping("/alipay")
- public class AliPayController {
-
- /**
- * 配置支付宝沙箱支付的格式 和签证
- */
- private static final String GATEWAY_URL = "https://openapi.alipaydev.com/gateway.do";
- private static final String FORMAT = "JSON";
- private static final String CHARSET = "UTF-8";
- //签名方式
- private static final String SIGN_TYPE = "RSA2";
-
- @Resource
- private AlipayConfig aliPayConfig;
-
- @Resource
- private OrdersMapper ordersMapper;
-
-
- /**
- * 支付的接口方法
- * @param aliPay
- * @param httpResponse
- * @throws Exception
- */
- @GetMapping("/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx
- public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
- // 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
- AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
- aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
-
- // 2. 创建 Request并设置Request参数
- AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); // 发送请求的 Request类
- request.setNotifyUrl(aliPayConfig.getNotifyUrl());
- request.setReturnUrl(aliPayConfig.getReturnUrl());
- JSONObject bizContent = new JSONObject();
- bizContent.set("out_trade_no", aliPay.getTraceNo()); // 我们自己生成的订单编号
- bizContent.set("total_amount", aliPay.getTotalAmount()); // 订单的总金额
- bizContent.set("subject", aliPay.getSubject()); // 支付的名称
- bizContent.set("product_code", "FAST_INSTANT_TRADE_PAY"); // 固定配置
- request.setBizContent(bizContent.toString());
-
- // 执行请求,拿到响应的结果,返回给浏览器
- String form = "";
- try {
- form = alipayClient.pageExecute(request).getBody(); // 调用SDK生成表单
- } catch (AlipayApiException e) {
- e.printStackTrace();
- }
- httpResponse.setContentType("text/html;charset=" + CHARSET);
- httpResponse.getWriter().write(form);// 直接将完整的表单html输出到页面
- httpResponse.getWriter().flush();
- httpResponse.getWriter().close();
- }
-
- @PostMapping("/notify") // 注意这里必须是POST接口
- public String payNotify(HttpServletRequest request) throws Exception {
- 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 outTradeNo = params.get("out_trade_no");
- String gmtPayment = params.get("gmt_payment");
- String alipayTradeNo = params.get("trade_no");
-
- String sign = params.get("sign");
- String content = AlipaySignature.getSignCheckContentV1(params);
- boolean checkSignature = AlipaySignature.rsa256CheckContent(content, sign, aliPayConfig.getAlipayPublicKey(), "UTF-8"); // 验证签名
- // 支付宝验签
- if (checkSignature) {
- // 验签通过
- 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"));
-
- // 查询订单 这里是支付的业务代码
- QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
- queryWrapper.eq("order_id", outTradeNo);
- Orders orders = ordersMapper.selectOne(queryWrapper);
-
- if (orders != null) {
- orders.setAlipayNo(alipayTradeNo);
- orders.setPayTime(new Date());
- orders.setState("已支付");
- ordersMapper.updateById(orders);
- }
- }
- }
- return "success";
- }
-
- @GetMapping("/return")
- public Result returnPay(AliPay aliPay) throws AlipayApiException {
- // 7天无理由退款
-
- String now = DateUtil.now();
-
- LambdaQueryWrapper<Orders> wrapper = new LambdaQueryWrapper<Orders>();
- wrapper.eq(Orders::getAlipayNo, aliPay.getTraceNo());
-
- //返回查询结果
-
-
- Orders orders = ordersMapper.selectOne(wrapper);
-
- if (orders != null) {
- // hutool工具类,判断时间间隔
-
- long between = DateUtil.between(
- DateUtil.parseDateTime(DateFormatUtil.DateToString(orders.getPayTime())),
- DateUtil.parseDateTime(now),
- DateUnit.DAY);
- if (between > 7) {
-
- return new Result(-1,"该订单已超过7天,不支持退款",null);
- }
- }
-
-
- // 1. 创建Client,通用SDK提供的Client,负责调用支付宝的API
- AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL,
- aliPayConfig.getAppId(), aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET,
- aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
- // 2. 创建 Request,设置参数
- AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
- JSONObject bizContent = new JSONObject();
- bizContent.set("trade_no", aliPay.getAlipayTraceNo()); // 支付宝回调的订单流水号
- bizContent.set("refund_amount", aliPay.getTotalAmount()); // 订单的总金额
- bizContent.set("out_request_no", aliPay.getTraceNo()); // 我的订单编号
-
- // 返回参数选项,按需传入
- //JSONArray queryOptions = new JSONArray();
- //queryOptions.add("refund_detail_item_list");
- //bizContent.put("query_options", queryOptions);
-
- request.setBizContent(bizContent.toString());
-
- // 3. 执行请求
- AlipayTradeRefundResponse response = alipayClient.execute(request);
- if (response.isSuccess()) { // 退款成功,isSuccess 为true
- System.out.println("调用成功");
-
- // 4. 更新数据库状态
-
- UpdateWrapper<Orders> wrapper1=new UpdateWrapper<>();
- //这表示给指定的一条数据修改,不然就给所有数据修改了
- wrapper1.eq("id",orders.getId())
- .set("state","已退款");
- ordersMapper.update(null, wrapper);
-
- return new Result(200,"退款成功");
- } else { // 退款失败,isSuccess 为false
- System.out.println(response.getBody());
-
- return new Result(4041, response.getBody(),"退款失败");
- }
-
- }
-
-
- }
关于沙箱支付的配置就完成了,其他的正常写,支付的时候调用该接口,就行
待补充
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。