fix online payment

online_payment
Raz 7 months ago
parent c1ac3ed998
commit 430af36802
  1. 3
      PadelClub/Data/CustomUser.swift
  2. 42
      PadelClub/Utils/Network/ConfigurationService.swift
  3. 18
      PadelClub/Views/Navigation/Agenda/EventListView.swift
  4. 19
      PadelClub/Views/Navigation/Umpire/UmpireView.swift
  5. 20
      PadelClub/Views/Shared/OnlineWaitingListFaqSheetView.swift
  6. 16
      PadelClub/Views/Shared/PaymentInfoSheetView.swift
  7. 10
      PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift

@ -20,6 +20,9 @@ enum RegistrationPaymentMode: Int, Codable {
case noFee = 2 case noFee = 2
case stripe = 3 case stripe = 3
static let stripeFixedFee = 0.25 // Fixed fee in euros
static let stripePercentageFee = 0.014 // 1.4%
func canEnableOnlinePayment() -> Bool { func canEnableOnlinePayment() -> Bool {
switch self { switch self {
case .disabled: case .disabled:

@ -28,13 +28,13 @@ struct TimeToConfirmConfig: Codable {
let timeProximityRules: [String: Int] let timeProximityRules: [String: Int]
let waitingListRules: [String: Int] let waitingListRules: [String: Int]
let businessRules: BusinessRules let businessRules: BusinessRules
let urgencyOverride: UrgencyOverride let minimumResponseTime: Int
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case timeProximityRules = "time_proximity_rules" case timeProximityRules = "time_proximity_rules"
case waitingListRules = "waiting_list_rules" case waitingListRules = "waiting_list_rules"
case businessRules = "business_rules" case businessRules = "business_rules"
case urgencyOverride = "urgency_override" case minimumResponseTime = "minimum_response_time"
} }
// Default configuration // Default configuration
@ -54,61 +54,25 @@ struct TimeToConfirmConfig: Codable {
businessRules: BusinessRules( businessRules: BusinessRules(
hours: Hours( hours: Hours(
start: 8, start: 8,
end: 21, end: 21
defaultConfirmationHour: 8
),
days: Days(
workingDays: [0, 1, 2, 3, 4, 5, 6],
weekend: []
) )
), ),
urgencyOverride: UrgencyOverride(
thresholds: [
"24": true,
"12": true
],
minimumResponseTime: 30 minimumResponseTime: 30
) )
)
} }
struct BusinessRules: Codable { struct BusinessRules: Codable {
let hours: Hours let hours: Hours
let days: Days
} }
struct Hours: Codable { struct Hours: Codable {
let start: Int let start: Int
let end: Int let end: Int
let defaultConfirmationHour: Int
private enum CodingKeys: String, CodingKey { private enum CodingKeys: String, CodingKey {
case start case start
case end case end
case defaultConfirmationHour = "default_confirmation_hour"
}
}
struct Days: Codable {
let workingDays: [Int]
let weekend: [Int]
private enum CodingKeys: String, CodingKey {
case workingDays = "working_days"
case weekend
}
}
struct UrgencyOverride: Codable {
let thresholds: [String: Bool]
let minimumResponseTime: Int
private enum CodingKeys: String, CodingKey {
case thresholds
case minimumResponseTime = "minimum_response_time"
} }
} }

@ -206,17 +206,29 @@ struct EventListView: View {
if dataStore.user.canEnableOnlinePayment() { if dataStore.user.canEnableOnlinePayment() {
Menu { Menu {
let templateTournament = Tournament.getTemplateTournament()
if let templateTournament {
NavigationLink {
RegistrationSetupView(tournament: templateTournament)
} label: {
Text("Voir le tournoi référence")
}
} else {
Text("Aucun tournoi référence")
}
if let templateTournament {
Button { Button {
if let templateTournament = Tournament.getTemplateTournament() {
pcTournaments.forEach { tournament in pcTournaments.forEach { tournament in
if tournament.onlineRegistrationCanBeEnabled() { if tournament.onlineRegistrationCanBeEnabled() {
tournament.setupRegistrationSettings(templateTournament: templateTournament) tournament.setupRegistrationSettings(templateTournament: templateTournament)
} }
} }
dataStore.tournaments.addOrUpdate(contentOfs: pcTournaments) dataStore.tournaments.addOrUpdate(contentOfs: pcTournaments)
}
} label: { } label: {
Text("Utiliser les réglages par défaut") Text("Utiliser ces réglages par défaut")
}
} }
} label: { } label: {
Text("Inscription et paiement en ligne") Text("Inscription et paiement en ligne")

@ -177,6 +177,25 @@ struct UmpireView: View {
} }
} }
if dataStore.user.canEnableOnlinePayment() {
Section {
if let tournamentTemplate = Tournament.getTemplateTournament() {
NavigationLink {
RegistrationSetupView(tournament: tournamentTemplate)
} label: {
Text("Référence")
Text(tournamentTemplate.tournamentTitle()).foregroundStyle(.secondary)
}
} else {
Text("Aucun tournoi référence. Choisissez-en un dans la liste d'activité")
}
} header: {
Text("Inscription et paiement en ligne")
} footer: {
Text("Tournoi référence utilisé pour les réglages des inscriptions en ligne")
}
}
Section { Section {
@Bindable var user = dataStore.user @Bindable var user = dataStore.user
Toggle(isOn: $user.disableRankingFederalRuling) { Toggle(isOn: $user.disableRankingFederalRuling) {

@ -32,9 +32,8 @@ struct OnlineWaitingListFaqSheetView: View {
// Get waiting list rules // Get waiting list rules
let waitingRules = timeToConfirmConfig.waitingListRules let waitingRules = timeToConfirmConfig.waitingListRules
// Get urgency thresholds // Get minimum response time
let urgencyThresholds = timeToConfirmConfig.urgencyOverride.thresholds let minResponseTime = timeToConfirmConfig.minimumResponseTime
let minResponseTime = timeToConfirmConfig.urgencyOverride.minimumResponseTime
return """ return """
FAQ pour les Arbitres - Confirmation des Équipes FAQ pour les Arbitres - Confirmation des Équipes
@ -53,23 +52,20 @@ struct OnlineWaitingListFaqSheetView: View {
- Tournoi dans plus de 72h \(formatMinutes(defaultTime)) - Tournoi dans plus de 72h \(formatMinutes(defaultTime))
Ces délais peuvent être raccourcis en fonction du nombre d'équipes en liste d'attente : Ces délais peuvent être raccourcis en fonction du nombre d'équipes en liste d'attente :
- \(waitingRules["30"] ?? 30)+ équipes en attente \(formatMinutes(waitingRules["30"] ?? 30)) - \(waitingRules["30"] ?? 30)+ équipes en attente \(formatMinutes(30))
- \(waitingRules["20"] ?? 20)+ équipes en attente \(formatMinutes(waitingRules["20"] ?? 60)) - \(waitingRules["20"] ?? 20)+ équipes en attente \(formatMinutes(60))
- \(waitingRules["10"] ?? 10)+ équipes en attente \(formatMinutes(waitingRules["10"] ?? 120)) - \(waitingRules["10"] ?? 10)+ équipes en attente \(formatMinutes(120))
Y a-t-il des exceptions à ces règles ? Y a-t-il des exceptions à ces règles ?
Oui, dans les situations urgentes : Oui, dans les situations urgentes :
- Si le tournoi commence dans moins de 24h, les restrictions d'heures ouvrables sont ignorées - Si le tournoi commence dans moins de 24h, les heures ouvrables s'étendent de 7h à 22h
- Si le tournoi commence dans moins de 12h, toutes les restrictions sont assouplies avec un minimum de \(minResponseTime) minutes de délai - Si le tournoi commence dans moins de 12h, les heures ouvrables s'étendent de 6h à 1h du matin
- Un délai minimum de \(minResponseTime) minutes est toujours respecté
Comment les délais sont-ils arrondis ? Comment les délais sont-ils arrondis ?
Les délais sont toujours arrondis à la demi-heure supérieure pour plus de simplicité. Les délais sont toujours arrondis à la demi-heure supérieure pour plus de simplicité.
Que se passe-t-il si le délai tombe en dehors des heures ouvrables ?
Si le délai calculé tombe en dehors des heures ouvrables (avant \(startHour)h ou après \(endHour)h), il est automatiquement reporté au jour ouvrable suivant à \(timeToConfirmConfig.businessRules.hours.defaultConfirmationHour)h du matin.
""" """
} }

@ -9,8 +9,14 @@ import SwiftUI
struct PaymentInfoSheetView: View { struct PaymentInfoSheetView: View {
@Environment(\.dismiss) private var dismiss @Environment(\.dismiss) private var dismiss
let paymentInfoText: String = let paymentConfig: PaymentConfig
"""
var paymentInfoText: String {
let stripePlatformFee = (paymentConfig.stripeFee * 100).formatted(.number.precision(.fractionLength(2)))
let stripePercentageFee = (RegistrationPaymentMode.stripePercentageFee * 100).formatted(.number.precision(.fractionLength(1)))
let stripeFixedFee = RegistrationPaymentMode.stripeFixedFee.formatted(.number.precision(.fractionLength(2)))
return """
Comment fonctionnent les paiements en ligne ? Comment fonctionnent les paiements en ligne ?
Les paiements en ligne permettent aux joueurs de régler les frais de tournoi directement via la plateforme. Voici les informations importantes à connaître : Les paiements en ligne permettent aux joueurs de régler les frais de tournoi directement via la plateforme. Voici les informations importantes à connaître :
@ -28,9 +34,9 @@ struct PaymentInfoSheetView: View {
- Les remboursements sont automatiquement traités via la même méthode de paiement utilisée - Les remboursements sont automatiquement traités via la même méthode de paiement utilisée
Commissions et frais : Commissions et frais :
- Padel Club prélève une commission de 0,75% sur chaque transaction - Padel Club prélève une commission de \(stripePlatformFee)% sur chaque transaction
- Cette commission couvre les frais de service et de maintenance de la plateforme - Cette commission couvre les frais de service et de maintenance de la plateforme
- Des frais supplémentaires de Stripe peuvent s'appliquer (environ 1,4% + 0,25 par transaction) - Des frais supplémentaires de Stripe s'appliquent (\(stripePercentageFee)% + \(stripeFixedFee) par transaction)
- Le montant total des frais est indiqué clairement avant validation du paiement - Le montant total des frais est indiqué clairement avant validation du paiement
Exigences pour les organisateurs : Exigences pour les organisateurs :
@ -46,6 +52,8 @@ struct PaymentInfoSheetView: View {
En cas de problème avec un paiement, veuillez contacter l'organisateur du tournoi ou le support Padel Club. En cas de problème avec un paiement, veuillez contacter l'organisateur du tournoi ou le support Padel Club.
""" """
}
var body: some View { var body: some View {
NavigationView { NavigationView {
ScrollView { ScrollView {

@ -177,7 +177,7 @@ struct RegistrationSetupView: View {
do { do {
self.timeToConfirmConfig = try await ConfigurationService.fetchTournamentConfig() self.timeToConfirmConfig = try await ConfigurationService.fetchTournamentConfig()
} catch { } catch {
print("Error fetching configuration: \(error)") print("Error fetching timeToConfirmConfig: \(error)")
} }
} }
} }
@ -290,7 +290,7 @@ struct RegistrationSetupView: View {
OnlineWaitingListFaqSheetView(timeToConfirmConfig: timeToConfirmConfig ?? TimeToConfirmConfig.defaultConfig) OnlineWaitingListFaqSheetView(timeToConfirmConfig: timeToConfirmConfig ?? TimeToConfirmConfig.defaultConfig)
} }
.sheet(isPresented: $showMorePaymentInfos) { .sheet(isPresented: $showMorePaymentInfos) {
PaymentInfoSheetView() PaymentInfoSheetView(paymentConfig: paymentConfig ?? PaymentConfig.defaultConfig)
} }
.toolbar(content: { .toolbar(content: {
@ -460,7 +460,7 @@ struct RegistrationSetupView: View {
do { do {
self.paymentConfig = try await ConfigurationService.fetchPaymentConfig() self.paymentConfig = try await ConfigurationService.fetchPaymentConfig()
} catch { } catch {
print("Error fetching configuration: \(error)") print("Error fetching paymentConfig: \(error)")
} }
} }
.onChange(of: [enableOnlinePayment, onlinePaymentIsMandatory, enableOnlinePaymentRefund]) { .onChange(of: [enableOnlinePayment, onlinePaymentIsMandatory, enableOnlinePaymentRefund]) {
@ -480,8 +480,8 @@ struct RegistrationSetupView: View {
if dataStore.user.registrationPaymentMode.requiresStripe() { if dataStore.user.registrationPaymentMode.requiresStripe() {
Section { Section {
let fixedFee = 0.25 // Fixed fee in euros let fixedFee = RegistrationPaymentMode.stripeFixedFee // Fixed fee in euros
let percentageFee = 0.012 // 1.2% let percentageFee = RegistrationPaymentMode.stripePercentageFee
let totalStripeFee = fixedFee + (entryFee * percentageFee) let totalStripeFee = fixedFee + (entryFee * percentageFee)
LabeledContent { LabeledContent {

Loading…
Cancel
Save