clean up stripe id verification

online_payment
Raz 7 months ago
parent 4baf30647d
commit 02969cc971
  1. 139
      PadelClub/Views/Tournament/Screen/RegistrationSetupView.swift

@ -30,6 +30,7 @@ struct RegistrationSetupView: View {
@State private var enableTimeToConfirm: Bool
@State private var isTemplate: Bool
@State private var isCorporateTournament: Bool
@State private var isValidating = false
// Online Payment
@State private var enableOnlinePayment: Bool
@ -297,31 +298,21 @@ struct RegistrationSetupView: View {
}
}
})
.toolbar(content: {
if focusedField != nil {
ToolbarItem(placement: .topBarLeading) {
Button("Annuler", role: .cancel) {
focusedField = nil
}
}
}
})
.toolbar {
if focusedField != nil {
if focusedField == ._stripeAccountId, stripeAccountId.isEmpty == false {
ToolbarItem(placement: .keyboard) {
HStack {
if focusedField == ._stripeAccountId, stripeAccountId.isEmpty == false {
Button("Effacer") {
stripeAccountId = ""
tournament.stripeAccountId = nil
}
.buttonStyle(.borderless)
Spacer()
Button("Valider") {
focusedField = nil
}
.buttonStyle(.bordered)
Button("Effacer") {
stripeAccountId = ""
stripeAccountIdIsInvalid = false
tournament.stripeAccountId = nil
}
.buttonStyle(.borderless)
Spacer()
Button("Valider") {
focusedField = nil
}
.buttonStyle(.bordered)
}
}
}
@ -418,12 +409,24 @@ struct RegistrationSetupView: View {
if isCorporateTournament == false, dataStore.user.registrationPaymentMode.requiresStripe() {
VStack(alignment: .leading) {
TextField("Identifiant du compte Stripe", text: $stripeAccountId)
.frame(maxWidth: .infinity)
.keyboardType(.default)
.focused($focusedField, equals: ._stripeAccountId)
LabeledContent {
if isValidating {
ProgressView()
} else if focusedField == nil, stripeAccountIdIsInvalid == false, stripeAccountId.isEmpty == false, isValidating == false {
Image(systemName: "checkmark.circle.fill").foregroundStyle(.green)
}
} label: {
TextField("Identifiant du compte Stripe", text: $stripeAccountId)
.frame(maxWidth: .infinity)
.keyboardType(.default)
.focused($focusedField, equals: ._stripeAccountId)
.disabled(isValidating)
}
if stripeAccountIdIsInvalid {
Text("Format d'identifiant Stripe invalide.").foregroundStyle(.logoRed)
Text("Identifiant Stripe invalide. Vous ne pouvez pas activer le paiement en ligne.").foregroundStyle(.logoRed)
Button("Ré-essayer") {
_confirmStripeAccountId()
}
}
}
}
@ -450,7 +453,7 @@ struct RegistrationSetupView: View {
}
.onChange(of: focusedField) { old, new in
if old == ._stripeAccountId {
_hasChanged()
_confirmStripeAccountId()
}
}
@ -461,12 +464,86 @@ struct RegistrationSetupView: View {
if stripeAccountId.isEmpty {
tournament.stripeAccountId = nil
} else if stripeAccountId.count >= 5, stripeAccountId.starts(with: "acct_") {
tournament.stripeAccountId = stripeAccountId.prefixMultilineTrimmed(255)
_checkStripeAccount(stripeAccountId.prefixMultilineTrimmed(255))
} else {
stripeAccountIdIsInvalid = true
}
}
private func _checkStripeAccount(_ accId: String) {
Task {
isValidating = true
do {
let response = try await _validateStripeAccountID(accId)
stripeAccountId = accId
stripeAccountIdIsInvalid = response.valid == false
enableOnlinePayment = response.valid
} catch {
stripeAccountIdIsInvalid = true
enableOnlinePayment = false
}
isValidating = false
}
}
private func _validateStripeAccountID(_ accountID: String) async throws -> ValidationResponse {
let apiPath = "\(URLs.activationHost.rawValue)/utils/validate-stripe-account/"
let url = URL(string: apiPath)!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body = ["account_id": accountID]
request.httpBody = try JSONEncoder().encode(body)
do {
let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse else {
throw ValidationError.invalidResponse
}
switch httpResponse.statusCode {
case 200...299:
let decodedResponse = try JSONDecoder().decode(ValidationResponse.self, from: data)
return decodedResponse
case 400:
// Handle bad request
let errorResponse = try JSONDecoder().decode(ValidationResponse.self, from: data)
return errorResponse
case 403:
// Handle permission error
let errorResponse = try JSONDecoder().decode(ValidationResponse.self, from: data)
return errorResponse
default:
throw ValidationError.invalidResponse
}
} catch let error as ValidationError {
throw error
} catch {
throw ValidationError.networkError(error)
}
}
struct ValidationResponse: Codable {
let valid: Bool
let account: AccountDetails?
let error: String?
}
struct AccountDetails: Codable {
let id: String
enum CodingKeys: String, CodingKey {
case id
}
}
enum ValidationError: Error {
case invalidResponse
case networkError(Error)
case invalidData
}
private func _hasChanged() {
hasChanges = true
}
@ -496,7 +573,11 @@ struct RegistrationSetupView: View {
}
tournament.enableTimeToConfirm = enableTimeToConfirm
_confirmStripeAccountId()
if stripeAccountIdIsInvalid == false {
tournament.stripeAccountId = stripeAccountId
} else {
tournament.stripeAccountId = nil
}
} else {
tournament.accountIsRequired = true
tournament.licenseIsRequired = true

Loading…
Cancel
Save