241 lines
13 KiB
PHP
241 lines
13 KiB
PHP
@extends('template.layout')
|
|
|
|
@section('content')
|
|
@php
|
|
$isSpanish = $datosPago['isSpanish'] ?? true;
|
|
$simbolo = $datosPago['simbolo'] ?? '$';
|
|
$total = $datosPago['total'] ?? 0;
|
|
$descripcionPago = $datosPago['descripcionPago'] ?? 'Reserva de vuelo';
|
|
$clipApiKey = config('clip.api_key', '');
|
|
$idCotizacion = $datosPago['id_cotizacion'] ?? 0;
|
|
|
|
$nombreVuelo = $datosPago['nombre_vuelo'] ?? 'Vuelo';
|
|
$jsonIncluye = $datosPago['json_incluye'] ?? [];
|
|
$cantidadPax = $datosPago['cantidad_pax'] ?? 0;
|
|
$precioUnitario = $datosPago['precio_unitario'] ?? 0;
|
|
$fechaVuelo = $datosPago['fecha_vuelo'] ?? null;
|
|
$adultos = $datosPago['adultos'] ?? 0;
|
|
$ninios = $datosPago['ninios'] ?? 0;
|
|
$responsable = $datosPago['responsable'] ?? [];
|
|
$adicionales = $datosPago['adicionales'] ?? [];
|
|
@endphp
|
|
|
|
<div class="booking-flow">
|
|
<div class="flight-details">
|
|
<div class="container">
|
|
<div class="details-grid">
|
|
<!-- COLUMNA IZQUIERDA: DETALLES DEL VUELO -->
|
|
<div class="main-card">
|
|
<div class="card-body">
|
|
<div class="flight-header">
|
|
<div class="flight-title">
|
|
<h1>{{ $nombreVuelo }}</h1>
|
|
<div class="subtitle">
|
|
<strong>{{ $isSpanish ? 'Folio' : 'Folio' }}:</strong> {{ $datosPago['vuelo_folio'] ?? '' }}
|
|
</div>
|
|
</div>
|
|
<div class="price-box">
|
|
@if(false) {{-- Si tuvieras descuento, aquí se mostraría --}}
|
|
<div class="price-old">{{ $simbolo }}999.99</div>
|
|
@endif
|
|
<div class="price-current">{{ $simbolo }}{{ number_format($total, 2) }}</div>
|
|
<div class="price-label">{{ $isSpanish ? 'Total a pagar' : 'Total to pay' }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="meta-info">
|
|
@if ($fechaVuelo)
|
|
<div class="meta-item">
|
|
<i class="fas fa-calendar-alt"></i>
|
|
{{ \Carbon\Carbon::parse($fechaVuelo)->format('d/m/Y') }}
|
|
</div>
|
|
@endif
|
|
<div class="meta-item">
|
|
<i class="fas fa-users"></i>
|
|
{{ $adultos }} {{ $isSpanish ? 'adultos' : 'adults' }}
|
|
@if ($ninios > 0) + {{ $ninios }} {{ $isSpanish ? 'niños' : 'children' }} @endif
|
|
</div>
|
|
@if ($cantidadPax > 0 && $precioUnitario > 0)
|
|
<div class="meta-item">
|
|
<i class="fas fa-tag"></i>
|
|
{{ $simbolo }}{{ number_format($precioUnitario, 2) }} x {{ $cantidadPax }} {{ $isSpanish ? 'pax' : 'pax' }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- EXTRAS COTIZADOS -->
|
|
@if (count($adicionales) > 0)
|
|
<div class="section">
|
|
<div class="section-subtitle">
|
|
<i class="fas fa-gem"></i>
|
|
{{ $isSpanish ? 'Extras cotizados' : 'Quoted extras' }}
|
|
</div>
|
|
<ul class="includes-list">
|
|
@foreach ($adicionales as $extra)
|
|
<li>
|
|
<i class="fas fa-plus-circle"></i>
|
|
{{ $isSpanish ? 'Servicio adicional' : 'Extra service' }} ID {{ $extra->id_servicio_adicional ?? 'N/A' }}
|
|
- {{ $simbolo }}{{ number_format($extra->precio_vendido ?? 0, 2) }}
|
|
({{ $extra->cantidades ?? 0 }} {{ $isSpanish ? 'unidad(es)' : 'unit(s)' }})
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- INCLUYE -->
|
|
@if (!empty($jsonIncluye) && is_array($jsonIncluye))
|
|
<div class="section">
|
|
<div class="section-subtitle">
|
|
<i class="fas fa-check-circle"></i>
|
|
{{ $isSpanish ? 'El vuelo incluye' : 'The flight includes' }}
|
|
</div>
|
|
<ul class="includes-list">
|
|
@foreach ($jsonIncluye as $item)
|
|
<li>
|
|
<i class="fas fa-check"></i>
|
|
{{ $item['titulo'] ?? '' }}
|
|
@if (!empty($item['subtitulo']))
|
|
<small> - {{ $item['subtitulo'] }}</small>
|
|
@endif
|
|
</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
<!-- DATOS DEL RESPONSABLE -->
|
|
@if (!empty($responsable['nombres']) || !empty($responsable['apellidos']))
|
|
<div class="section">
|
|
<div class="section-subtitle">
|
|
<i class="fas fa-user-circle"></i>
|
|
{{ $isSpanish ? 'Responsable' : 'Responsible' }}
|
|
</div>
|
|
<div class="info-list">
|
|
<li><i class="fas fa-user"></i> {{ $responsable['nombres'] ?? '' }} {{ $responsable['apellidos'] ?? '' }}</li>
|
|
<li><i class="fas fa-envelope"></i> {{ $responsable['email'] ?? '' }}</li>
|
|
<li><i class="fas fa-phone-alt"></i> {{ $responsable['telefono'] ?? '' }}</li>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<!-- COLUMNA DERECHA: FORMULARIO DE PAGO CON CLIP -->
|
|
<div class="sidebar">
|
|
<div class="sidebar-card">
|
|
<div class="card-title">
|
|
<i class="fas fa-credit-card"></i>
|
|
{{ $isSpanish ? 'Pagar con tarjeta' : 'Pay with card' }}
|
|
</div>
|
|
|
|
<form id="clip-payment-form">
|
|
<!-- Campos ocultos (necesarios para la lógica) -->
|
|
<div class="form-group" hidden>
|
|
<label>{{ $isSpanish ? 'Correo' : 'Email' }}</label>
|
|
<input type="email" id="payment_email" class="form-control" value="{{ $responsable['email'] ?? '' }}" hidden>
|
|
</div>
|
|
<div class="form-group" hidden>
|
|
<label>{{ $isSpanish ? 'Teléfono' : 'Phone' }}</label>
|
|
<input type="tel" id="payment_phone" class="form-control" value="{{ $responsable['telefono'] ?? '' }}" hidden>
|
|
</div>
|
|
<div class="form-group" hidden>
|
|
<label>{{ $isSpanish ? 'Descripción' : 'Description' }}</label>
|
|
<input type="text" id="payment_description" class="form-control" value="{{ $descripcionPago }}">
|
|
</div>
|
|
|
|
<!-- Widget de Clip -->
|
|
<div class="form-group">
|
|
<label>💳 {{ $isSpanish ? 'Datos de la tarjeta' : 'Card details' }}</label>
|
|
<div id="clip-checkout"></div>
|
|
</div>
|
|
|
|
<button type="submit" id="btnPagar" class="btn-pay">
|
|
<i class="fas fa-lock"></i>
|
|
{{ $isSpanish ? 'Pagar ahora' : 'Pay now' }}
|
|
</button>
|
|
|
|
<div class="trust-badges">
|
|
<div class="trust-badge"><i class="fas fa-shield-alt"></i> Pago 100% seguro</div>
|
|
<div class="trust-badge"><i class="fas fa-lock"></i> Datos encriptados</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('js')
|
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
|
|
<script src="https://sdk.clip.mx/js/clip-sdk.js"></script>
|
|
<script>
|
|
const ROUTE_SUCCESS = "/";
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const clipApiKey = @json($clipApiKey);
|
|
const isSpanish = @json($isSpanish);
|
|
const idCotizacion = @json($idCotizacion);
|
|
const API_TOKEN = "uI4mKo87A3donNXh3P2OUD9zjZOflQ4quyr9wqtO6pDRfdTD4cdvUKoHoF3BDeOq";
|
|
|
|
const clip = new ClipSDK(clipApiKey);
|
|
const clipCard = clip.element.create("Card", {
|
|
theme: document.body.classList.contains('light-mode') ? 'light' : 'dark',
|
|
locale: isSpanish ? "es" : "en"
|
|
});
|
|
clipCard.mount("clip-checkout");
|
|
|
|
document.getElementById('clip-payment-form').addEventListener('submit', async function(e) {
|
|
e.preventDefault();
|
|
const btn = document.getElementById('btnPagar');
|
|
try {
|
|
btn.disabled = true;
|
|
btn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> ' + (isSpanish ? 'Procesando...' : 'Processing...');
|
|
const cardToken = await clipCard.cardToken();
|
|
const payload = {
|
|
id_cotizacion: idCotizacion,
|
|
token: cardToken.id
|
|
};
|
|
const response = await axios.post('/api/vuelos/pago', payload, {
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'Authorization': `Bearer ${API_TOKEN}`
|
|
}
|
|
});
|
|
if (response.data.success) {
|
|
await Swal.fire({
|
|
icon: 'success',
|
|
title: isSpanish ? 'Pago exitoso' : 'Payment successful',
|
|
text: response.data.message,
|
|
background: 'var(--secondary)',
|
|
color: 'var(--text-primary)'
|
|
});
|
|
window.location.href = ROUTE_SUCCESS;
|
|
} else {
|
|
throw new Error(response.data.message);
|
|
}
|
|
} catch (error) {
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: isSpanish ? 'Error' : 'Error',
|
|
text: error.response?.data?.message || error.message,
|
|
background: 'var(--secondary)',
|
|
color: 'var(--text-primary)'
|
|
});
|
|
} finally {
|
|
btn.disabled = false;
|
|
btn.innerHTML = '<i class="fas fa-lock"></i> ' + (isSpanish ? 'Pagar ahora' : 'Pay now');
|
|
}
|
|
});
|
|
|
|
// Sincronizar tema de Clip con cambios de modo claro/oscuro (opcional)
|
|
const observer = new MutationObserver(() => {
|
|
const isLight = document.body.classList.contains('light-mode');
|
|
clipCard.update({ theme: isLight ? 'light' : 'dark' });
|
|
});
|
|
observer.observe(document.body, { attributes: true, attributeFilter: ['class'] });
|
|
});
|
|
</script>
|
|
@endpush |