149 lines
5.4 KiB
Vue
149 lines
5.4 KiB
Vue
<script setup lang="ts">
|
|
import { router } from '@inertiajs/vue3';
|
|
import axios from 'axios';
|
|
import { onMounted, ref } from 'vue';
|
|
|
|
interface Props {
|
|
message: string;
|
|
clientSessionId: string;
|
|
paymentProvider: 'stripe' | 'wise';
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
const checking = ref(true);
|
|
const pollCount = ref(0);
|
|
const maxPolls = 30; // Poll for 5 minutes (30 * 10 seconds)
|
|
|
|
// Poll payment status every 10 seconds
|
|
const checkPaymentStatus = async () => {
|
|
try {
|
|
const endpoint = props.paymentProvider === 'wise' ? '/wise/validate-payment' : '/stripe/validate-payment';
|
|
|
|
const response = await axios.get(endpoint, {
|
|
params: { client_session_id: props.clientSessionId },
|
|
});
|
|
|
|
if (response.data.success) {
|
|
// Payment succeeded! Redirect to success page
|
|
window.location.href = `/success?client_session_id=${props.clientSessionId}`;
|
|
} else {
|
|
pollCount.value++;
|
|
|
|
if (pollCount.value >= maxPolls) {
|
|
// Stop polling after max attempts
|
|
checking.value = false;
|
|
} else {
|
|
// Continue polling
|
|
setTimeout(checkPaymentStatus, 10000); // Check again in 10 seconds
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Error checking payment status:', error);
|
|
pollCount.value++;
|
|
|
|
if (pollCount.value < maxPolls) {
|
|
setTimeout(checkPaymentStatus, 10000);
|
|
} else {
|
|
checking.value = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
// Start polling after 2 seconds
|
|
setTimeout(checkPaymentStatus, 2000);
|
|
});
|
|
|
|
const refreshPage = () => {
|
|
window.location.reload();
|
|
};
|
|
|
|
const goHome = () => {
|
|
router.visit('/');
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex min-h-screen items-center justify-center bg-gradient-to-br from-[var(--light-ivory)] via-white to-[var(--linen)] px-4">
|
|
<div class="w-full max-w-md rounded-2xl border border-[var(--linen)] bg-white/90 p-8 shadow-xl backdrop-blur-sm">
|
|
<!-- Animated Loading Icon -->
|
|
<div class="mb-6 flex justify-center">
|
|
<div class="relative h-20 w-20">
|
|
<svg class="animate-spin text-[var(--subtle-gold)]" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
<path
|
|
class="opacity-75"
|
|
fill="currentColor"
|
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
></path>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Title -->
|
|
<h1 class="mb-4 text-center text-2xl font-bold text-[var(--midnight-blue)] md:text-3xl">Payment en cours</h1>
|
|
|
|
<!-- Message -->
|
|
<p class="mb-6 text-center text-base text-[var(--spiritual-earth)]">
|
|
{{ message }}
|
|
</p>
|
|
|
|
<!-- Provider Info -->
|
|
<div class="mb-6 rounded-lg bg-[var(--light-ivory)] p-4">
|
|
<p class="text-center text-sm text-[var(--midnight-blue)]">
|
|
<span class="font-semibold">Fournisseur de paiement:</span>
|
|
<span class="ml-2 capitalize">{{ paymentProvider }}</span>
|
|
</p>
|
|
<p v-if="checking" class="mt-2 text-center text-xs text-[var(--spiritual-earth)]">
|
|
Vérification automatique en cours... ({{ pollCount }}/{{ maxPolls }})
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Status Message -->
|
|
<div v-if="!checking" class="mb-6 rounded-lg border border-yellow-300 bg-yellow-50 p-4">
|
|
<p class="text-center text-sm text-yellow-800">
|
|
Le paiement prend plus de temps que prévu. Cela peut prendre quelques minutes pour que {{ paymentProvider }} traite votre
|
|
paiement.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="flex flex-col gap-3">
|
|
<button
|
|
v-if="!checking"
|
|
@click="refreshPage"
|
|
class="w-full rounded-full bg-[var(--subtle-gold)] px-6 py-3 font-semibold text-[var(--midnight-blue)] shadow-md transition-all duration-300 hover:shadow-lg"
|
|
>
|
|
Vérifier à nouveau
|
|
</button>
|
|
|
|
<button
|
|
@click="goHome"
|
|
class="w-full rounded-full border-2 border-[var(--midnight-blue)] bg-transparent px-6 py-3 font-semibold text-[var(--midnight-blue)] transition-all duration-300 hover:bg-[var(--midnight-blue)] hover:text-white"
|
|
>
|
|
Retour à l'accueil
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Help Text -->
|
|
<p class="mt-6 text-center text-xs text-[var(--spiritual-earth)]">
|
|
Si le problème persiste, veuillez contacter notre support avec votre ID de session:
|
|
<br />
|
|
<code class="mt-1 block rounded bg-gray-100 px-2 py-1 text-[10px]">{{ clientSessionId }}</code>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
@keyframes spin {
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
.animate-spin {
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
</style>
|