Contratto tecnico provider Cercaviaggio

Endpoint / documentazione integrazione

Questa pagina descrive gli endpoint oggi compatibili con le integrazioni attive in produzione. Partiamo subito con il contratto stabile v1 e teniamo la parte checkout in una sezione separata, marcata come evolutiva.

Panoramica contratto

Ultimo aggiornamento: 10/04/2026. Gli endpoint real-time obbligatori per Cercaviaggio sono search e quote. Gli endpoint sync_* sono necessari per importare fermate, linee, corse e tariffe base.

Contratto stabile v1
Routing endpoint: la reference implementation attuale usa api2.php?rquest=nome_endpoint. Esempio: https://provider.example.com/rest/cercaviaggio/api2.php?rquest=search.
Nota di versione: quando aggiungiamo nuovi vincoli o nuovi flussi, aggiorniamo questa pagina e incrementiamo il contratto.

Formato risposta standard

Tutti gli endpoint devono rispondere in JSON con envelope uniforme. In caso di errore success vale false e il dettaglio va in error.

{
    "success": true,
    "contract_version": "v1",
    "provider": "provider_code",
    "request_id": "cv_65f6f3e0f1d2e4.12345678",
    "data": {
        "status": "ok"
    },
    "error": null
}

Endpoint obbligatori di sync

Endpoint Metodo Parametri Uso
health GET nessuno Controllo rapido disponibilita provider e versione contratto.
sync_stops GET page, page_size, updated_since(opz.) Esporta fermate e metadati geografici/stato.
sync_lines GET page, page_size, updated_since(opz.) Esporta linee attive/visibili del provider.
sync_trips GET page, page_size, updated_since(opz.) Esporta corse e fermate ordinate per ogni corsa.
sync_fares GET page, page_size, updated_since(opz.) Esporta tariffe base fermata-fermata. Copertura attuale: base_route_fares_only.

Esempio item sync_stops

{
    "external_id": "118",
    "stop_id": 118,
    "name": "SALERNO - P.za Montpellier - P.co Pinocchio",
    "description": "Terminal autobus",
    "lat": 40.6773,
    "lon": 14.7676,
    "localita": 1,
    "address": {
        "indirizzo": "Piazza Montpellier",
        "comune": "Salerno",
        "provincia": "SA",
        "paese": "Italia"
    },
    "country_code": "IT",
    "timezone": "Europe/Rome",
    "sospensione": {
        "da": null,
        "a": null
    },
    "is_active": true,
    "updated_at": null
}

Esempio item sync_trips

{
    "external_id": "4123",
    "trip_id": 4123,
    "line_id": 3,
    "name": "SALERNO-ROMA",
    "tempo_acquisto": 30,
    "gruppo": "",
    "recapiti": "",
    "transitoria": 0,
    "direction_id": 1,
    "is_active": true,
    "is_visible": true,
    "stops": [
        {
            "stop_id": 118,
            "sequence": 1,
            "time": "04:35",
            "day_offset": 0,
            "distance": 0,
            "is_active": true,
            "gtfs": {
                "gtfs": 0,
                "gtfs2": 0,
                "gtfs3": 0
            },
            "lat": 40.6773,
            "lon": 14.7676
        },
        {
            "stop_id": 149,
            "sequence": 5,
            "time": "07:40",
            "day_offset": 0,
            "distance": 267.4,
            "is_active": true,
            "gtfs": {
                "gtfs": 0,
                "gtfs2": 0,
                "gtfs3": 0
            },
            "lat": 41.9096,
            "lon": 12.5307
        }
    ],
    "updated_at": null
}
Regole sync: page_size massimo 1000, identificativi stabili nel tempo, risposta con items, page, page_size, total, has_more, next_page, synced_at. Il parametro updated_since e gia previsto, ma nelle reference implementation attuali puo essere ignorato se il database sorgente non espone un updated_at affidabile.

Endpoint real-time obbligatori

Endpoint Metodo Parametri Uso
search GET part, arr, ad, bam, dt1, dt2(opz.) Restituisce le soluzioni del provider con segmenti e fares disponibili.
verifica_corse GET stessi parametri di search Alias di compatibilita storica. Deve comportarsi come search.
quote GET o POST part, arr, id_corsa, ad, bam, dt1, fare_id/id_promo(opz.), direction(opz.) Congela prezzo e disponibilita del segmento e restituisce quote_token.
locations GET indicator, query(opz.), departure_id se indicator=2 Helper opzionale per autocomplete/legacy app. Non e il cuore del contratto Cercaviaggio.

Struttura minima search

Input minimo: part, arr, ad, bam, dt1 in formato dd/mm/YYYY. dt2 e opzionale per ritorno.

{
    "solution_id": "c05f64f7a1a147f0e7a2d845",
    "direction": "outbound",
    "departure_datetime": "2026-03-21T04:35:00+01:00",
    "arrival_datetime": "2026-03-21T07:40:00+01:00",
    "duration_minutes": 185,
    "provider_corsa_ids": [
        4123
    ],
    "segments": [
        {
            "provider": "provider_code",
            "corsa_id": 4123,
            "from_id": 118,
            "from_name": "SALERNO - P.za Montpellier - P.co Pinocchio",
            "to_id": 149,
            "to_name": "ROMA - Stazione Tiburtina",
            "departure_time": "04:35",
            "arrival_time": "07:40"
        }
    ],
    "fares": [
        {
            "fare_id": "PROMO-7",
            "label": "Promo Web",
            "amount": 19.9,
            "original_amount": 24.9,
            "discount_percent": 20,
            "seats_available": 12,
            "change_allowed": true
        }
    ]
}

Struttura minima quote

quote deve accettare GET o POST e restituire token firmato, prezzo scelto, prezzo originario e disponibilita.

{
    "part": 118,
    "arr": 149,
    "id_corsa": 4123,
    "ad": 1,
    "bam": 0,
    "dt1": "21/03/2026",
    "fare_id": "PROMO-7",
    "direction": "outbound"
}
{
    "quote_id": "6fd2f9a2a1b7cc11ef3d6a88",
    "quote_token": "eyJ2IjoxLCJwcm92aWRlciI6InByb3ZpZGVyX2NvZGUifQ.signed",
    "status": "confirmed",
    "issued_at": "2026-03-17T10:45:00+00:00",
    "expires_at": "2026-03-17T10:55:00+00:00",
    "ttl_seconds": 600,
    "trip": {
        "provider": "provider_code",
        "corsa_id": 4123,
        "direction": "outbound",
        "from_id": 118,
        "from_name": "SALERNO - P.za Montpellier - P.co Pinocchio",
        "to_id": 149,
        "to_name": "ROMA - Stazione Tiburtina",
        "departure_datetime": "2026-03-21T04:35:00+01:00",
        "arrival_datetime": "2026-03-21T07:40:00+01:00",
        "duration_minutes": 185
    },
    "passengers": {
        "ad": 1,
        "bam": 0,
        "total": 1
    },
    "pricing": {
        "fare_id": "PROMO-7",
        "label": "Promo Web",
        "amount": 19.9,
        "original_amount": 24.9,
        "discount_percent": 20,
        "seats_available": 12,
        "change_allowed": true,
        "currency": "EUR"
    }
}
Prezzi: per essere compatibili con Cercaviaggio il provider deve restituire nelle fares almeno amount, original_amount, discount_percent, seats_available e change_allowed. In questo modo possiamo decidere lato piattaforma se mostrare prezzo intero o scontato.

Endpoint checkout in evoluzione

Bozza attuale

Questi endpoint esistono gia nelle integrazioni di riferimento, ma il flusso definitivo di checkout/biglietteria sara completato in un passaggio successivo. Li pubblichiamo ora solo come base tecnica, non come contratto immutabile.

Endpoint Metodo Parametri Uso
reserve POST header X-Idempotency-Key, body quote_token Bozza attuale per riserva breve del segmento. Da considerare evolutiva.
book POST header X-Idempotency-Key, body quote_token, reservation_token(opz.), shop_id(opz.) Bozza attuale per finalizzazione/acquisto. Sara estesa quando chiudiamo il checkout end-to-end.
Nota importante: quando definiremo in modo finale checkout, emissione ticket, annulli e cambi, questa pagina verra aggiornata e versionata. Conviene comunque iniziare oggi con il contratto stabile di sync/search/quote, che e la parte gia sicura.

Regole minime di implementazione