Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: PHP e PayPal IPN

  1. #1

    PHP e PayPal IPN

    Raga siccome ho fatto un sito di eCommerce (per il progetto di basi di dati) adesso, al di là del progetto, voglio concretizzare la fase di acquisto della merce proponendo metodi di pagamento OnLine quali PayPal e Carta di Credito.

    Riguardo PayPal ho scelto di usare il metodo di "Notifica Immediata di Pagamento" ovvero IPN ho fatto una marea di test e credo di aver raggiunto qualche risultato, finalmente, cercando un po qua ed un po la, vorrei solo dei consigli su alcune cose e magari sapere se ho proceduto bene.

    Ecco quindi la procedura che ho usato:

    1) Il cliente sceglie il metodo di pagamento PayPal e di conseguenza il pulsante "Acquista" (per finalizzare l'acquisto) avrà questo codice:
    codice:
        <form action="https://www.sandbox.paypal.com/it/cgi-bin/webscr" method="post">
            <input type="hidden" name="cmd" value="_cart">
            <input type="hidden" name="upload" value="1">
            <input type="hidden" name="business" value="...INDIRIZZO PRIMARIO PAYPALL...">
    
            <input type="hidden" name="item_name_1" value="...Nome prodotto 1...">
            <input type="hidden" name="item_count_1" value="...ID prodotto 1...">
            <input type="hidden" name="item_number_1" value="...ID prodotto 1...">
            <input type="hidden" name="quantity_1" value="...Quantita 1...">
            <input type="hidden" name="amount_1" value="...Prezzo 1...">
           
            <input type="hidden" name="item_name_X" value="...Nome prodotto X...">
            <input type="hidden" name="item_count_X" value="...ID prodotto X...">
            <input type="hidden" name="item_number_X" value="...ID prodotto X...">
            <input type="hidden" name="quantity_X" value="...quantita X...">
            <input type="hidden" name="amount_X" value="...prezzo X...">
    
            <input type="hidden" name="currency_code" value="EUR">
            <input type="hidden" name="shipping_1" value="...Costo Spedizione...">
    
            <input type="hidden" name="return" value="http://www.miosito.com/get_paypal.php?id=...SESSIONE...">
            <input type="hidden" name="cancel_return" value="http://www.miosito.com/get_paypal.php?id=...SESSIONE...">
            <input type="hidden" name="notify_url" value="http://www.miosito.com/get_paypal.php?id=...SESSIONE...">       
            <input type="image" src="http://www.sandbox.paypal.com/it_IT/i/btn/x-click-but01.gif" name="submit" alt="Effettua i tuoi pagamenti con PayPal. È un sistema rapido, gratuito e sicuro.">
        </form>

    E la pagina GET_PAYPAL.PHP invece contiene il codice preso da esempio su PayPal:
    Codice PHP:
    <?PHP

        
    // read the post from PayPal system and add 'cmd'
        
    $req 'cmd=_notify-validate';
        foreach (
    $_POST as $key => $value) {
            
    $value urlencode(stripslashes($value));
            
    $req .= "&$key=$value";
        }

        
    // post back to PayPal system to validate
        
    $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 ('www.sandbox.paypal.com'80$errno$errstr30);

        
    // assign posted variables to local 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'];

        if (!
    $fp) {
            
    // HTTP ERROR
        
    } else {
            
    fputs ($fp$header $req);
            while (!
    feof($fp)) {
                
    $res fgets ($fp1024);
                if (
    strcmp ($res"VERIFIED") == 0) {
                    
    // Verifica che payment_status è "Completed"
                    // Verifica che non hai già processato txn_id
                    // Verifica che receiver_email è la tua email primaria PayPal
                    // Verifica che payment_amount/payment_currency sono corretti
                    // Prosegui col pagamento
                    
    if ( strcmp ($payment_status"COMPLETED") == ) {
                        
    // Pagamento Completato
                        //.....
                    
    }

                }
                else if (
    strcmp ($res"INVALID") == 0) {
                    
    // log per una investigazione manuale
                    // Invio email di avviso
                    
    $mail_From "From: [email]mycommerce@noreply.com[/email]";
                    
    $mail_To "";
                    
    $mail_Subject "INVALID IPN";
                    
    $mail_Body $req;

                    foreach (
    $_POST as $key => $value){
                        
    $emailtext .= $key " = " .$value ."\n\n";
                    }
                    
    mail($mail_To$mail_Subject$emailtext "\n\n" $mail_Body$mail_From);
                }
            }
            
    fclose ($fp);
        }
    ?>

    Ora le mie domande sono:
    1) Mi conviene usare il metodo "_CART" passando quindi tutti i prodotti acquistati oppure usare "_XCLICK" passando un Titolo identificativo dello specifico ordine? (la seconda è più semplice...però la prima è più carina anche perchè permette di avere un buono storico anche su PayPal sia per il cliente che per me)

    2) Questo codice è completamente sicuro? Come può essere migliorato?

    3) Siccome dovrei gestire più metodi di pagamento come mi consigliate di strutturare la parte finale del carrello per fare in modo da standardizzare l'uso di un qualsiasi metodo?

  2. #2
    Uhm ok, quindi a te il tipo di pagamento viene scelto alla fine e come hai gestito il caricamento di una pagina piuttosto che un altra per i vari tipi di pagamento? (anche a livello di DB).

    Nel senso che se una persona sceglie di pagare con PayPal ci deve essere una FORM tipo quella di sopra, se una persona paga con carta di credito deve comparire il relativo codice per utilizzare le carte di credito, mentre se una persona sceglie bonifico gli devi visualizzare i dati per effettuare il bonifico...

    come hai gestito questa cosa?

    Io come ultima schermata ho messo un riepilogo generale dove poi c'è il tasto acquista e penso che li, una volta premuto il tasto, si deva caricare la relativa pagina per gestire i vari tipi di pagamento..

    Ti sei ispirato a qualche sito di eCommerce esistente per fare il tuo?

  3. #3
    Posso chiederti come hai gestito il carrello? Anche a livello di tabelle e sopratutto per avere un ID_CARRELLO, ID_ORDINE e le altre cose univoche gestite bene...

  4. #4
    Si, ti ringrazio...mi sei stato utile, anche se io ho strutturato questa cosa un po diversamente, essendo per l'esame di Basi di Dati ho dovuto puntare all'ottimizzazione quindi ho integrato la tabella per il "Carrello" con la tabella per gli "Ordini" dato che svolgono la stessa funzione.

    Ho solo aggiunto un campo che mi serve per sapere se quel particolare carrello si è poi concretizzato in un ordine oppure è rimasto un carrello...non so se ho reso l'idea.

    Ci ho poi aggiunto un campo per il tipo di spedizione richiesta e per il tipo di pagamento.

    Quello che sarebbe utile creare è un Trigger che ogni tanto elimina dalla tabella i carrelli che non si sono concretizzati in acquisti e che sono più vecchi di due giorni, ad esempio.

    Quello che non ho previsto è una diversificazione tra i dati di fatturazione e quelli di spedizione, tipo se uno vuole pagare a nome suo ma vuol far spedire la roba da un'altra parte...

  5. #5
    Originariamente inviato da devils_it
    X questo ho creato una funzione che dopo un giorno cancella gli ordini in sospeso nella tabella carrelo
    Ottimo...ma per fare una funzione del genere si crea cosa un trigger che a seconda della data del carrello (ed ovviamente se questo non è stato finalizzato in un ordine concreto) lo elimina?

    Me la passeresti?

    Io ho creato delle Stored Procedure per l'inserimento di un prodotto nel carrello e per l'aggiornamento/eliminazione di un prodotto dal carrello però volevo aggiungere anche questa..

  6. #6
    uhm capisco, io pensavo che l'avevi inserita proprio nella base di dati che ad esempio veniva richiamata ogni volta che si creava un nuovo carrello ed eliminava i carrelli, non diventati ordine, più vecchi di un giorno ad esempio...

  7. #7
    no raga, mi sto esaurendo....mi serve un buon modo per poter integrare più metodi di pagamento nel mio sito.

    Ho capito come funziona la gestione di PayPal ma adesso come faccio ad integrarla con successo nel mio sito?

    Io ho le tabelle fatte così (semplificandole):
    codice:
    TABLE ordini (
       idordine
       idcliente
       idpagamento
    );
    
    
    TABLE pagamento (
       idpagamento
       costo
       modulo
    );
    dove l'attributo "modulo" di pagamento ancora non esiste ma credo che io lo debba mettere per dare un indicazione sul modulo da usare.

    Ora una volta arrivati alla fine dell'acquisto a seconda del tipo di pagamento scelto (idpagamento) deve partire l'adeguata pagina di pagamento.

    Nella gestione dell'ordine ho la funzione finale che fa:
    Codice PHP:
    function finalizza() {
       
    // Memorizza gli ultimi dati relativi all'ordine
       // ...

       // Adesso devo far partire l'adeguato modulo di pagamento
       // ....come faccio ?? ...

    ecco la mia domanda è come faccio ora a gestire le varie opzioni?

    Ho pensato di creare un file (classe) per ogni tipo di pagamento in modo da rendere la cosa espandibile...ma poi come faccio a richiamare la giusta classe?

    help...

  8. #8
    raga ho risolto

    però...sapete come fare a gestire le cose magari anche con SSL ?

  9. #9
    Utente di HTML.it
    Registrato dal
    Mar 2008
    Messaggi
    1
    scusatemi ragazzi ma sono nuovissimo di questo forum e volevo sapere se qualcuno mi potesse dare una mano con l'ipn di paypal perchè cerco di testarlo su siti fittizi cioè ho un finto sito eshop in locale che mi permette di comprare un oggetto tramite paypal. Cliccando sul bottone per acquistare si passa su una pagina che salva la richiesta sul database e tramite redirect passa la palla alla sandbox di paypal (passa quindi le variabili necessarie tramite URL e non tramite form) la transazione viene portata a termine dal cliente registrato anch'esso con paypal e che alla fine viene reindirizzato sulla pagina di ringraziamento del sito eshop.
    Il mio file ipn.php apparentemente non viene neanche letto se uso il passaggio delle variabili tramite URL mentre se opto per il passaggio di dati tramite form il file viene letto da paypal ma non viene salvato nessun record sul database.
    Codice PHP:
    <?php

    ini_set
    ("SMTP","smtp.tiscali.it");
    //metti come secondo parametro l'indirizzo del server SMTP

    ini_set("smtp_port","25");
    //metti come secondo parametro il la porta del server SMTP

    ini_set("sendmail_from","mia@email.com");
    //metti come secondo parametro l'indirizzo e-mail del mittente

    mail('mia@email.com''test''è stato letto il file ipn','From: [email]altra@mail.com[/email]');


    /////////////////////////////////////////////////
    /////////////Begin Script below./////////////////
    /////////////////////////////////////////////////

    // read the post from PayPal system and add 'cmd'
    $req 'cmd=_notify-validate';
    foreach (
    $_POST as $key => $value) {
    $value urlencode(stripslashes($value));
    $req .= "&$key=$value";
    }
    // post back to PayPal system to validate
    $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 ('www.paypal.com'80$errno$errstr30);


    // assign posted variables to local variables
    $item_name $_POST['item_name'];
    $business $_POST['business'];
    $item_number $_POST['item_number'];
    $payment_status $_POST['payment_status'];
    $mc_gross $_POST['mc_gross'];
    $payment_currency $_POST['mc_currency'];
    $txn_id $_POST['txn_id'];
    $receiver_email $_POST['receiver_email'];
    $receiver_id $_POST['receiver_id'];
    $quantity $_POST['quantity'];
    $num_cart_items $_POST['num_cart_items'];
    $payment_date $_POST['payment_date'];
    $first_name $_POST['first_name'];
    $last_name $_POST['last_name'];
    $payment_type $_POST['payment_type'];
    $payment_status $_POST['payment_status'];
    $payment_gross $_POST['payment_gross'];
    $payment_fee $_POST['payment_fee'];
    $settle_amount $_POST['settle_amount'];
    $memo $_POST['memo'];
    $payer_email $_POST['payer_email'];
    $txn_type $_POST['txn_type'];
    $payer_status $_POST['payer_status'];
    $address_street $_POST['address_street'];
    $address_city $_POST['address_city'];
    $address_state $_POST['address_state'];
    $address_zip $_POST['address_zip'];
    $address_country $_POST['address_country'];
    $address_status $_POST['address_status'];
    $item_number $_POST['item_number'];
    $tax $_POST['tax'];
    $option_name1 $_POST['option_name1'];
    $option_selection1 $_POST['option_selection1'];
    $option_name2 $_POST['option_name2'];
    $option_selection2 $_POST['option_selection2'];
    $for_auction $_POST['for_auction'];
    $invoice $_POST['invoice'];
    $custom $_POST['custom'];
    $notify_version $_POST['notify_version'];
    $verify_sign $_POST['verify_sign'];
    $payer_business_name $_POST['payer_business_name'];
    $payer_id =$_POST['payer_id'];
    $mc_currency $_POST['mc_currency'];
    $mc_fee $_POST['mc_fee'];
    $exchange_rate $_POST['exchange_rate'];
    $settle_currency  $_POST['settle_currency'];
    $parent_txn_id  $_POST['parent_txn_id'];
    $pending_reason $_POST['pending_reason'];
    $reason_code $_POST['reason_code'];


    // subscription specific vars

    $subscr_id $_POST['subscr_id'];
    $subscr_date $_POST['subscr_date'];
    $subscr_effective  $_POST['subscr_effective'];
    $period1 $_POST['period1'];
    $period2 $_POST['period2'];
    $period3 $_POST['period3'];
    $amount1 $_POST['amount1'];
    $amount2 $_POST['amount2'];
    $amount3 $_POST['amount3'];
    $mc_amount1 $_POST['mc_amount1'];
    $mc_amount2 $_POST['mc_amount2'];
    $mc_amount3 $_POST['mcamount3'];
    $recurring $_POST['recurring'];
    $reattempt $_POST['reattempt'];
    $retry_at $_POST['retry_at'];
    $recur_times $_POST['recur_times'];
    $username $_POST['username'];
    $password $_POST['password'];

    //auction specific vars

    $for_auction $_POST['for_auction'];
    $auction_closing_date  $_POST['auction_closing_date'];
    $auction_multi_item  $_POST['auction_multi_item'];
    $auction_buyer_id  $_POST['auction_buyer_id'];



    //DB connect creds and email 
    $notify_email =  "mia@email.com";         //email address to which debug emails are sent to
    $DB_Server "localhost"//your MySQL Server
    $DB_Username "project"//your MySQL User Name
    $DB_Password "project"//your MySQL Password
    $DB_DBName "project"//your MySQL Database Name


    if (!$fp) {
    // HTTP ERROR
    } else {
    fputs ($fp$header $req);
    while (!
    feof($fp)) {
    $res fgets ($fp1024);
    if (
    strcmp ($res"VERIFIED") == 0) {



    //create MySQL connection
    $Connect = @mysql_connect($DB_Server$DB_Username$DB_Password)
    or die(
    "Couldn't connect to MySQL:
    mysql_error() . "
    mysql_errno());


    //select database
    $Db = @mysql_select_db($DB_DBName$Connect)
    or die(
    "Couldn't select database:
    mysql_error(). "
    mysql_errno());


    $fecha date("m")."/".date("d")."/".date("Y");
    $fecha date("Y").date("m").date("d");

    //check if transaction ID has been processed before
    $checkquery "select txnid from paypal_payment_info where txnid='".$txn_id."'";
    $sihay mysql_query($checkquery) or die("Duplicate txn id check query failed:
    mysql_error() . "
    mysql_errno());
    $nm mysql_num_rows($sihay);
    if (
    $nm == 0){

    //execute query



        
    if ($txn_type == "cart"){
        
    $strQuery "insert into paypal_payment_info(paymentstatus,buyer_email,firstname,lastname,street,city,state,zipcode,country,mc_gross,mc_fee,memo,paymenttype,paymentdate,txnid,pendingreason,reasoncode,tax,datecreation) values ('".$payment_status."','".$payer_email."','".$first_name."','".$last_name."','".$address_street."','".$address_city."','".$address_state."','".$address_zip."','".$address_country."','".$mc_gross."','".$mc_fee."','".$memo."','".$payment_type."','".$payment_date."','".$txn_id."','".$pending_reason."','".$reason_code."','".$tax."','".$fecha."')";

         
    $result mysql_query($strQuery) or die("Cart - paypal_payment_info, Query failed:
    mysql_error() . "
    mysql_errno());
         for (
    $i 1$i <= $num_cart_items$i++) {
             
    $itemname "item_name".$i;
             
    $itemnumber "item_number".$i;
             
    $on0 "option_name1_".$i;
             
    $os0 "option_selection1_".$i;
             
    $on1 "option_name2_".$i;
             
    $os1 "option_selection2_".$i;
             
    $quantity "quantity".$i;

             
    $struery "insert into paypal_cart_info(txnid,itemnumber,itemname,os0,on0,os1,on1,quantity,invoice,custom) values ('".$txn_id."','".$_POST[$itemnumber]."','".$_POST[$itemname]."','".$_POST[$on0]."','".$_POST[$os0]."','".$_POST[$on1]."','".$_POST[$os1]."','".$_POST[$quantity]."','".$invoice."','".$custom."')";
             
    $result mysql_query($struery) or die("Cart - paypal_cart_info, Query failed:
    mysql_error() . "
    mysql_errno());

         }
        }



        else{
         
    $strQuery "insert into paypal_payment_info(paymentstatus,buyer_email,firstname,lastname,street,city,state,zipcode,country,mc_gross,mc_fee,itemnumber,itemname,os0,on0,os1,on1,quantity,memo,paymenttype,paymentdate,txnid,pendingreason,reasoncode,tax,datecreation) values ('".$payment_status."','".$payer_email."','".$first_name."','".$last_name."','".$address_street."','".$address_city."','".$address_state."','".$address_zip."','".$address_country."','".$mc_gross."','".$mc_fee."','".$item_number."','".$item_name."','".$option_name1."','".$option_selection1."','".$option_name2."','".$option_selection2."','".$quantity."','".$memo."','".$payment_type."','".$payment_date."','".$txn_id."','".$pending_reason."','".$reason_code."','".$tax."','".$fecha."')";
         
    $result mysql_query("insert into paypal_payment_info(paymentstatus,buyer_email,firstname,lastname,street,city,state,zipcode,country,mc_gross,mc_fee,itemnumber,itemname,os0,on0,os1,on1,quantity,memo,paymenttype,paymentdate,txnid,pendingreason,reasoncode,tax,datecreation) values ('".$payment_status."','".$payer_email."','".$first_name."','".$last_name."','".$address_street."','".$address_city."','".$address_state."','".$address_zip."','".$address_country."','".$mc_gross."','".$mc_fee."','".$item_number."','".$item_name."','".$option_name1."','".$option_selection1."','".$option_name2."','".$option_selection2."','".$quantity."','".$memo."','".$payment_type."','".$payment_date."','".$txn_id."','".$pending_reason."','".$reason_code."','".$tax."','".$fecha."')") or die("Default - paypal_payment_info, Query failed:
    mysql_error() . "
    mysql_errno());
        }

    //inizio aggiornamento della mia tabella sul db
    $update="UPDATE tid_request SET status='commit' WHERE paldid='$business'";
    $ins_update=@mysql_query($update);
    //fine aggiornamento della mia tabella sul db

        // send an email in any case
     
    echo "Verified";
         
    mail($notify_email"VERIFIED IPN""$res\n $req\n $strQuery\n $struery\n  $strQuery2");
    }
    else {
    // send an email

    mail($notify_email"VERIFIED DUPLICATED TRANSACTION""$res\n $req \n $strQuery\n $struery\n  $strQuery2");
    }

        
    //subscription handling branch
        
    if ( $txn_type == "subscr_signup"  ||  $txn_type == "subscr_payment"  ) {

          
    // insert subscriber payment info into paypal_payment_info table
          
    $strQuery "insert into paypal_payment_info(paymentstatus,buyer_email,firstname,lastname,street,city,state,zipcode,country,mc_gross,mc_fee,memo,paymenttype,paymentdate,txnid,pendingreason,reasoncode,tax,datecreation) values ('".$payment_status."','".$payer_email."','".$first_name."','".$last_name."','".$address_street."','".$address_city."','".$address_state."','".$address_zip."','".$address_country."','".$mc_gross."','".$mc_fee."','".$memo."','".$payment_type."','".$payment_date."','".$txn_id."','".$pending_reason."','".$reason_code."','".$tax."','".$fecha."')";
          
    $result mysql_query($strQuery) or die("Subscription - paypal_payment_info, Query failed:
    mysql_error() . "
    mysql_errno());


             
    // insert subscriber info into paypal_subscription_info table
            
    $strQuery2 "insert into paypal_subscription_info(subscr_id , sub_event, subscr_date ,subscr_effective,period1,period2, period3, amount1 ,amount2 ,amount3,  mc_amount1,  mc_amount2,  mc_amount3, recurring, reattempt,retry_at, recur_times, username ,password, payment_txn_id, subscriber_emailaddress, datecreation) values ('".$subscr_id."', '".$txn_type."','".$subscr_date."','".$subscr_effective."','".$period1."','".$period2."','".$period3."','".$amount1."','".$amount2."','".$amount3."','".$mc_amount1."','".$mc_amount2."','".$mc_amount3."','".$recurring."','".$reattempt."','".$retry_at."','".$recur_times."','".$username."','".$password."', '".$txn_id."','".$payer_email."','".$fecha."')";
            
    $result mysql_query($strQuery2) or die("Subscription - paypal_subscription_info, Query failed:
    mysql_error() . "
    mysql_errno());


                 
    mail($notify_email"VERIFIED IPN""$res\n $req\n $strQuery\n $struery\n  $strQuery2");

        }
    }

    // if the IPN POST was 'INVALID'...do this


    else if (strcmp ($res"INVALID") == 0) {
    // log for manual investigation

    mail($notify_email"INVALID IPN""$res\n $req");
    }
    }
    fclose ($fp);
    }
    ?>
    questo è il mio script ipn.php dove all'inizio ho messo un invio di una email per sapere quando è stato aperto da paypal

  10. #10
    Utente di HTML.it
    Registrato dal
    Feb 2006
    Messaggi
    162
    Salve ragazzi, vorrei sapere come fate a verificare che il valore d txn_id non è già stato processato.
    Anche io sto sviluppando un sistema di iscrizioni dove l'utente si iscrive e paga tramite paypal la sua quota di iscrizione.
    Il valore txn_id essendo un valore automatico e cioè creato da paypal ad ogni pagamento non può essere inserito nel database insieme agli altri dati dell'utente al momento della sua iscrizione. La domanda è: come fate a verificare che il valore di txn_id che il sistema paypal vi reindirizza insieme al risultato della procedura (completed, failure, pending) corrisponda effettivamente a quella transazione? La domanda mi è sorta quando ho letto la riga del codice postato da leaderGL:
    // Verifica che non hai già processato txn_id
    ovviamente valore attribuito a nessun campo nel form di invio dati.

    Grazie mille!
    aspetto una vostra delucidazione
    Lothlorien

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.