IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Paypal ExpressCheckOut


Sujet :

Langage PHP

  1. #21
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    tu mets quoi dans $encoded_data ?

    Voici un appel :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    $settings = array(
        'USER' => 'abc',
        'PWD' => 'def',
        'SIGNATURE' => 'ijk',
        'METHOD' => 'SetExpressCheckout'
    );
     
    $data = array(
        'PAYMENTREQUEST_0_CURRENCYCODE' => '...',
        'PAYMENTREQUEST_0_AMT' => '123', // montant total,
        'PAYMENTREQUEST_0_PAYMENTACTION' => '...', // ,
        // ...
    );
     
    $defaults = array(
    	CURLOPT_POST => 1,
    	CURLOPT_HEADER => 0,
    	CURLOPT_URL => $url,
    	CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1",
    	CURLOPT_FRESH_CONNECT => 1,
    	CURLOPT_RETURNTRANSFER => 1,
    	CURLOPT_FORBID_REUSE => 1,
    	CURLOPT_TIMEOUT => 0,
    	CURLOPT_SSL_VERIFYPEER => 0,
    	CURLOPT_SSL_VERIFYHOST => 0,
    	CURLOPT_POSTFIELDS => http_build_query(array_merge($data, $settings), '', "&")
    );
     
    $ch = curl_init();
     
    curl_setopt_array($ch, $defaults);
     
    $result = curl_exec($ch);
     
    if ($result)
    {
        // analyse du résultat
        $data = explode('&', $data);
        $arr  = array();
     
        foreach ($data as $k => $v)
        {
    	$tmp = explode('=', $v);
    	$arr[$tmp[0]] = urldecode($tmp[1]);
        }
    }
    L'appel part d'un serveur n'utilisant pas SSL.

    Tout est dans la doc : ici avec des exemples à chaque étape

  2. #22
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 228
    Points : 60
    Points
    60
    Par défaut
    Je ne pige justement pas à quoi sert cette fonction "curlPost($encoded_data)" dans l'exemple que j'ai trouvé ... A priori ça n'est utilisé que dans un "if " (si on utilise curl alors ...).

    J'ai du mal à penser PHP en fait aussi. Mais ça va venir.

    Bref, si je comprends bien, ton exemple est dans le ipnlistener.php mais en fait les données (par exemple "PAYMENTREQUEST_0_AMT") viennent du ipn.php ?

    En fait, ipnlistener.php est transparent et utilisé par Paypal pendant que l'internaute est sur le site Paypal ? Il y a un "va et vient" entre Paypal et mon ipnlistener.php. Moi je pensais qu'il était exécuté quand l'internaute revenait vers mon site.

    Si ce que je dis est correct, alors je ne comprends pas pourquoi les traitement se font dans ipn.php (insertion de la commande en base par exemple).

    J'ai un peu l'impression de tout mélanger et de ne pas être clair.

  3. #23
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    L'IPN est le script d'analyse de la réponse automatique de PayPal.

    Suppose que le client traîne sur le site de Paypal et qu'il ferme le navigateur au dernier moment sans finaliser l'opération. Toi dans ta boutique tu ne peux pas savoir si la transaction a bien été finalisée vu que PayPal ne te permet pas de suivre le déroulement de la transaction une fois le client connecté à sa plateforme, pour toi, tout reste opaque pour des raisons de sécurité et de confidentialité.

    Donc PayPal ne va pas te laisser en carafe et va recontacter automatiquement ton site sur une URL que tu auras défini au préalable (&RETURNURL=) pour te passer des informations sur le déroulement de la transaction, le fameux message IPN (Instant Payment Notification). En cas de problème, PayPal va tenter de prévenir ton site pendant 4 jours à intervalles réguliers en réexpédiant l'IPN autant de fois que nécessaire. Pour y mettre fin, il est bon de prévenir le site PayPal en lui expédiant un simple header("HTTP/1.1 200 OK"); à la fin du script d'écoute. Donc ce script (ipn.php) qui ne reçoit uniquement que des données techniques relatives au déroulement du processus de paiement peut s'occuper directement du back-office de la commande en fonction du résultat reçu : la valider, la mettre en attente...

    De ton côté tu peux aussi redemander les détails de la transaction en reformulant une demande avec la directive &METHOD=GetExpressCheckoutDetails.

    Dans tous les cas, tu dois obligatoirement définir le paiement dans sont intégralité lors du premier appel à la plateforme PayPal, s'il est accepté, tu recevras le jeton de sécurité rattaché. Une fois reçu, les détails du paiement ne peuvent être modifiés. La moindre modification doit être reformulée via un nouveau processus de demande de paiement.

    Bienvenue dans le merveilleux monde du paiement en ligne (j'sais pas si tu dois après intégrer un paiement sécurisé ATOS en lien avec une banque quelconque, parce que c'est encore une autre problématique, savoureuse aussi )

  4. #24
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 228
    Points : 60
    Points
    60
    Par défaut
    Hello, non, pour le moment mon client n'a pensé qu'à Paypal lol. Ca me saoule assez de perdre autant de temps sur ce truc là.

    En tout cas au moins quand tu expliques je comprends C'est très gentil de ta part.

    Par contre, petit détail :

    Si je comprends bien, l'IPN (que l'internaute ne voit pas) doit gérer tout ce qui est technique (insertion en base, etc.) et le RETURNURL ne sert qu'à l'affichage pour l'internaute ? Mais alors comment recevoir les données dans les deux ?

  5. #25
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Je n'ai pas été exhaustif, désolé, tu dois utiliser la directive notify_url (attention, la syntaxe diffère en fonction de la forme d'appel de la plateforme (html form, rest, soap)) pour brancher dessus ton script ipn.php. Tu peux aussi procéder autrement et te dire que tant que le client n'est pas revenu sur ton site, c'est que la transaction est en suspens, du coup tu peux loger la notification ipn dans la fonction de traitement du retour du client, quand le client revient sur la boutique (&RETURNURL=), tu lances un appel manuel à paypal pour récupérer l'ipn (c'était le sens (pas claire, je te l'accorde) de ma réponse précédente).

    Bon garde la première solution, elle est plus simple et pense à activer l'ipn sur la plateforme PayPal pour ton site.

  6. #26
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 228
    Points : 60
    Points
    60
    Par défaut
    Ok, voilà en fait ce que j'ai dans mon formulaire de départ :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <input type="hidden" name="cancel" value="http://domaine.fr/cancel.php">
    <input type="hidden" name="return" value="http://domaine.fr/retour.php">
    <input type="hidden" name="notify_url" value="http://domaine.fr/ipn.php">
    Donc ça c'est bon ? L'IPN est bien activé sur Paypal.

    Je n'avais effectivement pas compris que RETURN devait recontacter Paypal (grâce au TOKEN ?..). En fait ce que j'essaye de faire est de récupérer les données de l'IPN dans RETURNURL. Donc ça ne pourra jamais fonctionner ... Le principe est maintenant clair. Je pensais que Paypal revenait sur IPN qui lui devait renvoyer sur RETURNURL.

    Plus qu'à trouver comment faire lol.

  7. #27
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Tu peux très bien demander manuellement les détails de la transaction à PayPal :
    avec un truc de ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $paypal_data = array(
    	'TOKEN' => $data['paypal']['token'],
    	'PAYERID' => $data['paypal']['payerid'],
    	'METHOD' => 'DoExpressCheckoutPayment',
    	'PAYMENTREQUEST_0_NOTIFYURL' => $url('payment/paypal/ipn'),
    	'RETURNFMFDETAILS' => 1
    );
    Mais bon après il va falloir te plonger encore bien plus loin dans la doc.

    Sache que l'api de PayPal est gigantesque, très modulaire et souple. C'est prévu à la base pour te passer intégralement de leur interface.
    Il est tout à fait possible de créer entièrement une interface dédiée à PayPal dans une application d'entreprise, ainsi tu peux gérer très finement les actions possibles en ce qui concerne le suivi des commandes/paiements/factures pour chaque type d'utilisateur.
    PayPal est une véritable banque en ligne.

  8. #28
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 228
    Points : 60
    Points
    60
    Par défaut
    Désolé du retard, j'ai dû m'occuper d'un autre client en urgence ...

    Je regarde tout ça. Mais donc si j'ai bien tout compris, les pages IPN et RETURN ne sont aucunement liées l'une à l'autre ?

    Merci en tout cas.

  9. #29
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 228
    Points : 60
    Points
    60
    Par défaut
    Rien à faire !

    Quand ça veut pô, ça veut pô

  10. #30
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 228
    Points : 60
    Points
    60
    Par défaut
    Bonjour Rawsrc,

    J'ai repris de zéro mais non, ça ne marche pas.

    En fait, mon IPN est ok dans Paypal Tools mais quand je test ensuite, l'insertion en base ne fonctionne pas. Il doit donc rester un problème. Je suis loin de la page "return" ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    <?php
        $paypalmode = 'sandbox'; //Sandbox for testing or empty ''
        $dbusername     = 'DB_Username'; //db username
        $dbpassword     = 'DB_Password'; //db password
        $dbhost     = 'DB_IP'; //db host
        $dbname     = 'DB_Name'; //db name
     
    if($_POST)
    {
            if($paypalmode=='sandbox')
            {
                $paypalmode     =   '.sandbox';
            }
            $req = 'cmd=' . urlencode('_notify-validate');
            foreach ($_POST as $key => $value) {
                $value = urlencode(stripslashes($value));
                $req .= "&$key=$value";
            }
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'https://www'.$paypalmode.'.paypal.com/cgi-bin/webscr');
            curl_setopt($ch, CURLOPT_HEADER, 0);
            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_HTTPHEADER, array('Host: www'.$paypalmode.'.paypal.com'));
            $res = curl_exec($ch);
            curl_close($ch);
     
            if (strcmp ($res, "VERIFIED") == 0)
            {
                $transaction_id = $_POST['txn_id'];
                $payerid = $_POST['payer_id'];
                $firstname = $_POST['first_name'];
                $lastname = $_POST['last_name'];
                $payeremail = $_POST['payer_email'];
                $paymentdate = $_POST['payment_date'];
                $paymentstatus = $_POST['payment_status'];
                $mdate= date('Y-m-d h:i:s',strtotime($paymentdate));
                $otherstuff = json_encode($_POST);
     
                $conn = mysql_connect($dbhost,$dbusername,$dbpassword);
                if (!$conn)
                {
                 die('Could not connect: ' . mysql_error());
                }
     
                mysql_select_db($dbname, $conn);
     
                // insertion en base
                $query = "INSERT INTO ibn_table
                (itransaction_id,ipayerid,iname,iemail,itransaction_date, ipaymentstatus,ieverything_else)
                VALUES
                ('$transaction_id','$payerid','$firstname $lastname','$payeremail','$mdate', '$paymentstatus','$otherstuff')";
     
                if(!mysql_query($query))
                {
                    //mysql error..!
                }
                mysql_close($conn);
            }
    }
    ?>

  11. #31
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    Un conseil avant d'arriver au traitement post IPN :
    Souvent les gens oublient que la réponse de Paypal doit être décodée avant lecture :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $pp_decoder = function($p)
    {
        $data = array();
     
        foreach (explode('&', $p) as $k => $v)
        {
            $tmp           = explode('=', $v);
            $data[$tmp[0]] = urldecode($data[1]);
        }
     
        return $data;
    };
    J'espère que tu y a pensé.

    IPN :

    Tu peux récupérer parfois des espaces intempestifs dans la réponse, remplace par ceci : $res = trim(curl_exec($ch));.
    strcmp() renvoie du typé donc tu il est préférable de faire comme ça : if (strcmp($res, "VERIFIED") === 0)Ensuite tu ne devrais pas faire aveuglément confiance à la réponse de PayPal : il serait préférable de bien s'assurer de la présence des clés du tableau $_POST avant de manipuler leur valeur.

    Tu ne sécurises rien avec ce code ^^ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $query = "INSERT INTO ibn_table
    (itransaction_id,ipayerid,iname,iemail,itransaction_date, ipaymentstatus,ieverything_else)
    VALUES
    ('$transaction_id','$payerid','$firstname $lastname','$payeremail','$mdate', '$paymentstatus','$otherstuff')";
    Log le déroulé du code et voit où il s'arrête.

  12. #32
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 228
    Points : 60
    Points
    60
    Par défaut
    Non, je n'avais pas pensé au décodage Je dois décoder les données avant le et ensuite les ré-encoder pour les renvoyer dans le POST ? Bizarrerie ça ...

    Ok pour le trim et pour le triple = ça, j'ai pigé.

    Pour la vérification des données, tu veux dire que je dois faire un pour chaque donnée reçue ?

    Par contre, qu'entends par la sécurisation de ma requête ?

  13. #33
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    C'est pas bizarre du tout : tu communiques avec un serveur de paiement :
    - tu encodes correctement tes requêtes,
    - tu les soumets au serveur,
    - tu reçois ses réponses,
    - tu les décodes,
    - tu les analyses et traites
    - et tu repars pour un tour.

    C'est une procédure tout ce qu'il y a de plus standard.

    Pour vérifier la présence des clés dans la réponse de PayPal, un simple isset() suffit. empty() englobe le isset() et pousse plus loin la vérification : ici

    Sécuriser une requête en base de données veut tout simplement dire échapper les données dangereuses, chose que tu ne fais pas du tout dans ton INSERT.

    EDIT :
    Si tu devais installer un paiement de type carte bancaire avec un établissement bancaire standard, tu devrais encoder toutes les requêtes via un binaire spécifique et décoder les réponses via un autre binaire avant de pouvoir les analyser et les traiter avec ton appli

  14. #34
    Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    228
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 228
    Points : 60
    Points
    60
    Par défaut
    Je sais que c'est normal rassures toi Mais du coup je ne vois pas où placer ça. Je trouve ça bizarre avant le POST ...

    Dans mon if VERIFIED, j'ai placé mes isset if (isset($_POST['txn_id'])) {($transaction_id = $_POST['txn_id'];} J'ai bien compris la différence. C'est effectivement mieux qu'un !empty.

    Pour la sécurité de la requête, tu suggère d'utiliser mysql_query et mysql_real_escape_string pour éviter les injections où je fais encore fausse route ? Humf, je viens de piger sorry : http://www.php.net//manual/fr/function.mysql-query.php

    Donc ça c'est correct ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (isset($_POST['txn_id'])) {($transaction_id = mysql_real_escape_string(htmlspecialchars($_POST['txn_id']));}
    Bon, ben finalement, ça change rien Marche pô !!!

Discussions similaires

  1. [PayPal] Intégration complète en PHP
    Par HALOMOTO dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 7
    Dernier message: 24/01/2010, 20h19
  2. paypal dans un freeware ?
    Par gregcat dans le forum Windows
    Réponses: 2
    Dernier message: 12/05/2006, 17h22
  3. Problème avec paypal
    Par Coussati dans le forum Applications
    Réponses: 7
    Dernier message: 04/03/2006, 23h41
  4. Site internet avec dons PAYPAL
    Par LhIaScZkTer dans le forum E-Commerce
    Réponses: 7
    Dernier message: 25/01/2006, 16h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo