[PHP-cURL] – Come ottenere il saldo disponibile dalla tua postepay


Salve ragazzi,

su richesta di un nostro lettore (antonio), scriverò un piccolo tutorial in php su come usare la mia classe cURL per recuperare automaticamente il saldo disponibile dalla nostra postepay…

Un pò quello che fa gia il mio software Renewal Reminder che tramite interfacciamento al sito delle poste italiane (in quel caso in .NET), riesce a recuperare il credito disponibile nella carta….

Torniamo al tutorial, quello che vi serve è:


  • Iscrizione al sito delle poste
  • Postepay personale
  • Classe cUrl (scaricabile qui)

Bene, iniziamo col creare un nuovo file php in cui andremo ad includere la classe cUrl PHP. La chiameremo esempio.php e per ora conterrà il codice:

<?php
ob_start();
include 'libs/curl.class.php';
?>

Bene abbiamo integrato la classe e inibito gli output delle chiamate, fatto questo iniziamo a creare 3 variabili che conterranno il nostro nome utente per accedere a poste.it, la nostra password, ed il numero della carta postepay.

$utente = "Nome.Cognome";
$pass = "svdesign";
$carta = "4023600612345678";

Ok, ora non ci resta che valorizzare una variabile con la nostra classe, ed andare ad effettuare le chiamate in https al server della posta, difficile? Nient’affatto!

Quindi per valorizzare la variabile scriviamo:

$curl = new cUrl();

ed ecco la prima richiesta al sito delle poste:

$var = $curl->cPost("https://bancopostaonline.poste.it/bpol/CARTEPRE/Logon.fcc", "USER=".$utente."&Password=".$pass."&btnSubmit=Invia&target=/bpol/cartepre/RedirectionGateway.ashx?type=SMACCESS&device_id=[[[INACCESSIBLE]]]");

Come potete vedere, abbiamo fatto una richiesta POST al server in cui inviamo il nostro nome utente e password per loggarci nel sito.

Non dovete tener conto dei cookie e delle sessioni, in quanto se ne occuperà tranquillamente la mia classe cUrl PHP 😉

Andiamo ora alla seconda richiesta:

$var2 = $curl->cGet("https://bancopostaonline.poste.it/bpol/cartepre/servizi/cartapostepay/cartapostepay.aspx?pnlstart=listamovimenti");

Questa volta è una richiesta GET, infatti andiamo semplicemente a caricare la pagina in cui ci viene chiesto il numero di carta per visualizzare la lista movimenti…. per quale motivo?

Semplicemente perché il sito delle poste, come qualunque altro sito sicuro, invia un token per controllare che non ci sia stato un furto di sessione bypassando il sistema di login.

Quello che faremo ora è recuperare tramite una semplice espressione regolare questo codice dal sorgente della pagina ricevuto dalla richiesta GET, in modo da poterlo inviare nelle richieste successive ed eludere il sistema di controllo del token.

Il Token incriminato è nella variabile __VIEWSTATE, ed ecco il codice:

$s1 = preg_match('#<input type="hidden" name="__VIEWSTATE" value="([^>]+)"#', $var2, $req);

In questo modo nell’array di cattura $req avremo il valore del viewstate da inviare nella terza richiesta che sarà quindi POST:

$var3 = $curl->cPost("https://bancopostaonline.poste.it/bpol/cartepre/servizi/cartapostepay/cartapostepay.aspx?pnlstart=listamovimenti", urlencode("CartaPostePaySelezionaCarta1:btnEsegui") . "=Esegui&" . urlencode("CartaPostePaySelezionaCarta1:txtNrCartaPre") . "=".$carta."&" . urlencode("CartaPostePaySelezionaCarta1:cmbLista") . "=40&__VIEWSTATE=". urlencode($req[1]));

In questa richiesta come potete vedere andiamo ad inviare tutti gli elementi del form presente nella lista movimenti e quindi: Il tasto invia dati, la casella di testo che dovrebbe contenere il numero di carta con il nostro numero di carta,  il numero di movimenti da visualizzare (non provate a cambiarli, la posta va solo con 40 movimenti purtroppo), ed infine il token __viewstate per dire che siamo sempre noi.

