SpringBoot 集成支付宝转账(提现功能)

支付宝转账功能

1.准备工作(下载证书、私钥、APPID)

支付宝转账我们需要证书,怎么获取证书我已经在另一篇 支付宝集成网页支付【证书模式】里面有说明怎么获取所需要的三个证书,不知道的可以去查看链接如下:
查看如何获取支付宝证书

这里需要注意自己的APP有没有转账的能力,不然无法实现!!!
在这里插入图片描述

2.导入依赖

        <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.13.50.ALL</version>
        </dependency>

3.创建配置类

这里的配置和证书支付的一样,有的就不需要创建了


/**
 * @author Lenovo
 */
public class AlipayConfig {
    /**
     * 应用公钥证书路径
     */
    public static final String APP_CERT_PATH = "static/cert/alipay/appCertPublicKey_2021001145671220.crt";
    /**
     * 支付宝公钥证书路径
     */
    public static final String ALIPAY_CERT_PATH = "static/cert/alipay/alipayCertPublicKey_RSA2.crt";
    /**
     * 支付宝根证书路径
     */
    public static final String ALIPAY_ROOT_CERT_PATH = "static/cert/alipay/alipayRootCert.crt";

    /**
     * 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID
     */
    public static String app_id = "APPID";

    /**
     * 私钥,您的PKCS8格式RSA2私钥(应用私钥)
     */
    public static String merchant_private_key = "应用私钥";

    /**
     * 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(可以使用natapp内容穿透完成外网设置)
     */
    public static String notify_url = "异步通知url/web/aliPay/aliPayCallBack";

    /**
     * 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
     */
    public static String return_url = "同步通知url";
    
    /**
     * 传参方式
     */
    public static final String format = "JSON";

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

    /**
     * 字符编码格式  固定
     */
    public static String charset = "utf-8";

    /**
     * 支付宝网关   开发环境
     */
    public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";

}


4.开始自己的业务模块

1.创建服务接口


import com.alipay.api.AlipayApiException;
import java.io.FileNotFoundException;
import java.rmi.ServerException;

/**
 * @Author ddz
 * @ClassName AliPayService
 * @Description
 * @Date 2021/7/19 10:59
 * @Version 1.0
 **/
public interface AliPayService {
    /**
     * 支付宝提现
     *
     * @param wOrderNumber 自定义订单号
     * @param amount       提现金额
     * @param name         真实姓名
     * @param zfbName      支付宝账户
     * @param operator     操作员
     * @throws Exception
     */
    void alipayWithdraw(String wOrderNumber, Double amount, String uId, String name, String zfbName, String operator) throws ServerException, FileNotFoundException, AlipayApiException;
}

2.创建接口实现类

package com.ruoyi.translate.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransToaccountTransferModel;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayFundTransOrderQueryResponse;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.google.gson.Gson;
import com.ruoyi.translate.config.AliPayConfig;
import com.ruoyi.translate.domain.Alipay;
import com.ruoyi.translate.domain.TbParamConfig;
import com.ruoyi.translate.domain.TbUserWithdraw;
import com.ruoyi.translate.mapper.TbParamConfigMapper;
import com.ruoyi.translate.mapper.TbUserWithdrawMapper;
import com.ruoyi.translate.service.AliPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import javax.annotation.Resource;
import java.io.*;
import java.rmi.ServerException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author ddz
 * @ClassName AliPayServiceImpl
 * @Description
 * @Date 2021/7/19 11:00
 * @Version 1.0
 **/
@Slf4j
@Service
public class AliPayServiceImpl implements AliPayService {

    @Resource
    private TbParamConfigMapper paramConfigMapper;
    @Resource
    private TbUserWithdrawMapper userWithdrawMapper;

    /**
     * 证书模式   获取文件路径
     *
     * @return
     * @throws FileNotFoundException
     * @throws ServerException
     */
    public String queryPath() throws FileNotFoundException, ServerException {
        String basePath = ResourceUtils.getURL("classpath:").getPath();
        basePath = this.initCart(basePath);

        return basePath;
    }

    /**
     * 证书模式 初始化证书文件
     *
     * @param basePath
     * @return
     * @throws ServerException
     */
    private String initCart(String basePath) throws ServerException {
        if (basePath.contains("jar!")) {
            if (basePath.startsWith("file:")) {
                basePath = basePath.replace("file:", "");
            }
            String appCertPath = AliPayConfig.APP_CERT_PATH;
            this.checkAndcopyCart(basePath, appCertPath);
            String alipayCertPath = AliPayConfig.ALIPAY_CERT_PATH;
            this.checkAndcopyCart(basePath, alipayCertPath);
            String alipayRootCertPath = AliPayConfig.ALIPAY_ROOT_CERT_PATH;
            this.checkAndcopyCart(basePath, alipayRootCertPath);
        }
        return basePath;
    }

