Last active
September 26, 2017 07:14
-
-
Save danvbe/79c7f557f37a473dedea to your computer and use it in GitHub Desktop.
Sonata PayPal issue fix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" ?> | |
<!-- Application\Sonata\PaymentBundle\Resources\config\payment.xml --> | |
<!-- TODO: Remember to load it in you app/config/config.yml --> | |
<container xmlns="http://symfony.com/schema/dic/services" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | |
<parameters> | |
<parameter key="sonata.payment.method.paypal.class">Application\Sonata\PaymentBundle\Component\Paypal</parameter> | |
</parameters> | |
</container> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Created by PhpStorm. | |
* User: danvbe | |
* Date: 7/25/14 | |
* Time: 2:49 PM | |
*/ | |
namespace Application\Sonata\PaymentBundle\Component; | |
use Sonata\Component\Payment\Paypal as BasePaypal; | |
use Sonata\Component\Order\OrderInterface; | |
use Sonata\Component\Payment\TransactionInterface; | |
class Paypal extends BasePaypal{ | |
/** | |
* {@inheritdoc} | |
*/ | |
public function sendbank(OrderInterface $order) | |
{ | |
$params = array( | |
'order' => $order->getReference(), | |
'bank' => $this->getCode(), | |
'check' => $this->generateUrlCheck($order), | |
); | |
$fields = array( | |
// paypal specific | |
'cmd' => '_xclick', | |
'charset' => 'utf-8', | |
'business' => $this->getOption('account'), | |
'cert_id' => $this->getOption('cert_id'), | |
'no_shipping' => '1', // client cannot add shipping address | |
'lc' => 'EN', // user interface language | |
'no_note' => '1', // no comment on paypal | |
// invoice information | |
'invoice' => $order->getReference(), | |
//FIRST CHANGE IS HERE | |
'amount' => round($order->getTotalInc(),2), | |
//SECOND CHANGE IS HERE | |
'currency_code' => $order->getCurrency()->getLabel(), | |
'item_name' => 'Order ' . $order->getReference(), | |
'bn' => 'Sonata/1.0', // Assign Build Notation for PayPal Support | |
// user information, for prepopulated form (paypal side) | |
'first_name' => $order->getBillingName(), | |
'last_name' => '', | |
'address1' => $order->getBillingAddress1(), | |
'address2' => $order->getBillingAddress2(), | |
'city' => $order->getBillingCity(), | |
'zip' => $order->getBillingPostcode(), | |
'country' => $order->getBillingCountryCode(), | |
// Callback information | |
'custom' => $this->generateUrlCheck($order), | |
'notify_url' => $this->router->generate($this->getOption('url_callback'), $params, true), | |
// user link | |
'cancel_return' => $this->router->generate($this->getOption('url_return_ko'), $params, true), | |
'return' => $this->router->generate($this->getOption('url_return_ok'), $params, true), | |
); | |
if ($this->getOption('debug', false)) { | |
$html = '<html><body>' . "\n"; | |
} else { | |
$html = '<html><body onload="document.getElementById(\'submit_button\').disabled = \'disabled\'; document.getElementById(\'formPaiement\').submit();">' . "\n"; | |
} | |
$method = $this->getOption('method', 'encrypt'); | |
$html .= sprintf('<form action="%s" method="%s" id="formPaiement" >' . "\n", $this->getOption('url_action'), 'POST'); | |
$html .= '<input type="hidden" name="cmd" value="_s-xclick">' . "\n"; | |
$html .= sprintf('<input type="hidden" name="encrypted" value="%s" />', call_user_func(array($this, $method), $fields)); | |
$html .= '<p>' . $this->translator->trans('process_to_paiement_bank_page', array(), 'PaymentBundle') . '</p>'; | |
$html .= '<input type="submit" id="submit_button" value="' . $this->translator->trans('process_to_paiement_btn', array(), 'PaymentBundle') . '" />'; | |
$html .= '</form>'; | |
$html .= '</body></html>'; | |
if ($this->getOption('debug', false)) { | |
echo "<!-- Encrypted Array : \n" . print_r($fields, 1) . "-->"; | |
} | |
$response = new \Symfony\Component\HttpFoundation\Response($html, 200, array( | |
'Content-Type' => 'text/html' | |
)); | |
$response->setPrivate(true); | |
return $response; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function sendConfirmationReceipt(TransactionInterface $transaction) | |
{ | |
if (!$transaction->isValid()) { | |
return new \Symfony\Component\HttpFoundation\Response(''); | |
} | |
$params = $transaction->getParameters(); | |
$params['cmd'] = '_notify-validate'; | |
//$this->getLogger()-> | |
/* | |
// retrieve the client | |
$client = $this | |
->getWebConnectorProvider() | |
->getNamedClient($this->getOption('web_connector_name', 'default')); | |
$client->request('POST', $this->getOption('url_action'), $params); | |
*/ | |
//I HAVE USED CURL HERE TO MAKE IT WORK ! | |
$ch = curl_init(); | |
curl_setopt($ch,CURLOPT_URL, $this->getOption('url_action')); | |
curl_setopt($ch,CURLOPT_POST, true); | |
curl_setopt($ch,CURLOPT_POSTFIELDS, $params); | |
$result = curl_exec($ch); | |
//if ($client->getResponse()->getContent() == 'VERIFIED') { | |
if ($result == 'VERIFIED') { | |
$transaction->setState(TransactionInterface::STATE_OK); | |
$transaction->setStatusCode(TransactionInterface::STATUS_VALIDATED); | |
$transaction->getOrder()->setValidatedAt(new \DateTime); | |
$transaction->getOrder()->setStatus(OrderInterface::STATUS_VALIDATED); | |
$transaction->getOrder()->setPaymentStatus(TransactionInterface::STATUS_VALIDATED); | |
} else { | |
$transaction->setState(TransactionInterface::STATE_KO); | |
$transaction->setStatusCode(TransactionInterface::STATUS_ERROR_VALIDATION); | |
// TODO error in status -> setting payment status to an order status value | |
$transaction->getOrder()->setPaymentStatus(OrderInterface::STATUS_ERROR); | |
if ($this->getLogger()) { | |
$this->getLogger()->emergency('[Paypal::sendAccuseReception] Paypal failed to check the postback'); | |
} | |
} | |
return new \Symfony\Component\HttpFoundation\Response(''); | |
} | |
} |
Thank's a lot man
Hey, I think there is another way:
- Override Paypal Method
parameters:
sonata.payment.method.paypal.class: Application\Sonata\PaymentBundle\Paypal\Services\Paypal
- Create Listener on PaymentEvents::PRE_CALLBACK
use Sonata\Component\Payment\PaymentSelectorInterface;
use Buzz\Browser;
class PaymentSubscriber implements EventSubscriberInterface {
/**
*
* @var BasePaypal
*/
private $browser;
/**
*
* @var PaymentSelectorInterface
*/
private $selector;
public function __construct(PaymentSelectorInterface $selector, Browser $browser) {
$this->selector = $selector;
$this->browser = $browser;
}
public static function getSubscribedEvents() {
return array(
PaymentEvents::PRE_CALLBACK => 'preCallback'
);
}
/**
* Set Browser in paypal payment method
*
* @param PaymentEvent $event
*/
public function preCallback(PaymentEvent $event) {
if ($event->getTransaction()->getPaymentCode() == 'paypal') {
$paypalMethod = $this->selector->getPayment($event->getTransaction()->getPaymentCode());
$paypalMethod->setWebConnectorProvider($this->browser);
}
}
}
- Register subscriber
application.payment.listeners.payment_subscriber:
class: Application\Sonata\PaymentBundle\Listeners\PaymentSubscriber
arguments: ["@sonata.payment.selector.simple", "@sonata.payment.browser.curl"]
tags:
- { name: kernel.event_subscriber }
- In Paypal method
public function sendConfirmationReceipt(TransactionInterface $transaction) {
if (!$transaction->isValid()) {
return new Response('ko', 404, array(
'Content-Type' => 'text/plain',
));
}
$params = $transaction->getParameters();
$params['cmd'] = '_notify-validate';
$browser = $this->getWebConnectorProvider()->submit($this->getOption('url_action'), $params);
if ($browser->getContent() == 'VERIFIED') {
$transaction->setState(TransactionInterface::STATE_OK);
$transaction->setStatusCode(TransactionInterface::STATUS_VALIDATED);
$transaction->getOrder()->setValidatedAt(new \DateTime());
$transaction->getOrder()->setStatus(OrderInterface::STATUS_VALIDATED);
$transaction->getOrder()->setPaymentStatus(TransactionInterface::STATUS_VALIDATED);
} else {
$transaction->setState(TransactionInterface::STATE_KO);
$transaction->setStatusCode(TransactionInterface::STATUS_ERROR_VALIDATION);
// TODO error in status -> setting payment status to an order status value
$transaction->getOrder()->setPaymentStatus(OrderInterface::STATUS_ERROR);
if ($this->getLogger()) {
$this->getLogger()->emergency('[Paypal::sendAccuseReception] Paypal failed to check the postback');
}
}
return new Response('ok', 200, array(
'Content-Type' => 'text/plain',
));
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you so much. It work for me.