Jump to content

Paypal et paiements différés


pppplus

Recommended Posts

Bonjour

Petit soucis, avec les paiements paypal différés.

Lorsque le paiement Paypal est mis en différé, la commande passe en erreur.
Ensuite, lorsque le paiement paypal est validé définitivement (après 5-10 jours en général), la commande n'est pas validée.

Y a-t-il une solution simple qui gèrerait ça facilement ?

Je suis en prestashop 1.2.5 (et ne peut pas mettre à jour, trop de développements à refaire) et j'utilise Paypal v1.6

En gros, je cherche une modif qui mettrait le paiement paypal différé en attente (comme un paiement par chèque par exemple) et lorsque paypal valide, la validation du paiement se fait automatiquement.

Si vous avez déjà quelque chose qui fonctionne, je suis preneur!
Et si ça n'existe pas, il faudra l'inventer...

J'ai recherché sur le forum, et je n'ai rien vu de tel, ce qui m'étonne un peu, car le cas a dû se produire de nombreuses fois. Merci d'avance si vous avez des infos.

Link to comment
Share on other sites

Si, Paypal envoie bien une nouvelle confirmation une fois le paiement définitivement validé.

Je suis en train de finir la modification du script. Normalement pour demain, puisque sandbox ne voulait plus marcher pour moi depuis 16h.
J'ai récupéré des bouts de codes de différentes version, pour faire un script qui marche avec la 1.2.5

La validation manuelle n'est pas possible, mon client a entre 300 et 500 commandes par jour. Et en Allemagne, c'est 1 paiement sur 10 qui passe en différé. Le volume à traiter est trop énorme.

Link to comment
Share on other sites

Voilà le script entier de /paypal/validation.php

J'ai pris des bouts de codes de différentes versions pour en faire un qui marche.
ATTENTION : marche uniquement sur PS 1.2.5 (à tester pour les autres versions)

<?php

include(dirname(__FILE__).'/../../config/config.inc.php');
include(dirname(__FILE__).'/paypal.php');

$errors = '';
$result = false;
$paypal = new Paypal();

// Fill params
$params = 'cmd=_notify-validate';
foreach ($_POST AS $key => $value)
   $params .= '&'.$key.'='.urlencode(stripslashes($value));

// PayPal Server
$paypalServer = 'www.'.(Configuration::get('PAYPAL_SANDBOX') ? 'sandbox.' : '').'paypal.com';

// Getting PayPal data...
if (function_exists('curl_exec'))
{
   // curl ready
   $ch = curl_init('https://' . $paypalServer . '/cgi-bin/webscr');

   // If the above fails, then try the url with a trailing slash (fixes problems on some servers)
    if (!$ch)
       $ch = curl_init('https://' . $paypalServer . '/cgi-bin/webscr/');

   if (!$ch)
       $errors .= $paypal->getL('connect').' '.$paypal->getL('curlmethodfailed');
   else
   {
       curl_setopt($ch, CURLOPT_POST, true);
       curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
       curl_setopt($ch, CURLOPT_HEADER, false);
       curl_setopt($ch, CURLOPT_TIMEOUT, 30);
       curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

       $result = curl_exec($ch);

       if ($result != 'VERIFIED')
           $errors .= $paypal->getL('curlmethod').$result.' cURL error:'.curl_error($ch);
       curl_close($ch);
   }
}
elseif (($fp = @fsockopen('ssl://' . $paypalServer, 443, $errno, $errstr, 30)) || ($fp = @fsockopen($paypalServer, 80, $errno, $errstr, 30)))
{
   // fsockopen ready
   $header = 'POST /cgi-bin/webscr HTTP/1.0'."\r\n" .
         'Host: '.$paypalServer."\r\n".
         'Content-Type: application/x-www-form-urlencoded'."\r\n".
         'Content-Length: '.Tools::strlen($params)."\r\n".
         'Connection: close'."\r\n\r\n";
   fputs($fp, $header.$params);

    $read = '';
    while (!feof($fp))
   {
       $reading = trim(fgets($fp, 1024));
       $read .= $reading;
       if (($reading == 'VERIFIED') || ($reading == 'INVALID'))
       {
            $result = $reading;
           break;
       }
    }
   if ($result != 'VERIFIED')
       $errors .= $paypal->getL('socketmethod').$result;
   fclose($fp);
}
else
   $errors = $paypal->getL('connect').$paypal->getL('nomethod');