Bene nella variabile $var3 abbiamo finalmente il contenuto della lista movimenti con i nostri 40 movimenti e il saldo contabile e disponibile con cui fare ciò che vogliamo quindi possiamo benissimo chiudere la connessione alla classe cURL e ripulire l’output come segue:

$curl->close();

ob_end_clean();

Per completezza del tutorial scrivo anche come ottenere il valore del saldo disponibile in una variabile con annessa spiegazione di ciò che ho fatto:

$intestatario = (int)strpos($var3, "Intestatario:");
$datacontabile = (int)strpos($var3, "DATA CONTABILE");

$pezzo = $datacontabile - $intestatario;

$pezzo1 = substr($var3, $intestatario, $pezzo);

$colonne = explode('<td nowrap="nowrap" align="Right">', $pezzo1);

$finenumero = strpos($colonne[3], "<");

$saldo = substr($colonne[3], 1, $finenumero-1);

echo $saldo;

Spiegando il codice:

Abbiamo rilevato, con strpos, le posizioni dei testi “Intestatario” e “Data contabile” che sono univoci nella pagina.
Dopodiché otteniamo il numero di lettere da salvare facendo una semplice sottrazione, e infine lo tagliamo con substr partendo dall’indice dell’intestatario.

Ora separiamo in un array le colonne fatte dai td del pezzo ottenuto prima, che sono esattamente 3.

Alla fine del saldo otterremo dei tag html, quindi con strpos otteniamo l’apertura del primo tag, e con substr tagliamo dall’indice 1 (l’indice 0 contiene una semplice +) fino ad 1 numero prima dell’apertura del tag.

Qui il file di esempio da scaricare direttamente: esempio

Spero di essere stato utile 😉



