Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.processout.sdk.api.model.adapter.napm

import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentRedirect
import com.squareup.moshi.FromJson
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.squareup.moshi.ToJson

internal class NativeAlternativePaymentDeepLinkConfigurationJsonAdapter {

@FromJson
fun fromJson(configuration: DeepLinkConfiguration) =
PONativeAlternativePaymentRedirect.DeepLinkConfiguration(
packageNames = configuration.android.packageNames
)

@ToJson
fun toJson(configuration: PONativeAlternativePaymentRedirect.DeepLinkConfiguration) =
DeepLinkConfiguration(
android = DeepLinkConfiguration.Android(
packageNames = configuration.packageNames
)
)

@JsonClass(generateAdapter = true)
data class DeepLinkConfiguration(
val android: Android
) {
@JsonClass(generateAdapter = true)
data class Android(
@Json(name = "package_names")
val packageNames: Set<String>
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import kotlinx.parcelize.Parcelize
* in the [PONativeAlternativePaymentAuthorizationRequest.redirectConfirmation]
* or the [PONativeAlternativePaymentTokenizationRequest.redirectConfirmation],
* depending on the flow.
* @param[deepLinkConfiguration] Additional deep link configuration.
*/
@Parcelize
@JsonClass(generateAdapter = true)
Expand All @@ -30,7 +31,9 @@ data class PONativeAlternativePaymentRedirect(
@Json(name = "type")
val rawType: String,
@Json(name = "confirmation_required")
val confirmationRequired: Boolean
val confirmationRequired: Boolean,
@Json(name = "deep_link")
val deepLinkConfiguration: DeepLinkConfiguration?
) : Parcelable {

/** Redirect type. */
Expand All @@ -54,4 +57,14 @@ data class PONativeAlternativePaymentRedirect(
@ProcessOutInternalApi
UNKNOWN(String())
}

/**
* Specifies additional deep link configuration.
*
* @param[packageNames] A set of app package names the deep link is intended to open.
*/
@Parcelize
data class DeepLinkConfiguration(
val packageNames: Set<String>
) : Parcelable
}
3 changes: 2 additions & 1 deletion sdk/src/main/kotlin/com/processout/sdk/di/NetworkGraph.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.processout.sdk.di

import com.processout.sdk.api.model.adapter.napm.NativeAlternativePaymentDeepLinkConfigurationJsonAdapter
import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod
import com.processout.sdk.api.model.response.PODynamicCheckoutPaymentMethod.*
import com.processout.sdk.api.model.response.napm.v2.NativeAlternativePaymentElement
Expand Down Expand Up @@ -85,7 +86,7 @@ internal class DefaultNetworkGraph(
.withSubtype(PONativeAlternativePaymentCustomerInstruction.Image::class.java, "image_url")
.withSubtype(PONativeAlternativePaymentCustomerInstruction.Barcode::class.java, "barcode")
.withDefaultValue(PONativeAlternativePaymentCustomerInstruction.Unknown)
)
).add(NativeAlternativePaymentDeepLinkConfigurationJsonAdapter())

private fun Moshi.Builder.addDynamicCheckoutAdapter() =
add(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.processout.sdk.api.model.response.napm.v2.*
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentAuthorizationResponse.Invoice
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentElement.Form.Parameter
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentElement.Form.Parameter.Otp.Subtype
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentRedirect.DeepLinkConfiguration
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentRedirect.RedirectType
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentState.*
import com.processout.sdk.api.service.POCustomerTokensService
Expand Down Expand Up @@ -672,7 +673,8 @@ internal class NativeAlternativePaymentInteractor(
)
RedirectType.DEEP_LINK -> deepLinkRedirect(
stateValue = stateValue,
redirectUrl = redirect.url
redirectUrl = redirect.url,
deepLinkConfiguration = redirect.deepLinkConfiguration
)
RedirectType.UNKNOWN -> failWithUnknownRedirect(redirect)
}
Expand Down Expand Up @@ -727,7 +729,8 @@ internal class NativeAlternativePaymentInteractor(

private fun deepLinkRedirect(
stateValue: NextStepStateValue,
redirectUrl: String
redirectUrl: String,
deepLinkConfiguration: DeepLinkConfiguration?
) {
_state.update {
NextStep(
Expand All @@ -737,7 +740,10 @@ internal class NativeAlternativePaymentInteractor(
)
)
}
val didOpenUrl = app.openDeepLink(url = redirectUrl)
val didOpenUrl = app.openDeepLink(
url = redirectUrl,
packageNames = deepLinkConfiguration?.packageNames
)
val redirectConfirmation = if (stateValue.redirect?.confirmationRequired == true)
PONativeAlternativePaymentRedirectConfirmation(success = didOpenUrl) else null
continuePayment(redirectConfirmation)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentRe
import com.processout.sdk.api.model.request.napm.v2.PONativeAlternativePaymentTokenizationRequest
import com.processout.sdk.api.model.response.POAlternativePaymentMethodResponse
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentRedirect
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentRedirect.DeepLinkConfiguration
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentRedirect.RedirectType
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentState
import com.processout.sdk.api.model.response.napm.v2.PONativeAlternativePaymentState.*
Expand Down Expand Up @@ -402,6 +403,7 @@ class PONativeAlternativePaymentLauncher private constructor(
)
RedirectType.DEEP_LINK -> deepLinkRedirect(
redirectUrl = redirect.url,
deepLinkConfiguration = redirect.deepLinkConfiguration,
configuration = configuration
)
RedirectType.UNKNOWN -> {
Expand Down Expand Up @@ -471,9 +473,13 @@ class PONativeAlternativePaymentLauncher private constructor(

private fun deepLinkRedirect(
redirectUrl: String,
deepLinkConfiguration: DeepLinkConfiguration?,
configuration: PONativeAlternativePaymentConfiguration
) {
val didOpenUrl = app.openDeepLink(url = redirectUrl)
val didOpenUrl = app.openDeepLink(
url = redirectUrl,
packageNames = deepLinkConfiguration?.packageNames
)
val confirmationRequired = when (val flow = configuration.flow) {
is Authorization -> flow.initialResponse?.redirect?.confirmationRequired
is Tokenization -> flow.initialResponse?.redirect?.confirmationRequired
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,34 @@ internal fun Application.currentAppLocale(): Locale =
?: LocaleListCompat.getAdjustedDefault()[0]
?: Locale.getDefault()

internal fun Application.openDeepLink(url: String): Boolean {
internal fun Application.openDeepLink(
url: String,
packageName: String? = null
): Boolean {
try {
val intent = Intent(Intent.ACTION_VIEW, url.toUri())
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
packageName?.let { intent.setPackage(it) }
startActivity(intent)
return true
} catch (e: ActivityNotFoundException) {
POLogger.warn("Failed to open deep link [%s] with exception: %s", url, e)
POLogger.warn("Failed to open deep link [%s] for package [%s] with exception: %s", url, packageName, e)
return false
}
}

internal fun Application.openDeepLink(
url: String,
packageNames: Set<String>?
): Boolean {
if (packageNames.isNullOrEmpty()) {
if (url.toUri().isWeb) {
POLogger.warn("Refused to open app link [%s] without a package, to prevent opening in an external browser.", url)
return false
}
return openDeepLink(url)
}
return packageNames.any { packageName ->
openDeepLink(url, packageName)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.processout.sdk.ui.shared.extension

import android.net.Uri

internal val Uri.isWeb: Boolean
get() = scheme?.lowercase() in setOf("http", "https")
Loading