php - laravel 5.5 中的 payhere 支付网关集成
问题描述
我正在尝试将PayHere支付网关集成到我使用Laravel 5.5构建的网站。因此,作为他们的文档,我已将他们的 api 集成如下。我正在使用实时服务器中的沙盒凭据进行测试。在这里我要做的是首先通过 a 传递付款详细信息 (如他们的文档中所示)<from>
.所以当我进行交易时,它应该是正常的,我也收到了来自支付网关的成功邮件。
但我的问题是我无法获取从支付网关发送的通知以检查我的支付状态以更新数据库。所以我写了一个简单的代码来检查支付状态码。(2 - 成功 / 0 - 待处理 / -1 - 取消 / -2 - 失败 / -3 -charged-back )
所以有人可以帮我解决这个问题。请参考下面我编写的用于测试实时服务器中的支付网关的示例代码
- 支付网关 API 详细信息
- Laravel 5.5 版
检查输出控制器
public function notifyUrl(Request $request){
//As their documentation
$merchant_id = $request -> input('merchant_id');
$order_id = $request -> input('order_id');
$payhere_amount = $request -> input('payhere_amount');
$payhere_currency = $request -> input('payhere_currency');
$status_code = $request -> input('status_code');
$md5sig = $request -> input('md5sig');
$merchant_secret = 'xxxxxxxxxxxxxxxxxxxx'; // Replace with your Merchant Secret (Can be found on your PayHere account's Settings page)
$local_md5sig = strtoupper (md5 ( $merchant_id . $order_id . $payhere_amount . $payhere_currency . $status_code . strtoupper(md5($merchant_secret)) ) );
// return $status_code;
if (($local_md5sig === $md5sig) AND ($status_code == 2) ){
$newStatus = new Status();
$newStatus ->status= 2;
$newStatus ->save();
}elseif(($local_md5sig === $md5sig) AND ($status_code == 0) ){
$newStatus = new Status();
$newStatus ->status= 0;
$newStatus ->save();
}elseif(($local_md5sig === $md5sig) AND ($status_code == -1) ){
$newStatus = new Status();
$newStatus ->status= -1;
$newStatus ->save();
}elseif(($local_md5sig === $md5sig) AND ($status_code == -2) ){
$newStatus = new Status();
$newStatus ->status= -2;
$newStatus ->save();
}elseif(($local_md5sig === $md5sig) AND ($status_code == -3) ){
$newStatus = new Status();
$newStatus ->status= -3;
$newStatus ->save();
}else{
$newStatus = new Status();
$newStatus ->status= 'Fail';
$newStatus ->save();
}
}
public function cancelUrl(){
return redirect()->route('shop.home');
}
public function returnUrl(){
return redirect()->route('shop.cart');
}
路线
$router //**using POST method hens they pass data via this url**
-> post ( 'payment/notify' , 'CheckOutController@notifyUrl' )
-> name ( 'shop.notifyUrl' ) ;
$router
-> get ( 'payment/cancelUrl' , 'CheckOutController@cancelUrl' )
-> name ( 'shop.cancelUrl' ) ;
$router
-> get ( 'payment/returnUrl' , 'CheckOutController@returnUrl' )
-> name ( 'shop.returnUrl' ) ;
结帐表格样本取自他们的文档
<form method="post" action="https://sandbox.payhere.lk/pay/checkout" >
<input type="hidden" name="merchant_id" value="000000"> <!-- Replace your Merchant ID -->
<input type="hidden" name="return_url" value="{{route ( 'shop.returnUrl' )}}">
<input type="hidden" name="cancel_url" value="{{route ( 'shop.cancelUrl' )}}">
<input type="hidden" name="notify_url" value="{{route ( 'shop.notifyUrl' )}}">
<input hidden type="text" name="order_id" value="xxxxx">
<input hidden type="text" name="items" value="xxxxxx">
<input hidden type="text" name="currency" value="LKR">
<input hidden type="text" name="amount" value="5000.0">
<br><br>Customer Details</br></br>
<input type="text" name="first_name" value="xxxxx">
<input type="text" name="last_name" value="xxxx">
<input type="text" name="email" value="xxxx">
<input type="text" name="phone" value="xxxx">
<input type="text" name="address" value=" xxxxx / xxxxxx/ xxxxxx/ Sri Lanka">
<input type="text" name="city" value="Colombo">
<input type="hidden" name="country" value="Sri Lanka">
</form>
更新 01(正如@RicardoAlbear 所说)
解决方案
感谢payhere的帮助,我能够解决我的问题。问题是我没有为我的 payhere 通知 url 排除 CSRF。所以 laravel 会自动拒绝通过通知 url 传递的数据。所以我所做的只是添加了 * (接受所有 url 。我们也可以指定 url,如 'www.exapmle.com/payhere/nofity'),现在它可以工作了。所以问题是我们需要为 payhere notify url 排除 CSRF。@RecardoAlbear 非常感谢您的支持。我能从你的评论中得到很多新东西。谢谢
对于未来的参考,payhere 可以在 Laravel 中集成如下
- 创建您的 payhere 帐户并获取一个 Mercer_id
- 如文档中所述,请按照步骤
排除 CSRF 保护
app\Http\Middleware\VerifyCsrfToken.php
<?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 */ //I have used * - means that it allows for all the url. But you can specify excluded url s as you wanted protected $except = [ '*', //this exclude all urls 'www.exapmle.com/payhere/nofity' ] ; }