准备工作:
1:已注册满 90 天,且已实名认证的企业支付宝账户。
2:已经成功签约并添加转账到支付宝能力。
3:具备专业技术人员开发能力或有专业的开发团队,能很好的理解官方文档。
4:有个已经实名认证的支付宝个人账号,方便测试。
支付宝官方参考文档:
转账到支付宝账户产品介绍 | 网页&移动应用支付宝文档中心https://opendocs.alipay.com/open/309/106235下面,我们来一步一步实现转账功能。
一:使用支付宝账户登录支付宝开发平台,找到控制台-->我的应用-->网页&移动应用(如图)
如果没有应用的话,首先创建应用,此处创建步骤忽略,具体请参考官方文档。
二:点击应用进入应用详情。
在能力列表查看是否已经添加了转账到支付宝账户,如果没有,需要点击添加能力按钮 添加。(如图)
注意:图片中左上角的APPID需要暂时记录下来,后面的代码中需要用到。
三:配置开发设置。
应用详情中点击应用信息,如图:
注意:
1、支付宝网关地址要暂时记下来,后面代码中需要用到。
2、虽然应用网关异步接收通知是选填,但为了避免突发情况比如突然断网、断电等异常情况下导致同步信息无法及时处理,此处的异步通知最好是配置一下,并且订单状态处理也应放在异步逻辑判断里,不在同步返回结果时处理。
3、接口加签方式必须使用公钥证书方式,如图:
图中用到的CSR文件 需要下载支付宝开放平台开发助手,然后生成,具体操作请参考步骤四。
四:获取应用公钥、应用私钥、CSR文件。
参考文档:
生成并配置密钥 | 开放平台支付宝文档中心https://opendocs.alipay.com/common/02kdnc1、根据自己电脑系统点击下图中的安装包安装。
2、生成应用公钥和应用私钥。
3、点击打开密钥文件路径可以看到刚才生成的应用私钥和应用公钥文件。如图:
注意,这里的公钥和私钥在后面的代码中会用到。
4、点击打开 文件位置,可以看到获取的CSR文件。
5、回到接口加签方式页面,先获取手机验证码,然后勾选同意协议,把刚才获取的csr文件上传。如图:
6、上传成功之后,支付宝会自动生成应用公钥证书、支付宝公钥证书、支付宝根证书,如图:
点击对应的下载按钮保存本地备用。这里下载的证书文件是正式环境下要用的。
注意:这三个证书后面代码中会用到。
五:下载SDK文件。
网页&移动应用学习路径 | 网页&移动应用支付宝文档中心https://opendocs.alipay.com/open/54/103419/根据自己的开发语言选择下载即可。
下载完成后,将sdk文件放入项目合适的位置中,我们以php版为例,放在了sdk文件夹下,起名叫alipay_dakuan。
六:获取沙盒测试环境下的证书文件。【如果不需要沙盒测试的话,请忽略这一步】
1、在我的应用-->网页&移动应用下找到沙箱,点击进入。如图:
2、获取沙盒环境下的APPID保存备用。【这里的appid跟步骤二中获取的应用appid不一样】
接口加签方式选择系统默认密钥。
【好处就是可以直接下载沙盒环境下的应用公钥证书、支付宝根证书、支付宝公钥证书,如果选择自定义密钥的话还需要通过支付宝开放平台开发助手获取支付宝公钥、支付宝私钥和csr文件并将csr文件上传,从而获取三个证书,这样就能省下来一个步骤。】
将证书模式开启。
沙盒环境下的支付宝网关地址复制留存,后面的代码中会用到。
异步通知应用网关地址也需要设置一下【这里测试时沙盒环境下没有走异步回调方法,不知道啥原因】。
点击证书模式后的查看,如下图:
将应用私钥复制保存,后面代码中会用到。
点击图中的下载证书,将沙盒环境下的应用公钥证书、支付宝公钥证书、支付宝根证书下载到本地保存,后面的代码中会用到。【注意:这里下载的三个证书是沙盒环境下的证书,不要跟之前步骤四、6中下载的正式环境下的证书混用】
在代码环境中,创建sandbox文件夹【文字随意命名,因为是沙盒环境下的证书,故命名为sandbox,见字识意】,并将三个沙盒环境证书放入此文件夹中。
如下图:
点击沙箱账号:查看商家账号和买家账号,后面的代码中会用到。
留意此时的余额,后面代码测试正常后,这里的余额会发生变化。
七:配置正式环境证书:
在项目sdk/alipay_dakuan文件夹下新建formal文件夹,并把上面下载的正式环境下的三个证书放在此文件夹下。
八:代码测试:
1、在支付宝开放平台用户登录的情况下,访问下面网址
https://opensupport.alipay.com/support/codelab/detail/488/552?ant_source=opendoc蚂蚁技术支持中心,致力于为开发者提供小程序各类能力及行业解决方案,在这里可以找到开发者、服务商、渠道商需要的各种能力、帮助及服务https://opensupport.alipay.com/support/codelab/detail/488/552?ant_source=opendoc通过点击下一步,查看自己开发时的准备工作是否都已经到位,如果系统提示有些信息未配置的话,请先参考之前的步骤把该配置、该获取的信息都处理好。
2、当点到第④步开发环境配置时,根据自己项目开发语言需要选择。
3、第⑤步时,选择必选接入接口选项卡,点击转账支付宝账户栏目,右侧就可以看到该接口需要的关键入参和关键出参介绍,点击右侧的代码示例,我们可以看到选择的对应编程语言的代码,这里的代码就是我们要用的。
因为我们下载的sdk初始包结构是这样的,所以,示例代码中引用sdk的时候使用的路径是aop/……
当我们把sdk包文件解压后,将aop里的文件放入项目中,文件夹的路径改为了sdk/alipay_dakuan【上面已经介绍过】,所以,我们项目中使用时的引用路径就需要按照实际路径进行修改。
参考下面的文档我们可以知道,转账到支付宝账户请求的API接口是alipay.fund.trans.uni.transfer
那么,我们在实例化请求类的时候,要写为AlipayFundTransUniTransferRequest【这里仅作为一个知识点提醒一下,此sdk中其他方法调用时生成请求类也是这种思路】
概述 | 网页&移动应用支付宝文档中心https://opendocs.alipay.com/open/02np93
创建一个测试文件,把上面的代码进行处理【正式环境证书和沙盒环境证书都集成在项目中,方便两方面测试】
public function test(){
//API_ROOT 是框架常量,可以根据自己实际项目文件路径改为以/开头的根路径
require_once API_ROOT.'/../sdk/alipay_dakuan/AopCertClient.php';
require_once API_ROOT.'/../sdk/alipay_dakuan/request/AlipayFundTransUniTransferRequest.php';
$is_sandbox=1; //沙盒环境 1/正式环境开关 0
// 初始化
$aop = new AopCertClient;
//沙盒环境下
if($is_sandbox){
//沙盒支付宝网关地址
$gateway_url="https://openapi.alipaydev.com/gateway.do";
//沙盒appid
$appid="2021**********00"; //【替换为自己的沙箱appid】
//沙盒应用私钥
$private_key='MIIEv**********ERWc='; //替换为自己沙盒环境下的应用私钥
//沙盒应用公钥证书路径,下载后保存位置的绝对路径
$appCertPath = API_ROOT.'/../sdk/alipay_dakuan/sandbox/appCertPublicKey_2021000118693500.crt'; //【上面讲解中有截图,可对照,替换为自己的文件名】
//沙盒支付宝公钥证书路径,下载后保存位置的绝对路径
$alipayCertPath = API_ROOT.'/../sdk/alipay_dakuan/sandbox/alipayCertPublicKey_RSA2.crt'; //【上面讲解中有截图,可对照,替换为自己的文件名】
//沙盒支付宝根证书路径,下载后保存位置的绝对路径
$rootCertPath = API_ROOT.'/../sdk/alipay_dakuan/sandbox/alipayRootCert.crt'; //【上面讲解中有截图,可对照,替换为自己的文件名】
}else{ //正式环境下
//正式支付宝网关地址
$gateway_url="https://openapi.alipay.com/gateway.do";
//正式appid
$appid="20180*********34"; //【替换为自己的应用appid】
//正式应用私钥
$private_key='MIIEvA********smclBNQ=='; //替换为自己正式环境下的应用私钥【这里的私钥最好以文件形式存储,不要写死在代码中防止泄露造成经济损失】
//正式应用公钥证书路径,下载后保存位置的绝对路径
$appCertPath = API_ROOT.'/../sdk/alipay_dakuan/formal/appCertPublicKey_2018012602080134.crt'; //【替换为自己正式环境下载的应用公钥证书在项目中的路径】
//正式支付宝公钥证书路径,下载后保存位置的绝对路径
$alipayCertPath = API_ROOT.'/../sdk/alipay_dakuan/formal/alipayCertPublicKey_RSA2.crt'; //【替换为自己正式环境下载的支付宝公钥证书在项目中的路径】
//正式支付宝根证书路径,下载后保存位置的绝对路径
$rootCertPath = API_ROOT.'/../sdk/alipay_dakuan/formal/alipayRootCert.crt'; //【替换为自己正式环境下载的支付宝根证书在项目中的路径】
}
$aop -> gatewayUrl=$gateway_url;
// 应用id,如何获取请参考:https://opensupport.alipay.com/support/helpcenter/190/201602493024
$aop -> appId = $appid;
// 密钥格式为pkcs8,如何获取私钥请参考:https://opensupport.alipay.com/support/helpcenter/207/201602471154?ant_source=antsupport
$aop -> rsaPrivateKey = $private_key;
// 设置签名类型
$aop -> signType= "RSA2";
// 设置请求格式,固定值json
$aop -> format = "json";
// 设置编码格式
$aop -> charset= "utf-8";
// 调用getPublicKey从支付宝公钥证书中提取公钥
$aop -> alipayrsaPublicKey = $aop -> getPublicKey($alipayCertPath);
// 是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内
$aop -> isCheckAlipayPublicCert = true;
// 调用getCertSN获取证书序列号
$aop -> appCertSN = $aop -> getCertSN($appCertPath);
// 调用getRootCertSN获取支付宝根证书序列号
$aop -> alipayRootCertSN = $aop -> getRootCertSN($rootCertPath);
// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.fund.trans.uni.transfer(单笔转账接口)
$request = new AlipayFundTransUniTransferRequest();
//按照入参列表说明进行配置
$param=[
'out_biz_no'=>date("YmdHis",time()).rand(1000,9999),
'trans_amount'=>'0.1',
'product_code'=>'TRANS_ACCOUNT_NO_PWD',
'biz_scene'=>'DIRECT_TRANSFER',
'payee_info'=>[
'identity_type'=>'ALIPAY_LOGON_ID',
'identity'=>'wox*****@sandbox.com', //沙盒买家账号[替换为自己的沙盒买家账号]
'name'=>'wox*****', //沙盒买家名称
],
'order_title'=>'沙盒转账测试',
'remark'=>'沙盒单笔转账',
'business_params'=>[
'payer_show_name'=>'沙盒卖家wspxxs1061' //沙盒卖家名称
]
];
if(!$is_sandbox){
$param['payee_info']=[
'identity_type'=>'ALIPAY_LOGON_ID',
'identity'=>'158******88', //正式买家账号【替换为自己的】
'name'=>'张三', //正式买家名称【替换为自己的】
];
$param['order_title']='正式转账测试';
$param['remark']='正式单笔转账';
$param['business_params']=[
'payer_show_name'=>'***公司' //正式卖家名称【替换为自己的】
];
}
$request -> setBizContent(json_encode($param));
$result = $aop -> execute($request);
$res=json_encode($result, JSON_UNESCAPED_UNICODE);
$arr=json_decode($res,true);
$code=$arr['alipay_fund_trans_uni_transfer_response']['code']; //通用状态码 10000表示成功
$msg=$arr['alipay_fund_trans_uni_transfer_response']['msg'];
$status=$arr['alipay_fund_trans_uni_transfer_response']['status']; //接口状态码
$out_biz_no=$arr['alipay_fund_trans_uni_transfer_response']['out_biz_no']; //系统唯一订单号
$order_id=$arr['alipay_fund_trans_uni_transfer_response']['order_id']; //支付宝订单号
//转账成功
if($code==10000 && $status=='SUCCESS'){
//******成功后续业务逻辑区域[根据自己业务需求自行处理]*******
……
……
//******后续业务逻辑区域*******
}else{
//******失败后续业务逻辑区域[根据自己业务需求自行处理]*******
……
……
//******后续业务逻辑区域*******
}
/*上面已经将参数列表按数组的方式重新整理,所以这里要注释掉
$request -> setBizContent("{".
// 商户端的唯一订单号,对于同一笔转账请求,商户需保证该订单号唯一
"\"out_biz_no\":\"2020062900001\",".
// 转账金额,TRANS_ACCOUNT_NO_PWD产品取值最低0.1
"\"trans_amount\":\"0.1\",".
// 产品码,单笔无密转账到支付宝账户固定为:TRANS_ACCOUNT_NO_PWD
"\"product_code\":\"TRANS_ACCOUNT_NO_PWD\",".
// 场景码,单笔无密转账到支付宝账户固定为:DIRECT_TRANSFER
"\"biz_scene\":\"DIRECT_TRANSFER\",".
// 转账业务的标题,用于在支付宝用户的账单里显示
"\"order_title\":\"转账标题\",".
// 收款方信息
"\"payee_info\":{".
// 参与方的唯一标识,收款支付宝账号或者支付宝吧账号唯一会员ID
"\"identity\":\"2088******\",".
// 参与方的标识类型:ALIPAY_USER_ID 支付宝的会员ID
"\"identity_type\":\"ALIPAY_USER_ID\",".
// 参与方真实姓名,如果非空,将校验收款支付宝账号姓名一致性。当identity_type=ALIPAY_LOGON_ID时,本字段必填
"\"name\":\"张三\"".
"},".
// 业务备注
"\"remark\":\"单笔转账\"".
"}");*/
}
当我们运行沙盒测试代码时,打印出同步返回结果如下:
刷新沙盒账号页面,可以看到商家账号减少了0.1元,买家账户增加了0.1元,说明转账成功。
正式环境下支付的账单:
正式环境下支付时,返回的同步信息如下:
正式环境比沙盒环境多了两个参数:
pay_fund_order_id、 trans_date
如果支付宝账户余额不足时,返回的信息如下:
返回错误码参考文档:
常见问题 | 网页&移动应用支付宝文档中心https://opendocs.alipay.com/open/309/rz82w5
公共错误码参考文档:
公共错误码 | 开放平台支付宝文档中心https://opendocs.alipay.com/common/02km9f业务错误码参考文档:
异步回调通知返回的参数:
注意:返回的同步参数和异步参数想要验证签名的话,不要用支付宝开放平台开发助手,因为会遇到很多莫名其妙的提示错误。
异步通知签名验证方法如下:
参考文档:
public function testsign(){
//API_ROOT 是框架常量,可以根据自己实际项目文件路径改为以/开头的根路径
require_once API_ROOT.'/../sdk/alipay_dakuan/AopCertClient.php';
$aop = new AopCertClient();
//证书路径【根据自己项目实际路径修改】
$alipayCertPath = API_ROOT.'/../sdk/alipay_dakuan/formal/alipayCertPublicKey_RSA2.crt';
//支付宝公钥赋值
$aop->alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath);
//编码格式
$aop->postCharset="UTF-8";
// 回调的待验签字符串,需要替换为自己获取的参数【回调的是个数组,为了方便演示,此处将数组转为了json】
$_POST='{"charset":"UTF-8","biz_content":"{\"pay_date\":\"2022-01-12 15:42:40\",\"biz_scene\":\"DIRECT_TRANSFER\",\"action_type\":\"FINISH\",\"pay_fund_order_id\":\"20220112110070001506340040637445\",\"origin_interface\":\"alipay.fund.trans.uni.transfer\",\"out_biz_no\":\"202201121542399130\",\"trans_amount\":\"0.10\",\"product_code\":\"TRANS_ACCOUNT_NO_PWD\",\"order_id\":\"20220112110070000006340017448668\",\"status\":\"SUCCESS\"}","utc_timestamp":"1641973360744","sign":"AfIvONPS\/1V1uM+QwkYr4su3U3gFBss\/iH2nhhI9ttqKl3R1WZ5jIf7ia\/omo60orzK5TVayK3L5nmfOHYMr4UVhb7cFS8uNM5WtvOarTyPbDfSqd2zq088hx0+Kvnl5r+PSHhci4eyJx6iB4Fvzv3YVF+qcl9jqYkzx\/E91TulBt20pDhA6M2decqcdiw+CG9qOK+cByqOv9ihKfEgmccYMvJQX+P5w+rgp72NJFGKpCXlO6sI9PggKPlIjXlORl6v0ayV6lvrVWJMxeywThTo8X4CRZX2UCxl0sx5A8vSyrc1yTc4KrkgtUuzCwTSvRhXh4nkUXEXbEDoe6nS4zg==","app_id":"2018**********34","version":"1.1","sign_type":"RSA2","notify_id":"2022011200222154240095431456806399","msg_method":"alipay.fund.trans.order.changed"}';
//签名方式
$sign_type="RSA2";
//把字符串转为数组
$data = json_decode($_POST,true);
//验签代码
$flag = $aop->rsaCheckV1($data, null, $sign_type);
if ($flag){
echo "success";
}else {
echo "fail";
}
}
同步验签的话参考文档:
数据验签 | 开放平台支付宝文档中心https://opendocs.alipay.com/common/02mse7#%E5%85%AC%E9%92%A5%E8%AF%81%E4%B9%A6%E6%96%B9%E5%BC%8F可以选择使用sdk公钥证书验签或者自行验签,因为在调用转账API时,sdk会主动验签,如果返回的同步数据是正常的,那么说明数据就没有问题。这里同步数据验签不做整理,感兴趣的话可以参考文档自行处理。
以上就是支付宝单笔转账接口的使用过程及注意事项,下课。