Caso Banca Raiffeisen: come combattere le frodi nelle reti CPA

Pubblicato: 2022-05-25

Man mano che il marketing digitale si sta evolvendo, così fa la frode pubblicitaria di affiliazione digitale che sta diventando una sfida avvincente per i marketer online. Viene eseguito inviando traffico spazzatura a siti Web o utilizzando bot per attivare premi di affiliazione. Indipendentemente dal metodo esatto, ci vuole comunque $ 1 su ogni $ 3 che viene fatto attraverso la pubblicità online. In altre parole, è una quantità significativa di entrate rubate che viene commessa ogni giorno.

In questo caso, descriviamo la soluzione fornita dal team OWOX BI per la banca Raiffeisen che tornerà utile sia per le banche che per qualsiasi altro utente della rete CPA.

Sommario

  • Sfida
  • Soluzione
    • Passaggio 1. Raccogli dati grezzi
    • Passaggio 2. Elabora i dati
    • Passaggio 3. Crea report
  • Risultati

Sfida

Gli specialisti di marketing di Raiffeisen hanno riscontrato un notevole aumento dei costi del traffico di affiliazione, con i ricavi rimasti invariati. Un altro problema era che i clienti della banca avevano brevi interruzioni di sessione durante l'inserimento dei dati per il modulo di domanda sul sito web.

Ecco perché Raiffeisen ha ipotizzato che alcuni dei suoi affiliati CPA avrebbero potuto sostituire il valore della fonte di traffico nella pagina di pagamento della banca. Funziona così: ad esempio, un utente installa un'estensione del browser per ottenere sconti. Quando l'utente accede al tuo sito Web e apre il checkout, l'estensione visualizza una finestra pop-up con un'offerta di sconto. Se ci sono dei clic sul collegamento dalla finestra pop-up, l'estensione riscrive automaticamente i dati sulla sorgente di traffico nel cookie con i dati sulla sorgente di traffico degli affiliati.

Soluzione

Il team di marketing ha deciso di iniziare con la raccolta di dati grezzi sul comportamento degli utenti per dimostrare l'ipotesi che gli affiliati riscrivano i dati della sorgente di traffico a proprio vantaggio. Successivamente, sono stati raccolti i dati sui clienti specifici. Questi clienti hanno avuto due sessioni sulla stessa pagina in meno di 60 secondi e la fonte di traffico della seconda sessione è stata spostata su quella dell'affiliato. Tali dati su questi clienti aiuterebbero a identificare i partner affiliati che hanno attribuito a se stessi il traffico proveniente da altri canali. Con questi dati forniti, potrebbe essere possibile interrompere la collaborazione con i webmaster che agiscono in malafede e ottimizzare il budget per il marketing.

Il team OWOX BI ha aiutato a raccogliere ed elaborare i dati necessari. Ecco uno schema per dimostrare il flusso di dati:

Passaggio 1. Raccogli dati grezzi

Google Analytics campiona i dati quando il numero di sessioni supera la soglia di campionamento. Ecco perché gli analisti di OWOX BI hanno suggerito di raccogliere i dati in Google BigQuery. Inoltre, questo data warehouse su cloud soddisfa i più elevati standard di sicurezza, il che è davvero importante per la banca.

