mr88fang 发表于 2023-9-8 17:07

支付宝企业转账到支付宝账户

## 准备工作

1. 注册企业支付宝
2. 企业认证
3. 产品中心(支付宝商家平台)->签约转账到支付宝账户
4. 创建应用(支付宝开放平台)默认签约会有一个应用

## 相关网站

- 支付宝开发文档:https://opendocs.alipay.com/open/309/106235?ref=api
- 支付宝开放平台:https://open.alipay.com/
- 支付宝商家平台:https://b.alipay.com/page/home

## 注意事项

- 创建的支付宝应用需要绑定对应的产品才可以使用
- 应用需要上线审核通过接口才可以调用
- **接口加签方式必须使用证书方式**
- 转账需要账号和实名认证姓名一致

## 代码示例

### 阿里SDK

```xml
<dependency>
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>4.38.72.ALL</version>
</dependency>
```

### 单例模式工具类

> 本示例所有证书都放在`resource/certs`目录下载加载

```java
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.domain.Participant;
import com.alipay.api.internal.util.file.FileUtils;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;

import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

/**
* @description:
* @author: Mr.Fang
* @create: 2023-9-8
**/
@Slf4j
public class AlipayUtil {

    private String URL = "https://openapi.alipay.com/gateway.do";
    private String APPID = "应用APPID";
    private String app_private_key = "certs/appPrivate.txt";
    private String CHARSET = "UTF8";
    private String FORMAT = "json";
    private String SIGN_TYPE = "RSA2";
    private String app_cert_path = "certs/appCertPublicKey.crt";
    private String alipay_cert_path = "certs/alipayCertPublicKey_RSA2.crt";
    private String alipay_root_cert_path = "certs/alipayRootCert.crt";
    private AlipayConfig alipayConfig;
    private static AlipayUtil instance;

    // 无惨构造,默认加载支付宝配置信息
    private AlipayUtil() throws IOException {
      alipayConfig = new AlipayConfig();
      //设置网关地址
      alipayConfig.setServerUrl(URL);
      //设置应用ID
      alipayConfig.setAppId(APPID);
      //设置应用私钥
      alipayConfig.setPrivateKey(readToString(new ClassPathResource(app_private_key).getInputStream()));

      //设置请求格式,固定值json
      alipayConfig.setFormat(FORMAT);
      //设置字符集
      alipayConfig.setCharset(CHARSET);
      //设置签名类型
      alipayConfig.setSignType(SIGN_TYPE);
      //设置应用公钥证书路径
      alipayConfig.setAppCertContent(readToString(new ClassPathResource(app_cert_path).getInputStream()));
      //设置支付宝公钥证书路径
      alipayConfig.setAlipayPublicCertContent(readToString(new ClassPathResource(alipay_cert_path).getInputStream()));
      //设置支付宝根证书路径
      alipayConfig.setRootCertContent(readToString(new ClassPathResource(alipay_root_cert_path).getInputStream()));
    }

    /**
   * 读取 resource 文件
   *
   * @Param inputStream
   * @return
   */
    private String readToString(InputStream inputStream) {
      try {
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte;
            int length;
            while ((length = dataInputStream.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            return output.toString();
      } catch (IOException e) {
            e.printStackTrace();
      }
      return null;
    }

    public static AlipayUtil getInstance() throws IOException {
      if (instance == null) {
            synchronized (AlipayUtil.class) {
                if (instance == null) {
                  instance = new AlipayUtil();
                }
            }
      }
      return instance;
    }

    /**
   * description: 支付宝企业转账到个人
   * create by: Mr.Fang
   *
   * @param bizNo    订单编号
   * @param amount   金额
   * @param title    转账说明
   * @param identity 支付宝手机号或邮箱
   * @param name   支付宝真实姓名
   * @return: Result<java.lang.String>
   * @date: 2023/9/8
   */
    public Result<String> transfer(String bizNo, String amount, String title, String identity, String name) throws AlipayApiException {
      AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
      AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
      AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();

      model.setOutBizNo(bizNo); // 订单编号
      model.setTransAmount(amount); // 金额
      model.setBizScene("DIRECT_TRANSFER");
      model.setProductCode("TRANS_ACCOUNT_NO_PWD");
      model.setOrderTitle(title); // 订单标题

      Participant payeeInfo = new Participant();
      payeeInfo.setIdentity(identity); // 用户支付宝账户
      payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); // 固定值
      payeeInfo.setName(name); // 用户真实姓名

      model.setPayeeInfo(payeeInfo);
      request.setBizModel(model);
      AlipayFundTransUniTransferResponse response = alipayClient.certificateExecute(request);
      log.info("转账响应结果:{}", response.getBody());
      if (response.isSuccess()) {
            return Result.OK("转账成功", response.getBody());
      }
      return Result.error("转账失败", response.getBody());
    }
}

```

### resource目录扩展

- springboot 打包jar文件后通过`ClassPathResource` 对象可以获取到文件,但是文件路径是无法使用的。
- 阿里提供的`AlipayConfig` 对象支持配置证书相关参数有两种方式:第一种证书内容,第二种文件路径。
- 通过`ClassPathResource` 拿到文件对象,`readToString`方法读取文件内容配置证书内容信息。

### AlipayConfig 部分代码

```java
public void setRootCertPath(String rootCertPath) {
    this.rootCertPath = rootCertPath;
}
……………………省略
public void setRootCertContent(String rootCertContent) {
    this.rootCertContent = rootCertContent;
}
```

baishuihao 发表于 2023-9-8 22:10

不懂,路过;
主要是不懂代码

13729181580 发表于 2023-9-8 22:13

感谢分享!我也不太懂,主要是看不懂代码

moruye 发表于 2023-9-8 22:14

flydj123 发表于 2023-9-9 14:37

可惜不懂啊,万一支付宝里面的钱被盗了就尴尬了

摘星七月天 发表于 2023-9-15 10:57

这样做的目的是什么呢,直接不能转吗

小吉喵 发表于 2023-9-15 14:19

主要是不懂代码

stone009 发表于 2023-9-16 09:53

摘星七月天 发表于 2023-9-15 10:57
这样做的目的是什么呢,直接不能转吗

一般是用在支付收款后再打款的情况。
比如:你是一个平台入驻的商户,顾客在你支付购买(支付宝付款)的钱会先进入平台支付宝企业商户,再由平台支付宝商户转款给你私人支付宝账户(比如你申请提现)

rxxcy 发表于 2023-9-17 11:32

走正常转账吗

┏老◆孫▃_ 发表于 2023-9-17 22:04

不懂,路过
页: [1]
查看完整版本: 支付宝企业转账到支付宝账户