注: 支付宝支付分为支付宝公钥和证书签名方式两种,如果需要使用退款功能要用证书签名方式开发
php接入支付宝证书方式签名
支付宝 PHP SDK 分为老版和新版,老版本的 PHP SDK(v3.4.2) 仅支持公钥方式加签。更新之后 PHP SDK 也可以使用证书进行签名和验签了。
下载之后将文件解压放到extend文件夹下的alipay文件
PHP普通调用示例(证书方式)
PHP接口里根据自己的需求获取订单标题/订单的描述/订单表中的订单号/订单金额
AliPay.php
<?php
/***
*
* @package APP支付宝支付
*
* @subpackage 支付宝支付
*
* @author Tggui 2017-7-4 23:52:27
*
*/
namespace app\app\model;
use think\Controller;
use think\Model;
class AliPay
{
public function __construct()
{
require_once "/first/ky/extend/alipay/aop/AopCertClient.php";
require_once "/first/ky/extend/alipay/aop/reques/AlipayTradeAppPayRequest.php";
}
/**
* 创建APP支付订单
*
* @param string $body 对一笔交易的具体描述信息。
* @param string $subject 商品的标题/交易标题/订单标题/订单关键字等。
* @param string $order_sn 商户网站唯一订单号
* @param string $order_sn $total_amount 转账金额
* @return array 返回订单信息
*/
public function tradeAppPay($body, $subject, $order_sn, $total_amount)
{
$aop = new \AopCertClient();
$appCertPath = "/cert/alipay/appCertPublicKey_2021002142648976.crt";
$alipayPublicKey = "/cert/alipay/alipayCertPublicKey_RSA2.crt";
$rootCertPath = "/www/cert/alipay/alipayRootCert.crt";
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
$aop->appId = '你的appid';
$aop->rsaPrivateKey = '你的应用私钥';
$aop->alipayrsaPublicKey = $aop->getPublicKey($alipayCertPath);//调用getPublicKey从支付宝公钥证书中提取公钥
$aop->apiVersion = '1.0';
$aop->signType = 'RSA2';
$aop->postCharset='utf-8';
$aop->format='json';
$aop->isCheckAlipayPublicCert = true;//是否校验自动下载的支付宝公钥证书,如果开启校验要保证支付宝根证书在有效期内
$aop->appCertSN = $aop->getCertSN($appCertPath);//调用getCertSN获取证书序列号
$aop->alipayRootCertSN = $aop->getRootCertSN($rootCertPath);//调用getRootCertSN获取支付宝根证书序列号
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
$request = new \AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数
$bizcontentarr = [
'body' => $body,
'subject' => $subject,
'out_trade_no' => "$order_sn",
'timeout_express' => '1d',//失效时间为 1天
'total_amount' => "$total_amount",//价格
'product_code' => 'QUICK_MSECURITY_PAY',
];
$bizcontent = json_encode($bizcontentarr, JSON_UNESCAPED_UNICODE);
$host =' xxx.com';
//商户外网可以访问的异步地址 (异步回掉地址,根据自己需求写)
$request->setNotifyUrl("https://{$host}/app/pay/AliPayNotify");
$request->setBizContent($bizcontent);
//这里和普通的接口调用不同,使用的是sdkExecute
$response = $aop->sdkExecute($request);
return $response;
}
我是将支付宝的配置写到了配置文件中,配置文件放在application/extra/alipay
这样基本可以调取到支付宝付款界面了,付款之后就是回调
异步回调接口
class Pay extends Api
{
/**
* 支付宝支付异步通知
*/
public function AliPayNotify()
{
$request = input('post.');
$signType = $request['sign_type'];
$alipay = new AliPay();
$flag = $alipay->rsaCheck($request, $signType);
if ($flag) {
//支付成功:TRADE_SUCCESS 交易完成:TRADE_FINISHED
if ($request['trade_status'] == 'TRADE_SUCCESS' || $request['trade_status'] == 'TRADE_FINISHED') {
//这里根据项目需求来写你的操作 如更新订单状态等信息 更新成功返回'success'即可
$object = json_decode(($request['fund_bill_list']), true);
$trade_type = $object[0]['fundChannel'];
$data1['batch'] = $request['trade_no']; //交易流水号
$buyer_pay_amount = $request['buyer_pay_amount'];
$out_trade_no = $request['out_trade_no']; //获取订单号
//需求处理完成之后必须返回success
exit('success'); //成功处理后必须输出这个字符串给支付宝
}
}
}
}
/**
* 异步通知验签
*
* @param string $params 参数
* @param string $signType 签名类型:默认RSA
* @return bool 是否通过
*/
public function rsaCheck($params, $signType)
{
$aop = new \AopCertClient();
$alipayPublicKey = "/www/cert/alipay/alipayCertPublicKey_RSA2.crt";
$aop->alipayrsaPublicKey = $aop->getPublicKey($alipayPublicKey);
return $aop->rsaCheckV1($params, NULL, $signType);
}
回调验签报错 openssl_verify(): supplied key param cannot be coerced into a public key
解决方案:
证书公钥要写上必须写(下面图中红色圈出)
必须!必须!必须!
重要的事情说三遍
完整的支付流程就走完了,支付成功之后的具体需求在回调接口里面完成即可!