/** * jQuery fontIconPicker - v2.3 * * An icon picker built on top of font icons and jQuery * * http://codeb.it/fontIconPicker * * Made by Alessandro Benoit & Swashata * Under MIT License * * {@link https://github.com/micc83/fontIconPicker} * * Modified by Visual Composer Dev Team */ (function ( $ ) { 'use strict'; // Create the defaults once var defaults = { theme: 'fip-vc-theme-grey', // The CSS theme to use with this fontIconPicker. You can set different themes on multiple elements on the same page source: false, // Icons source (array|false|object) emptyIcon: true, // Empty icon should be shown? emptyIconValue: '', // The value of the empty icon, change if you select has something else, say "none" iconsPerPage: 20, // Number of icons per page hasSearch: true, // Is search enabled? searchSource: false, // Give a manual search values. If using attributes then for proper search feature we also need to pass icon names under the same order of source useAttribute: false, // Whether to use attribute selector for printing icons attributeName: 'data-icon', // HTML Attribute name convertToHex: true, // Whether or not to convert to hexadecimal for attribute value. If true then please pass decimal integer value to the source (or as value="" attribute of the select field) allCategoryText: 'From all categories', // The text for the select all category option unCategorizedText: 'Uncategorized', // The text for the select uncategorized option iconDownClass: 'fip-icon-down-dir', // Class for icon down iconUpClass: 'fip-icon-up-dir', // Class for icon up iconLeftClass: 'fip-icon-left-dir', // Class for icon left iconRightClass: 'fip-icon-right-dir', // Class for icon right iconSearchClass: 'fip-icon-search', // Class for search iconCancelClass: 'fip-icon-cancel', // Class for search canceling iconSpinClass: 'fip-icon-spin3', // Class for fip-icon-spin3 iconBlockClass: 'fip-icon-block', // Class for block(none icon) searchPlaceholder: 'Search Icon', // Search icon text placeholder mainClass: 'vc-icons-selector' }; // The actual plugin constructor function Plugin( element, options ) { this.element = $( element ); this.settings = $.extend( {}, defaults, options ); if ( this.settings.emptyIcon ) { this.settings.iconsPerPage --; } this.iconPicker = $( '
', { 'class': this.settings.mainClass, style: 'position: relative', html: '
' + '' + '' + '' + '' + '' + '' + '
' + '' } ); this.iconContainer = this.iconPicker.find( '.fip-icons-container' ); this.searchIcon = this.iconPicker.find( '.selector-search i' ); this.iconsSearched = []; this.isSearch = false; this.totalPage = 1; this.currentPage = 1; this.currentIcon = false; this.initialized = false; this.iconsPaged = false; this.iconsCount = 0; this.open = false; // Set the default values for the search related variables this.searchValues = []; this.availableCategoriesSearch = []; // The trigger event for change this.triggerEvent = null; // Backups this.backupSource = []; this.backupSearch = []; // Set the default values of the category related variables this.isCategorized = false; // Automatically detects if the icon listing is categorized this.selectCategory = this.iconPicker.find( '.icon-category-select' ); // The category SELECT input field this.selectedCategory = false; // false means all categories are selected this.availableCategories = []; // Available categories, it is a two dimensional array which holds categorized icons this.unCategorizedKey = null; // Key of the uncategorized category // Initialize plugin this.quickInit(); } Plugin.prototype = { /** * Quick init */ quickInit: function () { var first = true; // Add the theme CSS to the iconPicker this.iconPicker.addClass( this.settings.theme ); // To properly calculate iconPicker height and width // We will first append it to body (with left: -9999px so that it is not visible) this.iconPicker.css( { left: - 9999 } ).appendTo( 'body' ); var iconPickerHeight = this.iconPicker.outerHeight(), iconPickerWidth = this.iconPicker.outerWidth(); // Now reset the iconPicker CSS this.iconPicker.css( { left: '' } ); // Add the icon picker after the select this.element.before( this.iconPicker ); // Hide source element // Instead of doing a display:none, we would rather // make the element invisible // and adjust the margin this.element.css( { visibility: 'hidden', top: 0, position: 'relative', zIndex: '-1', left: '-' + iconPickerWidth + 'px', display: 'none', height: iconPickerHeight + 'px', width: iconPickerWidth + 'px', // Reset all margin, border and padding padding: '0', margin: '0 -' + iconPickerWidth + 'px 0 0', // Left margin adjustment to account for dangling space border: '0 none', verticalAlign: 'top' } ).hide(); // Set the trigger event if ( ! this.element.is( 'select' ) ) { // Determine the event that is fired when user change the field value // Most modern browsers supports input event except IE 7, 8. // IE 9 supports input event but the event is still not fired if I press the backspace key. // Get IE version // https://gist.github.com/padolsey/527683/#comment-7595 var ieVersion = (function () { var v = 3, div = document.createElement( 'div' ), a = div.all || []; while ( div.innerHTML = '', a[ 0 ] ) { ; } return v > 4 ? v : ! v; }()); var el = document.createElement( 'div' ); this.triggerEvent = (ieVersion === 9 || ! ('oninput' in el)) ? [ 'keyup' ] : [ 'input', 'keyup' ]; // Let's keep the keyup event for scripts that listens to it } this.setSelectedIcon( this.element.val() ); /** * Category changer */ this.selectCategory.on( 'change keyup', $.proxy( function ( e ) { // Don't do anything if not categorized if ( this.isCategorized === false ) { return false; } var targetSelect = $( e.currentTarget ), currentCategory = targetSelect.val(); // Check if all categories are selected if ( targetSelect.val() === 'all' ) { // Restore from the backups // @note These backups must be rebuild on source change, otherwise it will lead to error this.settings.source = this.backupSource; this.searchValues = this.backupSearch; // No? So there is a specified category } else { var key = parseInt( currentCategory, 10 ); if ( this.availableCategories[ key ] ) { this.settings.source = this.availableCategories[ key ]; this.searchValues = this.availableCategoriesSearch[ key ]; } } this.resetSearch(); this.loadIcons(); }, this ) ); /** * On down arrow click */ this.iconPicker.find( '.selector-button' ).on( 'click', $.proxy( function () { if ( ! this.open && first ) { first = false; this.initCategories(); } // Open/Close the icon picker this.toggleIconSelector(); }, this ) ); /** * Next page */ this.iconPicker.find( '.selector-arrow-right' ).on( 'click', $.proxy( function ( e ) { if ( this.currentPage < this.totalPage ) { this.iconPicker.find( '.selector-arrow-left' ).show(); this.currentPage = this.currentPage + 1; this.renderIconContainer(); this.renderIcons(); } if ( this.currentPage === this.totalPage ) { $( e.currentTarget ).hide(); } }, this ) ); /** * Prev page */ this.iconPicker.find( '.selector-arrow-left' ).on( 'click', $.proxy( function ( e ) { if ( this.currentPage > 1 ) { this.iconPicker.find( '.selector-arrow-right' ).show(); this.currentPage = this.currentPage - 1; this.renderIconContainer(); this.renderIcons(); } if ( this.currentPage === 1 ) { $( e.currentTarget ).hide(); } }, this ) ); /** * Realtime Icon Search */ this.iconPicker.find( '.icons-search-input' ).on( 'keyup', $.proxy( function ( e ) { // Get the search string var searchString = $( e.currentTarget ).val(); // If the string is not empty if ( searchString === '' ) { this.resetSearch(); return; } // Set icon search to X to reset search this.searchIcon.removeClass( this.settings.iconSearchClass ); this.searchIcon.addClass( this.settings.iconCancelClass ); // Set this as a search this.isSearch = true; // Reset current page this.currentPage = 1; // Actual search // This has been modified to search the searchValues instead // Then return the value from the source if match is found this.iconsSearched = []; $.grep( this.searchValues, $.proxy( function ( n, i ) { if ( n.toLowerCase().search( searchString.toLowerCase() ) >= 0 ) { this.iconsSearched[ this.iconsSearched.length ] = this.settings.source[ i ]; return true; } }, this ) ); // Filter duplicates this.iconsSearched = this.iconsSearched.filter( this.getOnlyUnique ); // Render icon list this.renderIconContainer(); this.renderIcons(); }, this ) ); /** * Quit search */ this.iconPicker.find( '.selector-search i' ).on( 'click', $.proxy( function () { this.iconPicker.find( '.icons-search-input' ).focus(); this.resetSearch(); }, this ) ); /** * On icon selected */ this.iconContainer.on( 'click', '.fip-box', $.proxy( function ( e ) { this.setSelectedIcon( $( e.currentTarget ).find( 'i' ).attr( 'data-fip-value' ) ); this.toggleIconSelector(); }, this ) ); /** * Stop click propagation on iconpicker */ this.iconPicker.on( 'click', function ( event ) { event.stopPropagation(); return false; } ); /** * On click out */ $( 'html' ).on( 'click', $.proxy( function () { if ( this.open ) { this.toggleIconSelector(); } }, this ) ); }, /** * Init */ init: function () { // Add the theme CSS to the iconPicker this.iconPicker.addClass( this.settings.theme ); // To properly calculate iconPicker height and width // We will first append it to body (with left: -9999px so that it is not visible) this.iconPicker.css( { left: - 9999 } ).appendTo( 'body' ); var iconPickerHeight = this.iconPicker.outerHeight(), iconPickerWidth = this.iconPicker.outerWidth(); // Now reset the iconPicker CSS this.iconPicker.css( { left: '' } ); // Add the icon picker after the select this.element.before( this.iconPicker ); // Hide source element // Instead of doing a display:none, we would rather // make the element invisible // and adjust the margin this.element.css( { visibility: 'hidden', top: 0, position: 'relative', zIndex: '-1', left: '-' + iconPickerWidth + 'px', display: 'none', height: iconPickerHeight + 'px', width: iconPickerWidth + 'px', // Reset all margin, border and padding padding: '0', margin: '0 -' + iconPickerWidth + 'px 0 0', // Left margin adjustment to account for dangling space border: '0 none', verticalAlign: 'top' } ).hide(); // Set the trigger event if ( ! this.element.is( 'select' ) ) { // Determine the event that is fired when user change the field value // Most modern browsers supports input event except IE 7, 8. // IE 9 supports input event but the event is still not fired if I press the backspace key. // Get IE version // https://gist.github.com/padolsey/527683/#comment-7595 var ieVersion = (function () { var v = 3, div = document.createElement( 'div' ), a = div.all || []; while ( div.innerHTML = '', a[ 0 ] ) { ; } return v > 4 ? v : ! v; }()); var el = document.createElement( 'div' ); this.triggerEvent = (ieVersion === 9 || ! ('oninput' in el)) ? [ 'keyup' ] : [ 'input', 'keyup' ]; // Let's keep the keyup event for scripts that listens to it } this.initCategories(); /** * Category changer */ this.selectCategory.on( 'change keyup', $.proxy( function ( e ) { // Don't do anything if not categorized if ( this.isCategorized === false ) { return false; } var targetSelect = $( e.currentTarget ), currentCategory = targetSelect.val(); // Check if all categories are selected if ( targetSelect.val() === 'all' ) { // Restore from the backups // @note These backups must be rebuild on source change, otherwise it will lead to error this.settings.source = this.backupSource; this.searchValues = this.backupSearch; // No? So there is a specified category } else { var key = parseInt( currentCategory, 10 ); if ( this.availableCategories[ key ] ) { this.settings.source = this.availableCategories[ key ]; this.searchValues = this.availableCategoriesSearch[ key ]; } } this.resetSearch(); this.loadIcons(); }, this ) ); /** * On down arrow click */ this.iconPicker.find( '.selector-button' ).on( 'click', $.proxy( function () { // Open/Close the icon picker this.toggleIconSelector(); }, this ) ); /** * Next page */ this.iconPicker.find( '.selector-arrow-right' ).on( 'click', $.proxy( function ( e ) { if ( this.currentPage < this.totalPage ) { this.iconPicker.find( '.selector-arrow-left' ).show(); this.currentPage = this.currentPage + 1; this.renderIconContainer(); this.renderIcons(); } if ( this.currentPage === this.totalPage ) { $( e.currentTarget ).hide(); } }, this ) ); /** * Prev page */ this.iconPicker.find( '.selector-arrow-left' ).on( 'click', $.proxy( function ( e ) { if ( this.currentPage > 1 ) { this.iconPicker.find( '.selector-arrow-right' ).show(); this.currentPage = this.currentPage - 1; this.renderIconContainer(); this.renderIcons(); } if ( this.currentPage === 1 ) { $( e.currentTarget ).hide(); } }, this ) ); /** * Realtime Icon Search */ this.iconPicker.find( '.icons-search-input' ).on( 'keyup', $.proxy( function ( e ) { // Get the search string var searchString = $( e.currentTarget ).val(); // If the string is not empty if ( searchString === '' ) { this.resetSearch(); return; } // Set icon search to X to reset search this.searchIcon.removeClass( this.settings.iconSearchClass ); this.searchIcon.addClass( this.settings.iconCancelClass ); // Set this as a search this.isSearch = true; // Reset current page this.currentPage = 1; // Actual search // This has been modified to search the searchValues instead // Then return the value from the source if match is found this.iconsSearched = []; $.grep( this.searchValues, $.proxy( function ( n, i ) { if ( n.toLowerCase().search( searchString.toLowerCase() ) >= 0 ) { this.iconsSearched[ this.iconsSearched.length ] = this.settings.source[ i ]; return true; } }, this ) ); // Filter duplicates this.iconsSearched = this.iconsSearched.filter( this.getOnlyUnique ); // Render icon list this.renderIconContainer(); this.renderIcons(); }, this ) ); /** * Quit search */ this.iconPicker.find( '.selector-search i' ).on( 'click', $.proxy( function () { this.iconPicker.find( '.icons-search-input' ).focus(); this.resetSearch(); }, this ) ); /** * On icon selected */ this.iconContainer.on( 'click', '.fip-box', $.proxy( function ( e ) { this.setSelectedIcon( $( e.currentTarget ).find( 'i' ).attr( 'data-fip-value' ) ); this.toggleIconSelector(); }, this ) ); /** * Stop click propagation on iconpicker */ this.iconPicker.on( 'click', function ( event ) { event.stopPropagation(); return false; } ); /** * On click out */ $( 'html' ).on( 'click', $.proxy( function () { if ( this.open ) { this.toggleIconSelector(); } }, this ) ); }, initCategories: function () { // If current element is SELECT populate settings.source if ( ! this.settings.source && this.element.is( 'select' ) ) { // Reset the source and searchSource // These will be populated according to the available options this.settings.source = []; this.settings.searchSource = []; // Check if optgroup is present within the select // If it is present then the source has to be grouped if ( this.element.find( 'optgroup' ).length ) { // Set the categorized to true this.isCategorized = true; this.element.find( 'optgroup' ).each( $.proxy( function ( i, el ) { // Get the key of the new category array var thisCategoryKey = this.availableCategories.length, // Create the new option for the selectCategory SELECT field categoryOption = $( '' ).prependTo( this.selectCategory ); // Show it and set default value to all categories this.selectCategory.show().val( 'all' ).trigger( 'change' ); }, /** * Load icons */ loadIcons: function () { // Set the content of the popup as loading this.iconContainer.html( '' ); // If source is set if ( this.settings.source instanceof Array ) { // Render icons this.renderIconContainer(); this.renderIcons(); this.setContainerSelectedItems(); } }, /** * Render icons inside the popup */ renderIconContainer: function () { var offset, iconsPaged = []; // Set a temporary array for icons if ( this.isSearch ) { iconsPaged = this.iconsSearched; } else { iconsPaged = this.settings.source; } // Remove duplicates iconsPaged = [ ...new Set( iconsPaged ) ]; // Count elements this.iconsCount = iconsPaged.length; // Calculate total page number this.totalPage = Math.ceil( this.iconsCount / this.settings.iconsPerPage ); // Hide footer if no pagination is needed if ( this.totalPage > 1 ) { this.iconPicker.find( '.selector-footer' ).show(); } else { this.iconPicker.find( '.selector-footer' ).hide(); } // Set the text for page number index and total icons this.iconPicker.find( '.selector-pages' ).html( this.currentPage + '/' + this.totalPage + ' (' + this.iconsCount + ')' ); // Set the offset for slice offset = (this.currentPage - 1) * this.settings.iconsPerPage; // Should empty icon be shown? if ( this.settings.emptyIcon ) { // Reset icon container HTML and prepend empty icon this.iconContainer.html( '' ); // If not show an error when no icons are found } else if ( iconsPaged.length < 1 ) { this.iconContainer.html( '' ); return; // else empty the container } else { this.iconContainer.html( '' ); } // Set an array of current page icons iconsPaged = iconsPaged.slice( offset, offset + this.settings.iconsPerPage ); this.iconsPaged = iconsPaged; // List icons /*for (var i = 0, item; item = iconsPaged[i++];) { // Set the icon title var flipBoxTitle = item; $.grep(this.settings.source, $.proxy(function (e, i) { if (e === item) { flipBoxTitle = this.searchValues[i]; return true; } return false; }, this)); // Set the icon box $('', { html: '', 'class': 'fip-box', title: flipBoxTitle }).appendTo(this.iconContainer); }*/ }, setContainerSelectedItems: function () { // If no empty icon is allowed and no current value is set or current value is not inside the icon set if ( ! this.settings.emptyIcon && (! this.element.val() || $.inArray( this.element.val(), this.settings.source ) === - 1) ) { // Get the first icon this.setSelectedIcon( this.iconsPaged[ 0 ] ); } else if ( $.inArray( this.element.val(), this.settings.source ) === - 1 ) { // Set empty this.setSelectedIcon(); } else { // Set the default selected icon even if not set this.setSelectedIcon( this.element.val() ); } }, /** * Set Highlighted icon */ setHighlightedIcon: function () { this.iconContainer.find( '.current-icon' ).removeClass( 'current-icon' ); if ( this.currentIcon ) { this.iconContainer.find( '[data-fip-value="' + this.currentIcon + '"]' ).parent( 'span' ).addClass( 'current-icon' ); } }, /** * Set selected icon * * @param {string} theIcon */ setSelectedIcon: function ( theIcon ) { if ( theIcon === this.settings.iconBlockClass ) { theIcon = ''; } // Check if attribute is to be used if ( this.settings.useAttribute ) { if ( theIcon ) { this.iconPicker.find( '.selected-icon' ).html( '' ); } else { this.iconPicker.find( '.selected-icon' ).html( '' ); } // Use class } else { this.iconPicker.find( '.selected-icon' ).html( '' ); } // Set the value of the element and trigger change event this.element.val( (theIcon === '' ? this.settings.emptyIconValue : theIcon ) ).trigger( 'change' ); if ( this.triggerEvent !== null ) { // Trigger other events for ( var eventKey in this.triggerEvent ) { this.element.trigger( this.triggerEvent[ eventKey ] ); } } this.currentIcon = theIcon; this.setHighlightedIcon(); }, /** * Open/close popup (toggle) */ toggleIconSelector: function () { this.open = (! this.open) ? 1 : 0; this.iconPicker.find( '.selector-popup' ).slideToggle( 300 ); this.iconPicker.find( '.selector-button i' ).toggleClass( this.settings.iconDownClass ); this.iconPicker.find( '.selector-button i' ).toggleClass( this.settings.iconUpClass ); if ( this.open ) { this.iconPicker.find( '.icons-search-input' ).focus().select(); if ( ! this.initialized ) { this.renderIconContainer(); this.renderIcons(); this.initialized = true; } } }, renderIcons: function () { for ( var i = 0; i < this.iconsPaged.length; i ++ ) { var item = this.iconsPaged[ i ]; // Set the icon title var flipBoxTitle = item; $.grep( this.settings.source, $.proxy( function ( e, i ) { if ( e === item ) { flipBoxTitle = this.searchValues[ i ]; return true; } return false; }, this ) ); // Set the icon box $( '', { html: '', 'class': 'fip-box', title: flipBoxTitle } ).appendTo( this.iconContainer ); } this.setContainerSelectedItems(); }, /** * Reset search */ resetSearch: function () { // Empty input this.iconPicker.find( '.icons-search-input' ).val( '' ); // Reset search icon class this.searchIcon.removeClass( this.settings.iconCancelClass ); this.searchIcon.addClass( this.settings.iconSearchClass ); // Go back to page 1 and remove back arrow this.iconPicker.find( '.selector-arrow-left' ).hide(); this.currentPage = 1; this.isSearch = false; // Rerender icons this.renderIconContainer(); this.renderIcons(); // Restore pagination if needed if ( this.totalPage > 1 ) { this.iconPicker.find( '.selector-arrow-right' ).show(); } } }; // Lightweight plugin wrapper $.fn.vcFontIconPicker = function ( options ) { // Instantiate the plugin this.each( function () { if ( ! $.data( this, "vcFontIconPicker" ) ) { $.data( this, "vcFontIconPicker", new Plugin( this, options ) ); } } ); // setIcons method this.setIcons = $.proxy( function ( newIcons, iconSearch ) { if ( undefined === newIcons ) { newIcons = false; } if ( undefined === iconSearch ) { iconSearch = false; } this.each( function () { $.data( this, "vcFontIconPicker" ).settings.source = newIcons; $.data( this, "vcFontIconPicker" ).settings.searchSource = iconSearch; $.data( this, "vcFontIconPicker" ).initSourceIndex(); $.data( this, "vcFontIconPicker" ).resetSearch(); $.data( this, "vcFontIconPicker" ).loadIcons(); } ); }, this ); // destroy method this.destroyPicker = $.proxy( function () { this.each( function () { if ( ! $.data( this, "vcFontIconPicker" ) ) { return; } // Remove the iconPicker $.data( this, "vcFontIconPicker" ).iconPicker.remove(); // Reset the CSS $.data( this, "vcFontIconPicker" ).element.css( { visibility: '', top: '', position: '', zIndex: '', left: '', display: 'block', height: '', width: '', padding: '', margin: '', border: '', verticalAlign: '' } ).show(); // destroy data $.removeData( this, "vcFontIconPicker" ); } ); }, this ); // reInit method this.refreshPicker = $.proxy( function ( newOptions ) { if ( ! newOptions ) { newOptions = options; } // First destroy this.destroyPicker(); // Now reset this.each( function () { if ( ! $.data( this, "vcFontIconPicker" ) ) { $.data( this, "vcFontIconPicker", new Plugin( this, newOptions ) ); } } ); }, this ); return this; }; })( jQuery ); # Changelog ## [Unreleased] ## [1.0.4] - 2024-05-02 ### Fixed - Fix implicit nullable deprecation warning for PHP 8.4 ## [1.0.3] - 2022-01-10 ### Changed - Update PHPstan to 1.0 - Switched to GitHub Actions ## [1.0.2] - 2020-07-15 ### Added - Minor performance improvements ## [1.0.1] - 2020-06-16 ### Fixed - When calling `Punycode::decode()`, the case flags array would fail to populate when given an empty array. ## [1.0.0] - 2020-06-09 - Initial release

Come funziona la protezione contro le charge‑back nei casinò online e perché è importante per chi gioca ai bonus

Negli ultimi anni i pagamenti digitali hanno rivoluzionato il modo in cui i giocatori accedono ai casinò online. La velocità delle transazioni, la possibilità di depositare con carte di credito, portafogli elettronici o criptovalute ha reso il gioco più accessibile, ma ha anche introdotto nuove vulnerabilità. Tra queste, le charge‑back rappresentano una delle minacce più insidiose: si tratta di una reversa del pagamento avviata dal titolare della carta o dall’istituto finanziario, spesso a causa di una transazione contestata o di un sospetto di frode.

Quando una charge‑back viene avviata, l’intero importo del deposito può essere sottratto dal conto del casinò, con conseguenze immediate sia per l’operatore sia per il giocatore. Per gli operatori, la perdita di fondi può tradursi in costi amministrativi e nella necessità di rivedere le proprie politiche di bonus. Per i giocatori, la conseguenza più evidente è la potenziale cancellazione dei bonus già ricevuti, poiché molte offerte includono clausole che prevedono la restituzione del bonus in caso di contestazione del deposito.

Per approfondire le opzioni disponibili e confrontare le offerte più sicure, è possibile consultare risorse come siti scommesse, che forniscono una panoramica delle piattaforme più affidabili.

1. Che cos’è una charge‑back e perché può minacciare i tuoi bonus

Una charge‑back è una procedura di rimborso avviata dal titolare di una carta di credito o dal proprio istituto bancario, che annulla una transazione già effettuata. Non è una semplice restituzione: il denaro viene prelevato dal conto del merchant (in questo caso il casinò) e restituito al cliente, spesso senza che il merchant abbia la possibilità di contestare immediatamente.

Le cause più comuni includono:
Transazioni non riconosciute: il titolare della carta non ricorda di aver effettuato il deposito.
Frode: un criminale utilizza dati rubati per finanziare il conto di gioco.
Errori di pagamento: importi errati o doppi addebiti.

Nel contesto dei bonus, la maggior parte dei termini e condizioni prevede che il giocatore mantenga il deposito originale per un certo periodo e completi i requisiti di wagering. Se una charge‑back viene accettata, il casinò perde il denaro su cui aveva basato l’erogazione del bonus. Di conseguenza, l’operatore può revocare il bonus, bloccare i fondi associati o, nei casi più gravi, chiudere l’account.

Un esempio pratico: un nuovo giocatore riceve un bonus benvenuto del 100 % fino a €200 dopo aver depositato €100. Se la banca del giocatore avvia una charge‑back sul deposito di €100, il casinò si troverà a dover restituire €200 (deposito più bonus) senza aver ricevuto alcun valore reale. Per evitare questa perdita, gli operatori hanno sviluppato sistemi di protezione specifici, che analizzeremo nei paragrafi successivi.

2. I meccanismi di verifica adottati dai casinò online

Procedura KYC (Know Your Customer)

Il KYC richiede al giocatore di fornire documenti d’identità, prova di residenza e, talvolta, una copia della carta di pagamento. Questi dati consentono al casinò di verificare che il titolare della carta sia realmente il proprietario dell’account, riducendo drasticamente le possibilità di charge‑back per “transazioni non riconosciute”.

Autenticazione a due fattori (2FA)

Molti operatori offrono la 2FA per le operazioni di deposito e prelievo. Dopo aver inserito le credenziali, il giocatore riceve un codice temporaneo via SMS o app di autenticazione. Solo chi possiede il dispositivo può confermare la transazione, rendendo più difficile per un truffatore utilizzare dati rubati.

Analisi comportamentale e algoritmi anti‑fraud

I sistemi di intelligenza artificiale monitorano il comportamento di gioco in tempo reale: frequenza dei depositi, importi, giochi preferiti e pattern di puntata. Se un nuovo utente effettua un deposito di €500 e subito richiede un prelievo di €490, l’algoritmo segnala l’attività come sospetta e blocca temporaneamente l’account fino a una verifica manuale.

Meccanismo Scopo Beneficio per il giocatore
KYC Verifica identità Riduce il rischio di blocchi improvvisi
2FA Conferma transazione Aumenta la sicurezza del conto
Analisi comportamentale Rileva attività anomale Evita contestazioni e charge‑back

Questi strumenti, combinati, creano una rete di difesa multilivello che rende più difficile per un cliente o un truffatore avviare una charge‑back senza che il casinò possa intervenire tempestivamente.

3. Come i bonus sono protetti dalle charge‑back

Clausole “wagering” e “turnover”

Le condizioni di wagering richiedono al giocatore di scommettere un multiplo del valore del bonus (es. 30x €50 = €1500) prima di poter prelevare. Finché il requisito non è soddisfatto, i fondi del bonus rimangono “bloccati” e non possono essere oggetto di charge‑back, poiché il casinò non ha ancora trasferito valore reale al giocatore.

Fondi “bloccati” fino al completamento dei requisiti

Alcuni operatori segregano i depositi associati al bonus in un conto interno separato. Solo dopo il completamento del turnover, i fondi vengono trasferiti al saldo principale, rendendo più difficile per la banca contestare l’intera somma.

Verifica del bonus al momento del prelievo

Quando il giocatore richiede un payout, il sistema esegue una doppia verifica: controlla che non vi siano charge‑back pendenti e che tutti i requisiti di bonus siano stati rispettati. Se emerge una contestazione, il prelievo viene sospeso e il supporto del casinò interviene per risolvere la questione prima di liberare i fondi.

Un caso reale: un giocatore ha ricevuto un bonus di ricarica del 50 % su un deposito di €200. Dopo aver completato 20x il turnover, il sistema sblocca €300 (deposito + bonus). Se la banca avvia una charge‑back sul deposito originale, il casinò può trattenere il bonus già “guadagnato” perché il turnover è stato completato, proteggendo così la propria esposizione.

4. I principali fornitori di servizi di charge‑back protection

Chargeback Gurus

Specializzata nella gestione delle dispute, offre un cruscotto per monitorare le richieste di charge‑back in tempo reale e fornisce linee guida per rispondere rapidamente.

PaySafe

Fornisce un gateway di pagamento con integrazione di strumenti antifrode avanzati, inclusi controlli di geolocalizzazione e verifica dell’indirizzo IP.

Worldpay

Con una rete globale, Worldpay utilizza modelli predittivi per identificare transazioni ad alto rischio e offre servizi di recupero fondi in caso di charge‑back accettata.

Questi provider si collegano direttamente ai sistemi di pagamento dei casinò, creando un flusso continuo di dati sulla transazione. Per il giocatore, ciò si traduce in tempi di risoluzione più rapidi, meno interruzioni del gioco e una maggiore trasparenza sullo stato delle proprie operazioni.

5. Cosa devi fare tu per ridurre il rischio di charge‑back

  • Tieni traccia delle transazioni: salva le ricevute e controlla regolarmente il tuo estratto conto.
  • Usa metodi di pagamento certificati: carte di credito con 3D Secure, portafogli elettronici come Skrill o Neteller, o criptovalute su piattaforme affidabili.
  • Non condividere credenziali: password, codici 2FA e informazioni personali devono rimanere confidenziali.

Impostare avvisi di spesa e limiti di deposito

Molti casinò consentono di definire limiti giornalieri, settimanali o mensili. Attivare questi avvisi aiuta a evitare depositi involontari che potrebbero generare contestazioni.

Passi da seguire in caso di controversia

  1. Contatta immediatamente il supporto del casinò tramite chat live o email.
  2. Fornisci la prova del deposito (screenshot, estratto conto).
  3. Evita di aprire direttamente una disputa con la banca finché il casinò non ha risposto; spesso può risolvere la questione senza coinvolgere l’istituto finanziario.

Seguendo queste pratiche, il giocatore riduce al minimo le probabilità di incorrere in una charge‑back e mantiene intatti i propri bonus.

6. L’impatto della protezione charge‑back sui termini dei bonus

Bonus “senza protezione charge‑back”

Alcuni operatori più piccoli offrono bonus generosi ma non implementano sistemi anti‑fraud. In questi casi, i termini di payout includono clausole severe: “Il bonus sarà revocato in caso di charge‑back” e spesso non è previsto alcun periodo di blocco, lasciando il giocatore vulnerabile.

Bonus offerti da operatori con sistemi avanzati

Operatori che collaborano con provider come PaySafe o Worldpay tendono a includere clausole più equilibrate, ad esempio: “Il bonus rimarrà valido anche in caso di contestazione, purché il turnover sia completato”. Queste offerte spesso non richiedono requisiti di “refund” (restituzione del bonus) e presentano un payout più trasparente.

Come leggere le clausole

  • Verifica la presenza di “charge‑back protection” nella sezione Termini & Condizioni.
  • Controlla i requisiti di wagering: un turnover più alto può indicare una maggiore protezione.
  • Cerca indicazioni su “blocked funds”: se i fondi sono segregati, il rischio è minore.

Consultare risorse come Beyond Events può aiutare a confrontare rapidamente le politiche dei vari operatori, senza però attribuire a tale sito valutazioni o classifiche specifiche.

7. Futuro della sicurezza dei pagamenti nei casinò online

Blockchain e smart contract

Le transazioni basate su blockchain offrono una tracciabilità immutabile. Gli smart contract possono automatizzare il rilascio dei bonus solo dopo il completamento del wagering, eliminando la necessità di interventi manuali e riducendo le possibilità di charge‑back.

Intelligenza artificiale e machine learning

Gli algoritmi di AI stanno diventando sempre più sofisticati nel riconoscere pattern di frode in pochi secondi. L’apprendimento continuo permette di adattarsi a nuove tattiche di truffatori, migliorando la precisione delle segnalazioni.

Normative europee: PSD2 e GDPR

La direttiva PSD2 impone l’autenticazione forte del cliente (SCA) per tutte le transazioni online, aumentando la sicurezza dei pagamenti. Il GDPR, d’altro canto, obbliga gli operatori a proteggere i dati personali, riducendo il rischio di furti di identità che possono portare a charge‑back.

Queste innovazioni, combinate con una maggiore consapevolezza dei giocatori, stanno creando un ecosistema più sicuro, dove i bonus possono essere goduti senza timore di perdere i fondi a causa di dispute ingiustificate.

Conclusione

Abbiamo esplorato cosa sia una charge‑back, perché rappresenti una minaccia per i bonus e come i casinò online abbiano sviluppato sistemi di verifica, KYC, 2FA e analisi comportamentale per prevenirla. I bonus sono protetti tramite clausole di wagering, fondi bloccati e verifiche al momento del payout. I provider specializzati, come Chargeback Gurus, PaySafe e Worldpay, offrono soluzioni che accelerano la risoluzione delle dispute, mentre i giocatori possono ridurre il rischio mantenendo una buona gestione delle proprie transazioni e impostando limiti di spesa.

Infine, la protezione charge‑back influisce direttamente sui termini dei bonus: gli operatori più avanzati offrono condizioni più trasparenti e meno penalizzanti. Guardando al futuro, blockchain, AI e normative come PSD2 promettono ulteriori miglioramenti nella sicurezza dei pagamenti.

Per chi desidera giocare in tutta tranquillità, è consigliabile verificare le politiche di protezione dei propri operatori preferiti, consultare risorse affidabili come Beyond Events e sfruttare al meglio le offerte bonus, sapendo di essere tutelati contro le charge‑back.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top