Skip to content

Commit

Permalink
Merge pull request #1755 from Adyen/feature/stored-twint
Browse files Browse the repository at this point in the history
Stored twint
  • Loading branch information
OscarSpruit authored Sep 27, 2024
2 parents ec07578 + 7a7a492 commit fbf8395
Show file tree
Hide file tree
Showing 111 changed files with 4,367 additions and 747 deletions.
5 changes: 5 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
## New
- Added support for 6 more locales: Catalan (ca-ES), Icelandic (is-IS), Bulgarian (bg-BG),
Estonian (et-EE), Latvian (lv-LV) and Lithuanian (lt-lT).
- For Twint, storing payment details and paying with them is now supported. See the documentation [here](/docs/payment-methods/TWINT.md).

> [!WARNING]
> For the Twint component integration, you are now required to use `TwintComponent` instead of `InstantPaymentComponent`. See the [documentation](/docs/payment-methods/TWINT.md) to find out the details.
## Improved
- For UPI Intent an error message will be shown when "Continue" button is pressed without selecting
Expand All @@ -30,3 +34,4 @@
| Previous | Now |
|------------------------------------------|------------------------------------------|
| AdyenCheckout.TextAppearance.HeaderTitle | AdyenCheckout.TextAppearance.HeaderLabel |
- `com.adyen.checkout.instant.ActionHandlingMethod` is moved to `com.adyen.checkout.components.core.ActionHandlingMethod`
8 changes: 4 additions & 4 deletions action-core/api/action-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public final class com/adyen/checkout/action/core/GenericActionConfiguration$Bui
public synthetic fun addQRCodeActionConfiguration (Lcom/adyen/checkout/qrcode/QRCodeConfiguration;)Ljava/lang/Object;
public fun addRedirectActionConfiguration (Lcom/adyen/checkout/redirect/RedirectConfiguration;)Lcom/adyen/checkout/action/core/GenericActionConfiguration$Builder;
public synthetic fun addRedirectActionConfiguration (Lcom/adyen/checkout/redirect/RedirectConfiguration;)Ljava/lang/Object;
public fun addTwintActionConfiguration (Lcom/adyen/checkout/twint/TwintActionConfiguration;)Lcom/adyen/checkout/action/core/GenericActionConfiguration$Builder;
public synthetic fun addTwintActionConfiguration (Lcom/adyen/checkout/twint/TwintActionConfiguration;)Ljava/lang/Object;
public fun addTwintActionConfiguration (Lcom/adyen/checkout/twint/action/TwintActionConfiguration;)Lcom/adyen/checkout/action/core/GenericActionConfiguration$Builder;
public synthetic fun addTwintActionConfiguration (Lcom/adyen/checkout/twint/action/TwintActionConfiguration;)Ljava/lang/Object;
public fun addVoucherActionConfiguration (Lcom/adyen/checkout/voucher/VoucherConfiguration;)Lcom/adyen/checkout/action/core/GenericActionConfiguration$Builder;
public synthetic fun addVoucherActionConfiguration (Lcom/adyen/checkout/voucher/VoucherConfiguration;)Ljava/lang/Object;
public fun addWeChatPayActionConfiguration (Lcom/adyen/checkout/wechatpay/WeChatPayActionConfiguration;)Lcom/adyen/checkout/action/core/GenericActionConfiguration$Builder;
Expand Down Expand Up @@ -81,8 +81,8 @@ public abstract class com/adyen/checkout/action/core/internal/ActionHandlingPaym
public synthetic fun addQRCodeActionConfiguration (Lcom/adyen/checkout/qrcode/QRCodeConfiguration;)Ljava/lang/Object;
public final fun addRedirectActionConfiguration (Lcom/adyen/checkout/redirect/RedirectConfiguration;)Lcom/adyen/checkout/components/core/internal/BaseConfigurationBuilder;
public synthetic fun addRedirectActionConfiguration (Lcom/adyen/checkout/redirect/RedirectConfiguration;)Ljava/lang/Object;
public final fun addTwintActionConfiguration (Lcom/adyen/checkout/twint/TwintActionConfiguration;)Lcom/adyen/checkout/components/core/internal/BaseConfigurationBuilder;
public synthetic fun addTwintActionConfiguration (Lcom/adyen/checkout/twint/TwintActionConfiguration;)Ljava/lang/Object;
public final fun addTwintActionConfiguration (Lcom/adyen/checkout/twint/action/TwintActionConfiguration;)Lcom/adyen/checkout/components/core/internal/BaseConfigurationBuilder;
public synthetic fun addTwintActionConfiguration (Lcom/adyen/checkout/twint/action/TwintActionConfiguration;)Ljava/lang/Object;
public final fun addVoucherActionConfiguration (Lcom/adyen/checkout/voucher/VoucherConfiguration;)Lcom/adyen/checkout/components/core/internal/BaseConfigurationBuilder;
public synthetic fun addVoucherActionConfiguration (Lcom/adyen/checkout/voucher/VoucherConfiguration;)Ljava/lang/Object;
public final fun addWeChatPayActionConfiguration (Lcom/adyen/checkout/wechatpay/WeChatPayActionConfiguration;)Lcom/adyen/checkout/components/core/internal/BaseConfigurationBuilder;
Expand Down
4 changes: 2 additions & 2 deletions action-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ dependencies {
api project(':await')
api project(':qr-code')
api project(':redirect')
compileOnly project(':twint')
compileOnly project(':twint-action')
api project(':voucher')
compileOnly project(':wechatpay')

//Tests
testImplementation project(':3ds2')
testImplementation testFixtures(project(':test-core'))
testImplementation project(':twint')
testImplementation project(':twint-action')
testImplementation project(':wechatpay')
testImplementation testFixtures(project(':components-core'))
testImplementation testFixtures(project(':ui-core'))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.adyen.checkout.components.core.internal.Configuration
import com.adyen.checkout.core.Environment
import com.adyen.checkout.qrcode.QRCodeConfiguration
import com.adyen.checkout.redirect.RedirectConfiguration
import com.adyen.checkout.twint.TwintActionConfiguration
import com.adyen.checkout.twint.action.TwintActionConfiguration
import com.adyen.checkout.voucher.VoucherConfiguration
import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration
import kotlinx.parcelize.Parcelize
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.adyen.checkout.adyen3ds2.Adyen3DS2Configuration
import com.adyen.checkout.await.AwaitConfiguration
import com.adyen.checkout.qrcode.QRCodeConfiguration
import com.adyen.checkout.redirect.RedirectConfiguration
import com.adyen.checkout.twint.TwintActionConfiguration
import com.adyen.checkout.twint.action.TwintActionConfiguration
import com.adyen.checkout.voucher.VoucherConfiguration
import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import com.adyen.checkout.components.core.internal.Configuration
import com.adyen.checkout.core.Environment
import com.adyen.checkout.qrcode.QRCodeConfiguration
import com.adyen.checkout.redirect.RedirectConfiguration
import com.adyen.checkout.twint.TwintActionConfiguration
import com.adyen.checkout.twint.action.TwintActionConfiguration
import com.adyen.checkout.voucher.VoucherConfiguration
import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration
import java.util.Locale
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import com.adyen.checkout.components.core.internal.provider.ActionComponentProvi
import com.adyen.checkout.core.internal.util.runCompileOnly
import com.adyen.checkout.qrcode.QRCodeComponent
import com.adyen.checkout.redirect.RedirectComponent
import com.adyen.checkout.twint.TwintActionComponent
import com.adyen.checkout.twint.action.TwintActionComponent
import com.adyen.checkout.voucher.VoucherComponent
import com.adyen.checkout.wechatpay.WeChatPayActionComponent

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import com.adyen.checkout.core.exception.CheckoutException
import com.adyen.checkout.core.internal.util.LocaleProvider
import com.adyen.checkout.qrcode.internal.provider.QRCodeComponentProvider
import com.adyen.checkout.redirect.internal.provider.RedirectComponentProvider
import com.adyen.checkout.twint.internal.provider.TwintActionComponentProvider
import com.adyen.checkout.twint.action.internal.provider.TwintActionComponentProvider
import com.adyen.checkout.voucher.internal.provider.VoucherComponentProvider
import com.adyen.checkout.wechatpay.internal.provider.WeChatPayActionComponentProvider

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import com.adyen.checkout.core.exception.CheckoutException
import com.adyen.checkout.core.internal.util.LocaleProvider
import com.adyen.checkout.qrcode.internal.ui.QRCodeDelegate
import com.adyen.checkout.redirect.internal.ui.RedirectDelegate
import com.adyen.checkout.twint.internal.ui.TwintDelegate
import com.adyen.checkout.twint.action.internal.ui.TwintActionDelegate
import com.adyen.checkout.voucher.internal.ui.VoucherDelegate
import com.adyen.checkout.wechatpay.internal.ui.WeChatDelegate
import org.junit.jupiter.api.Assertions.assertInstanceOf
Expand Down Expand Up @@ -113,7 +113,10 @@ internal class ActionDelegateProviderTest(
SdkAction<WeChatPaySdkData>(paymentMethodType = PaymentMethodTypes.WECHAT_PAY_SDK),
WeChatDelegate::class.java,
),
arguments(SdkAction<TwintSdkData>(paymentMethodType = PaymentMethodTypes.TWINT), TwintDelegate::class.java),
arguments(
SdkAction<TwintSdkData>(paymentMethodType = PaymentMethodTypes.TWINT),
TwintActionDelegate::class.java,
),
)
}