// Printing errors...
if ($result == 'VERIFIED') {
   if (!isset($_POST['mc_gross']))
       $errors .= $paypal->getL('mc_gross').'
';
   if (!isset($_POST['payment_status']))
       $errors .= $paypal->getL('payment_status').'
';
   elseif ($_POST['payment_status'] != 'Completed')
       $errors .= $paypal->getL('payment').$_POST['payment_status'].'
';
   if (!isset($_POST['custom']))
       $errors .= $paypal->getL('custom').'
';
   if (!isset($_POST['txn_id']))
       $errors .= $paypal->getL('txn_id').'
';
   if (!isset($_POST['mc_currency']))
       $errors .= $paypal->getL('mc_currency').'
';

   if (empty($errors))
   {
       $cart = new Cart(intval($_POST['custom']));
       if (!$cart->id)
           $errors = $paypal->getL('cart').'
';
       elseif ($id_IPNOrder = Order::getOrderByCartId(intval($_POST['custom'])))
       {
           $errors = $paypal->getL('order').'
';
           if($_POST['payment_status']=='Completed')
               IPN_Status_Update($id_IPNOrder, $_POST['payment_status'], true);
       }
       else
       {
           $paypal->validateOrder($_POST['custom'], _PS_OS_PAYMENT_, floatval($_POST['mc_gross']), 
                                   $paypal->displayName, $paypal->getL('transaction').$_POST['txn_id']);
       }
   }
} else {
   $errors .= $paypal->getL('verified');
}

if (!empty($errors) AND isset($_POST['custom']))
{
   if ($_POST['payment_status'] == 'Pending')
       $paypal->validateOrder(intval($_POST['custom']), _PS_OS_PAYPAL_, floatval($_POST['mc_gross']), $paypal->displayName, $paypal->getL('transaction').$_POST['txn_id'].'
'.$errors);

   else
       $paypal->validateOrder(intval($_POST['custom']), _PS_OS_ERROR_, 0, $paypal->displayName, $errors.'
');
}

function IPN_Status_Update($idIPNOrder, $Status, $notify) {

   global $errors, $paypal;

   // The order already exists, so we need to update the order history.
   $lastIPNOrderStatus = OrderHistory::getLastOrderState($idIPNOrder);
   if (!Validate::isLoadedObject($lastIPNOrderStatus))
   {
       die(Tools::displayError());
   }
   $history = new OrderHistory();
   $history->id_order = $idIPNOrder;

   $history->changeIdOrderState(intval(_PS_OS_PAYMENT_), intval($idIPNOrder));

   if ($notify && (_PS_OS_PAYMENT_!=$lastIPNOrderStatus->id_order_state)) {
       if (!$history->addWithemail())
           $paypal->_errors[] = Tools::displayError($paypal->getL('emailnotsent'));
   } else {
       $history->add();
   }
   // Update the message in the BackOffice log too; handy for error checking
   // $errors will contain detail specific to the IPN, and is set in the switch code block above
   $errors .= 'Payment status change received: '.$Status;
   $msg = new Message();
   if (!Validate::isMessage($errors))
       $errors = $paypal->l('Payment message is not valid, please check your module!');
   $msg->message = $errors;
   $msg->id_order = intval($idIPNOrder);
   $msg->private = 1;
   $msg->add();
}

?>



N'hésitez pas à poster vos remarques en cas de pb.
Testé à de nombreuses reprises sur la sandbox, et est en production depuis 2 jours sans remontée d'erreurs pour l'instant.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...