Интеграция Omnipay с PayPal Express Checkout [symfony2]

Я пытаюсь интегрировать ominipay с PayPal Express Checkout на своем веб-сайте. У меня есть таблица commande (заказ на английском языке), где я сохраняю ссылку, дату, user_id , commande => [команда хранит: priceTTC, priceHT, адрес, количество, токен].

Когда пользователь нажимает кнопку «Оплатить», у меня возникает эта ошибка:

Контроллер «FLY\BookingsBundle\Controller\PayController::postPaymentAction» для URI «/payment/2» не может быть вызван.

Это мой validation.html.twig

 <form action="{{ path('postPayment', { 'id' : commande.id }) }}" 
    method="POST"/>
    <input name="token" type="hidden" value="{{ commande.commande.token }}" />
    <input name="price" type="hidden" value="{{ commande.commande.priceTTC }}" />
    <input name="date" type="hidden" value="{{ commande.date|date('dmyhms') }}" />
    <button type="submit" class="btn btn-success pull-right">Pay</button>
  </form>

Routing.yml

postPayment:
     pattern:  /payment/{id}
     defaults: { _controller: FLYBookingsBundle:Pay:postPayment }

getSuccessPayment:
     pattern:  /success/{id}
     defaults: { _controller: FLYBookingsBundle:Pay:getSuccessPayment }

PayController.php

class PayController extends Controller
{

    public function postPayment (Commandes $commande)
    {
        $params = array(
            'cancelUrl' => 'here you should place the url to which the users will be redirected if they cancel the payment',
            'returnUrl' => 'here you should place the url to which the response of PayPal will be proceeded', // in your case             //  you have registered in the routes 'payment_success'
            'amount' => $commande->get('priceTTC'),
        );

        session()->put('params', $params); // here you save the params to the session so you can use them later.
        session()->save();

        $gateway = Omnipay::create('PayPal_Express');
        $gateway->setUsername('xxxxxxxxx-facilitator_api1.gmail.com'); // here you should place the email of the business sandbox account
        $gateway->setPassword('xxxxxxxxxxxxxx'); // here will be the password for the account
        $gateway->setSignature('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); // and the signature for the account
        $gateway->setTestMode(true); // set it to true when you develop and when you go to production to false
        $response = $gateway->purchase($params)->send(); // here you send details to PayPal

        if ($response->isRedirect()) {
            // redirect to offsite payment gateway
            $response->redirect();
        }
        else {
            // payment failed: display message to customer
            echo $response->getMessage();
        }
    }

.

public function getSuccessPayment (Auth $auth, Transaction $transaction)
    {
        $gateway = Omnipay::create('PayPal_Express');
        $gateway->setUsername('xxxxxxxxxxx-facilitator_api1.gmail.com\''); // here you should place the email of the business sandbox account
        $gateway->setPassword('xxxxxxxxxxxxxxxx'); // here will be the password for the account
        $gateway->setSignature('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); // and the signature for the account
        $gateway->setTestMode(true);
        $params = session()->get('params');
        $response = $gateway->completePurchase($params)->send();
        $paypalResponse = $response->getData(); // this is the raw response object

        if(isset($paypalResponse['PAYMENTINFO_0_ACK']) && $paypalResponse['PAYMENTINFO_0_ACK'] === 'Success') {
            // here you process the response. Save to database ...

        }
        else {
            // Failed transaction ...
        }
    }
}

person Sirius    schedule 27.03.2016    source источник
comment
Это больше похоже на проблему symfony, чем на проблему omnipay. То, что вы делаете там в своем действии контроллера, выглядит правильно с точки зрения omnipay, но сообщение об ошибке, похоже, указывает на то, что маршрутизатор symfony не находит ваш контроллер. Я не эксперт по symfony, но, возможно, действие вашего контроллера должно называться postPaymentAction вместо postPayment?   -  person delatbabel    schedule 28.03.2016
comment
Я удалил маршрут в routing.yml и создал маршрут поверх моего контроллера следующим образом: /** * * @Route("/", name="pay") * @Method("GET") */ затем в validation.html.twig я изменил путь на pay. Кажется, это работает, но когда я нажимаю кнопку оплаты, она перенаправляет меня на пустую страницу. http://127.0.0.1/symfony/web/app_dev.php/?id=34 . я думаю, что я должен быть перенаправлен на PayPal, чтобы пользователь мог сделать платеж...?   -  person Sirius    schedule 28.03.2016
comment
я также изменил postPayment на postPaymentAction. Теперь у меня есть эта ошибка: Attempted to call function "session" from namespace "FLY\BookingsBundle\Controller" session()->put('params', $params); Думаю, я знаю, почему у меня много ошибок, потому что мой контроллер предназначен для работы с laravel, а не с symfony2.   -  person Sirius    schedule 28.03.2016
comment
Да, вы не можете использовать контроллеры laravel с symfony или наоборот.   -  person delatbabel    schedule 29.03.2016


Ответы (1)


Вызываемый метод контроллера Symfony должен заканчиваться словом Action.

public function postPayment(...) --> public function postPaymentAction(...)

Затем некоторые из ваших методов контроллера не являются валидными для symfony, вместо этого они кажутся основанными на laravel.

// Laravel
session()->put('params', $params); // here you save the params to the session so you can use them later.
session()->save();

-->
// Symfony

use Symfony\Component\HttpFoundation\Request;

public function postPaymentAction(Commandes $commande, Request $request)

$request->getSession(); // The request should be incldued as an action parameter
$session->set('params', $params);

Затем, что касается использования самого Omnipay, я бы сказал, что использование сторонней библиотеки внутри контроллера Symfony — ужасная практика.

Вместо этого я рекомендую вам использовать службу и передавать свои учетные данные из ее конфигурации (возможно, параметры).

http://symfony.com/doc/current/service_container.html

// Direct, bad practice
$gateway = Omnipay::create('PayPal_Express');
$gateway->setUsername('xxxxxxxxx-facilitator_api1.gmail.com'); // here you should place the email of the business sandbox account
$gateway->setPassword('xxxxxxxxxxxxxx'); // here will be the password for the account
$gateway->setSignature('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); // and the signature for the account
$gateway->setTestMode(true); // set it to true when you develop and when you go to production to false

$response = $gateway->purchase($params)->send(); // here you send details to PayPal

У вас даже уже есть сторонний пакет для этого:

https://github.com/colinodell/omnipay-bundle

// Using a Service to get a full-configured gateway
$gateway = $this->get('omnipay')->getDefaultGateway();

$response = $gateway->purchase($params)->send();

Вы также можете заблокировать методы HTTP в файле маршрутизатора, даже если это необязательно:

postPayment:
     pattern:  /payment/{id}
     method:   POST
     defaults: { _controller: FLYBookingsBundle:Pay:postPayment }

getSuccessPayment:
     pattern:  /success/{id}
     method:   GET
     defaults: { _controller: FLYBookingsBundle:Pay:getSuccessPayment }
person Flo Schild    schedule 01.09.2016
comment
Спасибо за ответ. Я уже нашел решение своей проблемы, я решил использовать экспресс-оплату Paypal с Payum. В моем следующем проекте я попытаюсь использовать Omnipay, и ваш ответ будет полезен. :) - person Sirius; 02.09.2016