0

ここで PayPal IPN シミュレーターを使用しています: https://developer.paypal.com/webapps/developer/applications/ipn_simulator

symfony2 と payum バンドル (古いバージョンの symfony とバンドル) で構築されたアプリケーションに情報を送信します。

支払い名と日付とともにレコードがデータベースに保存されるため、通知 URL でアプリケーションに確実に到達します (ファイアウォールの問題ではありません)。ただし、保存されている「詳細」はありません。

ただし、ここで提案されているように、Rest Client を使用してデータを含む URL に POST する場合: https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNIntro/#id08CKFJ00JYK

その後、レコードは支払いの名前と日付と詳細とともに保存されます!!

これは IPN シミュレータの問題ですか? ここで何が起こっているのかよくわかりません。リクエスト オブジェクトを何らかの方法でログに記録することはできますか?

4

1 に答える 1

0

@ hsb1007これが最終的に使用したものだと思います。しかし、主な問題であるペイパル側にいくつかの設定があったと確信しています. たくさんのテストをして待っていたのを覚えています

<?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;
}
于 2016-08-20T19:18:24.607 に答える