springboot接入支付宝支付

在springboot项目中接入支付宝支付

一、在官网申请开通

进入支付宝开放平台
在这里插入图片描述
支付宝扫码登录注册,填写相关信息。
因为我们是开发者,所以支付宝给我们提供一个完整的沙箱环境,只要登录开放平台就会给我们提供一个测试的商家账号和支付账号
在这里插入图片描述
这里需设置下开发者的密钥我们选择系统默认,第一个点击启用即可
在这里插入图片描述
设置好之后,点击查看。
在这里插入图片描述
可以看见沙箱环境下有商家信息买家信息
在这里插入图片描述

二、编写代码

将下面的代码复制到你的系统即可。注意:将里面的信息改成你自己的哦!

0、引入jar

<dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>3.0.0</version>
</dependency>

1、支付宝支付

/**
 * 支付配置信息
 * @author cxt
 * @date 2021/11/20
 */
public class AlipayConfig {
    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID
    public static String APP_ID = "2021******2179"; // 写你的AppID

    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String APP_PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCurNMo4AdLzKibsfGiz469NmXaGgypz2LBcKUwyXG4Cn0UAGDnxX+7+sshGyxMYrEczETZ8rRR6d7M4ZzyFGeHZN4aHCsUT7MyIVu+OtUpZr+H4zVllKbia7rCZgkWd8/r+kpxY1ikFhxWpu+hPi32ylA+9FdKPXSJrOq************************"; // 写你商户私钥

    // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhiWEgdjid1gy2nqKcNcoJTr7f9om6WNI6qaNnv0KW3vjjBHnrgnZIGHuI3XFpPyii0rtkVpRTEZcD1JBq21rPfPmS3EW7AVqdjPWTuz/7EgH2OvR4Sk/pvS9Lg7IqnJwG29r43WYwQ22x+K+CZSzTKmf5Vzk8m2cKumogvTyNf26+c/SIYVn4************************"; // 写你的支付宝公钥

    // 签名方式
    public static String sign_type = "RSA2";

    // 字符编码格式
    public static String CHARSET = "utf-8";

    // 支付宝网关,这是沙箱的网关
    public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";

    // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(开发环境时可以使用内网穿透工具,有很多,自行度)
    public static String notify_url = "http://pcfapi.natappfree.cc/ih/diagnose/pay/alipay/callback"; // 写你接受通知的接口地址

    // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(其实就是支付成功后返回的页面)
    public static String return_url = "http://172.16.16.102:8080/#/seeDoctor"; // 写你在支付成功之后进入的页面地址

    // 支付宝网关
    public static String log_path = "C:\\";
}
/**
 * @author: cxt
 * @time: 2021/11/18
 */
@RestController
@Api(tags = "支付接口")
@RequestMapping("/ih/diagnose/pay")
public class PayController {

    private PayService payService;

