对接支付宝【单笔转账接口】时发现资金支出类接口只能使用证书方式,遂引入最新sdk,修改原支付接口,并增加转账接口
AlipayBase.php
<?php
namespace app\models\alipay;
class AlipayBase{
protected $aop;
private $error;
protected $appCertPath;
protected $rootCertPath;
protected $appId;
protected $rsaPrivateKey;
protected $alipayrsaPublicKey;
protected $rsaPrivateKeyPath;
protected $alipayrsaPublicKeyPath;
public function __construct(){
$this->appId = 'test1111111111';//TODO 支付宝应用id
$this->rsaPrivateKeyPath = root_path() . "library/alipay/rsaPrivateKey.txt";//TODO 使用支付宝开放平台开发助手生成的应用私钥
$this->appCertPath = root_path() . "library/alipay/appCertPublicKey_2021001154615307.crt";//TODO 上传证书后生成的crt文件 证书
$this->rootCertPath = root_path() . "library/alipay/alipayRootCert.crt";//TODO 上传证书后生成的crt文件 支付宝根证书
$this->alipayrsaPublicKeyPath = root_path() . "library/alipay/alipayCertPublicKey_RSA2.txt";//TODO 上传证书后生成的txt文件 支付宝公钥证书(不能使用支付宝开放平台开发助手生成的应用公钥,这样子会导致支付回调验签失败)
$this->alipayrsaPublicKey = file_get_contents($this->alipayrsaPublicKeyPath);//TODO 代码示例中是这样获取的($aop->getPublicKey($alipayCertPath);//调用getPublicKey从支付宝公钥证书中提取公钥),获取不到,所以改成了file_get_contents
$this->rsaPrivateKey = file_get_contents($this->rsaPrivateKeyPath);
require_once root_path() . 'library/alipay/aop/AopCertClient.php';
//1、execute 使用
$aop = new \AopCertClient ();
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
$aop->apiVersion = '1.0';
$aop->signType = 'RSA2';
$aop->postCharset = 'utf-8';
$aop->format = 'json';
$aop->isCheckAlipayPublicCert = true;//是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内
$aop->appId = $this->appId;
$aop->rsaPrivateKey = $this->rsaPrivateKey;
$aop->alipayrsaPublicKey = $this->alipayrsaPublicKey;
$aop->appCertSN = $aop->getCertSN($this->appCertPath);//调用getCertSN获取证书序列号
$aop->alipayRootCertSN = $aop->getRootCertSN($this->rootCertPath);//调用getRootCertSN获取支付宝根证书序列号
$this->aop = $aop;
}
/**
* 获取错误信息
* @return mixed
*/
public function getError()
{
return $this->error;
}
/**
* 设置错误信息
* @param mixed $error
*/
public function setError($error = '支付宝服务异常,请重试'): bool
{
$this->error = $error;
return false;
}
}
Trans.php
<?php
namespace app\models\alipay;
/**
* 转账类
* Class Trans
* @package app\models\alipay
*/
class Trans extends AlipayBase {
/**
* 转账给支付宝
* @param $data
* @param string $order_title
* @return bool|\SimpleXMLElement
*/
public function transfer($data, $order_title = '提现'){
try {
require_once root_path() . 'library/alipay/aop/request/AlipayFundTransUniTransferRequest.php';
$request = new \AlipayFundTransUniTransferRequest ();
$param = [
'biz_scene' => 'DIRECT_TRANSFER',
'product_code' => 'TRANS_ACCOUNT_NO_PWD',
'order_title' => $order_title,
'out_biz_no' => $data['out_biz_no'],//TODO 订单号
'trans_amount' => $data['trans_amount'],//TODO 金额
'payee_info' => [
'identity_type' => 'ALIPAY_LOGON_ID',
'identity' => $data['identity'],//TODO 手机号
'name' => $data['name'],//TODO 姓名
]
];
$bizcontent = json_encode($param);
$request->setBizContent($bizcontent);
$result = $this->aop->execute($request);
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
$resultCode = $result->$responseNode->code;
if(!empty($resultCode)&&$resultCode == 10000){
return $result->$responseNode;
} else {
return $this->setError($result->$responseNode->sub_msg);
}
} catch (\Exception $e) {
return $this->setError($e->getMessage());
}
}
/**
* 查询转账订单
* @param $out_biz_no
* @return bool|\SimpleXMLElement
*/
public function find($out_biz_no){
try {
require_once root_path() . 'library/alipay/aop/request/AlipayFundTransOrderQueryRequest.php';
$request = new \AlipayFundTransOrderQueryRequest ();
$param = [
'out_biz_no' => $out_biz_no,//TODO 订单号
];
$bizcontent = json_encode($param);
$request->setBizContent($bizcontent);
$result = $this->aop->execute($request);
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
$resultCode = $result->$responseNode->code;
if(!empty($resultCode)&&$resultCode == 10000){
return $result->$responseNode;
} else {
return $this->setError($result->$responseNode->sub_msg);
}
} catch (\Exception $e) {
return $this->setError($e->getMessage());
}
}
}
AppPay.php
<?php
namespace app\models\alipay;
class AppPay extends AlipayBase {
/**
* 创建app支付订单
* @param $data 订单数据
* @param string $notify_url 回调地址
* @param string $subject 订单标题
* @param string $timeout_express 过期时间
* @return bool|string
*/
public function pay($data, $notify_url = '', $subject = '购物', $timeout_express = '30m'){
try {
require_once root_path() . 'library/alipay/aop/request/AlipayTradeAppPayRequest.php';
$request = new \AlipayTradeAppPayRequest ();
$param = [
"body" => $subject,
'subject' => $subject,//订单标题
"timeout_express" => $timeout_express,//支付订单有效时间
'out_trade_no' => $data['out_trade_no'],//订单号
'total_amount' => $data['total_amount'],//金额
];
$bizcontent = json_encode($param);
$alipay_notify_url = $notify_url;
$request->setNotifyUrl($alipay_notify_url);//TODO 必须在这里设置支付回调地址
$request->setBizContent($bizcontent);
$result = $this->aop->sdkExecute($request);//TODO 创建订单接口需要使用sdkExecute
return $result;
} catch (\Exception $e) {
return $this->setError($e->getMessage());
}
}
/**
* 回调验签
* @param $data 回调的post数据
* @return bool
*/
public function notify($data){
return $this->aop->rsaCheckV1($data, NULL, $data['sign_type']);
}
}
调用测试
//创建app支付订单接口
$data = [
'out_trade_no' => $out_trade_no,
'total_amount' => $amount
];
$appPay = new AppPay();
$response = $appPay->pay($data);
//支付回调验签
$appPay = new AppPay();
$flag = $appPay->notify($data);
//调用转账接口
$out_biz_no = 'test'.time();
$data = [
'out_biz_no' => $out_biz_no,
'trans_amount' => 1.00,
'identity' => '17539592164',
'name' => '哈哈'
];
$trans = new Trans();
$res = $trans->transfer($data);
if($res) var_dump('成功');
else var_dump($trans->getError());
//调用查询转账结果接口
$trans = new Trans();
$res = $trans->find($out_biz_no);
if($res) var_dump($res);
else var_dump($trans->getError());