All posts by mauro mascia

PayPal TLS 1.2

ATTENZIONE: Da fine gennaio 2016 la versione sandbox e dal 17 giugno 2016 30 giugno 2017 la versione di produzione consentiranno connessioni solo con TLS 1.2 e HTTP/1.1 per questioni di sicurezza. Questo vuol dire che i server sui quali sono ospitati i siti che utilizzano PayPal (e il plugin PayPal Pro Italia) hanno bisogno di una versione di OpenSSL che supporti TLS 1.2, quindi dalla versione 1.0.1c in su.

L’assenza della libreria OpenSSL con il supporto per TLS 1.2 comporta che alla ricezione delle notifiche IPN e PDT da parte di PayPal Pro (HSS) si ottenga un errore simile a questo (vedere il log):

02-10-2016 @ 18:33:46 - IPN Response: WP_Error Object
(
 [errors] => Array
  (
   [http_request_failed] => Array
    (
     [0] => error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
    )
  )
 [error_data] => Array
  (
  )
)

Tutto ciò si traduce nell’impossibilità di modificare lo stato dell’ordine.
Per questo motivo è importante che entro giugno 2016 2017 tutti i sistemi che utilizzano PayPal abbiano la OpenSSL aggiornata.

To check PHP, in a shell on your production system, run:

$ php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); var_dump(curl_exec($ch));'

On success, PayPal_Connection_OK is printed.
On failure, bool(false) will be printed.
You can get the specific error with curl_error($ch):

php -r '$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://tlstest.paypal.com/"); var_dump(curl_exec($ch)); var_dump(curl_error($ch));'

Maggiori informazioni sul problema a questi link:

GestPay errore 1142 – Identificare l’indirizzo IP corretto

Nelle ultime versioni dei plugin GestPay Starter e Pro ho inserito del codice che identifica l’indirizzo IP che interessa a GestPay: il codice effettua una chiamata (con cUrl) al sito http://icanhazip.com/ ed estrae l’indirizzo IP.
Se per qualche ragione non funzionasse, continuate pure la lettura

Quando il vostro sito è ospitato in un ambiente di hosting condiviso l’indirizzo IP del vostro sito è differente dall’indirizzo IP del server fisico, ed è questo l’indirizzo IP che interessa a GestPay. Infatti GestPay effettua una verifica anche sull’indirizzo IP, controllando che la provenienza di ogni chiamata faccia effettivamente parte degli indirizzi IP aggiunti nella pagina del backoffice GestPay (Configurazione –> Ambiente –> Indirizzi IP).

In linea di massima, per risolvere il problema dovreste contattare il vostro fornitore di hosting richiedendo il reale (o i reali) indirizzi IP da utilizzare. Questa operazione potrebbe essere difficile perché non è detto che siano tenuti a darvi tali informazioni.

Se in questo modo non fosse possibile, per conoscere l’esatto indirizzo IP del vostro Sito A (http://www.ilvostrositocongestpay.com) avete bisogno di due strumenti:

  • 1) Uno script PHP
  • 2) Un altro server su cui potete verificare il log degli accessi di un webserver

Lo script PHP, chiamiamolo per esempio gestpay-ip.php, sarà fatto in questo modo:

<?php

$ch = curl_init("http://www.tuosito.com/testpage");

curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);

?>;

e andrà inserito nella directory principale del vostro Sito A.
Questo script farà una chiamata verso un Sito B (http://www.tuosito.com).

Sull’altro server sarà presente il Sito B http://www.tuosito.com.

Mettendovi in tail sull’access.log del sito B, per esempio:

tail -f /var/log/apache2/www.tuosito.com-access.log

vedrete da quali indirizzi IP arrivano le chiamate (potreste dover aggiungere un | grep “testpage” al precedente comando).

A questo punto digitando e caricando nel browser la pagina http://www.ilvostrositocongestpay.com/gestpay-ip.php, lo script effettuerà una chiamata verso http://www.tuosito.com/testpage e nel log degli accessi vedrete l’indirizzo IP dal quale avvengono le chiamate. Ad esempio, sarà qualcosa di simile:

123.123.123.123 - - [15/Jan/2016:19:20:00 +0100] &amp;quot;GET /testpage HTTP/1.1&amp;quot; 405 363 &amp;quot;-&amp;quot; &amp;quot;Mozilla/5...

Questo indirizzo 123.123.123.123 (è un esempio!) sarà l’indirizzo IP da inserire nel backoffice di GestPay in Configurazione –> Ambiente –> Indirizzi IP.

Chiarimenti in merito all’utilizzo di GestPay (Starter/Pro) su più siti web

Con gli account GestPay Starter e GestPay Professional la comunicazione dell’esito della transazione viene effettuata da GestPay al momento del ritorno dell’utente al sito.

I passi sono questi:

  • 1) l’utente effettua il pagamento cliccando sul bottone dello shop
  • 2) arriva sulla pagina di GestPay e inserisce i dati della carta di credito
  • 3) al termine del pagamento deve cliccare su un bottone presente nella pagina di GestPay che lo riporta al sito
  • 4) tornato al sito le informazioni presenti nella URL consentono di modificare lo stato dell’ordine

Il punto 3) è quello fondamentale per la conclusione della transazione lato WooCommerce: verranno utilizzati i campi “URL risposta positiva” e “URL risposta negativa” (che vanno impostati nel backoffice di GestPay) per redirigere l’utente nel sito corretto e in base ai dati ricevuti lo stato dell’ordine verrà modificato di conseguenza (“completato” o “in lavorazione” per l’esito positivo, oppure “fallito” per l’esito negativo).

Quindi se nel campo “URL risposta positiva” avete inserito “http://www.miosito1.it/?wc-api=WC_Gateway_Gestpay_Starter” (oppure WC_Gateway_Gestpay_Pro se avete il plugin Pro) ma usate lo stesso account anche sul sito www.unaltromiosito.it allora succederà che chi conclude l’ordine su www.unaltromiosito.it verrà riportato su www.miosito1.it e quindi l’ordine non verrà completato (perché ci sarà una discordanza tra gli ordini).

Con l’account Starter non c’è nulla da fare: è possibile utilizzarlo su un solo sito perché non c’è alcun modo di distinguere il sito di partenza e questo si traduce in avere un account Starter per ogni sito che si vuole aprire.

Con l’account Professional invece è possibile distinguere il sito di partenza attraverso una procedura non proprio semplice che cerco di riassumere nei seguenti punti:

  • a) Nel backoffice di GestPay Professional bisogna abilitare un parametro custom chiamato, ad esempio, “SITO”.
  • b) Nel plugin Pro del primo sito (es. www.miosito1.it) va specificato il campo custom “SITO=sito1”
  • c) Nel plugin Pro del secondo sito (es. www.unaltromiosito.it) va specificato il campo custom “SITO=sito2”
  • d) Nel plugin Pro dell’ennesimo sito (es. www.miositoennesimo.it) va specificato il campo custom “SITO=sitoN”
  • e) Nel backoffice di GestPay va specificata la URL di ritorno positiva e negativa verso una pagina PHP che si occuperà di smistare le richieste e che può stare sul sito1, oppure sul sito2 oppure su un sito diverso
  • f) Nella pagina PHP bisogna estrarre i parametri “a” e “b” restituiti da GestPay
  • g) Grazie a questi parametri possiamo estrarre le informazioni del risultato e in particolare del campo custom “SITO”
  • h) Analizzando il valore di questo campo (che nel nostro esempio varrà “sito1” oppure “sito2” oppure “sitoN”) sappiamo da quale sito arriva la chiamata e quindi possiamo redirigere l’utente al sito corretto (riaggiungendo i parametri “a” e “b”)
  • i) L’utente arriva al sito corretto e lo stato dell’ordine cambia in base ai parametri “a” e “b”
  • Nel plugin GestPay Pro è presente un file “example_redirect-using-custominfo.php” che può servire come esempio per gestire i punti f), g) e h).
    Purtroppo questo è l’unico modo per poterlo utilizzare su più siti.

    L’alternativa è aggiungere all’account Professional anche il servizio Tokenization (per i costi del servizio riferirsi alla pagina dell’account Professional sul sito di GestPay) e usare il mio plugin GestPay Pro Tokenization (in questa pagina troverete ulteriori informazioni sui benefici del servizio Tokenization).
    Infatti, con il servizio Tokenization la comunicazione avviene Server-To-Server e non è necessario effettuare tutte le operazioni precedenti.

Create a POT file for themes and plugins


~$ cd /var/www/your-site-folder/wp-content/
~$ svn export http://i18n.svn.wordpress.org/tools/trunk/ makepot
~$ cd plugins/your-plugin-folder/languages
~$ php /var/www/your-site-folder/wp-content/makepot/makepot.php wp-plugin ../

With the last option you need to specify if you are creating a POT for a plugin or for a theme (for themes, use “wp-theme” instead of “wp-plugin”) and the last command line parameter is the plugin/theme folder (in this case ../ is pointing to /var/www/your-site-folder/wp-content/plugins/your-plugin-folder).
The resulting POT file will be saved under the “languages” folder (which of course must been already created).

GIT – merge selective files

To selectively merge files from one branch into another branch, run

git merge --no-ff --no-commit branchX

where: branchX is the branch you want to merge from into the current branch

The --no-commit option will stage the files that have been merged by Git without actually committing them. This will give you the opportunity to modify the merged files however you want to and then commit them yourself.

Depending on how you want to merge files, there are four cases:

1) You want a true merge. In this case, you accept the merged files the way Git merged them automatically and then commit them.

2) There are some files you don’t want to merge. For example, you want to retain the version in the current branch and ignore the version in the branch you are merging from.

To select the version in the current branch, run:

git checkout HEAD file1

This will retrieve the version of file1 in the current branch and overwrite the file automerged by Git.

3) If you want the version in branchX (and not a true merge), run:

git checkout branchX file1

This will retrieve the version of file1 in branchX and overwrite the file auto-merged by Git.

4) The last case is if you want to select only specific merges in file1. In this case, you can edit the modified file1 directly, update it to whatever you’d want the version of file1 to become, and then commit.

If Git cannot merge a file automatically, it will report it as “unmerged” file and produce a copy where you will need to resolve the conflicts manually.

To explain further with an example, let’s say you want to merge branchX into the current branch:

git merge --no-ff --no-commit branchX

You then run the git status command to view the status of modified files.

For example:

git status

# On branch master
# Changes to be committed:
#
#       modified:   file1
#       modified:   file2
#       modified:   file3
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       both modified:      file4

Where file1, file2, and file3 are the files git have successfully auto-merged.

What this means is that changes in the master and branchX for all those three files have been combined together without any conflicts.

You can inspect how the merge was done by running the git diff --cached file. For example:

git diff --cached file1
git diff --cached file2
git diff --cached file3

If you find some merge undesirable, you can edit the file directly, save, and then commit.

If you don’t want to merge file1 and want to retain the version in the current branch, run:

git checkout HEAD file1

If you don’t want to merge file2 and only want the version in branchX, run

git checkout branchX file2

If you want file3 to be merged automatically, don’t do anything. Git has already merged it at this point.

file4 above is a failed merge by Git. This means there are changes in both branches that occur on the same line. This is where you will need to resolve the conflicts manually. You can discard the merged done by editing the file directly or running the checkout command for the version in the branch you want file4 to become.

Finally, don’t forget to commit.

git commit

—————————————

source: http://stackoverflow.com/a/7292109/1992799

realizzare un e-commerce

Una delle situazioni ricorrenti che vengono affrontate da chi si accinge per la prima volta a creare un negozio online è quella di capire come funziona il pagamento, che differenze ci sono tra essi, se è sicuro, ecc. Insomma, per chi non ha mai affrontato il problema è normale sentirsi spaesati, un po’ come mi sentivo io diversi anni fa, quando per la prima volta creai il primo sito e-commerce.

Per questo motivo ritengo sia utile scrivere un breve articolo che parli in generale degli e-commerce e in particolare di WooCommerce per WordPress e poi scendere nei dettagli dei metodi di pagamento.

Un e-commerce altro non è che un normale sito web con in più una sezione dedicata alla vendita.

Tale sezione consta sostanzialmente di 3 componenti:

  • Una pagina dedicata ai prodotti
  • Un carrello (cart)
  • Una pagina di pagamento (checkout)

Oltre questo esiste una sezione di amministrazione dedicata alla gestione degli ordini e delle opzioni di vendita (tipologie di pagamento, email, utenti, impostazione della quantità minima acquistabile, impostazione della valuta e dei Paesi in cui vendere, gestione delle scorte del magazzino, ecc).

Andando più nel dettaglio, un e-commerce sarà realizzato più o meno così:

  • Una pagina in cui mostrare tutti i prodotti, preferibilmente “scremabili” per tipologia, caratteristiche ed eventualmente anche per prezzo se presenti in numero eccessivo.
  • Ogni prodotto avrà – preferibilmente (anche per una questione di SEO) – una propria pagina in cui verrà descritto, a parole e con alcune immagini, e avrà un bottone per l’acquisto.
  • Nella pagina del prodotto potrebbero comparire altri prodotti correlati per invogliare l’utente a proseguire con gli acquisti.
  • Quando l’utente farà click sul bottone di acquisto, l’articolo verrà aggiunto al carrello: è buona norma di vendita non portare subito l’utente al carrello perché magari vorrebbe acquistare altro. Il carrello deve comunque essere sempre ben visibile in modo da permettere all’utente di raggiungerlo velocemente (potrebbe voler modificare le quantità dei prodotti presenti, rimuoverne alcuni o concludere l’ordine pagando).
  • Ipotizzando che l’utente abbia deciso di concludere l’ordine, verrà mostrata una pagina di pagamento o checkout: a seconda del tipo di business si possono richiedere le informazioni di fatturazione più o meno dettagliate, quelle di spedizione ed eventualmente la creazione di un account utente.
  • Nel frattempo verrà creato un ordine nella sezione di amministrazione del sito con uno stato “pendente” (in attesa di pagamento).
  • Alla fine della procedura è di solito presente la scelta del metodo di pagamento: PayPal standard è uno dei metodi di pagamento più diffusi e per questo è incluso gratuitamente nell’installazione di base di WooCommerce (presumibilmente questo è vero anche per gli altri CMS). Altri metodi di pagamento, spesso forniti gratuitamente o a pagamento, consistono in un plugin che permette la comunicazione tra il sito dell’esercente e l’ente che fornisce il servizio di POS Virtuale.
  • Una volta scelto il metodo di pagamento e proceduto alla compilazione dei dati, il denaro verrà trasferito dal conto dell’acquirente a quello dell’esercente, lo stato dell’ordine di riferimento verrà modificato in “in lavorazione” o “completato” (a seconda della tipologia di prodotto) e verrà inviata un’email di conferma all’acquirente e una all’esercente.

Per realizzare tutto ciò esistono due alternative: partire da zero e sviluppare tutto (scelta non consigliata) oppure affidarsi ad un CMS (Content Management System) che farà quasi tutto quello che ci serve, molto spesso gratuitamente se ci si accontenta.

Esistono diverse piattaforme CMS già pronte e rodate per realizzare un e-commerce: Joomla con l’estensione VirtueMart, Magento, Drupal con i moduli Drupal Commerce o Ubercart, PrestaShop, OS-Commerce, WordPress con il plugin WP E-Commerce oppure con il plugin WooCommerce.

Ognuno di questi CMS (e loro varianti) ha i suoi pro e i suoi contro e in questo articolo non voglio dilungarmi sulla questione. Ma qualcuno si chiederà: “Perché WooCommerce?”

La scelta di consigliare WooCommerce, utilizzarlo costantemente ed estenderlo è data sia da un rapporto storico (è quello che utilizzo da più tempo e che conosco meglio), sia dalla ricchezza di estensioni, tale da poter soddisfare praticamente ogni tipo esigenza. Non è perfetto, questo lo si deve dire (ad esempio non esiste un plugin in grado di gestire come si deve – nel senso di esperienza utente – le spedizioni verso indirizzi multipli), ma confido nel fatto che ha quasi 6 milioni di download e che sia di proprietà di un team molto attivo (woothemes), oltre che avere una community Open Source molto ampia, per ritenerlo perfettibile. Se poi aggiungiamo che Wordpress è praticamente imbattibile in termini di diffusione, con l’attuale 23.3% del mercato globale dei siti web e il 60.7% fra i CMS (http://w3techs.com/technologies/overview/content_management/all), abbiamo una risposta chiara alla domanda di sopra.

Un metodo di pagamento di un e-commerce consiste in una serie di azioni che portano i soldi dal conto dell’acquirente a quello del venditore.

Per fare questo l’acquirente deve utilizzare una carta credito/debito o un servizio di pagamento come PayPal; il venditore deve avere un conto su cui riceverli. L’ente che fornisce il conto al venditore può essere una banca, Poste Italiane, o servizi di Internet Banking come PayPal, Braintree, Stripe, ecc.

L’ente che fornisce il conto al venditore molto spesso possiede un sistema che consente di ricevere i soldi dell’acquirente su Internet mentre altre volte non lo possiede e allora si rivolge ad enti terzi che forniscono tale sistema (come ad esempio XPay).

Questo sistema si chiama gateway di pagamento, detto anche POS Virtuale (Virtual POS – VPOS) in quanto è la controparte online dei classici POS fisici che troviamo abitualmente in negozi, ristoranti, ecc.

Tra le banche che operano in Italia

  • IwBank utilizza il VPOS IwSmile
  • Intesa San Paolo utilizza il VPOS MonetaOnline
  • UniCredit utilizza il VPOS PagOnline
  • Banca Sella utilizza il VPOS GestPay
  • Banca Nazionale del Lavoro utilizza il VPOS e-POSitivity
  • CartaSI utilizza il VPOS XPay
  • Monte dei Paschi di Siena e il Consorzio Triveneto utilizzano il VPOS MPShop
  • Poste Italiane utilizza il VPOS InProprio

Quindi, quando un venditore vuole realizzare un e-commerce dovrà avere stipulato un contratto con una banca e con un servizio di Internet Banking, scegliendo quello più consono alle proprie esigenze (sia in termini di funzionalità offerte dal gateway di pagamento, sia in termini di costi di commissione ed eventuali canoni mensili).

WooCommerce XPay Cartasì

Dopo quasi due anni dal suo primo rilascio WooCommerce XPay è uno dei gateway di pagamento per gli ecommerce basati su WordPress e WooCommerce più utilizzati.

Compatibile con l’offerta di CartaSì e QuiPago, semplicissimo da installare e configurare, aggiornato costantemente e con supporto tecnico diretto incluso.

Per tutto il mese di gennaio sarà acquistabile ad un prezzo scontato.

Acquistalo nel mio shop!

WooCommerce Xpay CartaSì, diffidate dalle imitazioni! ;)

Manuale PayPal Pro Italia

1. Introduzione

Il plugin per WooCommerce presentato in questo manuale integra il metodo di pagamento “PayPal Pro” nella sua versione per il circuito italiano (chiamata anche PayPal Pro Hosted Solution o HSS).

In questo post trovate informazioni importanti riguardo la comunicazione tra PayPal e il vostro sito.

Il plugin può essere acquistato in questo sito, all’indirizzo http://www.mauromascia.com/shop/product/woocommerce-paypal-pro-italia-payment-gateway/

Il plugin si occupa di reindirizzare il browser dell’utente verso la pagina di pagamento ospitata nei server sicuri di PayPal in cui l’acquirente potrà inserire le informazioni della propria carta di credito oppure utilizzare il proprio account PayPal o crearne uno (non obbligatorio, contrariamente alla versione Standard inclusa in WooCommerce).

In alternativa al reindirizzamento è possibile utilizzare la modalità iFrame che consiste nel mostrare il form di pagamento in una pagina del vostro sito: si noti che tale form non è ospitato sul vostro server ma è sempre e comunque ospitato nei server sicuri di PayPal.

Al termine della procedura di pagamento l’utente verrà reindirizzato verso il vostro sito (o, se si utilizza la modalità iFrame, su un’altra pagina del vostro sito) e nel frattempo arriverà (in modalità asincrona) la notifica del pagamento (attraverso IPN); il plugin, in base alla risposta ricevuta, si occuperà di aggiornare lo stato dell’ordine:

  • “in lavorazione” o “completato” in caso di risposta positiva (nota: lo stato dell’ordine viene impostato direttamente su “completato” solo ed esclusivamente se il tipo di prodotto è “virtuale” e “scaricabile”)
  • “annullato” o “fallito” in caso di rinuncia al pagamento o di errore nell’inserimento dei dati della carta

2. Configurazione Plugin

La configurazione del plugin è molto semplice e intuitiva: una volta installato il plugin (caricando il file zip dall’interfaccia oppure estraendo il contenuto del file zip e copiandolo all’interno della directory dei plugin di WordPress) è sufficiente recarsi nella pagina di amministrazione relativa ai sistemi di pagamento abilitati su WooCommerce, sotto il tab “Payment Gateways” o “Cassa” (nelle ultime versioni di WooCommerce) e cliccare sul link relativo a PayPal Pro, chiamato “PayPal Pro Italia”.

A questo punto verrà presentato un form di configurazione in cui andranno compilati i campi:

  • Abilita/Disabilita: un checkbox che se ha il segno di spunta (checked) abilita il metodo di pagamento PayPal Pro Italia, altrimenti lo disabilita
  • Titolo: il nome del metodo di pagamento mostrato agli utenti al momento del checkout (default “PayPal Pro”)
  • Descrizione: la descrizione del metodo di pagamento
  • PayPal Email: l’email dell’account PayPal Pro su cui ricevere i pagamenti; può essere inserito indistintamente l’account di test o quello di produzione. Nel primo caso (account di test), verificare che sia presente il segno di spunta su “PayPal sandbox”
  • Prefisso fattura: un eventuale prefisso per gli ordini
  • Payment Action: scegliere se catturare (default) o solo autorizzare i pagamenti.
  • URL di ritorno: la pagina su cui riportare l’utente una volta concluso il pagamento. Se non viene selezionato nulla verrà utilizzata la pagina di “Ordine Ricevuto” di WooCommerce. Si consiglia di non utilizzare la pagina “View Order” perché nel momento in cui il cliente viene rediretto in questa pagina lo stato dell’ordine non è ancora cambiato (le notifiche IPN di PayPal vengono inviate in modalità asincrona quindi separatamente e con un breve ritardo)
  • iFrame: se selezionato visualizza la pagina di pagamento di PayPal in un iFrame altrimenti redirige l’utente in una pagina esterna.
  • iFrame Mobile: se selezionato visualizza l’iFrame ottimizzato per i dispositivi mobile.
  • PayPal sandbox: un checkbox che, se ha il segno di spunta (checked), abilita gli acquisti fittizi verso il sito di test di PayPal (developer.paypal.com) in cui sarà possibile verificare le funzionalità del plugin prima di ufficializzarne la messa in produzione. Deselezionare questa voce per i pagamenti reali.
  • Log di debug: Consente di memorizzare gli eventi di PayPal, come le richieste di IPN, all’interno di un file di log (dentro wp-content/plugins/woocommerce/logs prima della versione 2.1 di WooCommerce oppure in wc-logs nella root del sito dalla versione 2.1 di WooCommerce in poi)

 

2.1 Extra: modificare icona PayPal

Se si desiderasse modificare l’icona di PayPal Pro presente nella pagina di pagamento è possibile utilizzare il filtro wc_gateway_paypal_pro_italia_icon.

Ad esempio:

add_filter( 'wc_gateway_paypal_pro_italia_icon', 'my_wc_gateway_paypal_pro_italia_icon' );
function my_wc_gateway_paypal_pro_italia_icon() {
    return get_template_directory_uri() . '/images/my-ppp.png';
}

dove “my-ppp.png” è un’immagine creata da voi e posizionata nella directory “images” del vostro tema (naturalmente questa posizione è puramente indicativa).

3. Configurazione account business

Qui di seguito verranno mostrate le impostazioni relative ad un account business nell’ambiente di test che, con buona approssimazione, saranno le stesse presenti nell’ambiente reale. Una volta effettuato l’accesso alla pagine dell’utente business:

  • https://www.sandbox.paypal.com

è possibile accedere alla pagina del profilo cliccando sul link “Profilo” in cui, sotto la voce “Impostazione dei Pagamenti sul sito web PayPal Pro”, è presente un link “Impostazioni”. Cliccando su tale link verrà mostrata la pagina delle impostazioni e in particolare siamo interessati alla sotto-sezione “Dati del cliente” mostrata nell’immagine seguente:

fig.2 – Raccolta dati cliente

Qui è possibile mettere un segno di spunta sui dati che verranno mostrati (ed eventualmente renderli modificabili) al cliente al momento del pagamento.

Si consiglia vivamente di non rendere tali dati modificabili in quanto così facendo si creerebbe una possibile incongruenza tra i dati presenti negli ordini di WooCommerce e quelli di PayPal.

Un’altra sotto-sezione di cui potremmo aver bisogno è quella relativa all’impostazione della redirezione dell’utente una volta completato il pagamento, a cui si accede tramite il link “Pagina di conferma del pagamento”:

fig.3 – Impostazioni pagina conferma pagamento

In questa sezione è necessario selezionare la voce “Nella pagina di conferma del mio sito” e più in basso è necessario specificare la URL verso la quale ricevere il cliente e mostrargli un messaggio di conferma dell’acquisto. Alternativamente si può utilizzare la pagina di conferma di PayPal in cui va comunque specificata la corretta URL di ritorno.

Nella sotto-sezione “URL e trasferimento dati” andranno – opzionalmente – specificate le pagine (le URL) per gestire la cancellazione dell’ordine e quella d’errore. Infine, nella sotto-sezione “Ricevuta via email” sarà possibile inserire le informazioni relative all’invio di un’email di conferma al cliente.

 

3.1. Configurazione indirizzo IPN

Infine, ma non per importanza, è necessario impostare la URL su cui ricevere le risposte PayPal sullo stato delle transazioni. Questo meccanismo consentirà a WooCommerce di rimanere in ascolto per le notifiche (inviate da PayPal in modo asincrono) e aggiornare così lo stato degli ordini.

Per attivare le notifiche, è necessario fare click su “Profilo” e poi su “Preferenze per la Notifica immediata di pagamento”

fig.4 – Preferenze per la Notifica immediata di pagamento

Qui va impostato il campo “URL notifica” su:

  • http://www.ilmiosito.com/?wc-api=WC_Gateway_PayPal_Pro_Italia

e il campo “Recapito messaggi” su “Abilitato”.

fig.5 – Abilitazione notifica immediata di pagamento

!!ATTENZIONE!! Questa parte è molto importante: senza questa configurazione non verranno aggiornati gli stati degli ordini!!

Le notifiche IPN possono essere abilitate solo se il sito è raggiungibile dall’esterno (quindi pubblico): per questo, per testare le notifiche IPN in locale, è necessario simulare localmente la notifica che invierebbe PayPal. In questa risposta su stackoverflow ho cercato di spiegare come fare:

http://stackoverflow.com/a/28127306/1992799

 

3.2. Configurazione notifiche con Trasferimento dati di pagamento (PDT)

Questo tipo di notifica è alternativo all’IPN descritto sopra e ha precedenza nel senso che, se sono configurati entrambi, PayPal utilizzerà prima la configurazione di PDT.

Rispetto alla IPN ha il pregio di aggiornare subito la pagina di ringraziamento: questo è importante nei casi in cui l’acquisto di un prodotto comporta il download di un file. Senza questa modalità, usando solo la IPN, l’utente dovrebbe aggiornare la pagina perché la notifica server-to-server che PayPal invia, arriva con un leggero ritardo rispetto all’arrivo dell’utente sul sito.

Detto questo passiamo alla configurazione lato backoffice di PayPal.

Una volta effettuato l’accesso e arrivati sulla pagina del profilo in basso trovate “Impostazioni dei Pagamenti su sito web” e cliccando su “Impostazioni” (sotto “PayPal Pro”) e poi su “Pagina di conferma del pagamento” avrete:

paypal-pro-italia-pdt-impostazioni

 

dovrete inserire la pagina dell’ordine ricevuto di WooCommerce relativa all’indirizzo del vostro sito:

http://www.ilmiosito.com/checkout/order-received

Mi raccomando: per PDT è importante che sia “/checkout/order-received”. Infatti il plugin sarà in ascolto su questa URL e quando PayPal riporterà l’utente su questa pagina aggiungerà il parametro “tx”, che rappresenta il numero della transazione; grazie a questo parametro è possibile chiedere a PayPal (grazie alle credenziali API) i dati dell’ordine e in base a quelli riportare l’utente verso la pagina corretta di ordine ricevuto.

A questo punto torniamo alla pagina del profilo e facciamo click su “Preferenze” sotto “Pagamenti su sito web e Pagamento express”. Qui potrebbe essere necessario attivare il ritorno automatico, impostandolo nuovamente su http://www.ilmiosito.com/checkout/order-received

Infine attivare Trasferimento dati di pagamento:

paypal-pro-italia-pdt-attiva-pdt

 

Qui prendete nota del “Token identità” perché ci servirà in seguito.

Le altre informazioni da recuperare sono quelle relative alle credenziali API: tornati al profilo selezioniamo “Richiedi credenziali API” che trovate sotto “Informazioni sul conto”.

paypal-pro-italia-pdt-informazioni-conto

La pagina mostrerà due opzioni:

paypal-pro-italia-pdt-impostazioni-api

Cliccando sul link “Visualizza firma API” della seconda opzione verrà mostrata la pagina:

paypal-pro-italia-pdt-impostazioni-api-credenziali

 

Qui è necessario cliccare sui vari “Mostra”. Ogni voce dovrà essere copiata e incollata nella pagina di configurazione del plugin:

paypal-pro-italia-pdt-attiva-pdt-plugin-configurazione

 

Copiate-incollate anche il “Token identità” che avete messo da parte prima.

Per testare la correttezza della configurazione potete disabilitare IPN e verificare che veniate riportati sulla corretta pagina di ordine ricevuto e che lo stato dell’ordine sia “completato” (o “in lavorazione”).

Se avete un ambiente locale in cui fare le prove, potete utilizzare – ad esempio – ngrok per avere un nome pubblico. In questo modo PayPal potrà inviarvi le notifiche e redirezionarvi correttamente al sito.

 

4. Note su Sandbox

Ecco alcuni link utili per comprendere la procedura di creazione degli account di test:

Aggiungo solo alcune note che non ho trovato in giro per il web e che potrebbe essere d’aiuto nella creazione di nuovi account di test.

Una volta creato l’account business sarà necessario verificare l’account e per questo, una volta raggiunta la pagina degli utenti:

bisogna cliccare sul link “Notifications” presente sotto il nome dell’account business appena creato. Questo aprirà un box in cui sono presenti le notifiche e tra queste dovrebbe essercene una in cui è presente un link da copiare e incollare sulla barra degli indirizzi del browser per rendere l’account, a tutti gli effetti, attivo.

Con il servizio Sandbox API di PayPal, tutti i partecipanti di ciascuna transazione (utenti di prova) sono fittizi e non dispongono di indirizzi email effettivi. Al fine di svolgere la prova, Sandbox è stato integrato con un sistema email indipendente. Ciascun sviluppatore API di PayPal dispone di una casella di posta in arrivo dove vengono spediti tutti i messaggi email indirizzati agli utenti di prova. Ciascun sviluppatore visualizza solo le email inviate agli utenti di prova collegati a uno sviluppatore specifico. Le email inviate a tutti gli utenti di prova collegati ad uno sviluppatore specifico saranno visualizzate nella stessa casella di posta in arrivo.

Si veda il link: https://www.paypal.com/it/cgi-bin/webscr?cmd=p/sell/ipn-test-outside per maggiori informazioni.

A questo punto, cliccando sul link “Sandbox site” (a fianco a “Notifications”), si arriverà al sito clone di quello reale in cui sarà necessario effettuare il login con l’account business precedentemente creato e richiedere le credenziali API.

Per far questo andare su “Profilo” e cliccare sul link “Richiedi credenziali API” o seguire il seguente link diretto:

https://paypalmanager.sandbox.paypal.com/reskinning.do?reskinExternalUrlServiceKey=paypal&reskinSection=profile&reskinRelativeUrl=cgi-bin/webscr?cmd=_profile-api-access

Nota: i link presenti in questa pagina potrebbero subire variazioni.

 

5. Identificare gli ordini pagati con un account PayPal o con carta

In seguito ad un ordine nella risposta restituita da PayPal tra i vari parametri è presente “payer_status“, che vale “verified” quando l’utente paga con un account PayPal valido, oppure “unverified” quando l’utente paga con carta.

Quindi per accedere a tale informazione si può aggiungere un filtro:


add_action( 'valid-paypal-pro-ita-ipn-request', 'my_valid_paypal_pro_ita_ipn_request' );
function my_valid_paypal_pro_ita_ipn_request( $posted ) {
	if (isset($posted['payer_status'])) {
		if ($posted['payer_status'] == 'unverified') {
			// Codice per il pagamento con carta, es.
			wp_mail( 'test.email@email.it', 'Pagamento con Carta', 'Pagamento con Carta' );
		}
		else {
			// Codice per il pagamento con paypal
			wp_mail( 'test.email@email.it', 'Pagamento con PayPal', 'Pagamento con PayPal' );
		}
	}
	
	// Oppure
	if (isset($posted['payer_status']) && !empty($posted['custom']) && !empty($posted['invoice'])) {

		$pp = new WC_Gateway_PayPal_Pro_Italia_IPN_Handler();
		$order = $pp->get_paypal_order($posted['custom'], $posted['invoice']);

		update_post_meta($order->id , '_paypalpro_payer_verified', ($posted['payer_status'] == 'verified'?true:false));
	}
}

