详细步骤:根据开发语言选择密钥格式。选择密钥长度,建议使用2048位。点击”生成密钥”,会自动生成商户应用公钥和应用私钥。点击”打开密钥文件路径”,即可找到生成的公私钥。找到上最下面提示的路径,可以找到:”应用公钥XXX.txt”和”应用私钥XXX.txt”,截如下:
单笔转账到通达信接口程序,支付宝账户接口调用
下载SDK
上传应用公钥并获取通达信接口程序,支付宝公钥
查看错误码
在“应用环境”-“接口加签方式”下方点击“设置应用公钥”。
下载后的SDK的文件结构:
在调用接口的时候,可能会报其它错误,可以从下面的网址中查找:https://docs.opealipay.com/291/106096/解释的错误有:
在使用通达信接口程序,支付宝接口的时候,需要使用通达信接口程序,支付宝的签名,这里需要使用通达信接口程序,支付宝的RSA生成工具。关于生成签名的网址:https://docs.opealipay.com/291/105971/从网址上可以下载Windows和MAC版本的RSA签名生成工具
概念介绍:应用私钥:由商户自己生成的RSA私钥,商户开发者使用应用私钥对字符串进行加签。应用公钥:是由商户自己生成的RSA公钥,商户需要上传到应用公钥到通达信接口程序,支付宝开放平台以便通达信接口程序,支付宝验证该公钥是否是商户自己发起的。通达信接口程序,支付宝公钥:通达信接口程序,支付宝的RSA公钥,商户使用通达信接口程序,支付宝公钥验证结果是否是通达信接口程序,支付宝返回的。
“单笔转账到通达信接口程序,支付宝账户”的接口调用,一般涉及到下面几个知识点
生成签名
将alipay的sdk打到本地maven仓库
RSA和RSA2签名算法区别
注:接口中的sign_type参数应与上传密钥的加签方式一致。例如接口参数中sign_type=RSA2,请求时就会使用此处设置的RSA2(SHA25公钥验签。
调用报错时自动排查
生成的私钥需要妥善保管,避免遗失,不要泄露。应用私钥需要填写到代码中供签名时使用。应用公钥需要提供给通达信接口程序,支付宝账号管理者上传到通达信接口程序,支付宝开放平台。
TIPS:除了使用通达信接口程序,支付宝提供的一键生成密钥工具外,也可以使用OpenSSL工具命令生成密钥。网址:https://docs.open.alipay.com/291/106130
关于通达信接口程序,支付宝支付,有多个界面可供下载,下载地址:
其中查看业务错误码是比较重要的一个排查问题的手段。实际项目中的调用案例:
package com.xxxx.pay.service;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.xxxx.comm.cache.impl.SysConfig;
import com.xxxx.comm.enumset.BusinessCodeEnum;
import com.xxxx.comm.util.PayOrderNumUtils;
import com.xxxx.dubbo.facade.soaIntf.pay.IAlipayService;
import com.xxxx.pay.data.beans.TbPayExtractCallbackRecord;
import com.xxxx.pay.data.mapper.TbPayExtractCallbackRecordMapper;
import com.xxxx.redis.core.RedisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* 功能:提现审核中通达信接口程序,支付宝自动打款
*
* @ClassName: AlipayService
* @version V1.0
* @date 2017-12-17
* @author tuzq
* Copyright 2017 xxxx.com, Inc. All rights reserved
*/
@Service(value = 'alipayService')
public class AlipayService implements IAlipayService {
private static Logger logger = LoggerFactory.getLogger(AlipayService.class);
@Autowired
RedisTemplate baseRedisTemplate;
@Resource(name = 'payExtractCallbackRecordMapper')
TbPayExtractCallbackRecordMapper payExtractCallbackRecordMapper;
/**
*
* 功能:转账到通达信接口程序,支付宝账户
*
* @author tuzq
* @date 2017-12-17
* @param receiptAccountName :收款账号名
* @param receiptAccountNumber:收款账号,通达信接口程序,支付宝账号
* @param remittanceMoney :收款金额
* @param ip :操作提现审核的机器的ip
* @param extractId :提现记录表中的id
* @param accountId :收款钱包账户表中的id
* @param userId :提现操作用户ID
* @param name :审核用户的用户名
* @param isDeleted :0:正常,1:删除
* @return
*/
public String pay2Alipay(
String receiptAccountName,
String receiptAccountNumber,
Double remittanceMoney,
String ip,
Long extractId,
Long accountId,
Long userId,
String name,
Integer isDeleted) {
//其中包含:code,msg,data三类信息,其中code = 0表示转账失败,1:转账成功,data中包含转账记录中的值
Map map = new HashMap();
//判断指定分钟内是否是同一个通达信接口程序,支付宝提现,如果是十分钟之内是同一个通达信接口程序,支付宝提现,则直接提示提现失败
//0:没有转账过,或没有转账成功过 1:10分钟内不能连续提现转账 2:已经转账过,不能重复提现转账
int isAccountIsWithdrawDeposited = judgeAccountIsWithdrawDeposited(1,receiptAccountNumber,extractId);
if (1 == isAccountIsWithdrawDeposited) {
map.put('code', 0);
map.put('msg','同一账户不能在10分钟内连续提现!');
map.put('data','');
return JSONObject.toJSONString(map);
}
if (2 == isAccountIsWithdrawDeposited) {
map.put('code',0);
map.put('msg','提现申请已受理并成功转账,不能重复提现转账!');
map.put('data','');
return JSONObject.toJSONString(map);
}
TbPayExtractCallbackRecord payExtractCallbackRecord = new TbPayExtractCallbackRecord();
try {
AlipayClient alipayClient = new DefaultAlipayClient(
//即:https://openapi.alipay.com/gateway.do
SysConfig.getValue('alipay_serverUrl'),
//即:用用的appid
SysConfig.getValue('alipay_appId'),
//即:通过验签工具生成的'商户 应用私钥' ,注意:
//1、这里若选用的是1024的,下面的alipay_alipayPulicKey'通达信接口程序,支付宝应用公钥'要使用 '通达信接口程序,支付宝账号管理者'上传应用公钥 后 的RSA后面对应的'通达信接口程序,支付宝公钥',alipay_signType 这个值配置成RSA
//2、这里若选用的是2048的,下面的alipay_alipayPulicKey'通达信接口程序,支付宝应用公钥'要使用 '通达信接口程序,支付宝账号管理者'上传应用公钥 后 的RSA2(SHA256)后面的'通达信接口程序,支付宝公钥',alipay_signType 这个值配置成RSA2
//上面推荐使用RSA2的签名方式
SysConfig.getValue('alipay_privateKey'),
'json',
'utf-8',
SysConfig.getValue('alipay_alipayPulicKey'),
SysConfig.getValue('alipay_signType'));
//注意:如果这里找不到这个API,需要将上文中下载的Alipay对应的SDK打到maven私服中去。具体打的方式:百度
AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
//创建一个唯一的businessCodeNum
String businessCodeNum = this.createUniqueBusinessCodeNum();
//businessCodeNum :相当于购买商品时的订单号,这个需要平台生成一个唯一的编号传递给Alipay接口
//ALIPAY_LOGONID :固定值
//receiptAccountNumber:即收款者通达信接口程序,支付宝账号
//receiptAccountName :通达信接口程序,支付宝账号中留的收款者真实名称
request.setBizContent('{' +
''out_biz_no':''+ businessCodeNum +'',' +
''payee_type':'ALIPAY_LOGONID',' +
''payee_account':'' + receiptAccountNumber + '',' +
''amount':'' + remittanceMoney + '',' +
''payer_show_name':'通达信接口程序,支付宝',' +
''payee_real_name':''+ receiptAccountName +'',' +
''remark':'提现审核通过,平台转账到通达信接口程序,支付宝账户'}');
AlipayFundTransToaccountTransferResponse response = null;
response = alipayClient.execute(request);
String data = response.getBody();
JSONObject jsonObject = JSONObject.parseObject(data).getJSONObject('alipay_fund_trans_toaccount_transfer_response');
logger.info('--------------------通达信接口程序,支付宝返回参数 start---------------------');
logger.info(jsonObject.toJSONString());
logger.info('--------------------通达信接口程序,支付宝返回参数 start ---------------------');
if(response.isSuccess()){
//正确格式类似:{'alipay_fund_trans_toaccount_transfer_response':{'code':'10000','msg':'Success','order_id':'20171219110070001502670020659574','out_biz_no':'TX20171219112511712151872','pay_date':'2017-12-19 11:25:19'}
String code = jsonObject.getString('code');
String msg = jsonObject.getString('msg');
String orderId = jsonObject.getString('order_id');
String outBizNo = jsonObject.getString('out_biz_no');
String payDate = jsonObject.getString('pay_date');
//设置记录
payExtractCallbackRecord.setAliCode(code);
payExtractCallbackRecord.setAliMsg(msg);
payExtractCallbackRecord.setAliOrderId(orderId);
payExtractCallbackRecord.setAliOutBizNo(outBizNo);
payExtractCallbackRecord.setAliPayDate(payDate);
//设置返回的状态code
map.put('code',1);
map.put('msg','通达信接口程序,支付宝转账成功!');
} else {
//错误格式类似:{'alipay_fund_trans_toaccount_transfer_response':{'code':'40002','msg':'Invalid Arguments','sub_code':'isv.invalid-app-id','sub_msg':'无效的AppID参数'}}
String code = jsonObject.getString('code');
String msg = jsonObject.getString('msg');
String sub_code = jsonObject.getString('sub_code');
String sub_msg = jsonObject.getString('sub_msg');
//设置错误记录
payExtractCallbackRecord.setAliCode(code);
payExtractCallbackRecord.setAliMsg(msg);
payExtractCallbackRecord.setAliSubCode(sub_code);
payExtractCallbackRecord.setAliSubMsg(sub_msg);
payExtractCallbackRecord.setAliOutBizNo(businessCodeNum);
//设置返回的状态code
map.put('code',0);
map.put('msg',sub_msg);
RedisUtil redisUtil = new RedisUtil(baseRedisTemplate);
redisUtil.remove(receiptAccountNumber);
}
} catch (AlipayApiException e) {
logger.error('提现审核通达信接口程序,支付宝调用通达信接口程序,支付宝接口出错{}',e.getMessage());
} finally {
payExtractCallbackRecord.setReceiptAccountName(receiptAccountName);
payExtractCallbackRecord.setReceiptAccountNumber(receiptAccountNumber);
payExtractCallbackRecord.setIp(ip);
payExtractCallbackRecord.setAccountId(accountId);
payExtractCallbackRecord.setOptUserId(userId);
payExtractCallbackRecord.setOptUserName(name);
//获取时间的毫秒值
Long timeMillis = System.currentTimeMillis() * 1000;
payExtractCallbackRecord.setCreateTime(timeMillis);
payExtractCallbackRecord.setUpdateTime(timeMillis);
payExtractCallbackRecord.setIsDeleted(0);
payExtractCallbackRecord.setRemittanceMoney(new BigDecimal(remittanceMoney));
payExtractCallbackRecord.setExtractId(extractId);
map.put('data',payExtractCallbackRecord);
payExtractCallbackRecordMapper.insertTbPayExtractCallbackRecord(payExtractCallbackRecord);
}
//将对象转换成JSONObject对象,方便后续使用json.put(key,value)进行添加扩张
//JSONObject json = (JSONObject) JSONObject.toJSON(payExtractCallbackRecord);
return JSONObject.toJSONString(map);
}
/**
* 判断账号是否已经提现过了,场景:
* 1、如果在指定时间内,直接返回,提示指定时间内不可以重复提现
* 2、如果没有这个信息,从提现信息表中查询是否有同一个ExtractId且是成功的(code=10000,有通达信接口程序,支付宝返回的ali_order_id)提现记录,且未被删除
* @param specifiedTime :指定时间,单位是分钟
* @param receiptAccountNumber :账号名称
* @param extractId :订单编号
* @return 0:没有转账过,或没有转账成功过 1:10分钟内不能连续提现转账 2:已经转账过,不能重复提现转账
*/
int judgeAccountIsWithdrawDeposited(int specifiedTime, String receiptAccountNumber,Long extractId) {
RedisUtil redisUtil = new RedisUtil(baseRedisTemplate);
//如果已经存在,直接返回true
if (redisUtil.exists(receiptAccountNumber)) {
return 1;
}
//通过extract_id,ali_code,ali_order_id,is_deleted = 0
List payExtractCallbackRecordList = payExtractCallbackRecordMapper.selectPayExtractCallbackRecordList(extractId,0);
//如果也是空的,说明没有转账成功过,将account设置进去,并且过期时间使10分钟
if (payExtractCallbackRecordList.isEmpty()) {
redisUtil.set(receiptAccountNumber,receiptAccountNumber,specifiedTime);
//没有转账过,或没有成功过
return 0;
}
//已经转账过,不能重复提现转账
return 2;
}
/**
* 创建唯一的订单编号
* @return
*/
public String createUniqueBusinessCodeNum() {
String businessCodeNum = PayOrderNumUtils.createPayOrderNum(BusinessCodeEnum.ALIPAY_TX,100000);
//避免高并发场景下businessCodeNum相同的情况下
RedisUtil redisUtil = new RedisUtil(baseRedisTemplate);
if(redisUtil.exists(businessCodeNum)) {
return createUniqueBusinessCodeNum();
}
//设置10分钟内过期
redisUtil.set(businessCodeNum,businessCodeNum,10 * 60 * 1000);
return businessCodeNum;
}
}
以下将通达信接口程序,支付宝的这块儿的内容罗列到本文中:注意:如果想上传应用公钥然后去获取通达信接口程序,支付宝公钥,这里用户需要是通达信接口程序,支付宝账号管理者点击签名验签工具右下角的“上传公钥”会打开通达信接口程序,支付宝开放平台网页,输入账号登录。,在代码中使用。关于笔者个人的这个页面显示的效果如下:若首次登录管理中心,请根据引导填写所需信息完成开发者入驻:第一步:点击认证,完成实名认证。第二步:点击编辑,完善信息。根据引导流程,完成手机绑定。第三步:签署协议,完成入驻。
建议使用RSA2加签方式。根据开发者的条件设置应用公钥或上传公钥证书,常规请点击设置应用公钥。若未绑定手机,请根据引导,完成手机绑定。完成手机短信验证。把签名验签工具里“公钥”的内容复制到此处,点击“保存”完成密钥设置。保存成功后,在同一页面查看或修改应用公钥或上传应用公钥证书。保存通达信接口程序,支付宝公钥内容,在代码中验签使用。
关于通达信接口程序,支付宝单笔转账到通达信接口程序,支付宝接口的调用,接口文档地址:https://docs.opealipay.com/api_28/alipay.funtrans.toaccount.transfer通过接口文档,可以了解到如下内容:
公共参数(请求地址、公共请求参数)
请求参数
公共响应参数
响应参数
请求示例
响应示例
异常示例
业务错误码
文章为作者独立观点,不代表股票交易接口观点