SpringBoot对接支付宝当面付

前言

支付宝当面付相比较微信支付的门槛比较低,但是无论对接微信支付还是支付宝支付都是比较麻烦的一件事,这里来记录一下对接支付宝当面付的过程。

我这里已经注册好了支付宝当面付的环境

申请当面付教程:支付宝当面付申请设置教程,支持个人用户

代码

1、依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.alipaytest</groupId>
    <artifactId>alipaytest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>alipaytest</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.6.13</spring-boot.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--        引入支付宝-->
        <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-easysdk -->
        <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>3.4.27.ALL</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.16</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
            <version>2.3.12.RELEASE</version>
        </dependency>

    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.alipaytest.alipaytest.AlipaytestApplication</mainClass>
                    <skip>true</skip>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

2、支付宝商户配置

*/
public class AliPayConfig {
//    商户APPID
    public static String APPID="你的AppID";//

    //    应用私钥pkcs8
    public static String RSA_PRIVATE_KEY="你的应用私钥";//真实

    //    服务器异步通知页面 http://或者https://完整路径 必须外网可以访问
    public static String notify_url="http://127.0.0.1:9090/alipaynotify";

    //    同步通知路径,支付后页面跳转
    public static String return_url="https://www.baidu.com";

    //    请求网关地址
    public static String server_URL="https://openapi.alipaydev.com/gateway.do";//
//    编码
    public static String CHARSET="UTF-8";
    //    返回格式
    public static String FORMAT="json";
    //    支付宝公钥
    public static String ALIPAY_PUBLIC_KEY="你的支付宝公钥";//真实
//    RSA2
    public static String SIGNTYPE="RSA2";

}

3、接口参数类

package com.alipaytest.pojo;

import com.sun.istack.internal.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.lang.NonNull;

import javax.validation.constraints.NotBlank;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class QrPayParam {

//    @NotNull(message = "流水单号不能空")
//    String out_trade_no;
    @NotBlank(message = "商品名称不能空")
    String subject;
    @NotBlank(message = "付款金额不能空")
    String total_amount;
    String body;
//    @NotNull(message = "二维码过期时间不能空")
//    String timeout_express;
//    @NotNull(message = "产品码不能空")
//    String product_code;
}


4、Controller接口

package com.alipaytest.controller;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipaytest.config.AliPayConfig;
import com.alipaytest.pojo.QrPayParam;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.HashMap;

/**
 * @author niuben
 */
@RestController
public class aliPayController {
    @ResponseBody
    @PostMapping("/pay")
    public HashMap<String, Object> pay(@RequestBody QrPayParam param) throws AlipayApiException {

        AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.server_URL,
                AliPayConfig.APPID, AliPayConfig.RSA_PRIVATE_KEY, AliPayConfig.FORMAT, AliPayConfig.CHARSET,
                AliPayConfig.ALIPAY_PUBLIC_KEY, AliPayConfig.SIGNTYPE);

        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        String idStr = IdUtil.getSnowflakeNextIdStr();//生成的流水号
        model.setOutTradeNo(idStr);//设置商家这边的流水单号 后台写
        model.setSubject(param.getSubject());//设置商品名称
        model.setTotalAmount(param.getTotal_amount());//设置付款金额
        model.setBody("test");//设置商品描述
        model.setTimeoutExpress("10m");//设置过期时间 格式:xxm 后台写
//        model.setProductCode(qrPayParam.getProduct_code());//设置产品码 - 二维码支付的话没有该功能


        request.setBizModel(model);//存入请求信息
        request.setNotifyUrl(AliPayConfig.notify_url);//设置通知地址
        request.setReturnUrl(AliPayConfig.return_url);//设置返回地址,二维码支付此功能无效

//        生成表单,二维码支付无表单
//        String form = alipayClient.pageExecute(request).getBody();

//        封装生成请求对象
        AlipayTradePrecreateResponse response = alipayClient.execute(request);

//        发送请求,获取返回信息
        System.out.println(response.getBody());

        HashMap<String, Object> map = new HashMap<>();



//        成功
        if (response.isSuccess()){
            System.out.println("调用成功");
            JSONObject responJson = JSONUtil.parseObj(response.getBody());
            JSONObject rsj = (JSONObject)responJson.get("alipay_trade_precreate_response");
            String qr_code = (String) rsj.get("qr_code");//获取二维码地址
            map.put("qrcode",qr_code);
            map.put("out_trade_no",idStr);

            return map;


        }else {
            JSONObject responJson = JSONUtil.parseObj(response.getBody());
            JSONObject rsj = (JSONObject)responJson.get("alipay_trade_precreate_response");
            String res = (String) rsj.get("sub_msg");//获取返回错误的信息
            map.put("sub_msg",res);
            return map;
        }
    }
    //    接收异步消息并同步订单状态
    @PostMapping("/alipaynotify")
    public ApiRequest getnotify(String trade_no, String out_trade_no){
        LambdaQueryWrapper<QrPay> wr = new LambdaQueryWrapper<QrPay>().eq(QrPay::getOutTradeNo, out_trade_no);
        QrPay order = payService.getOne(wr);
        System.out.println(order);
        order.setState(1);
        order.setPaytime(new DateTime().toString());
        order.setTradeNo(trade_no);
        System.out.println(order.getOutTradeNo());
        boolean update = payService.update(order, wr);//提交修改订单状态

        Integer uid = order.getUid();

        LambdaQueryWrapper<User> userwr = new LambdaQueryWrapper<User>().eq(User::getId, uid);
        User user = userService.getOne(userwr);
        BigDecimal money = user.getMoney();//现在余额
        System.out.println("现在余额:" +money);
        System.out.println("开始加鱼儿---"+ order.getTotalAmount().toString());
        BigDecimal newmonry = new BigDecimal( money.add(order.getTotalAmount()).toString());//现在余额加上充值金额
        System.out.println("新余额:"+newmonry);
        user.setMoney(newmonry);
        userService.update(user,userwr);


        return ApiRequest.ok(update);
    }
}

实现效果

前端将返回的链接转化为二维码即可
在这里插入图片描述