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
13 changes: 11 additions & 2 deletions core/src/main/java/io/snabble/sdk/checkout/Checkout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@ package io.snabble.sdk.checkout
import androidx.annotation.RestrictTo
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.LiveData
import io.snabble.sdk.*
import io.snabble.sdk.FulfillmentState
import io.snabble.sdk.MutableAccessibleLiveData
import io.snabble.sdk.PaymentMethod
import io.snabble.sdk.Product
import io.snabble.sdk.Project
import io.snabble.sdk.Snabble
import io.snabble.sdk.Snabble.instance
import io.snabble.sdk.payment.PaymentCredentials
import io.snabble.sdk.shoppingcart.ShoppingCart
import io.snabble.sdk.utils.Dispatch
import io.snabble.sdk.utils.Logger
import java.io.File
import java.util.*
import java.util.concurrent.Future

class Checkout @JvmOverloads constructor(
Expand Down Expand Up @@ -499,6 +503,7 @@ class Checkout @JvmOverloads constructor(
|| state == CheckoutState.PAYMENT_PROCESSING
|| (state == CheckoutState.PAYMENT_APPROVED && !areAllFulfillmentsClosed())
|| state == CheckoutState.PAYONE_SEPA_MANDATE_REQUIRED
|| state == CheckoutState.AUTHENTICATING
) {
scheduleNextPoll()
}
Expand Down Expand Up @@ -580,6 +585,10 @@ class Checkout @JvmOverloads constructor(
notifyStateChanged(CheckoutState.PAYMENT_PROCESSING)
}

CheckState.AUTHENTICATING -> {
notifyStateChanged(CheckoutState.AUTHENTICATING)
}

CheckState.SUCCESSFUL -> {
val exitToken = checkoutProcess.exitToken
return if (exitToken != null && (exitToken.format.isNullOrEmpty() || exitToken.value.isNullOrEmpty())) {
Expand Down
4 changes: 4 additions & 0 deletions core/src/main/java/io/snabble/sdk/checkout/CheckoutApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ enum class CheckState {
@SerializedName("unauthorized") UNAUTHORIZED,
@SerializedName("pending") PENDING,
@SerializedName("processing") PROCESSING,
@SerializedName("authenticating") AUTHENTICATING,
@SerializedName("successful") SUCCESSFUL,
@SerializedName("transferred") TRANSFERRED,
@SerializedName("failed") FAILED
Expand Down Expand Up @@ -387,6 +388,9 @@ data class CheckoutProcessResponse(
val authorizePaymentLink: String?
get() = links?.get("authorizePayment")?.href

val paymentRedirect: String?
get() = links?.get("paymentRedirect")?.href

val originCandidateLink: String?
get() = paymentResult?.originCandidateLink
}
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/io/snabble/sdk/checkout/CheckoutState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ enum class CheckoutState {
*/
VERIFYING_PAYMENT_METHOD,

/**
* The payment need further authentication.
* Use the paymentRedirect link provided for further authentication.
*/
AUTHENTICATING,

/**
* Age needs to be verified
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package io.snabble.sdk.ui.checkout

import android.os.Bundle
import android.view.View
import android.webkit.CookieManager
import android.webkit.WebResourceRequest
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import io.snabble.sdk.Snabble
import io.snabble.sdk.ui.BaseFragment
import io.snabble.sdk.ui.R
import io.snabble.sdk.utils.Logger

class AuthenticationFragment : BaseFragment(R.layout.snabble_fragment_authentication) {
override fun onActualViewCreated(view: View, savedInstanceState: Bundle?) {
super.onActualViewCreated(view, savedInstanceState)

val currentCheckout = Snabble.checkedInProject.value?.checkout

// Setup your views here after inflation
val webview = view.findViewById<WebView>(R.id.authentication_webview)
webview.setupCookies()

// Configure WebView settings
webview.settings.apply {
javaScriptEnabled = true
domStorageEnabled = true
loadWithOverviewMode = true
useWideViewPort = true
setSupportZoom(true)
builtInZoomControls = true
displayZoomControls = false

// Additional cookie-related settings
databaseEnabled = true
cacheMode = WebSettings.LOAD_DEFAULT
}

webview.webViewClient = object : WebViewClient() {
override fun onReceivedError(view: WebView?, errorCode: Int, description: String?, failingUrl: String?) {
Logger.d("onReceivedError $failingUrl")
}

override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
when (request.url.toString()) {
SUCCESS,
ERROR,
BACK -> {
// No need to pop it since we're polling for the checkout state in the activity
// and navigate away as soon the get an update state
return true
}
}
return super.shouldOverrideUrlLoading(view, request)
}
}

val redirectUrl = currentCheckout?.checkoutProcess?.paymentRedirect
redirectUrl?.let {
webview.loadUrl(it)
}
}

// Extension function for cleaner code
fun WebView.setupCookies() {
val cookieManager = CookieManager.getInstance()
cookieManager.setAcceptCookie(true)
cookieManager.setAcceptThirdPartyCookies(this, true)
cookieManager.flush()
}

private companion object {

const val SUCCESS = "snabble://payone/success"
const val ERROR = "snabble://payone/error"
const val BACK = "snabble://payone/back"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ class CheckoutActivity : FragmentActivity() {
}
}

CheckoutState.AUTHENTICATING -> R.id.snabble_nav_authentication

CheckoutState.DEPOSIT_RETURN_REDEMPTION_FAILED,
CheckoutState.PAYMENT_ABORTED -> {
finish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ val CheckoutState.isCheckoutState: Boolean
CheckoutState.WAIT_FOR_GATEKEEPER,
CheckoutState.WAIT_FOR_APPROVAL,
CheckoutState.PAYMENT_PROCESSING,
CheckoutState.AUTHENTICATING,
CheckoutState.PAYMENT_APPROVED,
CheckoutState.DENIED_TOO_YOUNG,
CheckoutState.DENIED_BY_PAYMENT_PROVIDER,
Expand Down
11 changes: 11 additions & 0 deletions ui/src/main/res/layout/snabble_fragment_authentication.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<WebView
android:id="@+id/authentication_webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
5 changes: 5 additions & 0 deletions ui/src/main/res/navigation/snabble_nav_checkout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@
android:name="io.snabble.sdk.ui.checkout.PaymentStatusFragment"
android:label="@string/Snabble.Checkout.title" />

<fragment
android:id="@+id/snabble_nav_authentication"
android:name="io.snabble.sdk.ui.checkout.AuthenticationFragment"
android:label="@string/Snabble.Checkout.title" />

<fragment
android:id="@+id/snabble_nav_payment_payone_sepa_mandate"
android:name="io.snabble.sdk.ui.payment.payone.sepa.mandate.PayoneSepaMandateFragment"
Expand Down