在yii2.0.55中接入支付宝需完成sdk引入、配置注册、pkcs#1私钥转换、网关调用封装及回调验签;跳过私钥格式转换或未关闭调试模式自动验签绕过,将导致生产环境签名失败。

在Yii2.0.55项目中接入支付宝支付接口,需完成SDK引入、配置文件注册、签名密钥处理、网关调用封装及回调验签全流程,缺一不可;若跳过私钥格式转换或未关闭调试模式下的自动验签绕过,将导致沙箱环境测试通过但生产环境签名失败。
下载并安装支付宝官方SDK
访问支付宝开放平台SDK下载页,下载最新版alipay-sdk-php-202308.zip(注意:非GitHub第三方包);解压后将整个aop目录复制到项目根目录下的vendor/alipay/路径下(若无vendor目录则手动创建)。
在composer.json的autoload段添加PSR-4映射:
【"Alipay\Aop\" : "vendor/alipay/aop/"】;执行composer dump-autoload刷新自动加载缓存,否则后续new AlipayAopClient()会报Class not found。
生成并转换RSA密钥对
使用支付宝提供的密钥工具生成RSA2密钥(2048位),导出应用私钥app_private_key.pem和支付宝公钥alipay_public_key.pem。
Yii2.0.55要求私钥必须为PKCS#1格式且无密码保护——若你导出的是PKCS#8格式(以-----BEGIN PRIVATE KEY-----开头),需用OpenSSL转为PKCS#1:
openssl rsa -in app_private_key.pem -out app_private_key_pkcs1.pem;【务必删除原PKCS#8私钥,只保留新生成的PKCS#1版本】,否则AlipayAopClient初始化时抛出“Unable to load private key”错误。
将app_private_key_pkcs1.pem和alipay_public_key.pem放入@app/config/certs/目录(需手动创建),并设置文件权限为600(Linux/macOS)或取消Windows继承权限,防止Web服务器直接暴露私钥。
注册支付宝组件与全局配置
在@app/config/web.php的components数组中添加:
'alipay' => [
'class' => 'common\components\AlipayService',
'appId' => 'your_app_id_here',
'gatewayUrl' => 'https://openapi.alipay.com/gateway.do',
'notifyUrl' => 'https://yourdomain.com/alipay/notify',
'returnUrl' => 'https://yourdomain.com/alipay/return',
'rsaPrivateKeyPath' => '@app/config/certs/app_private_key_pkcs1.pem',
'alipayPublicKeyPath' => '@app/config/certs/alipay_public_key.pem',
],
创建@app/common/components/AlipayService.php,继承yiiaseComponent,在init()方法中实例化AopClient并注入配置;【注意:不要在构造函数里new AopClient,否则无法被Yii容器管理】。
封装统一下单接口
在@app/modules/payment/controllers/PaymentController.php中新增actionCreateOrder():
第一步:接收前端传来的商品标题、金额、订单号(需全局唯一),校验金额是否为正数且小数点后最多两位;
第二步:构建AlipayTradePagePayRequest对象,设置bizContent为JSON字符串(含subject、out_trade_no、total_amount、product_code等字段);
第三步:调用$this->alipay->aopclient->pageExecute($request)获取重定向URL;
第四步:返回JSON结构{'redirect_url': 'https://openapi.alipay.com...'},前端用window.location.href跳转——【严禁用iframe嵌套或AJAX提交,否则支付宝无法正确识别用户设备】。
处理同步返回与异步通知
方法一:同步返回(returnUrl)
在actionReturn()中调用$this->alipay->aopclient->verifyReturn()验证签名,成功则渲染支付成功页面;失败则跳转错误页。此步骤仅作用户体验,【不可用于更新订单状态,因用户可能关闭浏览器导致请求中断】。
方法二:异步通知(notifyUrl)
在actionNotify()开头立即调用Yii::$app->response->format = yiiwebResponse::FORMAT_RAW并输出'success',防止Yii自动添加HTML头导致支付宝重复推送;
再读取file_get_contents('php://input')解析原始POST数据,用$this->alipay->aopclient->rsaCheckV1()验签;验签通过后更新订单状态并记录日志,最后再次输出'success'。











