Search code examples
phplaravelpayment-gatewayomnipaymollie

Laravel Omnipay - The transactionReference parameter is required


I'm working with the open source ticket system called Attendize.

They already have the payment provider Stripe integrated. Now I'm trying to make this work with the payment provider Mollie.

The problem is I keep stumbling on this error:

enter image description here

My code looks like this:

$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(),
    ]);
}

When I debug my code he's going into the elseif ($response->isRedirect()) {. I am being redirected to Mollie and a can do a successful payment. But when I am being redirect back to http://myurl.dev/e/1/checkout/success?is_payment_successful=1 I'm getting the error.

UPDATE:

In my return function I have the following code:

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,
        ]);
    }

}

The problem (error) is with $response = $transaction->send();.

The array $ticket_order['transaction_data'][0] contains this:

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

UPDATE 2:

I've added $gateway->setApiKey($apiKey); in my return function. But the problem is that my response is NOT successful. So he doesn't go into $response->isSuccessful(). When I dump my $response variable just before he checks if it's successful it shows this: https://pastebin.com/NKCsxJ7B.

You can see there's an error like this:

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

The payment in Mollie looks like this:

enter image description here

UPDATE 3:

In my return function I tried to check the status of the response object like this : $response->status(). This gave me the following error:

Call to undefined method Omnipay\Mollie\Message\CompletePurchaseResponse::status()

Then I tried $response->getStatus() but this gave me nothing back.


Solution

  • This might have something to do with this ticket: https://github.com/thephpleague/omnipay-eway/issues/13

    To solve this check I would suggest checking status code with

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

    My theory is that it is checking against 200

    The function is defined here:

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

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

    It will probably fail because you expect a redirect!

    201 because of my Postman test below enter image description here