Bonjour,

J'ai suivi le tuto 'Paiement Paypal' sur le site.
J'ai compris globalement le système et suis parvenu à quasi terminer d'installer le système à une exception prêt.

Je ne suis pas parvenu à comprendre comment était utilisé "file_put_contents".

J'ai cru comprendre qu'il fallait créer un fichier, j'ai donc créé "log.txt" et fait quelques modifications mais en vain.

Le code initial :

               if ($email_account == $receiver_email) {
                file_put_contents('log', print_r($_POST,true));
                $db = new PDO("mysql:host=localhost;dbname=insectelevage", "root", "");
                $req = $db->query('SELECT * FROM offers WHERE price='.$payement_amount.' LIMIT 1');
                $d = $req->fetch(PDO::FETCH_ASSOC);
                if(!empty($d)){
                    $duration = $d['duration'];
                    $uid = $custom['user_id'];
                    $data = serialize($_POST);
                //On met à jour la date d'expiration    
                    $db->query('UPDATE users3 SET expiration = DATE_ADD(NOW(), INTERVAL '.$duration.' MONTH) WHERE id = '.$uid);
                //On sauvegarde la commande
                $db->query("INSERT INTO orders SET user_id=$uid, amount=$payement_amount, created=NOW(), datas='$data'")
                    file_put_contents('log', 'Le paiement effectué avec success');
                }else{
                    file_put_contents('log', 'Le paiement ne correspond à aucune offre');

                }

Merci d'avance pour votre aide =)

25 réponses


Apache a t'il les droit pour ecrire dans ton fichier ?

Il y a une manipulation à faire pour s'en assurer ?

Ou se trouve ton fichier ?
Unix ou Windows ?

Windows.
Je travaille avec Wamp : J'ai vu un sous dossier : "Logs".
J'ai mis mon fichier dedans. J'ai essayé de le renommer en log ou log.txt
Sans succès :/.
Dans ce sous-dossier, il y a par contre des fichiers déjà existants :
access.log - apache_error.log - log_dir - mysql.log - php_error.log

Ton script essais d'ecrire dans un fichier appelé log au meme niveau que la ou est placé ton script.
Si le fichier n'existe pas il le créé sinon il l'ecrase.
(cf doc : http://php.net/manual/fr/function.file-put-contents.php)

Bonsoir.
Et quel est ton problème ?
Tu demande de l'aide, mais tu ne dis pas quel est ton problème.

Le fichier log qu'essaye d'acceder ton file_put_contents('log', ...
se trouve dans le meme dossier que ton script et non pas dans le dossier log de wamp ^.^

Merci pour vos réponses.
Je l'ai remis dans le dossier ou se trouve mon script (oui j'avais essayé aussi =p ).
J'ai oublié d'indiquer le message d'erreur :
"Parse error: syntax error, unexpected 'file_put_contents' (T_STRING)"

Mon dernier message pourrait laisser penser que le problème est réglé, mais toujours pas =/

L'erreur apparaît à quelle ligne ? Le premier file_put_contents() ?

C'est le second étrangement

Normal :

$db->query("INSERT INTO orders SET user_id=$uid, amount=$payement_amount, created=NOW(), datas='$data'")

Tu n'as pas mis de ; à la fin de cette ligne.

Hum ... Ca c'est fait --'. Merci.
"Heureusement", le problème n'est pas résolu pour autant ...

Notice: Undefined index: item_name

Ca concerne les lignes indiquées.
C'est pas une erreur de syntaxe cette fois-ci

$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
$item_name = $_POST['item_name'];                                                                        //Ligne concernée
$item_number = $_POST['item_number'];                                                               //Ligne concernée
$payment_status = $_POST['payment_status'];                                                     //Ligne concernée
$payment_amount = $_POST['mc_gross'];                                                               //Ligne concernée
$payment_currency = $_POST['mc_currency'];                                                      //Ligne concernée
$txn_id = $_POST['txn_id'];                                                                                         //Ligne concernée
$receiver_email = $_POST['receiver_email'];                                                         //Ligne concernée
$payer_email = $_POST['payer_email'];                                                                   //Ligne concernée
parse_str($_POST['custom'],$custom);                                                                    //Ligne concernée

Est-ce que les valeurs $_POST de ces lignes sont définies dans le formulaire ?

Affirmatif. Mais le formulaire se trouve dans un autre fichier.
Est-ce qu'un print_r($_POST) ne permettrait pas de résoudre cela ?

Donc, les données postées par le formulaire, ne sont pas transmises au fichier de ce code, c'est ça ?

En effet
Voici le formulaire dans un fichier

<h1>Choix de la formule</h1>
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<select name="amount">
<?php 
$req = $db->query('SELECT * FROM offers');
while($d = $req->fetch(PDO::FETCH_ASSOC)){
?>
<option value="<?php echo $d['price']; ?>"><?php echo $d['name']; ?> - <?php echo $d['price']; ?> euros</option>
<?php
}
?>
</select>
<input name="currency_code" type="hidden" value="EUR"/>
<input name="shipping" type="hidden" value="0.00"/>
<input name="tax" type="hidden" value="0.00"/>
<input name="return" type="hidden" value="localhost/success.php"/>
<input name="cancel_return" type="hidden" value="localhost/cancel.php"/>
<input name="notify_url" type="hidden" value="localhost/ipn.php"/>
<input name="cmd" type="hidden" value="_xclick"/>
<input name="business" type="hidden" value="seller-bambou-tennisman@hotmail.com"/>
<input name="item_name" type="hidden" value="Compte premium"/>
<input name="no_note" type="hidden" value="1"/>
<input name="lc" type="hidden" value="FR"/>
<input name="bn" type="hidden" value="PP-BuyNowBF"/>
<input name="custom" type="hidden" value="user_id=1"/>
<input type="submit" value="s'abonner">
</form>

Et les variables dans un autre fichier

$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
parse_str($_POST['custom'],$custom);

Tu passe bien par le formulaire pour executer le fichier ipn.php ?

En fait je constate que les variables définies ne proviennent pas du formulaire.
c'est un scénario qui me semble assez complexe. La validation du formulaire redirige vers Paypal.
Paypal doit, j'imagine, lui aussi renvoyer des informations.
Je vais chercher de mon côté. Merci pour votre aide =)

Ok, je suis quand même allé voir le code source du tutoriel et en fait, il est plutôt vieux ce tutoriel (septembre 2011 d'après les sources)
Il est donc possible qu'il ne soit plus fonctionnel, tu peux essayer d'apporter la modification suivante au cas où pour voir (elle est quand même de 2013, donc elle ne corrigera pas forcément ton problème.

problème avec les headers, il faut ajouter $header .= "Host: www.sandbox.paypal.com\r\n";

$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Host: www.sandbox.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

Source : https://gist.github.com/Grafikart/1201602#comment-879399

Mais d'après les commentaires du tutoriel, cela ne corrige pas le problème.

Oui j'avais vu quelqu'un d'autre qui avait ajouté cela mais le problème n'a pas été résolu (et je confirme).
Dommage ...
Encore merci à tous et bonne soirée =)

Sinon tu peux tester avec Paypal Express Checkout, ce tutoriel semble toujours être fonctionnel d'après des commentaires plutôt récent (quelques mois).
De rien et bonne soirée également.

Oui j'ai vu également ce tuto. Je comptais passer par là.

Tient, voila le code que j'utilise pour mon ipn paypal ( ca fonctionne parfaitement chez moi )
Pense a activer CURL sans quoi le script ne fonctionnera pas et a bien lire les commentaires que j'ai ecrit :)

<?php
define("DEBUG", 1);

define("USE_SANDBOX", 1); // Set le a 0 pour la version LIVE de ton script
define("LOG_FILE", "log"); // Ton fichier log

$email_account = "email@email.com"; // email

$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]);
}

