您现在的位置是: 网站首页> PHP> Laravel Laravel
Laravel 接入AlipaySDK支付宝支付接口
Smile 2020-12-30 19:07:41 PHP Laravel 阅读:3359
简介使用 Laravel7+ 接入支付宝网站移动支付,初次接入者会遇到各种问题和踩各种坑,本文详细记录接入过程中遇到的问题以及解决方案,避免之后接入再次会遇到
1、下载手机网站支付Demo,传送门
2、配置支付应用信息,个人可以先使用官方提供的沙箱应用环境,要上生产环境时改下支付配置即可,沙箱应用配置请参考官方文档,自行配置好
3、在 Laravel 中导入下载好的Demo,打开根目录下的composer.json文件,找到autoload加入Demo存放路径
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories",
"app/lib/Alipay"//Demo存放路径
]
}
保存好之后在项目更目录下运行 composer dump-autoload 命令
4、在config目录下新建 pay.php 配置文件,根据支付应用信息配置如下支付信息
<?php
return [
'alipay' => array(
//应用ID,您的APPID。
'app_id' => "",
//商户私钥,您的原始格式RSA私钥
'merchant_private_key' => "",
//异步通知地址
'notify_url' => "http://工程公网访问地址/alipay.trade.wap.pay-PHP-UTF-8/notify_url.php",
//同步跳转
'return_url' => "http://mitsein.com/alipay.trade.wap.pay-PHP-UTF-8/return_url.php",
//编码格式
'charset' => "UTF-8",
//签名方式
'sign_type'=>"RSA2",
//支付宝网关
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
//支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
'alipay_public_key' => "",
),
];
注:这里是个采坑点,特别需要注意配置文件里的支付宝公钥,千万不要配置成应用公钥,不然后面你可以调起支付,但是支付宝回调时会验证签名错误
5、接下来注册 Laravel 路由,如下
Route::get('/alipay', 'AlipayController@index')->name('alipay');
Route::any('/notify', 'AlipayController@notify')->name('notify');
Route::any('/result', 'AlipayController@result')->name('result');
注:这里是个采坑点,为避免采坑用 Route::any方式的路由, 因为支付宝服务端请求你的回调接口时notify异步回调使用的是POST方式,result同步回调时用的是GET方式
6、在App\Http\Middleware\VerifyCsrfToken里,将notify异步回调请求路径去除CSRF TOKEN的保护,如下
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'notify',
];
}
7、在支付控制器正常调起支付
public function index()
{
//商户订单号,商户网站订单系统中唯一订单号,必填
$out_trade_no = $_POST['WIDout_trade_no'];
//订单名称,必填
$subject = $_POST['WIDsubject'];
//付款金额,必填
$total_amount = $_POST['WIDtotal_amount'];
//商品描述,可空
$body = $_POST['WIDbody'];
//超时时间
$timeout_express="1m";
//支付宝配置
$config = config('pay.alipay');
$payRequestBuilder = new \AlipayTradeWapPayContentBuilder();
$payRequestBuilder->setBody($body);
$payRequestBuilder->setSubject($subject);
$payRequestBuilder->setOutTradeNo($out_trade_no);
$payRequestBuilder->setTotalAmount($total_amount);
$payRequestBuilder->setTimeExpress($timeout_express);
$payResponse = new \AlipayTradeService($config);
$result=$payResponse->wapPay($payRequestBuilder,$config['return_url'],$config['notify_url']);
return ;
}
8、到这一步你可能会遇到如下错误
Symfony\Component\ErrorHandler\Error\FatalError: Cannot redeclare decrypt() (previously declared in /vendor/laravel/framework/src/Illuminate/Foundation/helpers.php:372) in file vendor/Alipay/aop/AopEncrypt.php on line 51
报错原因:
alipaySDK中定义的Encrypt()/Decrypt()函数与Laravel中定义的Encrypt()/Decrypt()函数重名了
解决办法:
修改alipaySDK中定义的函数名称、修改引用的函数名称
修改方案:
在官方给的SDK中,一共有需要修改三个文件中的内容:
aop/AopEncrypt.php
aop/AopClient.php
lotusphp_runtime/Cookie/Cookie.php
在文件中查找encrypt/decrypt替换为alipayEncrypt/alipayDecrypt即可
9、改好之后,再次发起支付请求,你可能会再次遇到错误如下
The each() function is deprecated. This message will be suppressed on further calls
报错原因:
PHP7.2废除了each函数
解决办法:
找到AopClient.php文件中的buildRequestForm函数,修改如下
/**
* 建立请求,以表单HTML形式构造(默认)
* @param $para_temp 请求参数数组
* @return 提交表单HTML文本
*/
protected function buildRequestForm($para_temp) {
$sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='".$this->gatewayUrl."?charset=".trim($this->postCharset)."' method='POST'>";
foreach ($para_temp as $key => $val) {
if (false === $this->checkEmpty($val)) {
//$val = $this->characet($val, $this->postCharset);
$val = str_replace("'","'",$val);
//$val = str_replace("\"",""",$val);
$sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";
}
}
//submit按钮控件请不要含有name属性
$sHtml = $sHtml."<input type='submit' value='ok' style='display:none;''></form>";
$sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";
return $sHtml;
}
10、至此,你应该可以正常调起支付了,然后在回调函数处理你的订单业务逻辑,如还有问题请留言
很赞哦! (0)