45 Commenti

  1. Filippo ha detto:

    Ciao,

    volevo usare la tua classe per autenticarmi sul sito

    http://traffico.octotelematics.it/php/login.php

    che mostra la situazione del traffico in tempo reale.

    Ho fatto uno script veramente essenziale, tanto per provare a vedere cosa ottenevo, ma il risultato è una pagina con solo scritto “1”. Dove sbaglio?

    Lo script è il seguente:

    cPost(“http://traffico.octotelematics.it/php/login.php”, “email=”.$miaemail.”&password=”.$miapassword.”&formsubmitted=TRUE&Login=Login”);

    $curl->close();
    ob_end_clean();
    echo $pagina;
    ?>

    • Filippo ha detto:

      il commento è stato segato all’inizio dello script, che conteneva anche la seguente parte:

      ob_start();
      include ‘curl.class.php’;
      $miaemail= “”;
      $miapassword = “”;

      $curl = new cUrl();

      $pagina = $curl->cPost(…..

      • Stefano Venneri ha detto:

        Ciao, come puoi vedere dal sorgente della classe, la funzione per i dati GET ha il parametro:

        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER,1);

        che restituisce il sorgente della pagina, mentre il POST non ce l’ha..

        Quindi o dopo il post fai una richiesta get sulla pagina di destinazione, o semplicemente copi questo parametro nella function cPost.

        • Filippo ha detto:

          Ciao, grazie, ha funzionato. Solo che non capisco una cosa: se faccio il GET della pagina con la situazione del GRA di Roma:

          $paginahome = $curl->cGet(“http://traffico.octotelematics.it/traffic.html?fr=-1”);

          e la stampo mediante echo, ottengo a video la pagina con tanto di link di logout, che mi fa capire che l’autenticazione è avvenuta con successo. Vorrei però che lo script restituisse un’immagine specifica:

          $my_img = imagecreatefromgif(“http://traffico.octotelematics.it/dynamic/1.gif?ts=1”);
          header( “Content-type: image/gif” );
          imagegif( $my_img );
          imagedestroy( $my_img );

          ma ottengo un errore dovuto al fatto che il sistema mi vede di nuovo come non connesso e mi chiede di autenticarmi (lo vedo se prelevo l’immagine col GET e la stampo con echo). Secondo te, perché?

          Mi sapresti consigliare?

          Grazie ancora,
          Filippo

          • Stefano Venneri ha detto:

            Premetto che vado per congetture:

            Probabilmente il problema è da attribuire alla funzione “imagecreatefromgif” che va a richiamare l’immagine singolarmente.. mi spiego meglio:

            Quando vengono effettuate le chiamate, per essere collegate l’una all’altra, la mia classe gestisce anche i cookie e le sessioni, e quindi permette di aprire qualsiasi cosa come se loggato.

            Quando tu invece richiami l’immagine con “imagecreatefromgif”, questa funzione richiama l’immagine come se tu non avessi mai fatto il log…

            SOLUZIONE: Richiama l’immagine in GET con la classe,e salva l’output in una nuova immagine temporanea con fopen(“miaimmagine.gif”, “w”);

            dopodiché richiami questa immagine appena creata con “imagecreatefromgif”.. se così funziona hai individuato il problema.

          • Filippo ha detto:

            Il problema è che quando prelevo l’immagine con

            $gif = $curl->cGet(“http://traffico.octotelematics.it/dynamic/1.gif?ts=1”);

            se faccio

            echo $gif;

            ottengo una pagina in cui mi si dice che non sono connesso e mi devo autenticare. Quindi credo sia inutile salvarla in maniera temporanea…

          • Stefano Venneri ha detto:

            Puoi mandarmi lo script per email? Cosi provo a cercare il problema.

  2. Stefano Venneri ha detto:

    Ti scrivo le richieste che effettuo in renewals reminder, cosi provi tu stesso in php 😉

    GET: https://www.paypal.com/it/cgi-bin/webscr?cmd=_home
    Poi prendo la action del primo tag form che trovo,e gli mando in post i campi.

    Nell’action presa del form mi ricavo il valore della variabile dispatch.

    Faccio un post quindi su: https://www.paypal.com/it/cgi-bin/webscr?cmd=_login-submit&dispatch=” & dispatch
    Inviando i dati di login..

    Dopodiché l’autoredirect porterà all’account e quindi si potranno parsare i codici html per prelevare il credito.

    • giorgio delfini ha detto:

      Preciso, tempestivo e gentilissimo, come sempre 🙂 Provo al volo e speriamo bene.

      • giorgio delfini ha detto:

        Ciao, e’ perfetto, le indicazioni che mi hai dato, mi hanno tolto il 90% del carico.
        Ho solo dovuto dargli una “spintarella” in quanto l’autoredirect girava all’infinito senza darmi la pagina, cosi’ ho fatto una chiamata GET in piu’, dando in pasto al link di destinazione il token ricavato da regexp.
        Grazie mille,
        Giorgio.

    • matteo s ha detto:

      scusate,
      riesco a rispondere a commenti esistenti, ma non a postarne uno nuovo… è normale..?

  3. Giorgio Delfini ha detto:

    Ciao, non capisco invece come fare ad ottenere il saldo da paypal sempre con la classe cURL, come per la postepay.
    C’e’ un passaggio di dati tra un link e l’altro, con pausa di 3 secondi, e li’ perdo i dati; ho provato anche ricostruendo i cookies con preg_match(), e preg_match_all(), ma il risultato non cambia. Invece con il Renewals Reminder sotto Net Framework, funziona….. Aiuto !!!
    Giorgio.

  4. Bruno ha detto:

    Ciao, hanno cambiato completamente il sito…
    ho cercato di adattare lo script ma non riesco a fare nemmeno il login.
    E pure mi sembra strano…

    mettendo questi valori:
    $var = $curl->cPost(“https://postepay.poste.it/servizi_online/app_login/login.fcc”, “USER=”.$utente.”&PASSWORD”.$pass.”&bottone.x=34&bottone.y=11&target=%2Fportalppay%2FstartBenvenutoAction.do&smquerydata=&smauthreason=&smagentname=&postpreservationdata=&device_id=%5B%5B%5BINACCESSIBLE%5D%5D%5D”);

    Dovrebbe loggarsi, ma non lo fa.
    Hanno cambiato qualche altra cosa che mi sfugge secondo te?

  5. Dario ha detto:

    Ciao, ma la classe cURL che hai fatto funziona anche per recuperare contenuti anche in altri tipi di siti?

  6. Stefano Venneri ha detto:

    @giorgio delfini: Ho provato cosi velocemente, e mi logga perfettamente, però durante la richiesta della pagina che restituisce il credito mi butta fuori al login.

    Ti ho mandato anche una mail a riguardo con alcuni passi che sbagliavi..

    • giorgio delfini ha detto:

      ciao, sei incappato nello stesso mio problema, tutto bene fino al fetch della pagina del saldo. Siccome la mail che mi hai inviato, non e’ arrivata, ti prego di reinviarmela nuovamente, sono davvero curioso di sapere i passi che ho sbagliato, mi darebbe nuovi spunti per fare altri tentativi…
      Ti ringrazio in anticipo, e faccio tanti Auguri di Buone Feste a tutto il blog. Giorgio.

  7. giorgio delfini ha detto:

    Ciao, un articolo molto interessante, ho provato anche qualche variante con la funzione stristr(), e devo dire che la soluzione mi soddisfa di piu’. Un problema che ho riscontrato, e’ che non riesco a far funzionare lo script con il nuovo sito, postepay.it; esaminando i post-data con tamper data, vedo che non c’e’ la __VIEWSTATE, i dati in get passano solo tramite JSESSIONID, e riesco a parserizzarli; viene invece passato in post un numero univoco di 16 digits, (8 zeri, e altre 8 cifre), che corrisponde all’assegnazione carta, che e’ in parte coperta da asterischi.
    Come dicevo, una volta estratto questo valore con strpos(), e inviato insieme alla stringa di parametri postdata, lo script restituisce un bel NULL, e non capisco perche’…..

    • Stefano Venneri ha detto:

      Ciao, appena ho un briciolo di tempo farò delle prove e scriverò come ho risolto, o se è un procedimento lungo scriverò un altro articolo 😉

      • giorgio delfini ha detto:

        Ciao, scusa per l’intrusione; sei poi riuscito a fare qualcosa a riguardo, o non hai avuto tempo? Stavo leggendo un articolo interessante su “Flash, per inviare i dati in maniera asincrona.”, quando mi sono ricordato che nei parametri inviati, c’e’ proprio un riferimento a dei dati post-data inviati sotto estensione .swf…. Magari non c’entra niente, magari invece… Aspetto fiducioso sviluppi.

  8. Dr4gone ha detto:

    ho risolto in modo un po rozzo per ora 🙂
    Cosi:

    $inizio = (int)strpos($var3, “Intestatario:”);
    $fine = (int)strpos($var3, “Contattaci”);

    $pezzo = $fine – $inizio;

    $pezzo1 = substr($var3, $inizio, $pezzo);

    echo $pezzo1;
    Ma per quello che devo fare per ora è sufficente 😉

  9. StefanoV ha detto:

    Mi hai anticipato comunque si, basta fare un semplice form con le textbox

    • Dr4gone ha detto:

      Perfetto, grazie alla tua classe sono riuscito a fare una piccola app per il mio cellulare android.
      Sarebbe interessante sapere se si possono estrarre allo stesso modo i dati della lista movimenti, magari in formato csv o altro.

      Suggerimenti?

  10. Dr4gone ha detto:

    Ok ho risolto, con le texbox! 🙂

  11. Dr4gone ha detto:

    Ciao, funziona benissimo!
    Ma invece di inserire i dati Username, password e numero di carta direttamente nel file php, non si potrebbe in qualche modo fare una texbox e poi passare i valori inseriti dall’utente?

    Sto provando a farlo ma sono agli inizi, e le mie conoscenze del php sono scarse.
    Se si può fare potresti fare un esempio?

  12. antonio ha detto:

    Ora è sicuramente più comodo controllare il saldo della propria PostePay..
    Perfetto!
    Grazie. 🙂

  13. Antonio ha detto:

    Grazie! Proverò subito e ti farò sapere… 🙂

  14. StefanoV ha detto:

    Si è vero, dacci i tuoi dati d’accesso che proviamo 😛

  15. Rino Sp ha detto:

    E’ ora che tu inserisca delle Demo 😀 😀 😀

%d blogger hanno fatto clic su Mi Piace per questo: