Collegare WordPress al gestionale aziendale, al CRM o a servizi esterni è sempre più comune. Ma farlo male può esporre dati sensibili e rallentare il sito. Ecco il modo corretto.
Architettura di Integrazione
# Pattern consigliato
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ WordPress │────▶│ Middleware │────▶│ CRM/ERP │
│ (REST) │◀────│ (Queue) │◀────│ (API) │
└─────────────┘ └─────────────┘ └─────────────┘
# Vantaggi:
# - WordPress non esposto direttamente
# - Retry automatico in caso di errore
# - Rate limiting gestito
# - Log centralizzato
1. REST API Sicure in WordPress
Autenticazione Endpoint Custom
// Registra endpoint protetto
add_action( 'rest_api_init', function() {
register_rest_route( 'wpboutique/v1', '/sync-orders', [
'methods' => 'POST',
'callback' => 'sync_orders_callback',
'permission_callback' => 'verify_api_key',
]);
});
// Verifica API key
function verify_api_key( $request ) {
$api_key = $request->get_header( 'X-API-Key' );
$valid_key = get_option( 'external_api_key' );
if ( ! $api_key || ! hash_equals( $valid_key, $api_key ) ) {
return new wp_Error(
'unauthorized',
'API key non valida',
[ 'status' => 401 ]
);
}
return true;
}
// Callback protetto
function sync_orders_callback( $request ) {
$data = $request->get_json_params();
// Sanitizza TUTTO
$order_id = absint( $data['order_id'] ?? 0 );
$status = sanitize_text_field( $data['status'] ?? '' );
// Processa...
return rest_ensure_response( [ 'success' => true ] );
}
Rate Limiting
// Limita richieste per IP
function rate_limit_check( $request ) {
$ip = $_SERVER['REMOTE_ADDR'];
$transient_key = 'rate_limit_' . md5( $ip );
$count = get_transient( $transient_key ) ?: 0;
if ( $count >= 100 ) { // Max 100 richieste/minuto
return new wp_Error(
'rate_limited',
'Troppe richieste',
[ 'status' => 429 ]
);
}
set_transient( $transient_key, $count + 1, MINUTE_IN_SECONDS );
return true;
}
2. Chiamate API Esterne da WordPress
Pattern Corretto con wp_remote
// SEMPRE usare wp_remote_* invece di cURL diretto
function call_external_api( $endpoint, $data ) {
$response = wp_remote_post( $endpoint, [
'timeout' => 15, // Timeout ragionevole
'redirection' => 0, // No redirect automatici
'httpversion' => '1.1',
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . EXTERNAL_API_TOKEN,
],
'body' => wp_json_encode( $data ),
'sslverify' => true, // MAI disabilitare in produzione!
]);
if ( is_wp_error( $response ) ) {
// Log errore
error_log( 'API Error: ' . $response->get_error_message() );
return false;
}
$code = wp_remote_retrieve_response_code( $response );
$body = wp_remote_retrieve_body( $response );
if ( $code !== 200 ) {
error_log( "API returned {$code}: {$body}" );
return false;
}
return json_decode( $body, true );
}
Caching Risposte API
// Cache risposte per evitare chiamate ripetute
function get_external_data( $resource_id ) {
$cache_key = 'external_data_' . $resource_id;
$cached = get_transient( $cache_key );
if ( $cached !== false ) {
return $cached;
}
$data = call_external_api(
"https://api.example.com/resource/{$resource_id}"
);
if ( $data ) {
set_transient( $cache_key, $data, HOUR_IN_SECONDS );
}
return $data;
}
3. Webhook In Ingresso
Verificare Firma Webhook
// Verifica HMAC signature (standard per Stripe, GitHub, etc)
function verify_webhook_signature( $request ) {
$payload = $request->get_body();
$signature = $request->get_header( 'X-Signature' );
$secret = WEBHOOK_SECRET;
$expected = hash_hmac( 'sha256', $payload, $secret );
if ( ! hash_equals( $expected, $signature ) ) {
return new wp_Error(
'invalid_signature',
'Firma webhook non valida',
[ 'status' => 401 ]
);
}
return true;
}
4. Gestione Asincrona con Action Scheduler
Per operazioni lunghe, non bloccare la richiesta HTTP:
// Installa Action Scheduler (incluso in WooCommerce)
// oppure: composer require woocommerce/action-scheduler
// Schedula task invece di eseguirlo subito
function handle_order_webhook( $request ) {
$order_data = $request->get_json_params();
// Schedula processing asincrono
as_schedule_single_action(
time(),
'process_external_order',
[ 'order_data' => $order_data ],
'wpboutique'
);
// Rispondi subito (webhook non va in timeout)
return rest_ensure_response( [ 'queued' => true ] );
}
// Handler asincrono
add_action( 'process_external_order', function( $order_data ) {
// Elaborazione lunga qui...
// Se fallisce, Action Scheduler ritenta automaticamente
}, 10, 1 );
5. Sicurezza: Checklist
□ API key in variabili d'ambiente, MAI nel codice
□ HTTPS obbligatorio (sslverify = true)
□ Verifica firma per webhook
□ Rate limiting su endpoint esposti
□ Sanitizza TUTTO l'input
□ Log tutte le richieste per audit
□ Timeout ragionevoli (10-30s)
□ Retry con exponential backoff
□ Whitelist IP se possibile
Variabili d’Ambiente
// wp-config.php - Credenziali da environment
define( 'EXTERNAL_API_TOKEN', getenv( 'EXTERNAL_API_TOKEN' ) );
define( 'WEBHOOK_SECRET', getenv( 'WEBHOOK_SECRET' ) );
// In .env (non committare!)
EXTERNAL_API_TOKEN=your-secret-token
WEBHOOK_SECRET=your-webhook-secret
Devi integrare WordPress con il tuo gestionale? Progettiamo integrazioni sicure e scalabili. Contattaci per una consulenza architetturale.