$req = 'cmd=_notify-validate';
if(function_exists('get_magic_quotes_gpc')) {
    $get_magic_quotes_exists = true;
}
foreach ($myPost as $key => $value) {
    if($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) {
        $value = urlencode(stripslashes($value));
    } else {
        $value = urlencode($value);
    }
    $req .= "&$key=$value";
}

if(USE_SANDBOX == true) {
    $paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr";
} else {
    $paypal_url = "https://www.paypal.com/cgi-bin/webscr";
}

$ch = curl_init($paypal_url);
if ($ch == FALSE) {
    return FALSE;
}

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);

if(DEBUG == true) {
    curl_setopt($ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
}

curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close'));

$res = curl_exec($ch);
if (curl_errno($ch) != 0) // cURL error
    {
    if(DEBUG == true) { 
        error_log(date('[Y-m-d H:i e] '). "Impossible de se connecter a paypal" . curl_error($ch) . PHP_EOL, 3, LOG_FILE);
    }
    curl_close($ch);
    exit;

} else {
        if(DEBUG == true) {
            error_log(date('[Y-m-d H:i e] '). "HTTP request:". curl_getinfo($ch, CURLINFO_HEADER_OUT) ." IPN payload: $req" . PHP_EOL, 3, LOG_FILE);
            error_log(date('[Y-m-d H:i e] '). "HTTP response: $res" . PHP_EOL, 3, LOG_FILE);
            list($headers, $res) = explode("\r\n\r\n", $res, 2);
        }
        curl_close($ch);
}

if (strcmp ($res, "VERIFIED") == 0) {
    //Tes variables
    $item_name = $_POST['item_name'];
$item_number = $_POST['item_number'];
$payment_status = $_POST['payment_status'];
$payment_amount = $_POST['mc_gross'];
$payment_currency = $_POST['mc_currency'];
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];
    parse_str($_POST['custom'],$custom);
    //Tes variables

    if ( $email_account == $receiver_email) {
            //Tout est good a partir d'ici
    }
    if(DEBUG == true) {
        error_log(date('[Y-m-d H:i e] '). "IPN VERIFIER: $req ". PHP_EOL, 3, LOG_FILE);
    }
} else if (strcmp ($res, "INVALID") == 0) {
    if(DEBUG == true) {
        error_log(date('[Y-m-d H:i e] '). "IPN Invalide: $req" . PHP_EOL, 3, LOG_FILE);
    }
}
?>

Super ! Merci =)
Je vais travailler sur cela.