Per impostare l'importazione dei dati dal sito Web a Google BigQuery, Raiffeisen ha utilizzato OWOX BI Pipeline. In questo modo gli specialisti dell'azienda hanno ottenuto dati non campionati quasi in tempo reale e raccolto il timestamp di ogni hit. Tale soluzione ha consentito di tenere traccia di tutte le possibili sequenze di azioni dell'utente tra le sessioni, all'interno di un unico report. Ad esempio, hai bisogno di un rapporto sugli utenti che hanno visitato la pagina della tua azienda/promozione, sono tornati al sito Web tramite CPC e, infine, hanno acquistato qualcosa. Un'altra cosa necessaria è visualizzare queste visite per la data selezionata nel rapporto. Ecco la query per ottenere il rapporto di cui hai bisogno:

    SELECT cp.promo.date AS Date, cp.promo.clientId AS ClientId, cp.promo.time AS Promo_time, cp.cpc.time AS CPC_time, send.time AS SEND_time FROM ( SELECT promo.date, promo.clientId, promo.time, cpc.time FROM ( SELECT date, clientId, MIN(time) AS time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE page.pagePath CONTAINS '/promo/' AND type = 'pageview' AND traffic.medium != 'cpc' GROUP BY date, clientId, ORDER BY clientId ASC) AS promo LEFT JOIN ( SELECT date, clientId, traffic.medium, time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE traffic.medium = 'cpc' AND type = 'pageview' GROUP BY date, clientId, traffic.medium, time ORDER BY clientId ASC) AS cpc ON promo.clientId=cpc.clientId WHERE promo.time < cpc.time) AS cp LEFT JOIN ( SELECT date, clientId, time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE eventInfo.eventCategory = 'send_ok' AND type = 'event' GROUP BY date, clientId, time ORDER BY clientId ASC) AS send ON cp.promo.clientId = send.clientId WHERE cp.cpc.time < send.time
SELECT cp.promo.date AS Date, cp.promo.clientId AS ClientId, cp.promo.time AS Promo_time, cp.cpc.time AS CPC_time, send.time AS SEND_time FROM ( SELECT promo.date, promo.clientId, promo.time, cpc.time FROM ( SELECT date, clientId, MIN(time) AS time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE page.pagePath CONTAINS '/promo/' AND type = 'pageview' AND traffic.medium != 'cpc' GROUP BY date, clientId, ORDER BY clientId ASC) AS promo LEFT JOIN ( SELECT date, clientId, traffic.medium, time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE traffic.medium = 'cpc' AND type = 'pageview' GROUP BY date, clientId, traffic.medium, time ORDER BY clientId ASC) AS cpc ON promo.clientId=cpc.clientId WHERE promo.time < cpc.time) AS cp LEFT JOIN ( SELECT date, clientId, time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE eventInfo.eventCategory = 'send_ok' AND type = 'event' GROUP BY date, clientId, time ORDER BY clientId ASC) AS send ON cp.promo.clientId = send.clientId WHERE cp.cpc.time < send.time

Di seguito la tabella con tutti i dati ottenuti a seguito della query.

Passaggio 2. Elabora i dati

L'elenco dei valori necessari è stato creato per identificare i valori della sorgente di traffico che sono stati modificati con quella dell'affiliato:

  • ID utente.
  • Fonte e mezzo della prima e delle successive sessioni.
  • Il tempo tra le sessioni.
  • Il primo e l'ultimo URL di ogni sessione.
  • Eventi in ogni sessione.
  • Evento di transazione nella sessione finale.

Successivamente, per assicurarsi che i valori delle sorgenti di traffico siano stati definitivamente riscritti, gli analisti di OWOX BI hanno scelto di filtrare i dati tenendo conto di queste condizioni:

  • Il periodo di tempo tra le due sessioni dovrebbe essere fino a 60 secondi.
  • La pagina del sito web dovrebbe rimanere la stessa quando cambia la fonte.
  • Dovrebbe esserci una transazione nella sessione finale.
  • Il mezzo di traffico nella sessione finale dovrebbe essere un affiliato.

