Paypal IPN не работает, но отправка данных работает

Я использую симулятор PayPal IPN здесь: https://developer.paypal.com/webapps/developer/applications/ipn_simulator

для отправки информации в приложение, созданное с помощью symfony2 и пакета payum (старая версия symfony и пакета).

Он определенно попадает в приложение по URL-адресу уведомления (поэтому это не проблема брандмауэра), потому что в базе данных хранится запись с именем платежа и датой. Однако «подробности» не сохраняются.

Однако, если я использую Rest Client для POST по URL-адресу с данными, как предлагается здесь: https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNintro/#id08CKFJ00JYK

Затем запись сохраняется с именем платежа, датой и деталями!!

Это проблема с симулятором IPN? Я действительно не уверен, что здесь происходит, может быть, я мог бы попытаться как-то зарегистрировать объект запроса?


person timhc22    schedule 28.08.2015    source источник
comment
Привет! ты вообще решил этот вопрос? Я борюсь с прослушивателем IPN, и я просто не получаю никаких сведений о запросе от Paypal в объекте. Это просто Payum\Core\Request\Notify с инициализацией платежного токена =(   -  person hsb1007    schedule 18.08.2016
comment
Эй, это было давно, поэтому я не могу полностью вспомнить, что я сделал, но я помню, как это исправил. Я думаю, что это связано с необходимостью изменить некоторые настройки на стороне Paypal. постараюсь узнать, смогу ли я узнать   -  person timhc22    schedule 20.08.2016
comment
@ hsb1007 проверь мой ответ   -  person timhc22    schedule 20.08.2016


Ответы (1)


@ hsb1007 Я думаю, что это было то, что я наконец использовал. Но я почти уверен, что на стороне PayPal были некоторые настройки, которые были основной проблемой. Я просто помню, как много-много тестировал и ждал

<?php
namespace LabIT\CMSBundle\EventListener;

use Buzz\Client\ClientInterface;
use Exception;
use LabIT\CMSBundle\Entity\Payments\DetailsInterface;
use LabIT\CMSBundle\Helper\ApiHelper;
use LabIT\CMSBundle\Helper\PaymentHelper;
use LabIT\CMSBundle\Helper\SubscriptionHelper;
use LabIT\CMSBundle\Helper\UserHelper;
use Payum\Core\Action\PaymentAwareAction;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\Request\Notify;
use Payum\Paypal\Ipn\Api;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Log\LoggerInterface;

class PaymentListener extends PaymentAwareAction
{
/**
 * @var UserHelper
 */
protected $userHelper;
/**
 * @var PaymentHelper
 */
protected $paymentHelper;

/**
 * @var ApiHelper
 */
protected $apiHelper;

/**
 * @var SubscriptionHelper
 */
protected $subscriptionHelper;

/**
 * @var LoggerInterface
 */
protected $logger;
/**
 * @var
 */
protected $buzz;
/**
 * @var
 */
protected $sandbox;
/**
 * @var
 */
protected $paypalValidation;

/**
 * @param UserHelper $userHelper
 * @param PaymentHelper $paymentHelper
 * @param ApiHelper $apiHelper
 * @param SubscriptionHelper $subscriptionHelper
 * @param LoggerInterface $logger
 * @param ClientInterface $buzz
 * @param $sandbox
 * @param $paypalValidation
 */
public function __construct(
    UserHelper $userHelper,
    PaymentHelper $paymentHelper,
    ApiHelper $apiHelper,
    SubscriptionHelper $subscriptionHelper,
    LoggerInterface $logger,
    ClientInterface $buzz,
    $sandbox,
    $paypalValidation
) {
    $this->userHelper = $userHelper;
    $this->paymentHelper = $paymentHelper;
    $this->apiHelper = $apiHelper;
    $this->subscriptionHelper = $subscriptionHelper;
    $this->logger = $logger;
    $this->buzz = $buzz;
    $this->sandbox = $sandbox;
    $this->paypalValidation = $paypalValidation;
}

/**
 * {@inheritDoc}
 *
 * This is where all the IPNs from paypal get processed, acts in some ways like a controller
 *
 * @param Notify $request
 */
public function execute($request)
{
    $data = $_POST;

    // would be better to get this dynamically. It is the payment name defined in config,
    // but also forms part of the url set in the paypal notification backend
    $paymentName = 'post_a_job_with_paypal'; // todo maybe get this from the url

    $this->logger->notice('IPN received');
    // validate with paypal so it stops notifying (do this first because needs to be done within 30 seconds)
    if (true === $this->paypalValidation) {
        $this->validateWithPaypal($this->getPaypalArray());
    }

    $notificationDetails = $this->paymentHelper->createPaymentNotification($paymentName, $data);

    // todo other inspections of data? check email?

    $user = $this->paymentHelper->getNotificationUser($notificationDetails, $data);

    // these are only done for individual transactions //TODO STORE TRANSACTIONS IN TABLE?
    if (isset($data['txn_id'])) {
        $this->paymentHelper->getTransactionProcessed($data['txn_id']); // so don't process more than once //TODO ADD BACK IN AFTER ADDING TRANSACTION CLASS
        $this->subscriptionHelper->determineUserMembership($user, $notificationDetails); // automatically demote if payment fails
        $this->apiHelper->sendPaymentNotifications($user, $notificationDetails); // notify affiliates
        $this->paymentHelper->setTransactionProcessed($data['txn_id']); //set transaction to processed //TODO ADD BACK IN AFTER ADDING TRANSACTION CLASS
    }

    // handle recurring payment data (recurring payment info, but not recurring payment transaction
    if (isset($data['recurring_payment_id']) && !isset($data['txn_id'])) {
        $this->paymentHelper->setRecurringPaymentStatus($data);
        // cron job will determine user membership level because needs to check timestamp
    }
}
/**
 * {@inheritDoc}
 */
public function supports($request)
{
    return $request instanceof Notify;
}

/**
 * Send data back to paypal so paypal knows it was delivered successfully
 *
 * @param array $data
 *
 * @throws Exception
 */
protected function validateWithPaypal(array $data)
{
    $this->logger->notice('I am here');

    $options = array();
    $options['sandbox'] = $this->sandbox;
    $api = new Api($this->buzz, $options);

    // Verify the IPN via PayPal
    if (Api::NOTIFY_VERIFIED !== $api->notifyValidate($data)) {
        $this->logger->notice('paypal validation UNSUCCESSFUL');
        throw new Exception('Invalid IPN');
    }

    $this->logger->notice('paypal validation SUCCESSFUL');
    return;
}

/**
 * @return array
 */
protected function getPaypalArray()
{
    // Read POST data
    // reading posted data directly from $_POST causes serialization
    // issues with array data in POST. Reading raw POST data from input stream instead.
    $raw_post_data = file_get_contents('php://input');
    $raw_post_array = explode('&', $raw_post_data);
    $myPost = array();
    foreach ($raw_post_array as $keyval) {
        $keyval = explode ('=', $keyval);
        if (count($keyval) == 2)
            $myPost[$keyval[0]] = urldecode($keyval[1]);
    }
    return $myPost;
}
person timhc22    schedule 20.08.2016