【发布时间】:2014-02-26 18:53:49
【问题描述】:
我正在尝试将 SagePay Inframe Server 集成到我使用 Laravel 作为框架的站点中。我已经购买了 SSL 证书,一切正常,除了来自 Sagepay 的通知响应。我联系了他们的客户支持,并通过电子邮件发送了一个旧的 2.23 版开发工具包(显然他们没有最新协议的工具包,你可以从中获取),并且大部分代码都是从原始(过时的)代码库修改的。
在过去的 3 周里,我一直在尝试在一个控制器 (OrdersController) 中创建一组函数来处理 SagePays 的各种 POST 发送/响应,希望我可以为 Laravel 创建一个公共库,以便其他人没有需要经历地狱般的尝试来整合这个噩梦般的系统。
目前我的系统正确注册了交易,从该交易中向 Sagepay 发送了一个 notificationURL,我将 Sagepay 所需的必要 VendorTxCode(我创建)/VPSTxId 和 SecurityKey(sagepay 创建)字段存储在我的数据库中,并且我的用户被重定向在 iframe 中输入他们的卡详细信息。
根据文档,在用户输入他们的详细信息并继续他们的交易后,脚本应该检查状态/供应商TxCode/VPSTxId,并使用这些值从数据库中提取SecurityKey。如果 SecurityKey 不存在,则将用户重定向(使用 RedirectURL)到我指定的页面以处理错误。
我会在这里停下来,因为目前我没有从数据库中提取 SecurityKey,因此它不存在,这是确切的问题 - SagePay 应该从这一点将用户重定向到 /failure 页面,但是它没有,而是抛出这个一般错误:
错误代码:5006
错误描述:无法重定向到供应商的网站。供应商未能提供 RedirectionURL。
现在奇怪的是,如果我将相同的脚本(在 Laravel / 控制器框架之外)上传到例如“http://www.thisisanothersite/test/notification.php”,并更改 NotificationURL 以反映这一点,则 iframe 将重定向到所需的重定向网址。如果我在浏览器中加载脚本会显示以下(正确)响应:
Status=INVALID RedirectURL=https://development.myproject.co.uk/sagepay/failureStatusDetail=无法在我们的数据库中找到交易。
但是,如果我尝试从 Laravel 的上下文中查看脚本(例如“https://development.myproject.co.uk/sagepay/notification”),脚本会使用通常的 Illuminate 异常处理程序进行响应,您会期望看到 Laravel 错误。
我的问题是:有没有办法做以下任何事情:
1) 有没有办法为单个函数关闭与 laravel 相关的错误处理,以便我得到与在 Laravel 上下文之外时得到的完全相同的消息?
2) 在 Laravel 的上下文中创建一个独立脚本,这样我就可以使用数据库连接,但可以将其作为独立页面 (sagepay/notification.php) 访问,而不会妨碍控制器路由?
我目前针对上述内容的代码如下:
<?php
class OrdersController extends BaseController {
protected $layout = 'layouts.admin';
public function __construct(Order $order)
{
$this->order = $order;
}
public function notification() {
header("Content-type: text/plain");
$eoln = chr(13) . chr(10);
$strConnectTo = "TEST";
$strStatus=$this->cleanInput($_REQUEST["Status"],"Text");
$strVendorTxCode=$this->cleanInput($_REQUEST["VendorTxCode"],"VendorTxCode");
$strVPSTxId=$this->cleanInput($_REQUEST["VPSTxId"],"Text");
$strSecurityKey="";
$VendorTxCode = $strVendorTxCode;
$VPSTxId = $strVPSTxId;
$strSQL = Order::select('SecurityKey')->where('VendorTxCode', $VendorTxCode)->where('VPSTxId', $VPSTxId)->first();
if (strlen($strSQL->SecurityKey)==0)
{
ob_flush();
header("Content-type: text/html");
echo "Status=INVALID" . $eoln;
if ($strConnectTo=="LIVE") {
echo "RedirectURL=https://development.myproject.co.uk/sagepay/failure" . $eoln;
}
else {
echo "RedirectURL=https://development.myproject.co.uk/sagepay/failure" . $eoln;
}
echo "StatusDetail=Unable to find the transaction in our database." . $eoln;
exit();
}
else
{
// CODE TO DEAL WITH SUCCESS
}
}
}
路线是:
Route::any('sagepay/notification', 'OrdersController@notification');
Route::any('sagepay/failure', 'OrdersController@failure');
Route::resource('orders', 'OrdersController');
对这个问题的大小表示歉意,但我真的被难住了:/
【问题讨论】: