Webhook per i pagamenti

Aggiornamenti in tempo reale sulle transazioni.

I webhook per i pagamenti (in precedenza, Aggiornamenti in tempo reale) rappresentano un metodo fondamentale tramite cui ricevi informazioni sulle modifiche agli ordini apportate tramite Pagamenti di Facebook all'interno della tua app.

Panoramica

I webhook sono un sistema basato sulle iscrizioni tra Facebook e il tuo server. Attivi l'iscrizione per l'app affinché riceva gli aggiornamenti da Facebook tramite un endpoint HTTPS specificato. Quando viene aggiornato un ordine effettuato all'interno dell'app, emetteremo una richiesta HTTPS POST a tale endpoint, informando il server della modifica.

Esistono 3 scenari principali in cui gli aggiornamenti vengono inviati al server dello sviluppatore:

Attivazione dell'iscrizione ai webhook

Per l'attivazione dell'iscrizione ai webhook dei pagamenti, innanzitutto crea un URL dell'endpoint pubblico in grado di ricevere sia la richiesta HTTPS GET per la verifica dell'iscrizione sia la richiesta POST per le richieste di modifica dei dati. La struttura di entrambi questi tipi di richieste è descritta di seguito. In seguito, configura le iscrizioni all'oggetto payment della tua app. Puoi effettuare l'operazione in 2 modi:

In entrambi i casi, l'endpoint riceverà gli stessi dati nello stesso modo. Per maggiori informazioni sui dati che riceverà il server, consulta il Server di callback.

Attivazione dell'iscrizione mediante la Dashboard gestione app

Il modo più semplice per configurare l'app affinché riceva gli aggiornamenti dei webhook consiste nell'utilizzare la scheda Pagamenti della Dashboard gestione app. Trova la tua app nella dashboard e quindi clicca sulla tab Payments. La sezione Webhook sarà appena sotto la sezione Impostazioni della tua azienda.

Webhook per i pagamenti

Questa schermata elencherà lo stato dell'iscrizione dell'app, indipendentemente dal fatto che l'aggiunta sia avvenuta mediante questa scheda o l'API. Da qui è possibile modificare l'URL di callback dell'iscrizione e testarlo.

Nel campo "Callback", devi fornire un endpoint del server valido e pubblicamente accessibile. Si tratta dell'indirizzo che utilizzeremo sia per la verifica dell'iscrizione sia per l'invio degli aggiornamenti e la sua risposta deve essere simile a quella descritta nel Server di callback.

Infine, fornisci un "token di verifica". Questo token verrà inviato solo durante la fase di iscrizione per verificare che l'iscrizione provenga da un luogo sicuro e non verrà inviato nei normali aggiornamenti dei webhook.

Test delle impostazioni

Devi testare le impostazioni di callback prima del salvataggio dell'iscrizione. Verrà emessa una richiesta GET di verifica al tuo endpoint, contenente i parametri hub.mode, hub.challenge e hub.verify_token, e il test verificherà che vengano gestiti correttamente. Ad esempio, devi assicurarti che il tuo endpoint restituisca hub.challenge a Facebook:

Test delle impostazioni

Dopo aver inserito i dettagli dell'iscrizione, assicurati di cliccare sul pulsante "Salva modifiche" nella parte inferiore della pagina. Per modificare un'iscrizione è sufficiente modificare il contenuto dei campi, eseguire un nuovo test e quindi salvare nuovamente il modulo.

Attivazione dell'iscrizione mediante l'API Graph

È anche possibile configurare ed elencare le iscrizioni in modo programmatico, mediante l'API Graph. Avrai bisogno di access token dell'app, disponibile dallo Strumento di gestione token d'accesso oppure utilizzando l'endpoint /oauth dell'API Graph.

L'API Subscription è disponibile sull'endpoint https://graph.facebook.com/[APP_ID]/subscriptions.

Esistono 3 attività che puoi eseguire con quest'ultimo:

  • Aggiunta o modifica di un'iscrizione (inviando una richiesta HTTPS POST)
  • Elenco di tutte le iscrizioni esistenti (inviando una richiesta HTTPS GET)

Aggiunta e modifica delle iscrizioni

Per configurare un'iscrizione, invia una richiesta POST con i seguenti parametri. Questi parametri corrispondono ai campi del modulo descritto in precedenza:

  • object: come indicato in precedenza, il tipo di oggetto su cui desideri ricevere aggiornamenti. Specifica payments.
  • fields: una lista separata da virgole delle proprietà del tipo di oggetto su cui vorresti ricevere gli aggiornamenti relativamente alle modifiche. Specifica "azioni" e "contestazioni".
  • callback_url: un endpoint del server valido e pubblicamente accessibile.
  • verify_token: una stringa arbitraria inviata all'endpoint quando viene verificata l'iscrizione.

Quando riceviamo questa richiesta, come con la configurazione del modulo precedente, eseguiamo una richiesta GET alla callback per assicurarti che sia valida e pronta per la ricezione degli aggiornamenti. In particolare, devi assicurarti che il tuo endpoint restituisca hub.challenge a Facebook.

Poiché un'app può avere solo un'iscrizione per ogni tipo di oggetto, se esiste un'iscrizione per questo tipo di oggetto, i dati appena pubblicati sostituiscono tutti quelli esistenti.

Elenco delle iscrizioni

L'emissione di una richiesta HTTP GET all'API Subscription restituisce il contenuto con codifica JSON che elenca le tue iscrizioni. Ad esempio:

[
  {
    "object": "payments",
    "callback_url": "https://www.friendsmash.com/rtu.php",
    "fields": ["actions", "disputes"],
    "active": true
  }
]

Puoi utilizzare il Tool di esplorazione per la API Graph per provare direttamente con questa API; ricorda di utilizzare il token d'accesso della tua app.

Server di callback

Il server di callback deve gestire 2 tipi di richieste. Assicurati che sia su un URL pubblico in modo da poter effettuare correttamente queste richieste.

Verifica dell'iscrizione

Innanzitutto, i server di Facebook effettueranno una singola richiesta HTTPS GET all'URL di callback quando provi ad aggiungere o modificare un'iscrizione. Una stringa della query verrà aggiunta all'URL di callback con i seguenti parametri:

Parametro Descrizione

hub.mode

La stringa "subscribe" viene passata in questo parametro

hub.challenge

Una stringa casuale

hub.verify_token

Il valore verify_token specificato al momento della creazione dell'iscrizione

L'endpoint deve prima verificare hub.verify_token. Ciò garantisce che il server sappia che la richiesta è stata effettuata da Facebook e si riferisce all'iscrizione appena configurata.

Quindi deve solo restituire il valore hub.challenge, che conferma a Facebook che questo server è stato configurato per accettare callback e impedisce le vulnerabilità denial-of-dervice (DDoS).

Nota per gli sviluppatori PHP: in PHP, i punti e gli spazi nei nomi dei parametri relativi alla query vengono convertiti automaticamente in trattini bassi. Pertanto, devi accedere a questi parametri utilizzando $_GET['hub_mode'],$_GET['hub_challenge'] e $_GET['hub_verify_token'] se stai scrivendo l'endpoint di callback in PHP. Consulta questa nota nel manuale del linguaggio PHP per maggiori informazioni.

Ricezione degli aggiornamenti

A seguito di un'iscrizione eseguita correttamente, procederemo all'emissione di una richiesta HTTPS POST all'endpoint del server ogni volta che sono presenti delle modifiche (alle connessioni o ai campi scelti). Devi rispondere a questa richiesta con il codice HTTP 200.

Nota: consideriamo qualsiasi risposta HTTP diversa da 200 un errore. In queste circostanze, continueremo a riprovare l'invio dell'aggiornamento dei webhook. Se non rispondi correttamente, potresti ricevere lo stesso aggiornamento più volte.

La richiesta avrà il tipo di contenuto di application/json e il corpo comprenderà una stringa con codifica JSON contenente una o più modifiche.

Nota per gli sviluppatori PHP: in PHP, per ottenere i dati codificati dovresti utilizzare il seguente codice:

$data = file_get_contents("php://input");
$json = json_decode($data);`

I parametri hub.mode, hub.challenge e hub.verify_token non vengono inviati nuovamente dopo la conferma dell'iscrizione.

Di seguito un tipico esempio di callback effettuata per l'iscrizione dell'oggetto payments:

{
  "object": "payments",
  "entry": [
    {
      "id": "296989303750203",
      "time": 1347996346,
      "changed_fields": [
        "actions"
      ]
    }
  ]
}

È importante tenere presente che gli aggiornamenti dei webhook ti informano solo della modifica di un particolare pagamento, identificato dal campo id. Dopo la ricezione dell'aggiornamento, ti viene richiesto di interrogare l'API Graph per i dettagli della transazione, per gestire la modifica in modo appropriato.

Nota: mentre i webhook per gli altri tipi di oggetti possono essere eseguiti in batch, ciò non si applica agli aggiornamenti sui pagamenti.

Hai la garanzia di ricevere un nuovo aggiornamento ogni volta che viene aggiornata una transazione, sia per azione utente sia per azione sviluppatore.

Se un aggiornamento per il server non va a buon fine, riproveremo immediatamente, proseguendo con frequenza decrescente per le successive 24 ore.

Con ogni richiesta, inviamo un'intestazione HTTP X-Hub-Signature-256 che contiene la firma SHA256 del payload della richiesta, utilizzando la chiave segreta come chiave preceduta da sha256=. L'endpoint di callback può verificare questa firma per la convalida dell'integrità e dell'origine del payload.

Risposta agli aggiornamenti

Dopo la ricezione di un aggiornamento dal server, dovresti interrogare l'API Graph utilizzando il campo id per i dettagli sul nuovo stato della transazione. Quindi dovresti eseguire azioni a seconda dello stato.

Le sezioni seguenti elencano tutte le potenziali modifiche di stato che attivano l'invio di un aggiornamento. In generale, si dividono in:

  • Modifiche all'array actions che si verificano quando un pagamento viene completato in modo asincrono, viene emesso un rimborso (da te o da Facebook) o quando si verifica un chargeback.
  • Modifiche all'array disputes che si verificano quando un cliente presenta una contestazione sull'ordine.

Azioni

Ogni oggetto payment contiene un array intitolato actions, contenente la raccolta delle modifiche di stato relative alla transazione. Ogni voce presente nell'array actions dispone di una proprietà denominata type che descrive il tipo di azione che ha avuto luogo. type può avere i seguenti valori: charge, refund,chargeback, chargeback_reversale decline, che vengono spiegati completamente qui.

Di seguito un esempio di risposta dall'API Graph per un oggetto payment con azioni associate:

{
   "id": "3603105474213890",
   "user": {
      "name": "Marco Alvarez",
      "id": "500535225"
   },
   "application": {
      "name": "Friend Smash",
      "namespace": "friendsmashsample",
      "id": "241431489326925"
   },
   "actions": [
      {
         "type": "charge",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2013-03-22T21:18:54+0000",
         "time_updated": "2013-03-22T21:18:55+0000"
      },
      {
         "type": "refund",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2013-03-23T21:18:54+0000",
         "time_updated": "2013-03-23T21:18:55+0000"
      }
   ],
   "refundable_amount": {
      "currency": "USD",
      "amount": "0.00"
   },
   "items": [
      {
         "type": "IN_APP_PURCHASE",
         "product": "https://www.friendsmash.com/og/friend_smash_bomb.html",
         "quantity": 1
      }
   ],
   "country": "US",
   "created_time": "2013-03-22T21:18:54+0000",
   "payout_foreign_exchange_rate": 1,}`

Poiché hai attivato l'iscrizione per il campo actions durante la registrazione per i webhook, emetteremo un aggiornamento quando l'array cambia nel modo seguente:

Addebito

Inizialmente, tutti gli ordini contengono una voce di addebito con "status": "initiated". Un pagamento avviato indica che il pagamento è stato solo avviato e non è stato ancora completato completamente. Non invieremo aggiornamenti per i pagamenti che presentano lo stato avviato.

Quando un pagamento viene completato correttamente, "status": "initiated" verrà modificato in "status": "completed" ed emetteremo un aggiornamento. Una volta visualizzata questa modifica, controlla i tuoi registri di pagamento per verificare la presenza di una transazione nuova o esistente e rispondi come indicato di seguito:

  • Se l'ordine è già noto ed è stato evaso dalla callback JavaScript (preferibile come prima scelta), puoi ignorare in modo sicuro l'aggiornamento o utilizzarlo come ulteriore conferma.
  • Se l'ordine è noto, ma esiste in uno stato initiated, puoi procedere all'evasione dell'ordine, emettendo per il cliente l'articolo virtuale o la valuta associati. Questo pagamento può quindi essere contrassegnato in modo sicuro come completato.
  • Se l'ordine non è noto, indica il mancato completamento del processo lato client, probabilmente causato da problemi di connettività o dalla chiusura del browser durante l'acquisto da parte del cliente. Puoi ancora evadere e completare in modo sicuro questo ordine, perché Facebook rimane l'ultima fonte di informazioni attendibili sulla fatturazione degli utenti.

Riceverai anche gli aggiornamenti per i pagamenti che presentano "status": "failed", ma che non devono essere evasi.

Rimborso

Ogni volta che emetti un rimborso mediante l'API Graph, riceverai un aggiornamento. Analogamente a "type": "charge", un rimborso può anche avere uno stato diverso di cui devi essere a conoscenza. In particolare, è possibile che un rimborso non vada a buon fine, di solito a causa di un errore di elaborazione o di connettività, nel qual caso dovresti riprovare l'emissione del rimborso.

Chargeback, annullamento di chargeback e rifiuti

Analogamente ai rimborsi, ti verranno comunicati emissione di chargeback, annullamenti di chargeback o rifiuti. Un oggetto chargeback, chargeback reversal o decline verrà aggiunto all'array actions dei dati restituiti dell'API Graph per il pagamento.

Contestazioni

Ti informeremo mediante l'emissione di un aggiornamento quando viene avviata una contestazione. In questo caso, visualizzerai un nuovo array "disputes" come parte dell'oggetto payment. L'array conterrà l'ora di avvio della contestazione, il motivo per cui il cliente ha avviato la risposta e l'indirizzo e-mail del cliente, che puoi utilizzare per contattarlo direttamente per risolvere la contestazione.

Di seguito un esempio di risposta completa dall'API Graph per una transazione contestata:

{
   "id": "990361254213890",
   "user": {
      "name": "Marco Alvarez",
      "id": "500535225"
   },
   "application": {
      "name": "Friend Smash",
      "namespace": "friendsmashsample",
      "id": "241431489326925"
   },
   "actions": [
      {
         "type": "charge",
         "status": "completed",
         "currency": "USD",
         "amount": "0.99",
         "time_created": "2013-03-22T21:18:54+0000",
         "time_updated": "2013-03-22T21:18:55+0000"
      }
   ],
   "refundable_amount": {
      "currency": "USD",
      "amount": "0.99"
   },
   "items": [
      {
         "type": "IN_APP_PURCHASE",
         "product": "https://www.friendsmash.com/og/friend_smash_bomb.html",
         "quantity": 1
      }
   ],
   "country": "US",
   "created_time": "2013-03-22T21:18:54+0000",
   "payout_foreign_exchange_rate": 1,
   "disputes": [
      {
         "user_comment": "I didn't receive my item! I want a refund, please!",
         "time_created": "2013-03-24T18:21:02+0000",
         "user_email": "email\u0040domain.com",
         "status": "resolved", 
         "reason": "refunded_in_cash"
      }
   ]
}

Per maggiori informazioni sulla modalità di risposta alle contestazioni ed emissione di rimborsi, consulta Come gestire i pagamenti: gestione di contestazioni e rimborsi.