Ecco la query SQL che è stata utilizzata per ottenere i dati necessari:

    SELECT * FROM ( SELECT traff.clientId clientId, traff.page.pagePath pagePath, traff.traffic.source startSource, traff.traffic.medium startMedium, traff.time startTime, aff.evCategory eventCategory, aff.evlabel eventLabel, aff.evSource finishSource, aff.evMedium fifnishMedium, aff.time finishTime, aff.isTransaction isTransaction, aff.pagePath link, traff.time - aff.time AS diff FROM ( SELECT clientId, page.pagePath, traffic.source, traffic.medium, date, INTEGER(time) time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE traffic.medium != 'affiliate')AS traff JOIN ( SELECT total.date date, total.time time, total.clientId clientId, total.eventInfo.eventCategory evCategory, total.eventInfo.eventLabel evlabel, total.traffic.source evSource, total.traffic.medium evMedium, tr.eventInfo.eventCategory isTransaction, total.page.pagePath pagePath FROM ( SELECT clientId, page.pagePath, eventInfo.eventCategory, eventInfo.eventLabel, traffic.source, traffic.medium, date, INTEGER(time) time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE traffic.medium = 'affiliate') AS total LEFT JOIN ( SELECT clientId, date, eventInfo.eventCategory, INTEGER(time) time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE eventInfo.eventCategory = 'send_ok' GROUP BY 1, 2, 3, 4) AS tr ON total.clientId = tr.clientId AND total.date = tr.date WHERE tr.eventInfo.eventCategory = 'send_ok' AND tr.time>total.time)AS aff ON traff.clientId = aff.clientId) WHERE diff >-60 AND diff<0 GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ORDER BY clientId, finishTime
SELECT * FROM ( SELECT traff.clientId clientId, traff.page.pagePath pagePath, traff.traffic.source startSource, traff.traffic.medium startMedium, traff.time startTime, aff.evCategory eventCategory, aff.evlabel eventLabel, aff.evSource finishSource, aff.evMedium fifnishMedium, aff.time finishTime, aff.isTransaction isTransaction, aff.pagePath link, traff.time - aff.time AS diff FROM ( SELECT clientId, page.pagePath, traffic.source, traffic.medium, date, INTEGER(time) time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE traffic.medium != 'affiliate')AS traff JOIN ( SELECT total.date date, total.time time, total.clientId clientId, total.eventInfo.eventCategory evCategory, total.eventInfo.eventLabel evlabel, total.traffic.source evSource, total.traffic.medium evMedium, tr.eventInfo.eventCategory isTransaction, total.page.pagePath pagePath FROM ( SELECT clientId, page.pagePath, eventInfo.eventCategory, eventInfo.eventLabel, traffic.source, traffic.medium, date, INTEGER(time) time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE traffic.medium = 'affiliate') AS total LEFT JOIN ( SELECT clientId, date, eventInfo.eventCategory, INTEGER(time) time FROM TABLE_DATE_RANGE({dataSetName}.{tableName},TIMESTAMP('{startDate}'), TIMESTAMP('{endDate}')) WHERE eventInfo.eventCategory = 'send_ok' GROUP BY 1, 2, 3, 4) AS tr ON total.clientId = tr.clientId AND total.date = tr.date WHERE tr.eventInfo.eventCategory = 'send_ok' AND tr.time>total.time)AS aff ON traff.clientId = aff.clientId) WHERE diff >-60 AND diff<0 GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ORDER BY clientId, finishTime

Passaggio 3. Crea report

Per ulteriori analisi è stato applicato il componente aggiuntivo per importare i dati selezionati da Google BigQuery a Fogli Google. Utilizzando i dati importati, è stata creata la tabella con gli ID di ciascun cliente la cui sessione è stata chiusa e la nuova sessione è stata aperta sulla stessa pagina, in meno di un minuto tra le due sessioni.

Successivamente, i dati sono stati riuniti in una tabella pivot per dimostrare che i marketer di affiliazione hanno agito in malafede. I numeri nello screenshot qui sotto sono stati modificati e sono forniti a titolo di esempio:

Ad esempio, il rapporto mostra il numero di transazioni con un valore sorgente riscritto e quali affiliati hanno sostituito le sorgenti di traffico con le proprie. Il rapporto mostra anche quali canali sono stati derubati delle transazioni: CPC e organico.

Risultati

Il team OWOX BI ha aiutato a identificare ed eliminare rapidamente i punti deboli nelle reti CPA della banca. Grazie alla soluzione fornita la banca potrebbe monitorare le statistiche sugli affiliati (attribuire in modo più accurato conversioni e vendite ai canali di traffico) e portare alla luce i casi di frode nelle reti CPA. Il team marketing è riuscito a ottimizzare il budget pubblicitario interrompendo la collaborazione con due partner disonesti che hanno riscritto le sorgenti di traffico e sovrafatturato irragionevolmente Raiffeisen Bank.