diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequest.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequest.kt index 13be574..304fb16 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequest.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequest.kt @@ -6,7 +6,7 @@ data class OrderRequest ( @SerializedName("address_id") val addressId : Int, - @SerializedName("payment_method_id") + @SerializedName("payment_info_id") val paymentMethodId : Int, @SerializedName("ship_price") @@ -21,7 +21,7 @@ data class OrderRequest ( @SerializedName("is_negotiable") val isNego: Boolean, - @SerializedName("cart_items_id") + @SerializedName("cart_item_ids") val cartItemId: List, @SerializedName("ship_etd") diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequestBuy.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequestBuy.kt index 8e0b154..7e358dd 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequestBuy.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/dto/OrderRequestBuy.kt @@ -6,7 +6,7 @@ data class OrderRequestBuy ( @SerializedName("address_id") val addressId : Int, - @SerializedName("payment_method_id") + @SerializedName("payment_info_id") val paymentMethodId : Int, @SerializedName("ship_price") diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/CreateOrderResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/CreateOrderResponse.kt index ec67669..62ca4aa 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/CreateOrderResponse.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/order/CreateOrderResponse.kt @@ -70,7 +70,7 @@ data class OrderItemItem( data class Order( - @field:SerializedName("payment_method_id") + @field:SerializedName("payment_info_id") val paymentMethodId: Int, @field:SerializedName("auto_completed_at") diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/product/DetailStoreProductResponse.kt b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/product/DetailStoreProductResponse.kt index 308674b..fa02d06 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/product/DetailStoreProductResponse.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/api/response/customer/product/DetailStoreProductResponse.kt @@ -16,7 +16,7 @@ data class PaymentInfoItem( val id: Int = 1, @field:SerializedName("qris_image") - val qrisImage: String, + val qrisImage: String? = null, @field:SerializedName("bank_num") val bankNum: String, diff --git a/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt b/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt index 210d900..5af3dac 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/data/repository/OrderRepository.kt @@ -2,7 +2,6 @@ package com.alya.ecommerce_serang.data.repository import android.util.Log import com.alya.ecommerce_serang.data.api.dto.AddEvidenceMultipartRequest -import com.alya.ecommerce_serang.data.api.dto.CartItem import com.alya.ecommerce_serang.data.api.dto.CompletedOrderRequest import com.alya.ecommerce_serang.data.api.dto.CourierCostRequest import com.alya.ecommerce_serang.data.api.dto.CreateAddressRequest @@ -326,59 +325,35 @@ class OrderRepository(private val apiService: ApiService) { } } -// suspend fun uploadPaymentProof(request : AddEvidenceRequest): Result { -// return try { -// Log.d("OrderRepository", "Add Evidence : $request") -// val response = apiService.addEvidence(request) -// -// if (response.isSuccessful) { -// val addEvidenceResponse = response.body() -// if (addEvidenceResponse != null) { -// Log.d("OrderRepository", "Add Evidence successfully: ${addEvidenceResponse.message}") -// Result.Success(addEvidenceResponse) -// } else { -// Log.e("OrderRepository", "Response body was null") -// Result.Error(Exception("Empty response from server")) -// } -// } else { -// val errorBody = response.errorBody()?.string() ?: "Unknown error" -// Log.e("OrderRepository", "Error Add Evidence : $errorBody") -// Result.Error(Exception(errorBody)) -// } -// } catch (e: Exception) { -// Log.e("OrderRepository", "Exception Add Evidence ", e) -// Result.Error(e) -// } -// } -suspend fun uploadPaymentProof(request: AddEvidenceMultipartRequest): Result { - return try { - Log.d("OrderRepository", "Uploading payment proof...") + suspend fun uploadPaymentProof(request: AddEvidenceMultipartRequest): Result { + return try { + Log.d("OrderRepository", "Uploading payment proof...") - val response = apiService.addEvidenceMultipart( - orderId = request.orderId, - amount = request.amount, - evidence = request.evidence - ) + val response = apiService.addEvidenceMultipart( + orderId = request.orderId, + amount = request.amount, + evidence = request.evidence + ) - if (response.isSuccessful) { - val addEvidenceResponse = response.body() - if (addEvidenceResponse != null) { - Log.d("OrderRepository", "Payment proof uploaded successfully: ${addEvidenceResponse.message}") - Result.Success(addEvidenceResponse) + if (response.isSuccessful) { + val addEvidenceResponse = response.body() + if (addEvidenceResponse != null) { + Log.d("OrderRepository", "Payment proof uploaded successfully: ${addEvidenceResponse.message}") + Result.Success(addEvidenceResponse) + } else { + Log.e("OrderRepository", "Response body was null") + Result.Error(Exception("Empty response from server")) + } } else { - Log.e("OrderRepository", "Response body was null") - Result.Error(Exception("Empty response from server")) + val errorBody = response.errorBody()?.string() ?: "Unknown error" + Log.e("OrderRepository", "Error uploading payment proof: $errorBody") + Result.Error(Exception(errorBody)) } - } else { - val errorBody = response.errorBody()?.string() ?: "Unknown error" - Log.e("OrderRepository", "Error uploading payment proof: $errorBody") - Result.Error(Exception(errorBody)) + } catch (e: Exception) { + Log.e("OrderRepository", "Exception uploading payment proof", e) + Result.Error(e) } - } catch (e: Exception) { - Log.e("OrderRepository", "Exception uploading payment proof", e) - Result.Error(e) } -} suspend fun getOrderList(status: String): Result { return try { diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt index 7b27eeb..bdabd56 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartActivity.kt @@ -1,6 +1,5 @@ package com.alya.ecommerce_serang.ui.cart -import android.content.Intent import android.os.Bundle import android.view.View import android.widget.Toast @@ -101,11 +100,15 @@ class CartActivity : AppCompatActivity() { if (viewModel.totalSelectedCount.value ?: 0 > 0) { val selectedItems = viewModel.prepareCheckout() if (selectedItems.isNotEmpty()) { - // Navigate to checkout - val intent = Intent(this, CheckoutActivity::class.java) - // You would pass the selected items to the next activity - // intent.putExtra("SELECTED_ITEMS", selectedItems) - startActivity(intent) + // Check if all items are from the same store + val storeId = viewModel.activeStoreId.value + if (storeId != null) { + // Get cart item ids to pass to checkout + val cartItemIds = selectedItems.map { it.cartItemId } + CheckoutActivity.startForCart(this, cartItemIds) + } else { + Toast.makeText(this, "Please select items from a single store only", Toast.LENGTH_SHORT).show() + } } } else { Toast.makeText(this, "Pilih produk terlebih dahulu", Toast.LENGTH_SHORT).show() @@ -182,4 +185,7 @@ class CartActivity : AppCompatActivity() { val format = NumberFormat.getCurrencyInstance(Locale("id", "ID")) return format.format(amount).replace("Rp", "Rp ") } -} \ No newline at end of file + + +} + diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartViewModel.kt index 7841376..cc54fd1 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/cart/CartViewModel.kt @@ -285,10 +285,12 @@ class CartViewModel(private val repository: OrderRepository) : ViewModel() { val selectedItemsIds = _selectedItems.value ?: HashSet() val result = mutableListOf() - _cartItems.value?.forEach { dataItem -> - dataItem.cartItems.forEach { cartItem -> - if (selectedItemsIds.contains(cartItem.cartItemId)) { - result.add(cartItem) + if (activeStoreId != null){ + _cartItems.value?.forEach { dataItem -> + dataItem.cartItems.forEach { cartItem -> + if (selectedItemsIds.contains(cartItem.cartItemId)) { + result.add(cartItem) + } } } } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt index f3f9628..88dd5f6 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutActivity.kt @@ -30,6 +30,7 @@ class CheckoutActivity : AppCompatActivity() { private lateinit var binding: ActivityCheckoutBinding private lateinit var sessionManager: SessionManager private var paymentAdapter: PaymentMethodAdapter? = null + private var paymentMethodsLoaded = false private val viewModel: CheckoutViewModel by viewModels { BaseViewModelFactory { @@ -80,10 +81,10 @@ class CheckoutActivity : AppCompatActivity() { } } - viewModel.getPaymentMethods { paymentMethods -> - // Logging is just for debugging - Log.d("CheckoutActivity", "Loaded ${paymentMethods.size} payment methods") - } +// viewModel.getPaymentMethods { paymentMethods -> +// // Logging is just for debugging +// Log.d("CheckoutActivity", "Loaded ${paymentMethods.size} payment methods") +// } } private fun setupToolbar() { @@ -97,6 +98,12 @@ class CheckoutActivity : AppCompatActivity() { viewModel.checkoutData.observe(this) { data -> setupProductRecyclerView(data) updateOrderSummary() + + if (data != null) { + viewModel.getPaymentMethods { paymentMethods -> + Log.d("CheckoutActivity", "Loaded ${paymentMethods.size} payment methods") + } + } } // Observe address details @@ -106,23 +113,27 @@ class CheckoutActivity : AppCompatActivity() { } viewModel.availablePaymentMethods.observe(this) { paymentMethods -> - if (paymentMethods.isNotEmpty()) { + if (paymentMethods.isNotEmpty() && !paymentMethodsLoaded) { + Log.d("CheckoutActivity", "Setting up payment methods: ${paymentMethods.size} methods available") setupPaymentMethodsRecyclerView(paymentMethods) + paymentMethodsLoaded = true } } -// Observe selected payment viewModel.selectedPayment.observe(this) { selectedPayment -> if (selectedPayment != null) { - // Update the adapter to show the selected payment - paymentAdapter?.setSelectedPaymentName(selectedPayment.name) + Log.d("CheckoutActivity", "Observer notified of selected payment: ${selectedPayment.name}") - // Optional: Update other UI elements to show the selected payment - // For example: binding.tvSelectedPaymentMethod.text = selectedPayment.name + // Update the adapter ONLY if it exists + paymentAdapter?.let { adapter -> + // This line was causing issues - using setSelectedPayment instead of setSelectedPaymentName + adapter.setSelectedPaymentId(selectedPayment.id) + + Log.d("CheckoutActivity", "Updated adapter with selected payment: ${selectedPayment.id}") + } } } - // Observe loading state viewModel.isLoading.observe(this) { isLoading -> binding.btnPay.isEnabled = !isLoading @@ -156,14 +167,18 @@ class CheckoutActivity : AppCompatActivity() { // Debug logging Log.d("CheckoutActivity", "Setting up payment methods: ${paymentMethods.size} methods available") - paymentAdapter = PaymentMethodAdapter(paymentMethods) { payment -> - // We're using a hardcoded ID for now - viewModel.setPaymentMethod(1) - } + if (paymentAdapter == null) { + paymentAdapter = PaymentMethodAdapter(paymentMethods) { payment -> + Log.d("CheckoutActivity", "Payment selected in adapter: ${payment.name}") - binding.rvPaymentMethods.apply { - layoutManager = LinearLayoutManager(this@CheckoutActivity) - adapter = paymentAdapter + // Set this payment as selected in the ViewModel + viewModel.setPaymentMethod(payment.id) + } + + binding.rvPaymentMethods.apply { + layoutManager = LinearLayoutManager(this@CheckoutActivity) + adapter = paymentAdapter + } } } @@ -347,7 +362,13 @@ class CheckoutActivity : AppCompatActivity() { } // Check if payment method is selected - if (viewModel.selectedPayment.value == null) { + val paymentMethodId = if (checkoutData.isBuyNow) { + (checkoutData.orderRequest as OrderRequestBuy).paymentMethodId + } else { + (checkoutData.orderRequest as OrderRequest).paymentMethodId + } + + if (paymentMethodId <= 0) { Toast.makeText(this, "Silakan pilih metode pembayaran", Toast.LENGTH_SHORT).show() return false } diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt index aa3b14e..cba73c1 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/CheckoutViewModel.kt @@ -112,6 +112,10 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { } if (matchingItems.isNotEmpty() && storeData != null) { + if (matchingItems.size != cartItemIds.size) { + Log.w(TAG, "Not all requested cart items were found. Found ${matchingItems.size} out of ${cartItemIds.size}") + // Consider showing a warning or adjusting the list + } // Create initial OrderRequest object val orderRequest = OrderRequest( addressId = 0, // Will be set when user selects address @@ -133,6 +137,10 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { isBuyNow = false, cartItems = matchingItems ) + Log.d(TAG, "Setting sellerId to: ${storeData.storeId}") + + calculateSubtotal() + calculateTotal() } else { _errorMessage.value = "No matching cart items found" } @@ -153,6 +161,13 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { try { val storeId = _checkoutData.value?.sellerId ?: return@launch + Log.d(TAG, "Attempting to fetch payment methods for storeId: $storeId") + + if (storeId == null || storeId <= 0) { + Log.e(TAG, "Invalid storeId: $storeId - cannot fetch payment methods") + return@launch + } + // Use fetchStoreDetail instead of getStore val storeResult = repository.fetchStoreDetail(storeId) @@ -161,7 +176,7 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { // This will be updated once the backend provides proper IDs val paymentMethodsList = storeResult.data.paymentInfo.map { paymentInfo -> PaymentInfoItem( - id = 1, // Hardcoded payment ID + id = paymentInfo.id ?: 1, name = paymentInfo.name, bankNum = paymentInfo.bankNum, qrisImage = paymentInfo.qrisImage @@ -170,7 +185,10 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { Log.d(TAG, "Fetched ${paymentMethodsList.size} payment methods") - _availablePaymentMethods.value = paymentMethodsList + // Only update if we don't already have payment methods + if (_availablePaymentMethods.value.isNullOrEmpty()) { + _availablePaymentMethods.value = paymentMethodsList + } callback(paymentMethodsList) } else { _availablePaymentMethods.value = emptyList() @@ -186,9 +204,6 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { // Updated setPaymentMethod function fun setPaymentMethod(paymentId: Int) { - // We'll use the hardcoded ID (1) for now - val currentPaymentId = 1 - viewModelScope.launch { try { // Get the available payment methods @@ -200,26 +215,30 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { return@launch } - // Use the first payment method (or specific one if you prefer) - val selectedPayment = paymentMethods.first() + val selectedPayment = paymentMethods.find { it.id == paymentId } - // Set the selected payment + if (selectedPayment == null) { + Log.e(TAG, "Payment with ID $paymentId not found") + return@launch + } + + // Set the selected payment - IMPORTANT: do this first _selectedPayment.value = selectedPayment - Log.d(TAG, "Payment selected: Name=${selectedPayment.name}") + Log.d(TAG, "Payment selected: ID=${selectedPayment.id}, Name=${selectedPayment.name}") - // Update the order request with the payment method ID (hardcoded for now) + // Update the order request with the payment method ID val currentData = _checkoutData.value ?: return@launch // Different handling for Buy Now vs Cart checkout if (currentData.isBuyNow) { // For Buy Now checkout val buyRequest = currentData.orderRequest as OrderRequestBuy - val updatedRequest = buyRequest.copy(paymentMethodId = currentPaymentId) + val updatedRequest = buyRequest.copy(paymentMethodId = paymentId) _checkoutData.value = currentData.copy(orderRequest = updatedRequest) } else { // For Cart checkout val cartRequest = currentData.orderRequest as OrderRequest - val updatedRequest = cartRequest.copy(paymentMethodId = currentPaymentId) + val updatedRequest = cartRequest.copy(paymentMethodId = paymentId) _checkoutData.value = currentData.copy(orderRequest = updatedRequest) } } catch (e: Exception) { @@ -299,6 +318,39 @@ class CheckoutViewModel(private val repository: OrderRepository) : ViewModel() { try { val data = _checkoutData.value ?: throw Exception("No checkout data available") + if (data.orderRequest is OrderRequest) { + val request = data.orderRequest + + // Check for required fields + if (request.addressId <= 0) { + _errorMessage.value = "Please select a delivery address" + _isLoading.value = false + return@launch + } + + if (request.paymentMethodId <= 0) { + _errorMessage.value = "Please select a payment method" + _isLoading.value = false + return@launch + } + + if (request.shipPrice <= 0 || request.shipName.isBlank() || request.shipService.isBlank()) { + _errorMessage.value = "Please select a shipping method" + _isLoading.value = false + return@launch + } + } else if (data.orderRequest is OrderRequestBuy) { + val request = data.orderRequest + + // Similar validation for buy now + if (request.addressId <= 0 || request.paymentMethodId <= 0 || + request.shipPrice <= 0 || request.shipName.isBlank() || request.shipService.isBlank()) { + _errorMessage.value = "Please complete all required checkout information" + _isLoading.value = false + return@launch + } + } + val response = if (data.isBuyNow) { // For Buy Now, use the dedicated endpoint val buyRequest = data.orderRequest as OrderRequestBuy diff --git a/app/src/main/java/com/alya/ecommerce_serang/ui/order/PaymentMethodAdapter.kt b/app/src/main/java/com/alya/ecommerce_serang/ui/order/PaymentMethodAdapter.kt index 1bb1e69..dd2a20e 100644 --- a/app/src/main/java/com/alya/ecommerce_serang/ui/order/PaymentMethodAdapter.kt +++ b/app/src/main/java/com/alya/ecommerce_serang/ui/order/PaymentMethodAdapter.kt @@ -1,6 +1,8 @@ package com.alya.ecommerce_serang.ui.order +import android.util.Log import android.view.LayoutInflater +import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.alya.ecommerce_serang.R @@ -14,8 +16,8 @@ class PaymentMethodAdapter( private val onPaymentSelected: (PaymentInfoItem) -> Unit ) : RecyclerView.Adapter() { - // Selected payment name - private var selectedPaymentName: String? = null + // Track the selected payment by ID + private var selectedPaymentId: Int? = null class PaymentMethodViewHolder(val binding: ItemPaymentMethodBinding) : RecyclerView.ViewHolder(binding.root) @@ -38,16 +40,11 @@ class PaymentMethodAdapter( // Set payment method name tvPaymentMethodName.text = payment.name -// // Set bank account number if available -// if (!payment.bankNum.isNullOrEmpty()) { -// tvPaymentAccountNumber.visibility = View.VISIBLE -// tvPaymentAccountNumber.text = payment.bankNum -// } else { -// tvPaymentAccountNumber.visibility = View.GONE -// } + // Set radio button state based on selected payment ID + rbPaymentMethod.isChecked = payment.id == selectedPaymentId - // Set radio button state based on selected payment name - rbPaymentMethod.isChecked = payment.name == selectedPaymentName + // Debug log + Log.d("PaymentAdapter", "Binding item ${payment.name}, checked=${rbPaymentMethod.isChecked}") // Load payment icon if available if (!payment.qrisImage.isNullOrEmpty()) { @@ -55,31 +52,73 @@ class PaymentMethodAdapter( .load(payment.qrisImage) .apply( RequestOptions() - .placeholder(R.drawable.outline_store_24) - .error(R.drawable.outline_store_24)) + .placeholder(R.drawable.outline_store_24) + .error(R.drawable.outline_store_24) + ) .into(ivPaymentMethod) } else { // Default icon for bank transfers ivPaymentMethod.setImageResource(R.drawable.outline_store_24) } - // Handle click on the entire item - root.setOnClickListener { - onPaymentSelected(payment) - setSelectedPaymentName(payment.name) + // IMPORTANT: We need to fix the click handling to prevent re-fetching + val clickListener = View.OnClickListener { + val previousSelectedId = selectedPaymentId + selectedPaymentId = payment.id + + // Force the radio button to be checked + rbPaymentMethod.isChecked = true + + // Only notify if there was a change in selection + if (previousSelectedId != payment.id) { + notifyItemChanged(position) + + // Notify previous selection if it exists + if (previousSelectedId != null) { + val prevPosition = paymentMethods.indexOfFirst { it.id == previousSelectedId } + if (prevPosition >= 0) { + notifyItemChanged(prevPosition) + } + } + + // Call the callback ONLY ONCE + onPaymentSelected(payment) + + Log.d("PaymentAdapter", "Payment selected: ${payment.name}") + } } - // Handle click on the radio button - rbPaymentMethod.setOnClickListener { - onPaymentSelected(payment) - setSelectedPaymentName(payment.name) + // Apply the same click listener to both the root and the radio button + root.setOnClickListener(clickListener) + rbPaymentMethod.setOnClickListener(clickListener) + } + } + + // Set selected payment + fun setSelectedPaymentId(paymentId: Int) { + if (selectedPaymentId != paymentId) { + val previousSelectedId = selectedPaymentId + selectedPaymentId = paymentId + + Log.d("PaymentAdapter", "Setting selected payment ID to: $paymentId") + + // Update affected items only + if (previousSelectedId != null) { + val prevPosition = paymentMethods.indexOfFirst { it.id == previousSelectedId } + if (prevPosition >= 0) { + notifyItemChanged(prevPosition) + } + } + + val newPosition = paymentMethods.indexOfFirst { it.id == paymentId } + if (newPosition >= 0) { + notifyItemChanged(newPosition) } } } - // Set selected payment by name and refresh the UI - fun setSelectedPaymentName(paymentName: String) { - selectedPaymentName = paymentName - notifyDataSetChanged() // Update all items to reflect selection change + // Set selected payment object + fun setSelectedPayment(payment: PaymentInfoItem) { + setSelectedPaymentId(payment.id) } } \ No newline at end of file