1.从阿里云获取相关配置参数
appID,应用私钥,支付宝公钥,支付宝接口地址(https://openapi.alipay.com/gateway.do),公司商户号和证书相关。
注:加密方式要用证书加密。
2.工具类基本配置
@Component
public class AlipayUtils implements InitializingBean
{
public static final Logger log = Logger.getLogger(AlipayUtils.class);
public static AlipayClient alipayClient = null;
private static String certContent;
private static String alipayPublicCertContent;
private static String rootCertContent;
@Value("${alipayRequest.certContent}")
private String getCertContent;
@Value("${alipayRequest.alipayPublicCertContent}")
private String getAlipayPublicCertContent;
@Value("${alipayRequest.rootCertContent}")
private String getRootCertContent;
/**
注:因为我这是工具类,由于有多个环境,所以要用注入的方式放证书位置,而工具类中方法
都是静态方法,所以要实现InitializingBean接口,重新afterPropertiesSet()方法,
将值赋进来。
*/
@Override
public void afterPropertiesSet() throws Exception
{
AlipayUtils.certContent = this.getCertContent;
AlipayUtils.alipayPublicCertContent = this.getAlipayPublicCertContent;
AlipayUtils.rootCertContent = this.getRootCertContent;
}
/**
初始化支付宝证书请求
*/
private static AlipayClient getAlipayClientCertificate()
{
try
{
if (null == alipayClient)
{
CertAlipayRequest alipayConfig = new CertAlipayRequest();
alipayConfig.setPrivateKey(Configure.APP_PRIVATE_KEY);
alipayConfig.setServerUrl(Configure.SERVER_URL);
alipayConfig.setAppId(Configure.APP_ID);
alipayConfig.setCharset("UTF8");
alipayConfig.setSignType("RSA2");
alipayConfig.setEncryptor("");
alipayConfig.setFormat("json");
//由于本地测试读取不到配置项 配置的证书位置,所以通过加载类的方式读取证书位置
/*Properties pro = new Properties();
InputStream in = Object.class.getResourceAsStream("/application.properties");
pro.load(in);
String certContent = pro.getProperty("alipayRequest.certContent");
String alipayPublicCertContent = pro.getProperty("alipayRequest.alipayPublicCertContent");
String rootCertContent = pro.getProperty("alipayRequest.rootCertContent");*/
alipayConfig.setCertPath(certContent);
alipayConfig.setAlipayPublicCertPath(alipayPublicCertContent);
alipayConfig.setRootCertPath(rootCertContent);
alipayClient = new DefaultAlipayClient(alipayConfig);
}
return alipayClient;
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
3.单笔转账(alipay.fund.trans.uni.transfer(单笔转账接口))
阿里文档地址:文档地址
/**
* @Title alipayTransfer
* @Description //TODO(单笔转账接口)
* @Param [out_biz_no, trans_amount, name, identity, order_title]
* @Return AlipayFundTransUniTransferResponse
* @Throws
* @Date 9:23 2022/6/16
* @Author zy
*/
//out_biz_no 商家侧唯一订单号,由商家自定义。对于不同转账请求,商家需保证该订单号在自身系统唯一。
//trans_amount 订单总金额,单位为元,不支持千位分隔符,精确到小数点后两位,取值范围[0.1,100000000]。
//name 参与方真实姓名。如果非空,将校验收款支付宝账号姓名一致性。
// 当 identity_type=ALIPAY_LOGON_ID 时,本字段必填。若传入该属性,则在支付宝回单中将会显示这个属性。
//identity 参与方的标识 ID。
// 当 identity_type=ALIPAY_USER_ID 时,填写支付宝用户 UID。示例值:2088123412341234。
// 当 identity_type=ALIPAY_LOGON_ID 时,填写支付宝登录号。示例值:186xxxxxxxx。
//order_title 转账业务的标题,用于在支付宝用户的账单里显示。
public static AlipayFundTransUniTransferResponse alipayTransfer(String out_biz_no, String trans_amount,
String name, String identity,
String order_title)
{
AlipayClient alipayClient = getAlipayClientCertificate();
AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
model.setOutBizNo(out_biz_no);
model.setRemark("提现测试1");//可选
JSONObject json = new JSONObject();
json.put("payer_show_name_use_alias",Boolean.TRUE);
model.setBusinessParams(json.toJSONString());
model.setBizScene("DIRECT_TRANSFER");
Participant payeeInfo = new Participant();
payeeInfo.setIdentity(identity);
payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
payeeInfo.setName(name);
model.setPayeeInfo(payeeInfo);
model.setTransAmount(trans_amount);
model.setProductCode("TRANS_ACCOUNT_NO_PWD");
model.setOrderTitle(order_title); //20220606支付宝提现测试
request.setBizModel(model);
AlipayFundTransUniTransferResponse response = null;
try
{
if (alipayClient != null)
{
response = alipayClient.certificateExecute(request);
if (response.isSuccess())
{
System.out.println("调用成功");
}
else
{
System.out.println("调用失败");
}
return response;
}
}
catch (AlipayApiException e)
{
e.printStackTrace();
}
return response;
}
注释:
错误码 错误描述 解决方案
INVALID_PARAMETER 参数有误参数有误 请根据入参说明检查请求参数合法性。
SYSTEM_ERROR 系统繁忙 可能发生了网络或者系统异常,导致无法判定准确的转账结果。此时,商户不能直接当做转账成功或者失败处理,可以考虑采用相同的out_biz_no重发请求,或者通过调用“(alipay.fund.trans.order.query)”来查询该笔转账订单的最终状态。
EXCEED_LIMIT_SM_AMOUNT 单笔额度超限 请根据接入文档检查amount字段
EXCEED_LIMIT_MM_AMOUNT 月累计金额超限 请根据接入文档说明检查本月请求总金额+本次请求金额是否超限。
PAYCARD_UNABLE_PAYMENT 付款账户余额支付功能不可用 请付款账户登录支付宝账户开启余额支付功能。
PAYER_STATUS_ERROR 付款账号状态异常 请检查付款方是否进行了自助挂失,如果无,请联系支付宝客服检查用户状态是否正常。
PAYER_CERTIFY_CHECK_FAIL 付款方人行认证受限 付款方请升级认证等级。
PAYER_STATUS_ERROR 付款方用户状态不正常 请检查付款方是否进行了自助挂失,如果无,请联系支付宝客服检查用户状态是否正常。
PAYER_BALANCE_NOT_ENOUGH 余额不足,建议尽快充值。后续可登录电脑端支付宝,自主设置余额预警提醒功能。 支付时间点付款方余额不足,请向付款账户余额充值后再原请求重试。
PAYER_USER_INFO_ERROR 付款用户姓名或其它信息不一致 检查付款用户姓名payer_real_name与真实姓名一致性。
PAYMENT_INFO_INCONSISTENCY 两次请求商户单号一样,但是参数不一致 如果想重试前一次的请求,请用原参数重试,如果重新发送,请更换单号。
CARD_BIN_ERROR 收款人银行账号不正确 请确认收款人银行账号正确性,要求为借记卡卡号。
4.申请电子回单(alipay.data.bill.ereceipt.apply(申请电子回单(incubating))
阿里文档地址:文档地址
/**
* @Title alipayApply
* @Description //TODO(申请电子回单)
* @Param [key]
* @Return AlipayDataBillEreceiptApplyResponse
* @Throws
* @Date 9:23 2022/6/16
* @Author zy
*/
//key:文件申请号file_id信息。使用file_id可以查询处理状态,有效期:2天
public static AlipayDataBillEreceiptApplyResponse alipayApply(String key)
{
AlipayDataBillEreceiptApplyRequest request = new AlipayDataBillEreceiptApplyRequest();
request.setBizContent("{"
+ "\"type\":\"FUND_DETAIL\","
+ "\"key\":\"" + key + "\","
+ "\"bill_user_id\":\"" + Configure.QW_SELLER_ID + "\"" //商户号
+ "}");
AlipayDataBillEreceiptApplyResponse response = null;
try
{
response = alipayClient.certificateExecute(request);
if (response.isSuccess())
{
System.out.println("调用成功");
}
else
{
System.out.println("调用失败");
}
return response;
}
catch (AlipayApiException e)
{
e.printStackTrace();
}
return response;
}
```
注:支付宝证书请求以上方为准,支付宝官方文档未更新说明(2022.7.8)
5.**获取电子回单地址**(alipay.data.bill.ereceipt.query(查询电子回单状态(incubating)))
阿里文档地址:[文档地址](https://opendocs.alipay.com/open/02byut)
```java
/**
* @Title alipayQuery
* @Description //TODO(查询电子回单状态)
* @Param [out_biz_no, trans_amount, name, identity, order_title]
* @Return AlipayFundTransUniTransferResponse
* @Throws
* @Date 9:23 2022/6/16
* @Author zy
*/
//file_id : 根据申请id查询状态。通过 alipay.data.bill.ereceipt.apply(申请电子回单(incubating)) 接口同步响应获取。
public static AlipayDataBillEreceiptQueryResponse alipayQuery(String file_id)
{
AlipayClient alipayClient = getAlipayClientCertificate();
//查询电子回单状态
AlipayDataBillEreceiptQueryRequest request = new AlipayDataBillEreceiptQueryRequest();
request.setBizContent("{" +
"\"file_id\":\"" + file_id + "\"" +
" }");
AlipayDataBillEreceiptQueryResponse response = null;
try
{
response = alipayClient.certificateExecute(request);
if (response.isSuccess())
{
System.out.println("调用成功");
}
else
{
System.out.println("调用失败");
}
return response;
}
catch (AlipayApiException e)
{
e.printStackTrace();
}
return response;
}
public static void main(String[] args) throws Exception
{
AlipayClient alipayClient = getAlipayClientCertificate();
}