    // "支付宝支付接口"
    @PostMapping("/alipay")
    public void alipay(@RequestParam String registerId, @RequestParam boolean isAppoint, HttpServletResponse response) {
        try {
            payService.alipay(registerId, isAppoint, response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // TODO 可以不写这个接口,个人认为作用不大
    // "支付验证"
    @PostMapping("/alipay/check")
    public boolean alipayCheck(@RequestParam String registerId) {
        return payService.alipayCheck(registerId);
    }

    /**
     * 支付宝异步付款结果通知
     */
    @PostMapping("/alipay/callback")
    public void alipayCallback(HttpServletRequest request) {
        try {
            payService.alipayCallback(request);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 支付宝退款
     * 注意:支付宝服务器发送的url是没有登录状态的,需要在系统中设置放过登录校验,不然接收不到通知
     */
    @PostMapping("/alipay/refund/callback")
    public boolean alipayRefundCallback(@RequestParam String outTradeNo, @RequestParam String tradeNo,
                                        @RequestParam String refundAmount, @RequestParam String subject) {
        boolean result = false;
        try {
            result = payService.alipayRefund(outTradeNo, tradeNo, refundAmount, subject);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return result;
    }

    // 退费查询
    @PostMapping("/alipay/refund/alipayRefundSelect")
    public boolean alipayRefundCallback(@RequestParam String outRequestNo, @RequestParam String tradeNo) {
        return payService.alipayRefundSelect(outRequestNo, tradeNo);
    }

    @Autowired
    public void setPayService(PayService payService) {
        this.payService = payService;
    }
}
/**
 * @author cxt
 * @date 2021/11/20
 */
@Service
public class PayService {

    /**
     * 支付宝支付
     */
    public void alipay(String registerId, boolean isAppoint, HttpServletResponse response) throws IOException {
        DefaultAlipayClient client = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID, AlipayConfig.APP_PRIVATE_KEY,
                "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.sign_type);

        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        // todo 查询金额相关信息
        // 付款金额,必填
        String total_amount = String.valueOf(0.1);

        // 订单名称,必填
        String subject = "测试的名称";

        // 商品描述,可空
        String body = "就诊日期:" + new Date();

        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", registerId);
        bizContent.put("total_amount", total_amount);
        bizContent.put("subject", subject);
        bizContent.put("body", body);
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        alipayRequest.setBizContent(bizContent.toString());

        // 生成请求页面
        String form = "";
        try {
            form = client.pageExecute(alipayRequest).getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
        response.getWriter().write(form);
        response.getWriter().flush();
        response.getWriter().close();
    }

    /**
     * 支付校验
     *
     * @param registerId 订单号
     * @return
     */
    public boolean alipayCheck(String registerId) {
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID,
                AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,
                AlipayConfig.sign_type);

        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", registerId);
        request.setBizContent(bizContent.toString());

        AlipayTradeQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
            if (response.isSuccess()) {

                // TODO 异步通知接收不到,先用同步更新状态,上线时删除 --- 开始
                if (response.getTradeNo() != null) {
                    // update 订单表
                }
                // TODO 异步通知接收不到,先用同步更新状态,上线时删除 --- 结束


                return true;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 异步付款结果通知
     * 注意:支付宝服务器发送的url是没有登录状态的,需要在系统中设置放过登录校验,不然接收不到通知
     */
    public void alipayCallback(HttpServletRequest request) throws Exception {
        String tradeStatus = request.getParameter("trade_status"); // 交易状态
        String orderNo = request.getParameter("out_trade_no"); // 获取订单号
        String tradeNo = request.getParameter("trade_no"); // 支付宝交易凭证号

        Map<String, String> map = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        if (requestParams.isEmpty()) {
            throw new Exception("系统异常,异步通知参数为空");
        }
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            map.put(name, valueStr);
        }

        // 校验
        boolean signVerified = AlipaySignature.rsaCheckV1(map, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.sign_type);

        if (signVerified) {
            if (tradeStatus.equals("TRADE_SUCCESS")) {
                // 支付成功 -> 自己实现改订单状态
                // update 订单表   orderNo, tradeNo
            } else {
                // 其他可能触发的异步通知
                log.debug(tradeStatus);
            }
        }
    }

    /**
     * 支付宝退费
     *
     * @param outTradeNo   订单号
     * @param tradeNo      交易支付凭证号
     * @param refundAmount 交易金额
     * @param refundReason 退费原因
     */
    public boolean alipayRefund(String outTradeNo, String tradeNo, String refundAmount, String refundReason) throws AlipayApiException {
        // 获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID,
                AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,
                AlipayConfig.sign_type);

        // 设置请求参数
        AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", outTradeNo);
        bizContent.put("trade_no", tradeNo);
        bizContent.put("refund_amount", refundAmount);
        bizContent.put("refund_reason", refundReason);

        alipayRequest.setBizContent(bizContent.toString());

        boolean result = false;
        AlipayTradeRefundResponse response = alipayClient.execute(alipayRequest);
        boolean b = response.isSuccess();
        if (!b) {
            // 退款失败,重试三次
            for (int i = 0; i < 3; i++) {
                AlipayTradeRefundResponse loopResponse = alipayClient.execute(alipayRequest);
                boolean loopResult = loopResponse.isSuccess();
                if (loopResult) {
                    result = true;
                    break;
                }
            }
            if (!result) {
                log.error("订单:{},退款失败", outTradeNo);
            }
        } else {
            log.info("订单:{},退款成功", outTradeNo);
            result = true;
        }
        return result;
    }


    /**
     * 支付宝退款查询
     *
     * @param outRequestNo 订单号
     * @param tradeNo      交易支付凭证号
     */
    public boolean alipayRefundSelect(String outRequestNo, String tradeNo) {
        // 获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.APP_ID,
                AlipayConfig.APP_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY,
                AlipayConfig.sign_type);

        // 设置请求参数
        AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();

        JSONObject bizContent = new JSONObject();
        bizContent.put("trade_no", tradeNo);
        bizContent.put("out_request_no", outRequestNo);
        alipayRequest.setBizContent(bizContent.toString());

        boolean result = false;
        try {
            AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(alipayRequest);
            if (!response.isSuccess()) {
                for (int i = 0; i < 3; i++) {
                    AlipayTradeFastpayRefundQueryResponse loopResponse = alipayClient.execute(alipayRequest);
                    if (loopResponse.isSuccess()) {
                        result = true;
                        break;
                    }
                }
            } else {
                log.info("已退款");
                result = true;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return result;
    }

}

vue前端代码调用接口

// 点击挂号按钮调用
register(doctorId) {
      this.$http
        .post(`/ih/patient/diagnose/register/quick?doctorId=${doctorId}`)
        .then((res) => {
          if (res.status == 200) {
          	// 支付
            this.alipay(res.data.registerId);
          }
        });
    },
// 调用支付接口
alipay(registerId){
      this.$http
        .post(`/ih/diagnose/pay/alipay?registerId=${registerId}&isAppoint=false`)
        .then((res) => {
          document.querySelector("body").innerHTML = res.data; // 查找到当前页面的body,将后台返回的form替换掉他的内容
          document.forms[0].submit(); // 执行submit表单提交,让页面重定向,跳转到支付宝页面
        });
    },

这样就在页面看跳转到了支付界面,支付成功之后就会返回到你指定的页面。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值