    /**
     * 证书模式下需要
     *
     * @param basePath
     * @param path
     * @throws ServerException
     * @description 查找在该文件路径下是否已经存在这个文件,如果不存在,则拷贝文件
     */
    private void checkAndcopyCart(String basePath, String path) throws ServerException {
        InputStream cartInputStream = null;
        OutputStream cartOutputStream = null;
        String cartPath = basePath + path;
        File cartFile = new File(cartPath);
        File parentFile = cartFile.getParentFile();
        parentFile.mkdirs();
        try {
            if (!cartFile.exists()) {
                cartInputStream = ClassUtils.getDefaultClassLoader().getResourceAsStream(path);
                cartOutputStream = new FileOutputStream(cartFile);
                byte[] buf = new byte[1024];
                int bytesRead;
                while ((bytesRead = cartInputStream.read(buf)) != -1) {
                    cartOutputStream.write(buf, 0, bytesRead);
                }
                cartInputStream.close();
                cartOutputStream.close();
            }
        } catch (IOException e) {
            throw new ServerException(e.getMessage());
        }
    }

    /**
     * 支付宝提现
     *
     * @param wOrderNumber 自定义订单号
     * @param amount       提现金额
     * @param uId          用户id
     * @param name         真实姓名
     * @param zfbName      支付宝账户
     * @param operator
     * @throws Exception
     */
    @Override
    public void alipayWithdraw(String wOrderNumber, Double amount, String uId, String name, String zfbName, String operator) throws ServerException, FileNotFoundException, AlipayApiException {
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        String basePath = this.queryPath();
        //构造client
        CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
        // 设置网关地址
        certAlipayRequest.setServerUrl(AliPayConfig.gatewayUrl);
        //设置应用AppId
        certAlipayRequest.setAppId(AliPayConfig.app_id);
        //设置应用私钥
        certAlipayRequest.setPrivateKey(AliPayConfig.merchant_private_key);
        // 设置请求格式,固定值json
        certAlipayRequest.setFormat(AliPayConfig.format);
        // 设置字符集
        certAlipayRequest.setCharset(AliPayConfig.charset);
        // 设置签名类型
        certAlipayRequest.setSignType(AliPayConfig.signType);
        // 设置应用公钥证书路径
        certAlipayRequest.setCertPath(basePath + AliPayConfig.APP_CERT_PATH);
        // 设置支付宝公钥证书路径
        certAlipayRequest.setAlipayPublicCertPath(basePath + AliPayConfig.ALIPAY_CERT_PATH);
        // 设置支付宝根证书路径
        certAlipayRequest.setRootCertPath(basePath + AliPayConfig.ALIPAY_ROOT_CERT_PATH);
        // 构造client
        AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
        //请求对象
        AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
        // 设置请求参数
        AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
        // 金额
        model.setAmount(String.valueOf(amount));
        // 商户单号  订单id
        model.setOutBizNo(wOrderNumber);
        // 收款方支付宝账号
        model.setPayeeAccount(zfbName);
        // 收款方姓名
        model.setPayeeRealName(name);
        // 收款方账户类型
        model.setPayeeType("ALIPAY_LOGONID");
        // 备注
        model.setRemark("用户提现");
        // 设置请求参数
        request.setBizModel(model);
        AlipayFundTransToaccountTransferResponse response = null;
        /*--------------------- 这段可设置提现标题的方案 ----------------------*/
/*      AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
        model.setProductCode("TRANS_ACCOUNT_NO_PWD");
        model.setBizScene("DIRECT_TRANSFER");
        // 金额
        model.setTransAmount(String.valueOf(amount));
        // 商户单号  订单id
        model.setOutBizNo(wOrderNumber);
        // 收款方支付宝账号
        Participant participant = new Participant();
        //账号
        participant.setIdentity(zfbName);
        // 真实姓名
        participant.setName(name);
        participant.setIdentityType("ALIPAY_LOGON_ID");
        model.setPayeeInfo(participant);
        // 转账业务的标题
        model.setOrderTitle("用户:" + name + "提现");
        // 备注
        model.setRemark("用户提现");
        // 设置请求参数
        request.setBizModel(model);
        AlipayFundTransUniTransferResponse response = null;*/
		/*-----------------------------------------------------------------*/
        try {
            response = alipayClient.certificateExecute(request);
            if (response.isSuccess()) {
                if ("10000".equals(response.getCode())) {
                    /**
                     * 转账成功   这里写自己的业务代码
                     * */
                }
            }
        } catch (AlipayApiException e) {
              System.out.println("转账失败");
        }
    }
}

到这里算是基本完成,后面的就是自己的一些测试代码了。
这个代码比较简陋,还需自己去完善一下。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LOVE_DDZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值