Skip to content

Commit

Permalink
[MERGE] #78 -> develop
Browse files Browse the repository at this point in the history
[FEAT/#78] Portone 결제 모듈 세팅
  • Loading branch information
Marchbreeze committed Aug 19, 2024
2 parents 29d3bbf + 3968766 commit 09fee99
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 29 deletions.
6 changes: 6 additions & 0 deletions presentation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ android {
"MERCHANT_UID",
gradleLocalProperties(rootDir).getProperty("merchant.uid"),
)

buildConfigField(
"String",
"PAYMENT_UID",
gradleLocalProperties(rootDir).getProperty("payment.uid"),
)
}

compileOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class PhoneActivity : BaseActivity<ActivityPhoneBinding>(R.layout.activity_phone
}

private fun startIamportCertification() {
Timber.tag("okhttp").d("START IAMPORT CERTIFICATION")
Iamport.certification(
userCode = IAMPORT_CODE,
iamPortCertification =
Expand All @@ -75,6 +76,7 @@ class PhoneActivity : BaseActivity<ActivityPhoneBinding>(R.layout.activity_phone
}
} else {
Timber.tag("okhttp").d("IAMPORT CERTIFICATION ERROR : $response")
toast(stringOf(R.string.error_msg))
setLoadingScreen(false)
}
}
Expand Down Expand Up @@ -134,6 +136,7 @@ class PhoneActivity : BaseActivity<ActivityPhoneBinding>(R.layout.activity_phone

override fun onDestroy() {
super.onDestroy()

Iamport.close()
termBottomSheet = null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ import co.orange.core.extension.toast
import co.orange.core.state.UiState
import co.orange.domain.entity.response.AddressInfoModel
import co.orange.domain.entity.response.BuyProgressModel
import co.orange.presentation.buy.push.BuyPushActivity
import co.orange.presentation.setting.delivery.DeliveryActivity
import coil.load
import com.iamport.sdk.domain.core.Iamport
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kr.genti.presentation.BuildConfig.IAMPORT_CODE
import kr.genti.presentation.R
import kr.genti.presentation.databinding.ActivityBuyProgressBinding
import timber.log.Timber

@AndroidEntryPoint
class BuyProgressActivity :
Expand All @@ -35,7 +37,7 @@ class BuyProgressActivity :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

binding.vm = viewModel
initView()
initExitBtnListener()
initDeliveryChangeBtnListener()
initTermBtnListener()
Expand All @@ -50,6 +52,11 @@ class BuyProgressActivity :
getIntentInfo()
}

private fun initView() {
binding.vm = viewModel
Iamport.init(this)
}

private fun initExitBtnListener() {
binding.btnExit.setOnSingleClickListener { finish() }
}
Expand Down Expand Up @@ -85,19 +92,43 @@ class BuyProgressActivity :
private fun initConfirmBtnListener() {
binding.btnConfirmPurchase.setOnSingleClickListener {
// TODO 구매 요청 서버통신 이후
BuyPushActivity.createIntent(this, viewModel.productId).apply {
startActivity(this)
}
startIamportPurchase()
// BuyPushActivity.createIntent(this, viewModel.productId).apply {
// startActivity(this)
// }
}
}

private fun getIntentInfo() {
with(viewModel) {
if (productId.isEmpty()) productId = intent.getStringExtra(EXTRA_PRODUCT_ID).orEmpty()
if (productId.isEmpty()) {
productId = intent.getStringExtra(EXTRA_PRODUCT_ID).orEmpty()
optionList = intent.getLongArrayExtra(EXTRA_OPTION_LIST)?.toList()
}
getBuyProgressDataFromServer()
}
}

private fun startIamportPurchase() {
val request = viewModel.createIamportRequest()
if (request == null) {
toast(stringOf(R.string.error_msg))
return
}
Timber.tag("okhttp").d("IAMPORT PURCHASE REQUEST : $request")
Iamport.payment(
userCode = IAMPORT_CODE,
iamPortRequest = request,
) { response ->
Timber.tag("okhttp").d("IAMPORT PURCHASE RESPONSE : $response")
if (response != null && response.success == true) {
// TODO
} else {
toast(stringOf(R.string.error_msg))
}
}
}

private fun observeGetBuyProgressDataState() {
viewModel.getBuyProgressDataState.flowWithLifecycle(lifecycle).distinctUntilChanged()
.onEach { state ->
Expand Down Expand Up @@ -146,16 +177,25 @@ class BuyProgressActivity :
}
}

override fun onDestroy() {
super.onDestroy()

Iamport.close()
}

companion object {
private const val EXTRA_PRODUCT_ID = "EXTRA_PRODUCT_ID"
private const val EXTRA_OPTION_LIST = "EXTRA_OPTION_LIST"

@JvmStatic
fun createIntent(
context: Context,
productId: String,
optionList: Array<Long>? = null,
): Intent =
Intent(context, BuyProgressActivity::class.java).apply {
putExtra(EXTRA_PRODUCT_ID, productId)
putExtra(EXTRA_OPTION_LIST, optionList)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ import androidx.lifecycle.viewModelScope
import co.orange.core.state.UiState
import co.orange.domain.entity.response.BuyProgressModel
import co.orange.domain.repository.BuyRepository
import com.iamport.sdk.data.sdk.IamPortRequest
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kr.genti.presentation.BuildConfig.PAYMENT_UID
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
Expand All @@ -19,12 +22,15 @@ class BuyProgressViewModel
private val buyRepository: BuyRepository,
) : ViewModel() {
var productId: String = ""
var optionList: List<Long>? = null
var buyProgressData: BuyProgressModel? = null

var payMethodId = MutableLiveData<Int>(-1)
var payMethod = ""

var isTermAllSelected = MutableLiveData<Boolean>(false)
var isTermServiceSelected = MutableLiveData<Boolean>(false)
var isTermPurchaseSelected = MutableLiveData<Boolean>(false)
var isAddressSelected = false
var isMethodSelected = true
var isCompleted = MutableLiveData<Boolean>(false)

private val _getBuyProgressDataState =
Expand All @@ -48,11 +54,26 @@ class BuyProgressViewModel
checkIsCompleted()
}

fun setPayMethod(methodId: Int) {
payMethodId.value = methodId
payMethod =
when (methodId) {
0 -> "card"
1 -> "naverpay_card"
2 -> "kakao"
3 -> "samsungpay"
4 -> "trans"
5 -> "phone"
else -> return
}
checkIsCompleted()
}

private fun checkIsCompleted() {
isTermAllSelected.value =
(isTermServiceSelected.value == true && isTermPurchaseSelected.value == true)
isCompleted.value =
(isTermServiceSelected.value == true && isTermPurchaseSelected.value == true && isAddressSelected && isMethodSelected)
(isTermAllSelected.value == true && !buyProgressData?.addressInfo?.address.isNullOrBlank() && payMethod.isNotBlank())
}

fun getBuyProgressDataFromServer() {
Expand All @@ -61,13 +82,35 @@ class BuyProgressViewModel
// TODO 추후 productId 활용
buyRepository.getBuyProgressData("0110055338")
.onSuccess {
isAddressSelected = !it.addressInfo.address.isNullOrEmpty()
checkIsCompleted()
buyProgressData = it
_getBuyProgressDataState.value = UiState.Success(it)
}
.onFailure {
_getBuyProgressDataState.value = UiState.Failure(it.message.toString())
}
}
}

fun createIamportRequest(): IamPortRequest? {
return if (buyProgressData?.productName.isNullOrBlank() || payMethod.isBlank()) {
Timber.tag("okhttp").d("IAMPORT PURCHASE REQUEST ERROR : $buyProgressData & $payMethod")
null
} else {
IamPortRequest(
pg = NICE_PAYMENTS,
pay_method = payMethod,
// TODO 추후 수정
name = "예시상품",
merchant_uid = "0123456789",
amount = buyProgressData?.totalPrice.toString(),
buyer_name = buyProgressData?.addressInfo?.recipient,
buyer_tel = buyProgressData?.addressInfo?.recipientPhone,
)
}
}

companion object {
private const val NICE_PAYMENTS = "nice_v2.{$PAYMENT_UID}"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class DetailViewModel
var infoUrl: String = ""
var interestCount: Int = 0
var optionList = listOf<ProductOptionModel>()
var selectedOptionList = mutableListOf<Long>()

private val _getProductDetailState =
MutableStateFlow<UiState<ProductDetailModel>>(UiState.Empty)
Expand All @@ -43,6 +44,7 @@ class DetailViewModel
infoUrl = it.infoUrl
interestCount = it.interestCount
optionList = it.optionList
selectedOptionList = MutableList(optionList.size) { -1 }
isLiked = it.isInterested
_getProductDetailState.value = UiState.Success(it)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import co.orange.domain.entity.response.ProductOptionModel
import kr.genti.presentation.databinding.ItemOptionBinding

class OptionAdapter(
private val itemClick: (Long, Long) -> Unit,
private val itemClick: (Int, Long) -> Unit,
) : ListAdapter<ProductOptionModel, OptionViewHolder>(diffUtil) {
override fun onCreateViewHolder(
parent: ViewGroup,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,11 @@ class OptionBottomSheet :

private fun initPurchaseBtnListener() {
binding.btnPurchase.setOnSingleClickListener {
// TODO 버튼 활성화 설정
BuyProgressActivity.createIntent(
requireContext(),
viewModel.productId,
).apply {
startActivity(this)
}
viewModel.selectedOptionList.toTypedArray(),
).apply { startActivity(this) }
}
}

Expand All @@ -80,10 +78,13 @@ class OptionBottomSheet :
}

private fun initItemClickListener(
optionId: Long,
position: Int,
optionDetailId: Long,
) {
// TODO 옵션 저장
if (position < viewModel.selectedOptionList.size) {
viewModel.selectedOptionList[position] = optionDetailId
}
binding.btnPurchase.isEnabled = !viewModel.selectedOptionList.contains(-1)
}

private fun setInterestCount() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import kr.genti.presentation.databinding.ItemOptionBinding

class OptionViewHolder(
val binding: ItemOptionBinding,
private val itemClick: (Long, Long) -> Unit,
private val itemClick: (Int, Long) -> Unit,
) : RecyclerView.ViewHolder(binding.root) {
var selectedItemId: Long = -1
var selectedPosition: Int = -1

fun onBind(
item: ProductOptionModel,
position: Int,
) {
selectedItemId = item.optionId
selectedPosition = position
with(binding) {
tvOptionItemTitle.text = item.type
tvOptionItemTitle.setOnClickListener {
Expand All @@ -32,6 +32,6 @@ class OptionViewHolder(
}

private fun initItemClickListener(optionDetailId: Long) {
itemClick(selectedItemId, optionDetailId)
itemClick(selectedPosition, optionDetailId)
}
}
Loading

0 comments on commit 09fee99

Please sign in to comment.