WooCommerce: Creazione manuale di ordini

Il problema

Sono il gestore di e-commerce basato su WooCommerce e a volte ho bisogno di creare manualmente gli ordini per i miei clienti.
Vorrei inoltre che il mio cliente ricevesse un’email con il link per pagare l’ordine che ho creato per lui.

Pre-requisiti

– WooCommerce, meglio se aggiornato ad una delle ultime versioni.

La soluzione

  • Creare un utente WordPress, specificando il ruolo “Customer” e salvare.
  • Modificare l’utente appena creato perché nel frattempo saranno comparsi i campi relativi all’indirizzo di fatturazione (billing) aggiunti da WooCommerce. Completare tali campi, in particolare l’indirizzo e-mail (senza il quale non potranno essere spedite le e-mail).
  • Creare un prodotto, se non presente.
  • Creare un ordine:
    • Associare l’utente all’ordine
    • Caricare i Dettagli di fatturazione (Billing Details)
    • Aggiungere il prodotto (o i prodotti)
    • Assicurarsi che lo stato dell’ordine sia su “in attesa” (pending)
    • Calcolare il totale mediante apposito bottone (senza questo il totale rimarrebbe zero e i gateway di pagamento non comparirebbero nella pagina di pagamento)
    • Salvare
  • Dal menù “Azioni” selezionare “Fattura cliente” e cliccare sul bottone laterale: questo comporterà l’invio dell’email al cliente.
  • WordPress Tips: extend the Text Widget allowing shortcodes and custom classes

    What follows is a small tip to create an extension of the base “text” widget of WordPress, to allow the execution of shortcodes and to allow to specify one or more classes (space separated) per-widget.
    In this way it will be really simple identify the widget in our CSS.

    The class is really simple to manage and extend (if you know what this class does: if not, you can read more at http://codex.wordpress.org/Widgets_API).

    To give it a try, just replace “Mytheme” and “mytheme” with your theme (or child theme) name and put the code into the function.php file.
    You can alternatively create a simple plugin, but this is left as an exercise for the reader :P

    
    /**
     * Advanced Text widget class
     */
    class Mytheme_Widget_Text extends WP_Widget {
    
    	function __construct() {
    		parent::__construct(
    			'mytheme_widget_text',
    			__('Mytheme: Arbitrary Text/HTML and shortcodes.'),
    			array( 'description' => __( 'Output an arbitrary text/HTML and/or shortcodes.', 'mytheme' ), ) 
    		);
    	}
    
    	function widget( $args, $instance ) {
    		extract($args);
    		$title = apply_filters( 'mytheme_widget_text', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
    		$text = apply_filters( 'mytheme_widget_text', empty( $instance['text'] ) ? '' : $instance['text'], $instance );
    		$class = apply_filters( 'mytheme_widget_text', empty( $instance['class'] ) ? '' : $instance['class'], $instance );
    
    		echo $before_widget;
    		if ( !empty( $title ) ) { echo $before_title . $title . $after_title; } ?>
    			<div class="mytheme-textwidget <?php echo $class; ?>"><?php echo !empty( $instance['filter'] ) ? wpautop( $text ) : $text; ?></div>
    		<?php
    		echo $after_widget;
    	}
    
    	function update( $new_instance, $old_instance ) {
    		$instance = $old_instance;
    		$instance['title'] = strip_tags($new_instance['title']);
    		$instance['class'] = strip_tags($new_instance['class']);
    
    		if ( current_user_can('unfiltered_html') )
    			$instance['text'] =  $new_instance['text'];
    		else
    			$instance['text'] = stripslashes( wp_filter_post_kses( addslashes($new_instance['text']) ) ); // wp_filter_post_kses() expects slashed
    		$instance['filter'] = isset($new_instance['filter']);
    
    		return $instance;
    	}
    
    	function form( $instance ) {
    		$instance = wp_parse_args( (array) $instance, array(
    				'title' => '',
    				'text' => '',
    				'class' => ''
    			)
    		);
    		$title = strip_tags($instance['title']);
    		$text = esc_textarea($instance['text']);
    		$class = esc_textarea($instance['class']);
    	?>
    		<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label>
    		<input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></p>
    
    		<p><label for="<?php echo $this->get_field_id('class'); ?>"><?php _e('Class:'); ?></label>
    		<input class="widefat" id="<?php echo $this->get_field_id('class'); ?>" name="<?php echo $this->get_field_name('class'); ?>" type="text" value="<?php echo esc_attr($class); ?>" /></p>
    
    		<textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>">
    		    <?php echo $text; ?>
    		</textarea>
    
    		<p><input id="<?php echo $this->get_field_id('filter'); ?>" name="<?php echo $this->get_field_name('filter'); ?>" type="checkbox" <?php checked(isset($instance['filter']) ? $instance['filter'] : 0); ?> />&nbsp;<label for="<?php echo $this->get_field_id('filter'); ?>"><?php _e('Automatically add paragraphs'); ?></label></p>
    	<?php
    	}
    }
    
    
    // Register and load the widget
    function mytheme_load_widget() {
    	register_widget( 'mytheme_widget_text' );
    
    	// Allow to execute shortcodes on mytheme_widget_text
    	add_filter('mytheme_widget_text', 'do_shortcode');
    }
    add_action( 'widgets_init', 'mytheme_load_widget' );
    
    

    Stato degli ordini di WooCommerce

    Recentemente mi è stato chiesto come impostare automaticamente lo stato degli ordini di WooCommerce su “completato” anziché su “in lavorazione”, quando il pagamento di un ordine avvenuto tramite uno dei miei plugin è stato completato correttamente.
    Per rispondere a questa domanda bisogna sapere che WooCommerce consente già di far questo se tutti i prodotti di un ordine sono di tipo virtuale (virtual) e contemporaneamente scaricabili (downloadable).
    Nel rispetto di questa scelta architetturale, presa dal team di WooCommerce, i miei plugin (che estendono i gateway di pagamento di WooCommerce) si comportano nella stessa maniera.

    Quello che avviene in WooCommerce è quanto segue (lo si trova nel file class-wc-order.php):

    public function payment_complete() {
    
      [...]
      
    	$order_needs_processing = true;
    
    	if ( sizeof( $this->get_items() ) > 0 ) {
    		foreach( $this->get_items() as $item ) {
    			if ( $item['product_id'] > 0 ) {
    				$_product = $this->get_product_from_item( $item );
    
    				if ( ( $_product->is_downloadable() && $_product->is_virtual() )
    						|| ! apply_filters( 'woocommerce_order_item_needs_processing', true, $_product, $this->id ) ) {
    					$order_needs_processing = false;
    					continue;
    				}
    
    			}
    			$order_needs_processing = true;
    			break;
    		}
    	}
    
    	$new_order_status = $order_needs_processing ? 'processing' : 'completed';
    
    	$new_order_status = apply_filters( 'woocommerce_payment_complete_order_status', $new_order_status, $this->id );
      [...]
    

    Se però si volesse aggirare questa impostazione, si ha a disposizione una semplice strada che consiste nell’aggiungere un po’ di codice alla fine del file functions.php del tema attivo (preferibilmente in un child theme), sfruttando il filtro “woocommerce_payment_complete_order_status“.

    In questo articolo How to set WooCommerce Virtual Order Status to Complete after Payment troviamo il codice che risolve questo “problema” in modo molto semplice:

    add_filter( 'woocommerce_payment_complete_order_status', 'virtual_order_payment_complete_order_status', 10, 2 );
    function virtual_order_payment_complete_order_status( $order_status, $order_id ) {
      $order = new WC_Order( $order_id );
     
      if ( 'processing' == $order_status && ( 'on-hold' == $order->status || 'pending' == $order->status || 'failed' == $order->status ) ) {
        $virtual_order = null;
        if ( count( $order->get_items() ) > 0 ) {
          foreach( $order->get_items() as $item ) {
            if ( 'line_item' == $item['type'] ) {
              $_product = $order->get_product_from_item( $item );
              if ( ! $_product->is_virtual() ) {
                // once we've found one non-virtual product we know we're done, break out of the loop
                $virtual_order = false;
                break;
              }
              else {
                $virtual_order = true;
              }
            }
          }
        }
     
        // virtual order, mark as completed
        if ( $virtual_order ) {
          return 'completed';
        }
      }
     
      // non-virtual order, return original status
      return $order_status;
    }
    

    In questo modo basterà impostare i prodotti come “virtuali” (senza per forza essere “scaricabili”) per avere automaticamente lo stato degli ordini su “completato”.

    Come potete notare, per ogni prodotto presente nell’ordine verifichiamo che il prodotto sia virtuale. Se nell’ordine troviamo anche un solo prodotto non virtuale non possiamo (o meglio vogliamo) che l’ordine venga automaticamente contrassegnato come completato (perché magari potremmo voler gestire le scorte).

    Se proprio volessimo, potremmo fare la cosa per qualsiasi prodotto (senza neppur dover specificare “virtuale”) inserendo il seguente codice sempre alla fine del file functions.php del tema attivo:

    add_filter('woocommerce_payment_complete_order_status', 'all_orders_payment_complete_order_status', 10, 2);
    function all_orders_payment_complete_order_status($order_status, $order_id) {
    	$order = new WC_Order($order_id);
    	if ('processing' == $order_status && ('on-hold' == $order->status || 'pending' == $order->status || 'failed' == $order->status)) {
    		if (count($order->get_items()) > 0) { return 'completed'; }
    	}
    	return $order_status;
    }
    

    In questo caso non facciamo alcun controllo sul fatto che un prodotto sia virtuale o meno: semplicemente se l’ordine è valido vogliamo impostare lo stato su “completed”.

    El Born NYC

    El Born è un ristorante e bar che porta l’esperienza di Barcellona a Brooklyn.

    Realizzato con CSS e Javascript sul CMS Expression Engine, è un sito web semplice ma ben rifinito, in cui abbiamo riposto una grande attenzione ai dettagli e alla compatibilità dei browser e dei dispositivi mobili.

    Extending Drupal Search on other User fields

    The default Drupal “search by user” is performed by the hook search_execute implemented by the user module (here is the full code), which searches on the “name” field (if you can administer users it searches also on the email).
    But what about searching on other fields?

    As a user is an entity on Drupal 7, it can be extended with other fields, such as the first name, the last name, a biography, a city, and so on.
    Let’s say we have defined these fields:

    • field_first_name
    • field_last_name
    • field_biography

    and we want that searches can be performed also on these fields.
    To do so, when using the standard Drupal search and therefore without creating indexes with the Search APIs or with Apache Solr, we can implement two hooks in our module:

    /**
     * Implements hook_search_info().
     *
     * @see hook_search_info()
     */
    function YOUR_MODULE_search_info() {
      return array(
        'title' => 'People',
      );
    }
    /**
     * Implements hook_search_execute().
     *
     * @see hook_search_execute()
     */
    function YOUR_MODULE_search_execute($keys = NULL, $conditions = NULL) {
    
       $find = array();
      // Replace wildcards with MySQL/PostgreSQL wildcards.
      $keys = preg_replace('!\*+!', '%', $keys);
      $query = db_select('users', 'u')->extend('PagerDefault');
      $query->distinct();
      $query->fields('u', array('uid'));
    
      // Additional tables
      $query->join('field_data_field_first_name', 'fn', 'fn.entity_id = u.uid');
      $query->join('field_data_field_last_name', 'ln', 'ln.entity_id = u.uid');
      $query->join('field_data_field_biography', 'sb', 'sb.entity_id = u.uid');
    
      $query->fields('u', array('mail'));
      $query->condition(
        db_or()
          ->condition('u.name', '%' . db_like($keys) . '%', 'LIKE')
          ->condition('u.mail', '%' . db_like($keys) . '%', 'LIKE')
    
          // Additional fields
          ->condition('field_first_name_value', '%' . db_like($keys) . '%', 'LIKE')
          ->condition('field_last_name_value', '%' . db_like($keys) . '%', 'LIKE')
          ->condition('field_biography_value', '%' . db_like($keys) . '%', 'LIKE')
      );
    
      $uids = $query->limit(15)->execute()->fetchCol();
      $accounts = user_load_multiple($uids);
    
      $results = array();
      foreach ($accounts as $account) {
        $result = array(
          'title' => format_username($account),
          'link' => url('user/' . $account->uid, array('absolute' => TRUE)),
        );
        if (user_access('administer users')) {
          $result['title'] .= ' (' . $account->mail . ')';
        }
        $results[] = $result;
      }
    
      return $results;
    }
    

    The first hook adds an additional ‘People’ (or name it as you like) tab to the Drupal search page which can be enabled in admin/config/search/settings under “Active search modules” (you should uncheck the default “User” tab).
    The second hook joins the field’s tables in the query and the value of these fields in the conditions of the query.

    In this way a searched key can be found also inside the additional fields of the user.

    Limiting concurrent connections per IP

    After playing around with ab (apache benchmark) in a test server, I’ve found particulary annoying that with this simple tool I could break this test server.

    The problem is that a server have a limitate number of resources (CPU/RAM) and for that reason is not possible to accept too many concurrent requests from the same source. This is the base of DoS attacks: saturating the target machine with many requests, so much so that it cannot respond (or it can do it realy slowly) to legitimate traffic.

    What ab does is to open a new TCP connection every time he makes a request and each of them is a new thread of apache which consumes CPU and RAM; after an X number of concurrent connections, the server becomes overloaded with a consequent impossibility to take back it’s control (it needs a forced reboot).

    To mitigate this annoying situations there are many tutorials on the net but many of them are simply old, bad documented or simply does not do the work they should do.

    Many pages report iptable rules like that:

    iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
    

    but this rule simply won’t work for this case because it’s about packets, not connections.

    Other pages which talk about apache’s modules (like mod_security) are really far to be really useful.

    At the end, what worked for me is the great article written by Alessio Rocchi on his Mitigate DDoS with iptables and ipt_recent. He describe line by line what happens and after a little bit of trial and error, I’ve also found what works for my test case:

    #!/bin/bash
    iptables -F
    iptables -X
    iptables -N ATTACKED
    iptables -N ATTK_CHECK
    iptables -N SYN_FLOOD
    iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
    iptables -A INPUT -f -j DROP
    iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
    iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
    iptables -A INPUT -p tcp --syn -j SYN_FLOOD
    iptables -A SYN_FLOOD -p tcp --syn -m hashlimit --hashlimit 2/sec --hashlimit-burst 3 --hashlimit-htable-expire 3600 --hashlimit-mode srcip  --hashlimit-name synflood -j ACCEPT
    iptables -A SYN_FLOOD -j ATTK_CHECK
    iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
    iptables -A INPUT -p tcp -m tcp --dport 80 -m recent --update --seconds 1800 --name BANNED --rsource -j DROP
    iptables -A INPUT -p tcp -m tcp --dport 80 -m state --state NEW -j ATTK_CHECK
    iptables -A ATTACKED -m limit --limit 5/min -j LOG --log-prefix "IPTABLES (Rule ATTACKED): " --log-level 7
    iptables -A ATTACKED -m recent --set --name BANNED --rsource -j DROP
    iptables -A ATTK_CHECK -m recent --set --name ATTK
    iptables -A ATTK_CHECK -m recent --update --seconds 120 --hitcount 20 --name ATTK --rsource -j ATTACKED
    iptables -A ATTK_CHECK -m recent --update --seconds 60 --hitcount 6 --name ATTK --rsource -j ATTACKED
    iptables -A ATTK_CHECK -j ACCEPT
    

    The really important rule is where the hashlimit sets the max number of concurrent connections in each second for each ip (thanks to –hashlimit-mode srcip).
    I’ve put it at 2/sec because of the small test server I was using but I think you can adjust it for your needs ;)

    Ubuntu Edge – Uno smartphone che è un PC ma anche un progetto ambizioso e rivoluzionario

    ubuntu-edge

    E’ in corso una piccola rivoluzione tecnologica, sappiatelo! La notizia rimbalza tra i social network e i blog e non posso astenermi dal dare il mio contributo alla divulgazione di questo progetto tanto ambizioso quanto promettente.

    Nel primo paragrafo “What is Ubuntu Edge” presente nella pagina di indiegogo si può leggere:

    In the car industry, Formula 1 provides a commercial testbed for cutting-edge technologies. The Ubuntu Edge project aims to do the same for the mobile phone industry — to provide a low-volume, high-technology platform, crowdfunded by enthusiasts and mobile computing professionals. A pioneering project that accelerates the adoption of new technologies and drives them down into the mainstream.

    Di cosa stiamo parlando esattamente? Il succo del discorso sarebbe “uno smartphone” ma fin qui nessuno farebbe tanto caso alla cosa, abituati come siamo (chi più, chi meno) a vederli in svariate forme e dimensioni, potenza e colori, in casa Samsung, Apple, Nokia, ecc (non me ne vogliano le altre innumerevoli aziende!). Se aggiungiamo che collegandolo a un’apposita dock trasforma il monitor di casa in un PC vero e proprio, cominciamo a rizzare le orecchie!

    ubuntu-edge-dock

    Ma la reale differenza fra uno smartphone prodotto dalle suddette multinazionali e il gioiellino oggetto di questo articolo è come si arriva ad averlo: il team di Ubuntu/Canonical ha scelto una strada differente per “commercializzare” il suo prodotto, una strada che parla direttamente con il mercato attraverso il web. Non è stato inventato nulla, questo è bene precisarlo, ma nell’utilizzare il crowdfunding, una soluzione ormai consolidata da anni, si è scelto di sfruttarlo fino in fondo, proponendo una soglia mai vista prima di 32 milioni di dollari cioè circa 25 milioni di euro!

    Questa cifra potrebbe sembrare risibile per società come Apple che hanno un fatturato annuo di circa 150 miliardi di dollari e un utile netto di circa 40, ma come tutti sanno, Ubuntu (o meglio la società Canonical che sta dietro), non naviga nell’oro (fonti come Wiki segnalano 30 milioni di dollari nel 2009, ma non riesco a trovare una fonte più aggiornata) per via della sua natura.
    Volendo proseguire il confronto parliamo di 70 mila dipendenti di Apple contro i 500 di Canonical. Insomma, stiamo parlando di due realtà diverse, su questo nessuno potrà sollevare alcun dubbio.

    Non mi dilungherò nell’elogio delle qualità tecniche di questo smartphone:

    • Ubuntu e Android in dual boot
    • CPU da 2.4GHz quad-core
    • 4GB RAM
    • 128GB storage
    • Display da 4.5 inch 1280×720 HD (in zaffiro)
    • Corpo in metallo

    Insomma, paragonandolo alle auto di Formula 1 ci intendiamo.

    Il progetto ha 30 giorni di tempo per raggiungere l’altissima cifra fissata e procedere all’eventuale produzione:

    If we don’t reach our target then we will focus only on commercially available handsets and there will not be an Ubuntu Edge.

    Il primo giorno è passato con un “incasso” di circa 100 mila dollari all’ora e continuando di questo passo potrebbero raggiungere l’ambizioso obiettivo in soli 15 giorni!


    Update 23/08/2013

    Per molti il sogno finisce qui (almeno per ora) ma dopo 30 giorni “folli” non si può parlare di trionfo, ma neppure di sconfitta!
    Rimangono sicuramente alcuni dati di fatto:

    • Il progetto di crowdfunding Ubuntu Edge ha battuto ogni record, totalizzando quasi 13 milioni di dollari ($12809906) in 30 giorni, il 40% di quanto preventivato
    • Non avendo raggiunto la cifra prestabilita, tutti i soldi versati saranno rimborsati nel giro di 5 giorni
    • Quasi 20 mila persone hanno creduto in questo progetto, pagando per un prodotto che avrebbero potuto avere solo dopo quasi un anno (Maggio 2014)
    • Diverse società hanno messo gli occhi sul progetto Ubuntu Edge e sul sistema Ubuntu per smartphone

    Infine, non si esclude un secondo tentativo: nel post di fine campagna Mark Shuttleworth dice:

    […] And who knows, perhaps one day we’ll take everything we’ve learned from this campaign — achievements and mistakes — and try it all over again.

    Beh, non ci resta che augurare buona fortuna al futuro di Ubuntu!

    Cheers!