| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /tmp/sc/ |
Upload File : |
<?php
/* Smarty version 3.1.30, created on 2026-06-27 05:56:50
from "/var/www/clients/client1/web17/web/includes/templates/templates/broker/api.tpl" */
/* @var Smarty_Internal_Template $_smarty_tpl */
if ($_smarty_tpl->_decodeProperties($_smarty_tpl, array (
'version' => '3.1.30',
'unifunc' => 'content_6a3f4a02795467_59190939',
'has_nocache_code' => false,
'file_dependency' =>
array (
'3e35569da40dac27313cefd46be6c2533ebef4b5' =>
array (
0 => '/var/www/clients/client1/web17/web/includes/templates/templates/broker/api.tpl',
1 => 1782148280,
2 => 'file',
),
),
'includes' =>
array (
),
),false)) {
function content_6a3f4a02795467_59190939 (Smarty_Internal_Template $_smarty_tpl) {
?>
<link rel="stylesheet" href="<?php echo @constant('SITE_URL');?>
/assets/css/cockpit.css?v=<?php echo filemtime((@constant('PATH_SYSTEM')).('/assets/css/cockpit.css'));?>
">
<div class="page-header">
<div class="stat-label"><a href="<?php echo @constant('SITE_URL');?>
/broker/" class="text-decoration-none">Vermittler-Portal</a> · API</div>
<h1 class="h3 mb-0">API & Schnittstelle</h1>
<div class="text-muted small mt-1">Erstellen Sie Zugangs-Token, um Schiffe & Anlauftermine abzufragen und Buchungen automatisiert anzulegen oder zu bearbeiten.</div>
</div>
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">Ihre API-Token</span>
<button class="btn btn-primary btn-sm" id="pkAddBtn"><i class="material-icons sm" style="vertical-align:-4px;">add</i> Token erstellen</button>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead><tr><th>Name / Zweck</th><th>Token-Präfix</th><th>Status</th><th>Erstellt</th><th>Zuletzt genutzt</th><th class="text-end">Aktion</th></tr></thead>
<tbody id="pkBody"><tr><td colspan="6" class="text-center text-muted py-4">Wird geladen …</td></tr></tbody>
</table>
</div>
<div class="card-footer text-muted small">Der vollständige Token wird aus Sicherheitsgründen <strong>nur einmal direkt nach dem Erstellen</strong> angezeigt. Bewahren Sie ihn sicher auf.</div>
</div>
<div class="card">
<div class="card-header fw-bold">Dokumentation für Partner</div>
<div class="card-body">
<h6 class="fw-bold">Basis-URL</h6>
<p><code><?php echo @constant('SITE_URL');?>
/api.php</code></p>
<h6 class="fw-bold mt-3">Authentifizierung</h6>
<p class="mb-1">Senden Sie Ihren Token bei jeder Anfrage – auf eine der folgenden Arten:</p>
<ul class="mb-2">
<li>Header <code>Authorization: Bearer IHR_TOKEN</code> <span class="text-muted">(empfohlen)</span></li>
<li>Header <code>X-API-Key: IHR_TOKEN</code></li>
<li>Query-Parameter <code>?api_key=IHR_TOKEN</code></li>
</ul>
<div class="alert alert-info small">
Mit einem Partner-Token können Sie <strong>Schiffe & Termine lesen</strong>, <strong>Preise berechnen</strong> sowie
Buchungen <strong>anlegen und bearbeiten</strong>. Bearbeiten/Lesen ist dabei strikt auf <strong>Ihre eigenen, über die API
angelegten Buchungen</strong> begrenzt – fremde Buchungen sind nicht zugänglich. Neue Buchungen werden automatisch Ihrem
Partner-Konto zugeordnet.
</div>
<h6 class="fw-bold mt-3">1) Schiffe abrufen</h6>
<p class="text-muted small mb-1">Alle Schiffe (eindeutige Namen) mit Anzahl Termine.</p>
<pre class="ml-code">GET /api.php?resource=event&action=ships
curl -H "Authorization: Bearer IHR_TOKEN" \
"https://seaside.pacim.de/api.php?resource=event&action=ships"
Antwort:
{ "ok": true, "ships": [ { "ship": "AIDAmar", "cruise_id": "...", "dates": 12 }, ... ] }</pre>
<h6 class="fw-bold mt-3">2) Anlauftermine abrufen</h6>
<p class="text-muted small mb-1">Termine, optional je Schiff und Zeitraum gefiltert. Mit <code>action=upcoming</code> nur kommende Termine.</p>
<pre class="ml-code">GET /api.php?resource=event&action=list&ship=AIDAmar&from=2026-07-01&active=1
curl -H "Authorization: Bearer IHR_TOKEN" \
"https://seaside.pacim.de/api.php?resource=event&action=list&ship=AIDAmar&from=2026-07-01&active=1"
Antwort:
{ "ok": true, "events": [
{ "id": 1149, "ship": "AIDAmar", "begin": "2026-07-03 11:00:00", "end": "2026-07-08 ...",
"indoor": 5, "outdoor": 30, "valet": 5, "active": 1 }, ... ] }</pre>
<h6 class="fw-bold mt-3">3) Preis berechnen <span class="text-muted fw-normal">(optional)</span></h6>
<pre class="ml-code">GET /api.php?resource=product&action=price&type=1&begin=2026-07-03&end=2026-07-08
# type: 1 = Hallenparkplatz, 2 = Außenparkplatz
Antwort: { "ok": true, "quote": { "duration": 5, "net": ..., "gross": ..., "commission": ... } }</pre>
<h6 class="fw-bold mt-3">4) Buchung anlegen</h6>
<p class="text-muted small mb-1">Legt Kunde, Rechnung und Buchung an. Die Buchung wird automatisch Ihrem Partner-Konto zugeordnet.</p>
<pre class="ml-code">POST /api.php?resource=booking&action=create
Content-Type: application/json
curl -X POST -H "Authorization: Bearer IHR_TOKEN" -H "Content-Type: application/json" \
"https://seaside.pacim.de/api.php?resource=booking&action=create" -d '{
"type": 1,
"begin": "2026-07-03",
"end": "2026-07-08",
"event_id": 1149,
"plate": "HRO-AB 123",
"guests": 2,
"car": "car",
"valet": false,
"products": [],
"checkin": "10:30",
"hint": "Bitte Stellplatz nahe Ausgang, reise mit Hund.",
"gender": 3,
"customer": {
"firstname": "Max", "lastname": "Mustermann",
"email": "max@example.com", "phone": "0381 ...",
"company": "Acme GmbH",
"street": "Musterstr. 1", "zip": "18119", "city": "Rostock"
}
}'
# booking_no/edit_hash NICHT mitsenden -> das System vergibt automatisch einen eindeutigen
# 6-stelligen Buchungscode (booking_no) UND ein 32-stelliges edit_hash (Capability-Token).
# hint: optionaler Freitext-Hinweis zur Buchung (kann später per update geändert werden).
# Postleitzahl: Feld "zip" (oder "zipcode") -> wird als Kunden-PLZ gespeichert.
# Rechnung auf Firma: gender = 3 (+ company); gender = 0 = Privatperson. gender top-level ODER in customer.
# car: car|transporter|camper|trailercar; valet:true = Fahrzeugübergabe; checkin "HH:MM".
# Zusatzfahrzeug: statt event_id "parent_booking_id" senden -> Event/Termin UND Rechnungsanschrift werden übernommen.
Antwort (booking_no = 6-stelliger Buchungscode, edit_hash = Capability-Token fuer Doc-Download):
{ "ok": true, "invoice_id": 122690, "booking_id": 114750, "booking_no": "462CTA", "edit_hash": "…32 hex…", "hint": "Bitte Stellplatz nahe Ausgang …",
"files": {
"booking_confirmation": "…/api.php?resource=booking&action=file&invoice_id=122690&edit_hash=…&type=booking&download=1",
"invoice": "…&type=invoice&download=1"
} }
# files.* sind direkte Download-Links: mit gueltigem edit_hash AUCH ohne Token aufrufbar
# (Buchungsbestaetigung type=booking; Rechnung type=invoice, nur mit Rechnungsnummer).</pre>
<h6 class="fw-bold mt-3">5) Eigene Buchung lesen</h6>
<pre class="ml-code">GET /api.php?resource=booking&action=get&invoice_id=122690
curl -H "Authorization: Bearer IHR_TOKEN" \
"https://seaside.pacim.de/api.php?resource=booking&action=get&invoice_id=122690"
# Liefert invoice, customer, bookings, positions + Links zu Buchungsbestätigung/Rechnung (PDF).
# Nur eigene Buchungen – sonst 403.</pre>
<h6 class="fw-bold mt-3">6) Eigene Buchung bearbeiten</h6>
<p class="text-muted small mb-1">Nur Buchungen, die über Ihren Token angelegt wurden. Es werden nur die gesendeten Felder geändert.</p>
<pre class="ml-code">POST /api.php?resource=booking&action=update
Content-Type: application/json
curl -X POST -H "Authorization: Bearer IHR_TOKEN" -H "Content-Type: application/json" \
"https://seaside.pacim.de/api.php?resource=booking&action=update" -d '{
"booking_id": 114750,
"guests": 3,
"plate": "HRO-XY 999",
"begin": "2026-07-04", "end": "2026-07-09",
"type": 2, // 1 = Halle, 2 = Außen (Stellplatz-Wechsel)
"valet": true, // VALET (1) statt Shuttle (0)
"extras": [4, 5], // VOLLSTÄNDIGE Liste der Zusatzprodukt-IDs ([] = alle entfernen)
"hint": "Geänderter Hinweis – Anhänger statt Hund.", // Freitext-Hinweis ändern
"address": { "street": "Musterstr. 1", "zip": "18119", "city": "Rostock", "country": "DE" }
}'
# type/valet/extras bauen die Positionen neu auf; der Preis wird serverseitig neu berechnet
# (kein "price" senden). PLZ via address.zip ODER customer.zip.
# Vor-/Nachname (firstname/lastname) sind NICHT änderbar und werden ignoriert.
# Wohnmobil/Gespann + Halle bzw. + VALET -> 422 invalid_combination.
Antwort: { "ok": true, "booking_id": 114750, "invoice_price": 302.52 }</pre>
<h6 class="fw-bold mt-3">7) Buchung suchen (Buchungscode + Nachname)</h6>
<p class="text-muted small mb-1">Kunden-Login-Logik: Buchung über <strong>booking_no</strong> (6-stelliger Buchungscode) + <strong>Nachname</strong> finden. Nur eigene Buchungen.</p>
<pre class="ml-code">POST /api.php?resource=booking&action=find
Content-Type: application/json
curl -X POST -H "Authorization: Bearer IHR_TOKEN" -H "Content-Type: application/json" \
"https://seaside.pacim.de/api.php?resource=booking&action=find" -d '{
"booking_no": "462CTA",
"lastname": "Mustermann"
}'
# Nachname case-insensitive; bei Firmenkunden ggf. Firmenname. Treffer nur bei exakter Übereinstimmung.
Antwort (Auszug):
{ "ok": true, "booking": {
"booking_id": 114750, "invoice_id": 122690, "booking_no": "462CTA", "edit_hash": "…32 hex…",
"cancelled": false, "status": "active", // active | cancelled (storniert)
"begin": "2026-07-03", "end": "2026-07-08", "type": 1, "valet": 0,
"license_plate": "HRO-AB 123", "persons": 2, "checkin": "10:30",
"hint": "Bitte Stellplatz nahe Ausgang, reise mit Hund.",
"customer": { "firstname": "Max", "lastname": "Mustermann", … },
"event": { "ship_name": "AIDAmar", "event_id": 1149, … }
} }
# Nicht gefunden / falscher Nachname: { "ok": false, "error": "not_found" }
# Anreise heute/in der Vergangenheit: { "ok": false, "error": "booking_past" } – Buchung wird nicht mehr ausgeliefert (auch get/file).
# Mit booking_no + edit_hash aus der Antwort: Doc-Download via action=file (siehe oben).</pre>
<h6 class="fw-bold mt-3">Fehlerantworten</h6>
<pre class="ml-code">401 { "ok": false, "error": "Ungültiger oder fehlender API-Schlüssel." }
403 { "ok": false, "error": "Kein Zugriff auf diese Buchung." } # fremde Buchung
404 { "ok": false, "error": "Buchung nicht gefunden." }</pre>
<p class="text-muted small mt-2 mb-0">Bei Fragen zur Schnittstelle wenden Sie sich an info@parken-am-schiff.de.</p>
</div>
</div>
<div class="modal fade" id="pkCreateModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header"><h5 class="modal-title">Neuen API-Token erstellen</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<div class="modal-body">
<label class="form-label">Name / Zweck</label>
<input type="text" class="form-control" id="pkName" placeholder="z. B. Buchungssystem Reisebüro" autocomplete="off">
<div class="form-text">Nur zur Wiedererkennung. Der Token erhält automatisch die Partner-Berechtigungen.</div>
<div class="small mt-2" id="pkCreateMsg"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Abbrechen</button>
<button type="button" class="btn btn-primary" id="pkCreateSave"><i class="material-icons sm" style="vertical-align:-4px;">vpn_key</i> Erstellen</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="pkShowModal" tabindex="-1" data-bs-backdrop="static" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header"><h5 class="modal-title">Ihr neuer API-Token</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<div class="modal-body">
<div class="alert alert-warning small mb-2">Bitte jetzt kopieren – dieser Token wird <strong>nicht erneut angezeigt</strong>.</div>
<div class="input-group">
<input type="text" class="form-control" id="pkShowValue" readonly style="font-family:ui-monospace,monospace;">
<button class="btn btn-outline-secondary" id="pkCopyBtn" type="button"><i class="material-icons sm" style="vertical-align:-4px;">content_copy</i></button>
</div>
<div class="small text-success mt-1 d-none" id="pkCopied">In die Zwischenablage kopiert.</div>
</div>
<div class="modal-footer"><button type="button" class="btn btn-primary" data-bs-dismiss="modal">Fertig</button></div>
</div>
</div>
</div>
<style>
.ml-code{ background:#0f1b2d; color:#e6edf5; border-radius:8px; padding:12px 14px; font-size:12.5px; line-height:1.5; overflow:auto; white-space:pre; }
#pkBody .form-check-input{ -webkit-appearance:auto; appearance:auto; width:1.1em; height:1.1em; min-height:auto; margin:0; }
</style>
<?php echo '<script'; ?>
src="<?php echo @constant('SITE_URL');?>
/assets/js/broker-api-keys.js?v=<?php echo filemtime((@constant('PATH_SYSTEM')).('/assets/js/broker-api-keys.js'));?>
"><?php echo '</script'; ?>
>
<?php }
}