Expand Down
54 changes: 51 additions & 3 deletions components-core/api/components-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ public final class com/adyen/checkout/components/core/ActionComponentData$Creato
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/adyen/checkout/components/core/ActionHandlingMethod : java/lang/Enum {
public static final field PREFER_NATIVE Lcom/adyen/checkout/components/core/ActionHandlingMethod;
public static final field PREFER_WEB Lcom/adyen/checkout/components/core/ActionHandlingMethod;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public static fun valueOf (Ljava/lang/String;)Lcom/adyen/checkout/components/core/ActionHandlingMethod;
public static fun values ()[Lcom/adyen/checkout/components/core/ActionHandlingMethod;
}

public final class com/adyen/checkout/components/core/Address : com/adyen/checkout/core/internal/data/model/ModelObject {
public static final field ADDRESS_COUNTRY_NULL_PLACEHOLDER Ljava/lang/String;
public static final field ADDRESS_NULL_PLACEHOLDER Ljava/lang/String;
Expand Down Expand Up @@ -1394,14 +1402,16 @@ public final class com/adyen/checkout/components/core/action/TwintSdkData : com/
public static final field CREATOR Landroid/os/Parcelable$Creator;
public static final field Companion Lcom/adyen/checkout/components/core/action/TwintSdkData$Companion;
public static final field SERIALIZER Lcom/adyen/checkout/core/internal/data/model/ModelObject$Serializer;
public fun <init> (Ljava/lang/String;)V
public fun <init> (Ljava/lang/String;Z)V
public final fun component1 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;)Lcom/adyen/checkout/components/core/action/TwintSdkData;
public static synthetic fun copy$default (Lcom/adyen/checkout/components/core/action/TwintSdkData;Ljava/lang/String;ILjava/lang/Object;)Lcom/adyen/checkout/components/core/action/TwintSdkData;
public final fun component2 ()Z
public final fun copy (Ljava/lang/String;Z)Lcom/adyen/checkout/components/core/action/TwintSdkData;
public static synthetic fun copy$default (Lcom/adyen/checkout/components/core/action/TwintSdkData;Ljava/lang/String;ZILjava/lang/Object;)Lcom/adyen/checkout/components/core/action/TwintSdkData;
public fun describeContents ()I
public fun equals (Ljava/lang/Object;)Z
public final fun getToken ()Ljava/lang/String;
public fun hashCode ()I
public final fun isStored ()Z
public fun toString ()Ljava/lang/String;
public fun writeToParcel (Landroid/os/Parcel;I)V
}
Expand Down Expand Up @@ -2862,6 +2872,44 @@ public final class com/adyen/checkout/components/core/paymentmethod/SevenElevenP
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod : com/adyen/checkout/components/core/paymentmethod/PaymentMethodDetails {
public static final field CREATOR Landroid/os/Parcelable$Creator;
public static final field Companion Lcom/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod$Companion;
public static final field SERIALIZER Lcom/adyen/checkout/core/internal/data/model/ModelObject$Serializer;
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Ljava/lang/String;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Ljava/lang/String;
public final fun component4 ()Ljava/lang/String;
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod;
public static synthetic fun copy$default (Lcom/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lcom/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod;
public fun describeContents ()I
public fun equals (Ljava/lang/Object;)Z
public fun getCheckoutAttemptId ()Ljava/lang/String;
public final fun getStoredPaymentMethodId ()Ljava/lang/String;
public final fun getSubtype ()Ljava/lang/String;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
public fun setCheckoutAttemptId (Ljava/lang/String;)V
public final fun setStoredPaymentMethodId (Ljava/lang/String;)V
public final fun setSubtype (Ljava/lang/String;)V
public fun setType (Ljava/lang/String;)V
public fun toString ()Ljava/lang/String;
public fun writeToParcel (Landroid/os/Parcel;I)V
}

public final class com/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod$Companion {
}

public final class com/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod$Creator : android/os/Parcelable$Creator {
public fun <init> ()V
public final fun createFromParcel (Landroid/os/Parcel;)Lcom/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod;
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
public final fun newArray (I)[Lcom/adyen/checkout/components/core/paymentmethod/TwintPaymentMethod;
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/adyen/checkout/components/core/paymentmethod/UPIPaymentMethod : com/adyen/checkout/components/core/paymentmethod/PaymentMethodDetails {
public static final field CREATOR Landroid/os/Parcelable$Creator;
public static final field Companion Lcom/adyen/checkout/components/core/paymentmethod/UPIPaymentMethod$Companion;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 Adyen N.V.
*
* This file is open source and available under the MIT license. See the LICENSE file for more info.
*
* Created by oscars on 7/8/2024.
*/

package com.adyen.checkout.components.core

/**
* Used to configure the method used to handle actions.
*/
enum class ActionHandlingMethod {
/**
* The action will be handled in a native way (e.g. using a SDK). **If** there is no way to handle the action
* natively, then a fallback method will be used (e.g. a web flow).
*/
PREFER_NATIVE,

/**
* The action will be handled with a web flow. **If** there is no way to handle the action with a web flow, then
* native method will be used.
*/
PREFER_WEB,
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ object PaymentMethodTypes {
const val PAY_BY_BANK = "paybybank"
const val SCHEME = "scheme"
const val SEPA = "sepadirectdebit"
const val TWINT = "twint"
const val UPI = "upi"
const val UPI_INTENT = "upi_intent"
const val UPI_COLLECT = "upi_collect"
Expand All @@ -56,7 +57,6 @@ object PaymentMethodTypes {
const val PAY_NOW = "paynow"
const val PIX = "pix"
const val PROMPT_PAY = "promptpay"
const val TWINT = "twint"
const val WECHAT_PAY_SDK = "wechatpaySDK"
const val MULTIBANCO = "multibanco"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ import org.json.JSONObject
@Parcelize
data class TwintSdkData(
val token: String,
val isStored: Boolean,
) : SdkData() {

companion object {

private const val TOKEN = "token"
private const val IS_STORED = "isStored"

@JvmField
val SERIALIZER: Serializer<TwintSdkData> = object : Serializer<TwintSdkData> {
override fun serialize(modelObject: TwintSdkData): JSONObject {
return try {
JSONObject().apply {
putOpt(TOKEN, modelObject.token)
putOpt(IS_STORED, modelObject.isStored)
}
} catch (e: JSONException) {
throw ModelSerializationException(TwintSdkData::class.java, e)
Expand All @@ -38,6 +41,7 @@ data class TwintSdkData(
return try {
TwintSdkData(
token = jsonObject.getString(TOKEN),
isStored = jsonObject.optBoolean(IS_STORED),
)
} catch (e: JSONException) {
throw ModelSerializationException(TwintSdkData::class.java, e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ abstract class PaymentMethodDetails : ModelObject() {
PaymentMethodTypes.MOLPAY_THAILAND,
PaymentMethodTypes.MOLPAY_VIETNAM -> MolpayPaymentMethod.SERIALIZER

PaymentMethodTypes.TWINT -> TwintPaymentMethod.SERIALIZER

PaymentMethodTypes.UPI,
PaymentMethodTypes.UPI_COLLECT,
PaymentMethodTypes.UPI_QR,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2024 Adyen N.V.
*
* This file is open source and available under the MIT license. See the LICENSE file for more info.
*
* Created by oscars on 31/7/2024.
*/

package com.adyen.checkout.components.core.paymentmethod

import com.adyen.checkout.core.exception.ModelSerializationException
import com.adyen.checkout.core.internal.data.model.getStringOrNull
import kotlinx.parcelize.Parcelize
import org.json.JSONException
import org.json.JSONObject

@Parcelize
data class TwintPaymentMethod(
override var type: String?,
override var checkoutAttemptId: String?,
var subtype: String? = null,
var storedPaymentMethodId: String? = null,
) : PaymentMethodDetails() {

companion object {
private const val SUBTYPE = "subtype"
private const val STORED_PAYMENT_METHOD_ID = "storedPaymentMethodId"

@JvmField
val SERIALIZER: Serializer<TwintPaymentMethod> = object : Serializer<TwintPaymentMethod> {
override fun serialize(modelObject: TwintPaymentMethod): JSONObject {
return try {
JSONObject().apply {
putOpt(TYPE, modelObject.type)
putOpt(CHECKOUT_ATTEMPT_ID, modelObject.checkoutAttemptId)
putOpt(SUBTYPE, modelObject.subtype)
putOpt(STORED_PAYMENT_METHOD_ID, modelObject.storedPaymentMethodId)
}
} catch (e: JSONException) {
throw ModelSerializationException(BlikPaymentMethod::class.java, e)
}
}

override fun deserialize(jsonObject: JSONObject): TwintPaymentMethod {
return TwintPaymentMethod(
type = jsonObject.getStringOrNull(TYPE),
checkoutAttemptId = jsonObject.getStringOrNull(CHECKOUT_ATTEMPT_ID),
subtype = jsonObject.getStringOrNull(SUBTYPE),
storedPaymentMethodId = jsonObject.getStringOrNull(STORED_PAYMENT_METHOD_ID),
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ internal class TwintSdkDataTest {
fun `when serializing, then all fields should be serialized correctly`() {
val request = TwintSdkData(
token = "testToken",
isStored = true,
)

val actual = TwintSdkData.SERIALIZER.serialize(request)

val expected = JSONObject()
.put("token", "testToken")
.put("isStored", true)

assertEquals(expected.toString(), actual.toString())
}
Expand All @@ -26,11 +28,13 @@ internal class TwintSdkDataTest {
fun `when deserializing, then all fields should be deserializing correctly`() {
val response = JSONObject()
.put("token", "testToken")
.put("isStored", true)

val actual = TwintSdkData.SERIALIZER.deserialize(response)

val expected = TwintSdkData(
token = "testToken",
isStored = true,
)

assertEquals(expected, actual)
Expand Down
Loading

0 comments on commit fbf8395

Please sign in to comment.