支付宝接口调用

“单笔转账到支付宝账户”的接口调用,一般涉及到下面几个知识点

1、生成签名

在使用支付宝接口的时候,需要使用支付宝的签名,这里需要使用支付宝的RSA生成工具。
关于生成签名的网址:https://docs.open.alipay.com/291/105971/
从网址上可以下载Windows和MAC版本的RSA签名生成工具

下载该工具后,解压打开文件夹,运行“RSA签名验签工具.bat”(WINDOWS)或“RSA签名验签工具.command”(MAC_OSX),目录结构如下:

其中界面类似如下:
RSA签名算法生成的格式

RSA2签名算法生成的格式:

概念介绍:
应用私钥:由商户自己生成的RSA私钥,商户开发者使用应用私钥对字符串进行加签。
应用公钥:是由商户自己生成的RSA公钥,商户需要上传到应用公钥到支付宝开放平台以便支付宝验证该公钥是否是商户自己发起的。
支付宝公钥:支付宝的RSA公钥,商户使用支付宝公钥验证结果是否是支付宝返回的。

详细步骤:
1、根据开发语言选择密钥格式。
2、选择密钥长度,建议使用2048位。
3、点击”生成密钥”,会自动生成商户应用公钥和应用私钥。
4、点击”打开密钥文件路径”,即可找到生成的公私钥。找到上图最下面提示的路径,可以找到:”应用公钥XXX.txt”和”应用私钥XXX.txt”,截图如下:

生成的私钥需要妥善保管,避免遗失,不要泄露。应用私钥需要填写到代码中供签名时使用。应用公钥需要提供给支付宝账号管理者上传到支付宝开放平台。

TIPS:除了使用支付宝提供的一键生成密钥工具外,也可以使用OpenSSL工具命令生成密钥。网址:https://docs.open.alipay.com/291/106130

2、上传应用公钥并获取支付宝公钥

官方文档:https://docs.open.alipay.com/291/105972

以下将支付宝的这块儿的内容罗列到本文中:
注意:如果想上传应用公钥然后去获取支付宝公钥,这里用户需要是支付宝账号管理者
1. 点击签名验签工具右下角的“上传公钥”会打开支付宝开放平台网页,输入账号登录。(建议使用IE或Chrome浏览器。)

2. 在“我的应用”中,选择要配置密钥的应用,点击“查看”。记录对应的APPID(下图红框处),在代码中使用。

关于笔者个人的这个页面显示的效果如下:

若首次登录管理中心,请根据引导填写所需信息完成开发者入驻:
第一步:点击认证,完成实名认证。

第二步:点击编辑,完善信息。

根据引导流程,完成手机绑定。

第三步:签署协议,完成入驻。

  1. 在“应用环境”-“接口加签方式”下方点击“设置应用公钥”。

注:接口中的sign_type参数应与上传密钥的加签方式一致。例如接口参数中sign_type=RSA2,请求时就会使用此处设置的RSA2(SHA256)公钥验签。

建议使用RSA2加签方式。

根据开发者的条件设置应用公钥或上传公钥证书,常规请点击设置应用公钥。

若未绑定手机,请根据引导,完成手机绑定。

完成手机短信验证。

把签名验签工具里“公钥”的内容复制到此处,点击“保存”完成密钥设置。

保存成功后,在同一页面查看或修改应用公钥或上传应用公钥证书。

保存支付宝公钥内容,在代码中验签使用。

3、下载SDK

关于支付宝支付,有多个界面可供下载,下载地址:

https://docs.open.alipay.com/54/103419/

下载后的SDK的文件结构:

4、单笔转账到支付宝账户接口调用

关于支付宝单笔转账到支付宝接口的调用,接口文档地址:https://docs.open.alipay.com/api_28/alipay.fund.trans.toaccount.transfer
通过接口文档,可以了解到如下内容:

公共参数(请求地址、公共请求参数)
请求参数
公共响应参数
响应参数
请求示例
响应示例
异常示例
业务错误码

其中查看业务错误码是比较重要的一个排查问题的手段。
实际项目中的调用案例:

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;/*** <p class="detail">* 功能:提现审核中支付宝自动打款* </p>* @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);@AutowiredRedisTemplate<Serializable, Object> baseRedisTemplate;@Resource(name = "payExtractCallbackRecordMapper")TbPayExtractCallbackRecordMapper payExtractCallbackRecordMapper;/*** <p class="detail">* 功能:转账到支付宝账户* </p>* @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<String,Object> map = new HashMap<String,Object>();//判断指定分钟内是否是同一个支付宝提现,如果是十分钟之内是同一个支付宝提现,则直接提示提现失败//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.doSysConfig.getValue("alipay_serverUrl"),//即:用用的appidSysConfig.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();//创建一个唯一的businessCodeNumString 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);//设置返回的状态codemap.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);//设置返回的状态codemap.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);//如果已经存在,直接返回trueif (redisUtil.exists(receiptAccountNumber)) {return 1;}//通过extract_id,ali_code,ali_order_id,is_deleted = 0List<TbPayExtractCallbackRecord> 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;}}

5、调用报错时自动排查

在调用接口的时候,可能会报其它错误,可以从下面的网址中查找:
https://docs.open.alipay.com/291/106096/
解释的错误有:

6、RSA和RSA2签名算法区别

参考网址:https://docs.open.alipay.com/291/106115/

7、查看错误码

在调用接口的时候,会返回code,其中code的解释说明文档为:
https://docs.open.alipay.com/common/105806
类似:

8、将alipay的sdk打到本地maven仓库

参考网址:
http://blog.csdn.net/tototuzuoquan/article/details/78831835

支付宝支付之“单笔转账到支付宝账户接口”的调用(生成签名、上传应用公钥、下载SDK、接口调用、报错自动排查、查看错误码)相关推荐

  1. Java 支付宝支付,退款,单笔转账到支付宝账户(单笔转账到支付宝账户)

    上次分享了支付宝订单退款的代码,今天分享一下支付宝转账的操作.  现在是有一个余额提现的功能,本来是打算做提现到银行卡的,但是客户嫌麻烦不想注册银联的开放平台账户,就说先提现到支付宝就行,二期再做银行 ...

  2. java 支付宝转账_Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝订单退款)...

    上一篇写到支付宝的支付,这代码copy下来就能直接用了,   我写学习文档时会经常贴 官方参数文档的案例地址, 因为我觉得 请求参数,响应参数说明 官方文档整理的很好,毕竟官方不会误导大家. 我学一个 ...

  3. java 支付宝 退款_Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝支付)

    最近一直在接触第三方,刚接入完支付宝的API做一下总结,个人能力薄弱有不对的地方望指教.  做的是一个小型电商项目,所以会接入第三方的支付和登入功能, 第一次接入第三方撸了很多官方文档. 然后创建应用 ...

  4. Java 支付宝支付,退款,单笔转账到支付宝账户(支付宝支付)

    最近一直在接触第三方,刚接入完支付宝的API做一下总结,个人能力薄弱有不对的地方望指教.  做的是一个小型电商项目,所以会接入第三方的支付和登入功能, 第一次接入第三方撸了很多官方文档. 进入主题, ...

  5. 如何使用支付宝沙箱测试单笔转账到支付宝账号(php版)

    说明:    本帖是利用支付宝沙箱测试电脑网站支付接口    测试环境:Apache2.4.23 +php 5.6.25    沙箱环境测试正式环境请修改网关为下方值 正式环境网关:https://o ...

  6. 支付宝单笔转账到支付宝账户(用于分成或者退款)

    超快速接入 支付宝官方文档 直接上代码 SDK AlipayUtils 支付宝官方文档 转账到支付宝用户快速接入 单笔转账到支付宝账户接入助手 直接上代码 SDK <!-- https://mv ...

  7. 平台资金提现解决方案之实现单笔转账到支付宝账户功能

    大家好,我是小悟 使用场景 不管是做APP.电脑网站.手机网站还是小程序,为了推广基本上都离不开用户分佣的场景. 换句话说就是在其平台内为每个用户设置"电子钱包"功能,而电子钱包在 ...

  8. java支付宝提现功能,单笔转账到支付宝账户(公钥证书方式)

    最近在开发商户分润系统(给商户分红),涉及到给商户账号提现功能,我们使用的是支付宝转账,通过公钥证书方式实现的. 在支付宝开放平台里找了好久的开发文档,但是介绍更多的是普通公钥的方式,这个方式比较简单 ...

  9. Springboot整支付宝网站支付、APP支付、单笔转账给用户、退款功能

    一.概述 最近在写项目,遇到了要调用支付宝支付的地方(后台管理页面的网站支付,APP内的用户支付,APP内用户提现也就是单笔转账给用户.退款).研究了好久,全部调通了,下面把我的代码分享出来. 首先那 ...

最新文章

  1. 实现一个div在浏览器水平居中
  2. 随机生成mysql测试表大量数据
  3. Visual Studio 2017 新功能(下)
  4. 如何选择面向对象语言
  5. wamp php 升级,wamp升级PHP7.1
  6. 线序及模式配置Linux,[CCNA图文笔记]-1-水晶头线序及设备互联法则
  7. c语言加减乘除运算代码_科协推文 || 走进C语言
  8. SSR远程登陆服务器配置
  9. 【项目实战】仓库信息管理系统(layui+SSM+SpringBoot)
  10. Ubuntu 21.10 编写 eBPF tc 程序
  11. # Scroll 系列
  12. 基于NB-IoT城市智能井盖监控解决方案
  13. 微信js-sdk引入!绝对干货
  14. 自然的密码---36幅由算法生成的六芒星图像
  15. python程序run不了_无法通过计划程序正确运行Python脚本
  16. 不是iso文件或不能识别的格式
  17. RS422/485规范的偏置/端接电阻取值说明
  18. 完美迁移C盘已装软件与游戏,无需重新安装~
  19. java/php/net/python会员健身系统管理设计
  20. 自己操作SMT贴片过程 BGA QFN封装

热门文章

  1. HTML、CSS学习笔记3(平面转换:位移、旋转、缩放,渐变)
  2. JAVA性能优化,从此不再重启tomcat服务
  3. flask常用的第三方平台,第三方库,扩展包
  4. I.MX8M mini物联网开发板框架及屏幕接口详解
  5. 使用PowerBuilder 9编绎DLL类型,有点问题.处理过程记录如下.”Error opening file ‘c:\windows\system32\cgen\en32t.h’”
  6. npm install 很慢、卡死怎么解决
  7. Top,vmstat命令排查CPU使用率,负载问题
  8. 天龙八部新目标服务器未响应,新天龙八部怀旧服有多火?4个月后开新服,玩家排队5小时没进去...
  9. 瑞萨RL78系列单片机报内存溢出故障的解决过程。RA78K0R error E3206: Segment ‘@@CODEL‘ can‘t allocate to memory - ignored
  10. linux命令行下载BT种子和磁力链接