feat(cards): implement full saved card management and transparent checkout
- ApiCardModels.swift: SavedCard, SaveCardPayload, CreditCardOrderPayload, etc. - ApiOrderModels.swift: add savedCardId, clientCpfCnpj, creditCard, creditCardHolderInfo to CreateOrderPayload; Codable for item/addon payloads - ApiService.swift: listCards, saveCard, updateCard, deleteCard, updateProfileCpf - AppState.ProfileState: add cpf field - CheckoutView: CardSelectionSheet (list saved cards + add new), rewrite PaymentCardView (submits order with card data), CardPaymentContext carries full order data - CheckoutView+Logic: buildCreateOrderPayload accepts card params, new loadSavedCards/confirmOrderWithSavedCard/handleOrderResponse helpers, redirect credit card confirm to CardSelectionSheet - OrdersView: CREDIT_CARD pending orders go to tracking (not card form, since card is now submitted with order) - UserProfileView: CPF field with mask, save via PATCH /api/customer/profile
This commit is contained in:
67
pedi-foods/Sources/PediFoods/Services/ApiCardModels.swift
Normal file
67
pedi-foods/Sources/PediFoods/Services/ApiCardModels.swift
Normal file
@@ -0,0 +1,67 @@
|
||||
import Foundation
|
||||
|
||||
struct SavedCard: Decodable, Identifiable, Hashable {
|
||||
let id: String
|
||||
let nickname: String?
|
||||
let holderName: String
|
||||
let last4: String
|
||||
let brand: String?
|
||||
let expiryMonth: String
|
||||
let expiryYear: String
|
||||
let isDefault: Bool
|
||||
|
||||
var displayLabel: String {
|
||||
if let nickname, nickname.isEmpty == false { return nickname }
|
||||
let brandLabel = (brand ?? "Cartão").capitalized
|
||||
return "\(brandLabel) •••• \(last4)"
|
||||
}
|
||||
|
||||
var expiryLabel: String { "\(expiryMonth)/\(expiryYear)" }
|
||||
}
|
||||
|
||||
struct SaveCardCreditCardPayload: Encodable {
|
||||
let holderName: String
|
||||
let number: String
|
||||
let expiryMonth: String
|
||||
let expiryYear: String
|
||||
let ccv: String
|
||||
}
|
||||
|
||||
struct SaveCardHolderInfoPayload: Encodable {
|
||||
let name: String
|
||||
let email: String
|
||||
let cpfCnpj: String
|
||||
let postalCode: String
|
||||
let addressNumber: String
|
||||
let phone: String
|
||||
}
|
||||
|
||||
struct SaveCardPayload: Encodable {
|
||||
let creditCard: SaveCardCreditCardPayload
|
||||
let creditCardHolderInfo: SaveCardHolderInfoPayload
|
||||
let nickname: String?
|
||||
let isDefault: Bool
|
||||
}
|
||||
|
||||
struct UpdateCardPayload: Encodable {
|
||||
let nickname: String?
|
||||
let isDefault: Bool?
|
||||
}
|
||||
|
||||
struct SavedCardResult: Decodable {
|
||||
let id: String
|
||||
let holderName: String
|
||||
let last4: String
|
||||
let brand: String?
|
||||
let expiryMonth: String
|
||||
let expiryYear: String
|
||||
let isDefault: Bool
|
||||
}
|
||||
|
||||
struct CreditCardOrderPayload: Encodable {
|
||||
let holderName: String
|
||||
let number: String
|
||||
let expiryMonth: String
|
||||
let expiryYear: String
|
||||
let ccv: String
|
||||
}
|
||||
Reference in New Issue
Block a user