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("转账失败");
}
}
}
到这里算是基本完成,后面的就是自己的一些测试代码了。
这个代码比较简陋,还需自己去完善一下。