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:
Daniel Arantes Loverde
2026-06-03 17:32:30 -03:00
parent 2d27240cee
commit 6b397db494
8 changed files with 636 additions and 177 deletions

View File

@@ -633,7 +633,6 @@ struct OrderEntryDestinationView: View {
@State var isResolvingRoute = true
@State var didResolve = false
@State var pixContext: PixPaymentContext? = nil
@State var cardContext: CardPaymentContext? = nil
@State var orderTrackingContext: OrderTrackingContext? = nil
@State var orderDetails: PublicOrderResult? = nil
@@ -658,16 +657,6 @@ struct OrderEntryDestinationView: View {
orderTrackingContext = OrderTrackingContext(orderId: pixContext.orderId, shortId: pixContext.shortId)
}
)
} else if let cardContext {
PaymentCardView(
context: cardContext,
onPaymentConfirmed: {
orderTrackingContext = OrderTrackingContext(orderId: cardContext.orderId, shortId: cardContext.shortId)
},
onOpenTracking: {
orderTrackingContext = OrderTrackingContext(orderId: cardContext.orderId, shortId: cardContext.shortId)
}
)
} else if let orderDetails {
OrderDetailsView(order: orderDetails, orderId: orderId, initialShortId: initialShortId)
} else {
@@ -725,11 +714,7 @@ struct OrderEntryDestinationView: View {
return
}
if normalizedMethod == "CREDIT_CARD" || normalizedMethod == "DEBIT_CARD" {
cardContext = CardPaymentContext(
orderId: order.id,
shortId: order.shortId ?? initialShortId,
total: order.total ?? fallbackTotal ?? 0
)
orderTrackingContext = OrderTrackingContext(orderId: order.id, shortId: order.shortId ?? initialShortId)
return
}
}