Skip to content

Commit

Permalink
Merge pull request #33 from iamport/features/chai-subscribe
Browse files Browse the repository at this point in the history
feat : CHAI 정기결제 연동 Features/chai subscribe
  • Loading branch information
kjh5833 authored Jun 23, 2021
2 parents 9f61359 + 2307943 commit 32d5d73
Show file tree
Hide file tree
Showing 23 changed files with 378 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected void onCreate(Bundle savedInstanceState) {
.amount("3200")
.buyer_name("김아임포트").build();

Iamport.INSTANCE.payment("imp19424728", request,
Iamport.INSTANCE.payment("imp19424728", null, request,
iamPortApprove -> {
// (Optional) CHAI 최종 결제전 콜백 함수.
return Unit.INSTANCE;
Expand Down
11 changes: 8 additions & 3 deletions app/src/main/java/com/iamport/sampleapp/ui/PaymentFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class PaymentFragment : BaseFragment<PaymentFragmentBinding>() {
company = "유어포트",
)

Iamport.certification(userCode, certification) { callBackListener.result(it) }
Iamport.certification(userCode, iamPortCertification = certification) { callBackListener.result(it) }
}


Expand All @@ -154,7 +154,8 @@ class PaymentFragment : BaseFragment<PaymentFragmentBinding>() {
name = paymentName, // 주문명
merchant_uid = merchantUid, // 주문번호
amount = amount, // 결제금액
buyer_name = "남궁안녕"
buyer_name = "남궁안녕",
// customer_uid = getRandomCustomerUid()
)

val userCode = Util.getUserCode(viewDataBinding.userCode.selectedItemPosition)
Expand All @@ -174,7 +175,7 @@ class PaymentFragment : BaseFragment<PaymentFragmentBinding>() {
// approveCallback = { approveCallback(it) },
// paymentResultCallback = { callBackListener.result(it) })

Iamport.payment(userCode, request) { callBackListener.result(it) }
Iamport.payment(userCode, iamPortRequest = request) { callBackListener.result(it) }
}

/**
Expand Down Expand Up @@ -240,4 +241,8 @@ class PaymentFragment : BaseFragment<PaymentFragmentBinding>() {
return "muid_aos_${Date().time}"
}

private fun getRandomCustomerUid(): String {
return "mcuid_aos_${Date().time}"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class WebViewModeFragment : Fragment() {
Iamport.enableWebViewMode(it)
Log.d("WebViewMode", "iamport sdk webview mode? ${Iamport.isWebViewMode()}")
// 아임포트에 결제 요청하기
Iamport.payment("iamport", request, paymentResultCallback = {
Iamport.payment("iamport", iamPortRequest = request, paymentResultCallback = {
// 결제 완료 후 결과 콜백을 토스트 메시지로 보여줌
Toast.makeText(this.context, "결제결과 => $it", Toast.LENGTH_LONG).show()
})
Expand All @@ -69,7 +69,7 @@ class WebViewModeFragment : Fragment() {
binding?.mobilewebButton?.setOnClickListener {
// 모바일 웹 단독 모드
binding?.webview?.let {
binding?.webview?.loadUrl(CONST.PAYMENT_MOBILE_WEB_FILE_URL)
it.loadUrl(CONST.PAYMENT_MOBILE_WEB_FILE_URL)
Iamport.pluginMobileWebSupporter(it)
}
}
Expand Down
23 changes: 21 additions & 2 deletions sdk/src/main/java/com/iamport/sdk/data/chai/CHAI.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
package com.iamport.sdk.data.chai

import com.iamport.sdk.domain.utils.CONST
import com.orhanobut.logger.Logger

// 차이 네이티브 결제 관련
object CHAI {
var pkg: String? = null
const val SINGLE_ACTIVITY_VERSION: Long = 2000169
const val PAYMENT_ID = "paymentId"
const val IDEMPOENCY_KEY = "idempotencyKey"
const val SUBSCRIPTION_ID = "subscriptionId"
const val IDEMPOTENCY_KEY = "idempotencyKey"
const val STATUS = "status"
const val NATIVE = "native"
const val CHANNEL = "mobile"
const val MODE = "staging"
}

// 차이 mode 설정에 따라 chai server url 이 다름
enum class CHAI_MODE(val url: String) {
prod(CONST.CHAI_SERVICE_URL),
staging(CONST.CHAI_SERVICE_STAGING_URL),
dev(CONST.CHAI_SERVICE_DEV_URL);

companion object {
fun getChaiUrl(mode: String?): String {
return values().find { mode == (it.name) }?.url ?: run {
Logger.w("Not found CHAI mode => [$mode]")
prod.url // default
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ data class PrepareRequest(
val tax_free: String?, // 결제금액 중 면세공급가액,
val name: String, //주문명,
val merchant_uid: String, // 가맹점 주문번호,
val customer_uid: String?, // 정기결제용
val user_code: String, // 아임포트 가맹점 식별코드,
val tier_code: String?, // 아임포트 agency 하위계정 tier code,
val pg_id: String, // 차이계정 public Key, // 복수PG로직에 따라 Http 요청 1에서 받은 정보 + 요청인자 활용
Expand Down Expand Up @@ -49,6 +50,7 @@ data class PrepareRequest(
tax_free = Util.getOrZeroString(tax_free),
name = Util.getOrEmpty(name),
merchant_uid = merchant_uid,
customer_uid = customer_uid,
user_code = payment.userCode,
tier_code = empty,
pg_id = chaiId,
Expand Down
43 changes: 23 additions & 20 deletions sdk/src/main/java/com/iamport/sdk/data/chai/response/ChaiPayment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,36 @@ package com.iamport.sdk.data.chai.response
//* 응답본문(Response) :
data class ChaiPayment(
val paymentId: String, // "198ad2c1cc485629447c4527247c198bdb0cd82c",
// val merchantUserId: String,
val type: String, // "payment",
val status: String, // "waiting",
val displayStatus: String, // "waiting",
val idempotencyKey: String, // "CHAIINIpayTest20201027153612605769",
val currency: String, // "KRW",
val checkoutAmount: Int, // 1004,
val discountAmount: Int, // 0,
val billingAmount: Int, // 1004,
val pointAmount: Int, // 0,
val cashAmount: Int, // 0,
val chargingAmount: Int, // 0,
val cashbackAmount: Int, // 0,
val taxFreeAmount: Int, // 0,
val bookShowAmount: Int, // 0,
val serviceFeeAmount: Int, // 0,
val merchantDiscountAmount: Int, // 0,
val merchantCashbackAmount: Int, // 0,
val canceledAmount: Int, // 0,
val canceledBillingAmount: Int, // 0,
val canceledPointAmount: Int, // 0,
val canceledCashAmount: Int, // 0,
val canceledDiscountAmount: Int, // 0,
val canceledCashbackAmount: Int, // 0,
val checkoutAmount: Float, // 1004,
val discountAmount: Float, // 0,
val billingAmount: Float, // 1004,
val pointAmount: Float, // 0,
val cashAmount: Float, // 0,
val chargingAmount: Float, // 0,
val cashbackAmount: Float, // 0,
val taxFreeAmount: Float, // 0,
val bookShowAmount: Float, // 0,
val serviceFeeAmount: Float, // 0,
val merchantDiscountAmount: Float, // 0,
val merchantCashbackAmount: Float, // 0,
val canceledAmount: Float, // 0,
val canceledBillingAmount: Float, // 0,
val canceledPointAmount: Float, // 0,
val canceledCashAmount: Float, // 0,
val canceledDiscountAmount: Float, // 0,
val canceledCashbackAmount: Float, // 0,
val returnUrl: String, // "https://ksmobile.inicis.com/smart/chaipayAcsResult.ini",
val description: String, // "결제테스트",
val cashbacks: ArrayList<String?>, // [], // TODO 이거 모르겠네
// val cashbacks: ArrayList<String?>, // [], // TODO 이거 모르겠네
val createdAt: String, // "2020-10-27T06:36:12.218Z",
val updatedAt: String, // "2020-10-27T06:36:12.218Z",
val metadata: PaymentMetadata,
)
) : BaseChaiPayment()

open class BaseChaiPayment
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ enum class ChaiPaymentStatus {
waiting, prepared,
approved,
user_canceled, canceled, failed, timeout,
confirmed, partial_confirmed;
confirmed, partial_confirmed, inactive, churn;

companion object {
fun from(displayStatus: String): ChaiPaymentStatus? = values().find { it.name == displayStatus }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.iamport.sdk.data.chai.response

data class ChaiPaymentSubscription(
val subscriptionId: String,
val status: String,
val displayStatus: String,
val idempotencyKey: String,
val checkoutAmount: Float,
val returnUrl: String,
val description: String,
val merchantUserId: String,
val createdAt: String, // "2020-10-27T06:36:12.218Z",
val updatedAt: String, // "2020-10-27T06:36:12.218Z",
): BaseChaiPayment()
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.iamport.sdk.data.chai.response

data class PaymentMetadata(val merchantId: String) // "INIpayTest"
data class PaymentMetadata(val merchantId: String?) // "INIpayTest"
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import kotlinx.parcelize.Parcelize
data class PrepareData(
val impUid: String,
val paymentId: String?,
val idempotencyKey: String?,
val returnUrl: String?,
val publicAPIKey: String?,
val subscriptionId: String?,
val idempotencyKey: String,
val returnUrl: String,
val publicAPIKey: String,
val mode: String?,
val isSbcr: Boolean?, // FIXME: 서버 배포 후 non nullable 로
) : Parcelable
9 changes: 9 additions & 0 deletions sdk/src/main/java/com/iamport/sdk/data/remote/ChaiApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.iamport.sdk.data.remote

import com.iamport.sdk.data.chai.CHAI
import com.iamport.sdk.data.chai.response.ChaiPayment
import com.iamport.sdk.data.chai.response.ChaiPaymentSubscription
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers
Expand All @@ -17,4 +18,12 @@ interface ChaiApi {
@Path(CHAI.PAYMENT_ID) chaiPaymentId: String,
): ChaiPayment

@Headers("Content-Type:application/json")
@GET("/v1/payment/subscription/{${CHAI.SUBSCRIPTION_ID}}")
suspend fun getChaiPaymentSubscription(
@Header("Idempotency-Key") idempotencyKey: String,
@Header("public-API-Key") publicApiKey: String,
@Path(CHAI.SUBSCRIPTION_ID) chaiSubscriptionId: String,
): ChaiPaymentSubscription

}
16 changes: 14 additions & 2 deletions sdk/src/main/java/com/iamport/sdk/data/remote/IamportApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,20 @@ interface IamportApi {
suspend fun postApprove(
@Path(CONST.IMP_USER_CODE) impUserCode: String,
@Path(CONST.IMP_UID) impUid: String,
@Query(CHAI.PAYMENT_ID) paymentId: String?,
@Query(CHAI.IDEMPOENCY_KEY) idempotencyKey: String?,
@Query(CHAI.PAYMENT_ID) paymentId: String,
@Query(CHAI.IDEMPOTENCY_KEY) idempotencyKey: String,
@Query(CHAI.STATUS) status: ChaiPaymentStatus,
@Query(CHAI.NATIVE) native: String
): Approve

@Headers("Content-Type:application/json")
@GET("chai_payments/result/{${CONST.IMP_USER_CODE}}/{${CONST.IMP_UID}}/{${CONST.IMP_CUSTOMER_UID}}?")
suspend fun postApproveSubscription(
@Path(CONST.IMP_USER_CODE) impUserCode: String,
@Path(CONST.IMP_UID) impUid: String,
@Path(CONST.IMP_CUSTOMER_UID) impCustomerUid: String,
@Query(CHAI.SUBSCRIPTION_ID) subscriptionId: String,
@Query(CHAI.IDEMPOTENCY_KEY) idempotencyKey: String,
@Query(CHAI.STATUS) status: ChaiPaymentStatus,
@Query(CHAI.NATIVE) native: String
): Approve
Expand Down
17 changes: 12 additions & 5 deletions sdk/src/main/java/com/iamport/sdk/data/sdk/IamPortApprove.kt
Original file line number Diff line number Diff line change
@@ -1,29 +1,36 @@
package com.iamport.sdk.data.sdk

import android.os.Parcelable
import com.iamport.sdk.data.chai.response.ChaiPaymentStatus
import com.iamport.sdk.data.chai.response.PrepareData
import kotlinx.parcelize.Parcelize

@Parcelize
data class IamPortApprove(
val userCode: String,
val merchantUid: String,
val customerUid: String?,
val paymentId: String?,
val impUid: String?,
val idempotencyKey: String?,
val publicAPIKey: String?,
val subscriptionId: String?,
val impUid: String,
val idempotencyKey: String,
val publicAPIKey: String,
var status: ChaiPaymentStatus,
val msg: String? = null
) : Parcelable {

companion object {
fun make(payment: Payment, data: PrepareData): IamPortApprove {
fun make(payment: Payment, data: PrepareData, status: ChaiPaymentStatus): IamPortApprove {
return IamPortApprove(
userCode = payment.userCode,
merchantUid = payment.getMerchantUid(),
customerUid = payment.getCustomerUid(),
paymentId = data.paymentId,
subscriptionId = data.subscriptionId,
impUid = data.impUid,
idempotencyKey = data.idempotencyKey,
publicAPIKey = data.publicAPIKey
publicAPIKey = data.publicAPIKey,
status = status
)
}
}
Expand Down
10 changes: 9 additions & 1 deletion sdk/src/main/java/com/iamport/sdk/data/sdk/Payment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,15 @@ data class Payment(
return when(getStatus()) {
STATUS.PAYMENT -> iamPortRequest?.merchant_uid ?: CONST.EMPTY_STR
STATUS.CERT -> iamPortCertification?.merchant_uid ?: CONST.EMPTY_STR
STATUS.ERROR -> "ERR : iamPortCertification & iamPortRequest NULL"
STATUS.ERROR -> CONST.EMPTY_STR
}
}

fun getCustomerUid(): String {
return when(getStatus()) {
STATUS.PAYMENT -> iamPortRequest?.customer_uid ?: CONST.EMPTY_STR
STATUS.CERT -> CONST.EMPTY_STR
STATUS.ERROR -> CONST.EMPTY_STR
}
}

Expand Down
Loading

0 comments on commit 32d5d73

Please sign in to comment.