Laravel Omnipay - transactionReference 参数是必需的

Posted

技术标签:

【中文标题】Laravel Omnipay - transactionReference 参数是必需的【英文标题】:Laravel Omnipay - The transactionReference parameter is required 【发布时间】:2017-10-24 07:36:51 【问题描述】:

我正在使用名为Attendize 的开源票务系统。

他们已经集成了支付服务提供商Stripe。现在,我正在尝试与付款提供商Mollie 合作。

问题是我一直遇到这个错误:

我的代码如下所示:

$transaction_data += [
    'transactionId' => $event_id . date('YmdHis'),
    'returnUrl' => route('showEventCheckoutPaymentReturn', [
        'event_id'              => $event_id,
        'is_payment_successful' => 1
    ]),
];

$apiKey = "test_gSDS4xNA96AfNmmdwB3fAA47******";
$gateway->setApiKey($apiKey);


$transaction = $gateway->purchase($transaction_data);

$response = $transaction->send();

if ($response->isSuccessful()) 

    session()->push('ticket_order_' . $event_id . '.transaction_id',
        $response->getTransactionReference());

    return $this->completeOrder($event_id);

 elseif ($response->isRedirect()) 
    /*
     * As we're going off-site for payment we need to store some data in a session so it's available
     * when we return
     */
    session()->push('ticket_order_' . $event_id . '.transaction_data', $transaction_data);
    Log::info("Redirect url: " . $response->getRedirectUrl());

    $return = [
        'status'       => 'success',
        'redirectUrl'  => $response->getRedirectUrl(),
        'message'      => 'Redirecting to ' . $ticket_order['payment_gateway']->provider_name
    ];

    // GET method requests should not have redirectData on the JSON return string
    if($response->getRedirectMethod() == 'POST') 
        $return['redirectData'] = $response->getRedirectData();
    

    return response()->json($return);

 else 
    // display error to customer
    return response()->json([
        'status'  => 'error',
        'message' => $response->getMessage(),
    ]);

当我调试我的代码时,他会进入elseif ($response->isRedirect()) 。我被重定向到 Mollie,并且可以成功付款。但是当我被重定向回http://myurl.dev/e/1/checkout/success?is_payment_successful=1 时,我得到了错误。

更新:

在我的返回函数中,我有以下代码:

public function showEventCheckoutPaymentReturn(Request $request, $event_id)

    if ($request->get('is_payment_cancelled') == '1') 
        session()->flash('message', 'You cancelled your payment. You may try again.');
        return response()->redirectToRoute('showEventCheckout', [
            'event_id'             => $event_id,
            'is_payment_cancelled' => 1,
        ]);
    

    $ticket_order = session()->get('ticket_order_' . $event_id);
    $gateway = Omnipay::create($ticket_order['payment_gateway']->name);

    $gateway->initialize($ticket_order['account_payment_gateway']->config + [
            'testMode' => config('attendize.enable_test_payments'),
        ]);

    $transaction = $gateway->completePurchase($ticket_order['transaction_data'][0]);

    $response = $transaction->send();

    if ($response->isSuccessful()) 
        session()->push('ticket_order_' . $event_id . '.transaction_id', $response->getTransactionReference());
        return $this->completeOrder($event_id, false);
     else 
        session()->flash('message', $response->getMessage());
        return response()->redirectToRoute('showEventCheckout', [
            'event_id'          => $event_id,
            'is_payment_failed' => 1,
        ]);
    


问题(错误)出在$response = $transaction->send();

数组$ticket_order['transaction_data'][0] 包含以下内容:

Array
(
    [amount] => 80
    [currency] => EUR
    [description] => Order for customer: niels@email.be
    [transactionId] => 120170529082422
    [returnUrl] => http://eventy.dev/e/1/checkout/success?is_payment_successful=1
)

更新 2:

我在返回函数中添加了$gateway->setApiKey($apiKey);。但问题是我的回复成功。所以他没有进入$response->isSuccessful()。当我在他检查它是否成功之前转储我的$response 变量时,它会显示:https://pastebin.com/NKCsxJ7B。

你可以看到这样的错误:

[error] => Array ( [type] => request [message] => The payment id is invalid )

Mollie 的付款方式如下:

更新 3:

在我的返回函数中,我尝试像这样检查响应对象的状态:$response->status()。这给了我以下错误:

调用未定义的方法 Omnipay\Mollie\Message\CompletePurchaseResponse::status()

然后我尝试了$response->getStatus(),但这并没有给我任何回报。

【问题讨论】:

您在此处发布的代码是创建付款的代码。此代码有效,因为您将被重定向到 Mollie。你也可以把http://myurl.dev/e/1/checkout/success?is_payment_successful=1的代码贴出来吗?获取付款状态时,您可能未正确传递付款 ID。 @Daan,我已经用我的返回函数更新了我的主题。 【参考方案1】:

这可能与这张票有关:https://github.com/thephpleague/omnipay-eway/issues/13

为了解决这个检查,我建议检查状态代码

if ($request->status() == 201) 
    //successful created

我的理论是它正在检查 200

函数在这里定义:

https://github.com/thephpleague/omnipay-mollie/blob/master/src/Message/AbstractResponse.php

  public function isSuccessful()
    
        return !$this->isRedirect() && !isset($this->data['error']);
    

它可能会失败,因为您期望重定向!

201 因为下面是我的 Postman 测试

【讨论】:

我在哪里做检查? 您的问题中有代码显示:if ($response->isSuccessful()) ,只需将其替换为适当的状态代码检查即可。它没有必须为 201,这取决于请求。也许最好只检查代码是否 a 2 开头(意味着在 http 领域成功) 然后我收到错误“方法代码不存在。”。 再次阅读代码后显示名称为getCode()github.com/thephpleague/omnipay-multisafepay/blob/master/src/… 当然,你明白了! :)【参考方案2】:

@Daan 在他的评论中说的是正确的,您从登录页面而不是创建交易的页面收到错误。

在该着陆页上,您会收到这样的电话:

$omnipay->completePurchase($data);

在该@data 数组中,您需要包含'transactionReference' 字段,该字段应该是您的http://myurl.dev/e/1/checkout/success?is_payment_successful=‌​1 URL 收到的POST 参数之一。

可能有用的调试帮助是打印出该 URL 处的代码或记录整个 $_POST 数组,然后您可以使用它来检查需要从该数组中提取的参数。网关之间会有所不同。

【讨论】:

太好了,感谢您这样做,我现在可以看到您的问题所在。此参数:[transactionId] => 120170529082422 需要作为transactionReference 传递。因此,您需要将$ticket_order['transaction_data'][0] 存储到一个数组中,然后像这样修改数组$myArray['transactionReference'] = $myArray['transactionId']; 不要删除任何参数,omnipay 将忽略它不需要的参数。 我已经添加了 transactionReference。但是现在当我检查响应是否成功时,我将进入 else 。当我检查消息时,我收到“未经授权的请求”。 您是否在返回函数中包含$gateway->setApiKey($apiKey); 行? @Daan,现在我这样做了,但现在我收到消息“付款 ID 无效”。 您确定在两个脚本中使用了相同的 API 密钥和测试模式吗?

以上是关于Laravel Omnipay - transactionReference 参数是必需的的主要内容,如果未能解决你的问题,请参考以下文章

使用 laravel 5.1 安装 Omnipay/payu

Omnipay 贝宝与 laravel 4 的集成

使用 Laravel Omnipay(mollie 网关)进行支付

Laravel 5.3 - Omnipay Paypal Express 不返回成功消息

使用 Omnipay 将 PayPal REST API 集成到 Laravel - 需要 card 参数

在 OctoberCMS 插件中使用 Omnipay