diff --git a/android/navi-payment/src/main/java/com/navi/payment/model/initiatesdk/PaymentSDKProvider.kt b/android/navi-payment/src/main/java/com/navi/payment/model/initiatesdk/PaymentSDKProvider.kt index 0d19bfc59e..d23e7ea0cc 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/model/initiatesdk/PaymentSDKProvider.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/model/initiatesdk/PaymentSDKProvider.kt @@ -8,5 +8,7 @@ package com.navi.payment.model.initiatesdk enum class PaymentSDKProvider { - JUSPAY + JUSPAY, + NAVI_PAY, + ICICI_BANK } diff --git a/android/navi-payment/src/main/java/com/navi/payment/network/deserializers/PayNowResponseDeserializer.kt b/android/navi-payment/src/main/java/com/navi/payment/network/deserializers/PayNowResponseDeserializer.kt new file mode 100644 index 0000000000..127e829200 --- /dev/null +++ b/android/navi-payment/src/main/java/com/navi/payment/network/deserializers/PayNowResponseDeserializer.kt @@ -0,0 +1,46 @@ +/* + * + * * Copyright © 2024 by Navi Technologies Limited + * * All rights reserved. Strictly confidential + * + */ + +package com.navi.payment.network.deserializers + +import com.google.gson.JsonDeserializationContext +import com.google.gson.JsonDeserializer +import com.google.gson.JsonElement +import com.navi.payment.paymentscreen.model.ExternalPayNowResponse +import com.navi.payment.paymentscreen.model.IntentUriPayNowResponse +import com.navi.payment.paymentscreen.model.InternalPayNowResponse +import com.navi.payment.paymentscreen.model.PayActionType +import com.navi.payment.paymentscreen.model.PayNowResponse +import java.lang.reflect.Type + +class PayNowResponseDeserializer : JsonDeserializer { + override fun deserialize( + json: JsonElement?, + typeOfT: Type?, + context: JsonDeserializationContext? + ): PayNowResponse? { + json?.let { + val jsonObject = it.asJsonObject + if (!jsonObject.has("actionType")) return null + return when (jsonObject["actionType"].asString) { + PayActionType.INTERNAL.name -> { + context?.deserialize(jsonObject, InternalPayNowResponse::class.java) + } + PayActionType.EXTERNAL.name -> { + context?.deserialize(jsonObject, ExternalPayNowResponse::class.java) + } + PayActionType.INTENT_URI_DIRECT_INTEGRATION.name -> { + context?.deserialize(jsonObject, IntentUriPayNowResponse::class.java) + } + else -> { + null + } + } + } + return null + } +} diff --git a/android/navi-payment/src/main/java/com/navi/payment/network/di/PaymentNetworkModule.kt b/android/navi-payment/src/main/java/com/navi/payment/network/di/PaymentNetworkModule.kt index 46a535958c..5b22aa9b87 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/network/di/PaymentNetworkModule.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/network/di/PaymentNetworkModule.kt @@ -18,6 +18,7 @@ import com.navi.payment.model.paymentmethod.GenericPaymentMethodResponse import com.navi.payment.model.paymentresult.PaymentResultData import com.navi.payment.model.paymentresult.PaymentSDKActionConfig import com.navi.payment.nativepayment.model.BasePaymentInstrument +import com.navi.payment.network.deserializers.PayNowResponseDeserializer import com.navi.payment.network.deserializers.PaymentInstrumentDeserializer import com.navi.payment.network.deserializers.PaymentSDKActionDeserializer import com.navi.payment.network.deserializers.PaymentSDKConfigDeserializer @@ -29,6 +30,7 @@ import com.navi.payment.network.retrofit.NetworkInfo import com.navi.payment.network.retrofit.RetrofitService import com.navi.payment.network.util.ApiConstants import com.navi.payment.network.util.PaymentsSdkRetrofit +import com.navi.payment.paymentscreen.model.PayNowResponse import com.navi.payment.paymentscreen.model.TransactionResponseMetaData import com.navi.paymentclients.deserializers.ThirdPartyPayloadDeserializer import com.navi.paymentclients.model.thirdparty.ThirdPartyResultData @@ -109,6 +111,7 @@ object PaymentNetworkModule { TransactionResponseDataDeserializer() ) .registerTypeAdapter(BasePaymentInstrument::class.java, PaymentInstrumentDeserializer()) + .registerTypeAdapter(PayNowResponse::class.java, PayNowResponseDeserializer()) .registerUiTronDeSerializers() .create() } diff --git a/android/navi-payment/src/main/java/com/navi/payment/paymentscreen/model/PayNowResponse.kt b/android/navi-payment/src/main/java/com/navi/payment/paymentscreen/model/PayNowResponse.kt index 13bb93f3ba..fdb2a9cc85 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/paymentscreen/model/PayNowResponse.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/paymentscreen/model/PayNowResponse.kt @@ -10,11 +10,71 @@ package com.navi.payment.paymentscreen.model import com.google.gson.annotations.SerializedName import com.navi.common.model.RequestConfig -data class PayNowResponse( - @SerializedName("provider") val provider: String? = null, - @SerializedName("methodName") val methodName: String? = null, - @SerializedName("providerPayload") val providerPayload: Any? = null, - @SerializedName("pollingConfiguration") val pollingConfiguration: RequestConfig? = null, - @SerializedName("transactionReferenceId") val transactionReferenceId: String? = null, - @SerializedName("paymentOrderReferenceId") val paymentOrderReferenceId: String? = null, +abstract class PayNowResponse { + abstract val provider: String? + abstract val methodName: String? + abstract val pollingConfiguration: RequestConfig? + abstract val transactionReferenceId: String? + abstract val paymentOrderReferenceId: String? + abstract val providerPayload: Any? + abstract val actionType: PayActionType? +} + +enum class PayActionType { + @SerializedName("INTERNAL") INTERNAL, + @SerializedName("EXTERNAL") EXTERNAL, + @SerializedName("INTENT_URI_DIRECT_INTEGRATION") INTENT_URI_DIRECT_INTEGRATION, +} + +data class InternalPayNowResponse( + @SerializedName("provider") override val provider: String?, + @SerializedName("methodName") override val methodName: String?, + @SerializedName("pollingConfiguration") override val pollingConfiguration: RequestConfig?, + @SerializedName("transactionReferenceId") override val transactionReferenceId: String?, + @SerializedName("paymentOrderReferenceId") override val paymentOrderReferenceId: String?, + @SerializedName("providerPayload") override val providerPayload: NaviPayProcessPayload?, + @SerializedName("actionType") override val actionType: PayActionType? +) : PayNowResponse() + +data class ExternalPayNowResponse( + @SerializedName("provider") override val provider: String?, + @SerializedName("methodName") override val methodName: String?, + @SerializedName("pollingConfiguration") override val pollingConfiguration: RequestConfig?, + @SerializedName("transactionReferenceId") override val transactionReferenceId: String?, + @SerializedName("paymentOrderReferenceId") override val paymentOrderReferenceId: String?, + @SerializedName("providerPayload") override val providerPayload: ExternalProcessPayload?, + @SerializedName("actionType") override val actionType: PayActionType? +) : PayNowResponse() + +data class IntentUriPayNowResponse( + @SerializedName("provider") override val provider: String?, + @SerializedName("methodName") override val methodName: String?, + @SerializedName("pollingConfiguration") override val pollingConfiguration: RequestConfig?, + @SerializedName("transactionReferenceId") override val transactionReferenceId: String?, + @SerializedName("paymentOrderReferenceId") override val paymentOrderReferenceId: String?, + @SerializedName("providerPayload") override val providerPayload: IntentUriProcessPayload?, + @SerializedName("actionType") override val actionType: PayActionType? +) : PayNowResponse() + +data class NaviPayProcessPayload( + @SerializedName("naviPayAction") val naviPayAction: String, + @SerializedName("naviPayUpiUriKey") val naviPayUpiUriKey: String, + @SerializedName("naviPayOfTypeIntentTransaction") val naviPayOfTypeIntentTransaction: Boolean, + @SerializedName("sourceModule") val sourceModule: String, + @SerializedName("payerBankAccountId") val payerBankAccountId: String, + @SerializedName("metadata") val metadata: Map = mapOf(), + @SerializedName("sendMoneyScreenSource") val sendMoneyScreenSource: String, + @SerializedName("needsResult") val needsResult: Boolean, + @SerializedName("tstoreOrderReferenceId") val tstoreOrderReferenceId: String? = null, +) + +data class ExternalProcessPayload( + @SerializedName("requestId") val requestId: String, + @SerializedName("service") val service: String, + @SerializedName("payload") val payload: Any? +) + +data class IntentUriProcessPayload( + @SerializedName("intentUri") val intentUri: String, + @SerializedName("upiAppName") val upiAppPackageName: String ) diff --git a/android/navi-payment/src/main/java/com/navi/payment/paymentscreen/ui/PaymentMethodFragment.kt b/android/navi-payment/src/main/java/com/navi/payment/paymentscreen/ui/PaymentMethodFragment.kt index 262ca41e65..94d5155106 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/paymentscreen/ui/PaymentMethodFragment.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/paymentscreen/ui/PaymentMethodFragment.kt @@ -8,8 +8,10 @@ package com.navi.payment.paymentscreen.ui import android.annotation.SuppressLint +import android.app.Activity import android.content.Context import android.content.Intent +import android.net.Uri import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -50,8 +52,10 @@ import com.navi.common.uitron.model.action.InitiatePayAmountAction import com.navi.common.uitron.model.action.UpiAction import com.navi.common.uitron.model.action.UpiIntent import com.navi.common.upi.CANCEL +import com.navi.common.utils.EMPTY import com.navi.common.utils.TemporaryStorageHelper import com.navi.common.utils.isNetworkAvailable +import com.navi.common.utils.log import com.navi.common.utils.observeNonNull import com.navi.common.utils.observeNullable import com.navi.common.utils.stringToJsonObject @@ -67,6 +71,7 @@ import com.navi.payment.model.common.PaymentSdkInitParams import com.navi.payment.model.common.PaymentSdkTypes import com.navi.payment.model.common.SDKIntegrationConfig import com.navi.payment.model.initiatesdk.PaymentPrefetchMethodRequest +import com.navi.payment.model.initiatesdk.PaymentSDKProvider import com.navi.payment.model.paymentmethod.PaymentMethodResponse import com.navi.payment.model.paymentmethod.PaymentScreenIntegrationMethodDetailResponse import com.navi.payment.model.paymentresult.PaymentPrefetchMethodDetailsResponse @@ -77,6 +82,8 @@ import com.navi.payment.paymentscreen.composables.PaymentErrorScreen import com.navi.payment.paymentscreen.model.ApiConfigType import com.navi.payment.paymentscreen.model.ApiRequestObjectVarsConfig import com.navi.payment.paymentscreen.model.BaseEventsData +import com.navi.payment.paymentscreen.model.ExternalPayNowResponse +import com.navi.payment.paymentscreen.model.IntentUriPayNowResponse import com.navi.payment.paymentscreen.model.NaviPaymentBottomSheetConfig import com.navi.payment.paymentscreen.model.NaviPaymentScreenResponse import com.navi.payment.paymentscreen.model.PayNowResponse @@ -189,6 +196,13 @@ class PaymentMethodFragment : PaymentScreenBaseFragment(), PaymentBackListener, } } + private val intentUriLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + if (it.resultCode == Activity.RESULT_OK) { + openPaymentLoaderScreen(EMPTY) + } + } + @Inject @PaymentsSdkRetrofit lateinit var deserializer: Gson @OptIn(ExperimentalComposeUiApi::class) @@ -615,33 +629,7 @@ class PaymentMethodFragment : PaymentScreenBaseFragment(), PaymentBackListener, private fun handlePayNowResponse(response: PayNowResponse?) { if (handleNetworkAvailability()) { - response?.let { - val payload = - PaymentScreenUtil.getRequestObjectWithVarsForSDK( - Gson().toJson(response.providerPayload), - viewModel.requestObjVars, - viewModel - ) - viewModel.transactionReferenceId = response.transactionReferenceId - viewModel.requestConfig = response.pollingConfiguration - viewModel.paymentMethodName = response.methodName.orEmpty() - paymentScreenAnalytics.onProcessSDKLoad(addBaseAttributes(null)) - hideLoader() - processSDK( - payload, - response.methodName.orEmpty(), - response.pollingConfiguration, - object : PaymentScreenListener { - override fun onSDKResponse( - data: JSONObject?, - methodName: String, - pollingConfiguration: RequestConfig? - ) { - handleResponseByMethodName(data) - } - } - ) - } + response?.let { startPayment(payNowResponse = response) } } } @@ -1122,4 +1110,60 @@ class PaymentMethodFragment : PaymentScreenBaseFragment(), PaymentBackListener, } } } + + private fun startPayment(payNowResponse: PayNowResponse) { + viewModel.transactionReferenceId = payNowResponse.transactionReferenceId + viewModel.requestConfig = payNowResponse.pollingConfiguration + viewModel.paymentMethodName = payNowResponse.methodName.orEmpty() + hideLoader() + when (payNowResponse) { + is ExternalPayNowResponse -> { + startExternalPayment(payNowResponse) + } + is IntentUriPayNowResponse -> { + startIntentUriPayment(payNowResponse) + } + else -> {} + } + } + + private fun startExternalPayment(payNowResponse: ExternalPayNowResponse) { + when (payNowResponse.provider) { + PaymentSDKProvider.JUSPAY.name -> { + val payload = + PaymentScreenUtil.getRequestObjectWithVarsForSDK( + Gson().toJson(payNowResponse.providerPayload), + viewModel.requestObjVars, + viewModel + ) + paymentScreenAnalytics.onProcessSDKLoad(addBaseAttributes(null)) + processSDK( + payload, + payNowResponse.methodName.orEmpty(), + payNowResponse.pollingConfiguration, + object : PaymentScreenListener { + override fun onSDKResponse( + data: JSONObject?, + methodName: String, + pollingConfiguration: RequestConfig? + ) { + handleResponseByMethodName(data) + } + } + ) + } + else -> {} + } + } + + private fun startIntentUriPayment(payNowResponse: IntentUriPayNowResponse) { + try { + val intent = + Intent(Intent.ACTION_VIEW, Uri.parse(payNowResponse.providerPayload?.intentUri)) + intent.setPackage(payNowResponse.providerPayload?.upiAppPackageName.orEmpty()) + intentUriLauncher.launch(intent) + } catch (e: Exception) { + e.log() + } + } } diff --git a/android/navi-payment/src/main/java/com/navi/payment/utils/Constants.kt b/android/navi-payment/src/main/java/com/navi/payment/utils/Constants.kt index 2ea14dcf59..fa698d140a 100644 --- a/android/navi-payment/src/main/java/com/navi/payment/utils/Constants.kt +++ b/android/navi-payment/src/main/java/com/navi/payment/utils/Constants.kt @@ -1,6 +1,6 @@ /* * - * * Copyright © 2023 by Navi Technologies Limited + * * Copyright © 2023-2024 by Navi Technologies Limited * * All rights reserved. Strictly confidential * */ @@ -12,8 +12,8 @@ import androidx.annotation.Keep @Keep object Constants { - val PAYMENT_SDK_VERSION = "android_1.3.0" - val COMPOSE_PAYMENT_SDK_VERSION = "android_2.0.0" + val PAYMENT_SDK_VERSION = "android_1.4.0" + val COMPOSE_PAYMENT_SDK_VERSION = "android_2.1.0" val SDK_CONFIG_KEY = "sdkConfigKey" val EXTERNAL_ORDER_ID = "externalOrderId"