diff --git a/GenesisAndroid/build.gradle b/GenesisAndroid/build.gradle index aee5f30..8f1fd63 100644 --- a/GenesisAndroid/build.gradle +++ b/GenesisAndroid/build.gradle @@ -5,7 +5,7 @@ apply plugin: 'kotlin-kapt' ext { PUBLISH_GROUP_ID = 'com.emerchantpay.gateway' - PUBLISH_VERSION = '1.3.3' + PUBLISH_VERSION = '1.3.4' PUBLISH_ARTIFACT_ID = 'genesis-android' PUBLISH_DESCRIPTION = 'Genesis Android SDK' PUBLISH_URL = 'https://github.com/GenesisGateway/android_sdk' @@ -27,7 +27,7 @@ android { minSdkVersion 19 targetSdkVersion 33 versionCode 1 - versionName "1.3.0" + versionName "1.3.4" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/WPFTransactionTypes.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/WPFTransactionTypes.kt index e2fa9ef..908e410 100644 --- a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/WPFTransactionTypes.kt +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/WPFTransactionTypes.kt @@ -15,12 +15,6 @@ enum class WPFTransactionTypes(val value: String) { // 3D-Secure Sale SALE3D("sale3d"), - // Standard initial recurring - INIT_RECURRING_SALE("init_recurring_sale"), - - // 3D-based initial recurring - INIT_RECURRING_SALE3D("init_recurring_sale3d"), - // Card verification without any financial impact ACCOUNT_VERIFICATION("account_verification"), diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringAmountType.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringAmountType.kt new file mode 100644 index 0000000..290d2f5 --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringAmountType.kt @@ -0,0 +1,13 @@ +package com.emerchantpay.gateway.genesisandroid.api.constants + +import java.util.* + +enum class RecurringAmountType(val value: String) { + // Amount types + FIXED("fixed"), + MAX("max"); + + override fun toString(): String { + return name.lowercase(Locale.ROOT) + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringCategory.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringCategory.kt new file mode 100644 index 0000000..0df9c80 --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringCategory.kt @@ -0,0 +1,12 @@ +package com.emerchantpay.gateway.genesisandroid.api.constants.recurring + +import java.util.* + +enum class RecurringCategory(val value: String) { + SUBSCRIPTION("subscription"), + STANDING_ORDER("stanging_order"); + + override fun toString(): String { + return name.lowercase(Locale.ROOT) + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringFrequency.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringFrequency.kt new file mode 100644 index 0000000..8dd5e94 --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringFrequency.kt @@ -0,0 +1,23 @@ +package com.emerchantpay.gateway.genesisandroid.api.constants + +import java.util.* + +enum class RecurringFrequency(val value: String) { + // Frequency + DAYLY("daily"), + TWICE_WEEKLY("twice_weekly"), + WEEKLY("weekly"), + TEN_DAYS("ten_days"), + FORTNIGHTLY("fortnightly"), + MONTHLY("monthly"), + EVERY_TWO_MONTHS("every_two_months"), + TRIMESTER("trimester"), + QUARTERLY("quarterly"), + TWICE_YEARLY("twice_yearly"), + ANUALLY("annually"), + UNSCHEDULED("unscheduled"); + + override fun toString(): String { + return name.lowercase(Locale.ROOT) + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringInterval.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringInterval.kt new file mode 100644 index 0000000..8cfe1ab --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringInterval.kt @@ -0,0 +1,13 @@ +package com.emerchantpay.gateway.genesisandroid.api.constants + +import java.util.* + +enum class RecurringInterval(val value: String) { + // Interval + DAYS("days"), + MONTHS("months"); + + override fun toString(): String { + return name.lowercase(Locale.ROOT) + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringMode.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringMode.kt new file mode 100644 index 0000000..91ae3c9 --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringMode.kt @@ -0,0 +1,13 @@ +package com.emerchantpay.gateway.genesisandroid.api.constants + +import java.util.* + +enum class RecurringMode(val value: String) { + // Mode + AUTOMATIC("automatic"), + MANUAL("manual"); + + override fun toString(): String { + return name.lowercase(Locale.ROOT) + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringPaymentType.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringPaymentType.kt new file mode 100644 index 0000000..d72d572 --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringPaymentType.kt @@ -0,0 +1,15 @@ +package com.emerchantpay.gateway.genesisandroid.api.constants + +import java.util.* + +enum class RecurringPaymentType(val value: String) { + // Payment types + INITIAL("initial"), + SUBSEQUENT("subsequent"), + MODIFICATION("modification"), + CANCELLATION("cancellation"); + + override fun toString(): String { + return name.lowercase(Locale.ROOT) + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringType.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringType.kt new file mode 100644 index 0000000..de2b642 --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/constants/recurring/RecurringType.kt @@ -0,0 +1,12 @@ +package com.emerchantpay.gateway.genesisandroid.api.constants.recurring + +import java.util.* + +enum class RecurringType(val value: String) { + INITIAL("initial"), + MANAGED("managed"); + + override fun toString(): String { + return name.lowercase(Locale.ROOT) + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/interfaces/recurring/CommonManagedRecurringAttributes.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/interfaces/recurring/CommonManagedRecurringAttributes.kt new file mode 100644 index 0000000..708ea2f --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/interfaces/recurring/CommonManagedRecurringAttributes.kt @@ -0,0 +1,45 @@ +package com.emerchantpay.gateway.genesisandroid.api.interfaces.recurring + +import com.emerchantpay.gateway.genesisandroid.api.constants.RecurringInterval +import com.emerchantpay.gateway.genesisandroid.api.constants.RecurringMode +import com.emerchantpay.gateway.genesisandroid.api.util.RequestBuilder +import java.text.SimpleDateFormat +import java.util.* + +interface CommonManagedRecurringAttributes: IndianManagedRecurringAttributes { + + fun setMode(mode: RecurringMode) { + requestBuilder.addElement("mode", mode.toString()) + } + + fun setInterval(interval: RecurringInterval) { + requestBuilder.addElement("interval", interval.toString()) + } + + fun setFirstDate(firstDate: Date?) { + firstDate?.let { requestBuilder.addElement("first_date", SimpleDateFormat(DATE_FORMAT).format(it)) } + } + + fun setTimeOfDay(timeOfDay: Int) { + requestBuilder.addElement("time_of_day", timeOfDay) + } + + fun setPeriod(period: Int) { + requestBuilder.addElement("period", period) + } + + fun setAmount(amount: Int) { + requestBuilder.addElement("amount", amount) + } + + fun setMaxCount(maxCount: Int) { + requestBuilder.addElement("max_count", maxCount) + } + + fun buildManagedRecurringAttributes(): RequestBuilder = requestBuilder + + companion object { + private const val DATE_FORMAT = "yyyy-MM-dd" + private val requestBuilder = RequestBuilder("") + } +} diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/interfaces/recurring/IndianManagedRecurringAttributes.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/interfaces/recurring/IndianManagedRecurringAttributes.kt new file mode 100644 index 0000000..ee694f3 --- /dev/null +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/interfaces/recurring/IndianManagedRecurringAttributes.kt @@ -0,0 +1,39 @@ +package com.emerchantpay.gateway.genesisandroid.api.interfaces.recurring + +import com.emerchantpay.gateway.genesisandroid.api.constants.RecurringAmountType +import com.emerchantpay.gateway.genesisandroid.api.constants.RecurringFrequency +import com.emerchantpay.gateway.genesisandroid.api.constants.RecurringPaymentType +import com.emerchantpay.gateway.genesisandroid.api.util.RequestBuilder + +interface IndianManagedRecurringAttributes { + + fun setPaymentType(paymentType: RecurringPaymentType) { + requestBuilder.addElement("payment_type", paymentType.value) + } + + fun setAmountType(amountType: RecurringAmountType) { + requestBuilder.addElement("amount_type", amountType.value) + } + + fun setFrequency(frequency: RecurringFrequency) { + requestBuilder.addElement("frequency", frequency.value) + } + + fun setRegistrationReferenceNumber(referenceNumber: Int) { + requestBuilder.addElement("registration_reference_number", referenceNumber.toString()) + } + + fun setMaxAmount(maxAmount: Int) { + requestBuilder.addElement("max_amount", maxAmount.toString()) + } + + fun setValidated(validated: Boolean) { + requestBuilder.addElement("validated", validated.toString()) + } + + fun buildIndianManagedRecurringAttributes(): RequestBuilder = requestBuilder + + companion object { + private val requestBuilder = RequestBuilder("") + } +} diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/request/PaymentRequest.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/request/PaymentRequest.kt index bdc2bcb..98d8812 100644 --- a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/request/PaymentRequest.kt +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/request/PaymentRequest.kt @@ -4,6 +4,8 @@ import android.content.Context import com.emerchantpay.gateway.genesisandroid.api.constants.SharedPrefConstants import com.emerchantpay.gateway.genesisandroid.api.constants.URLConstants import com.emerchantpay.gateway.genesisandroid.api.constants.WPFTransactionTypes +import com.emerchantpay.gateway.genesisandroid.api.constants.recurring.RecurringCategory +import com.emerchantpay.gateway.genesisandroid.api.constants.recurring.RecurringType import com.emerchantpay.gateway.genesisandroid.api.interfaces.BaseAttributes import com.emerchantpay.gateway.genesisandroid.api.interfaces.RiskParamsAttributes import com.emerchantpay.gateway.genesisandroid.api.interfaces.customerinfo.CustomerInfoAttributes @@ -118,11 +120,14 @@ open class PaymentRequest : Request, PaymentAttributes, CustomerInfoAttributes, val returnCancelUrl: String get() = URLConstants.CANCEL_URL + // Recurring + private var recurringType: String? = null + private var recurringCategory: String? = null + @Throws(IllegalAccessException::class) - constructor( - context: Context?, transactionId: String?, amount: BigDecimal?, currency: Currency, customerEmail: String?, - customerPhone: String?, billingAddress: PaymentAddress?, notificationUrl: String?, - transactionTypes: TransactionTypesRequest) : super() { + constructor(context: Context?, transactionId: String?, amount: BigDecimal?, currency: Currency, customerEmail: String?, + customerPhone: String?, billingAddress: PaymentAddress?, notificationUrl: String?, + transactionTypes: TransactionTypesRequest) : super() { this.context = context this.transactionId = transactionId!! @@ -135,7 +140,7 @@ open class PaymentRequest : Request, PaymentAttributes, CustomerInfoAttributes, this.transactionTypes = transactionTypes when { - notificationUrl != null && notificationUrl.isNotEmpty() -> this.notificationUrl = notificationUrl + notificationUrl != null && notificationUrl.isNotBlank() -> this.notificationUrl = notificationUrl } // Init params @@ -381,6 +386,14 @@ open class PaymentRequest : Request, PaymentAttributes, CustomerInfoAttributes, return reminders.addReminder(channel, after) } + fun setRecurringType(recurringType: RecurringType) { + this.recurringType = recurringType.value + } + + fun setRecurringCategory(recurringCategory: RecurringCategory) { + this.recurringCategory = recurringCategory.value + } + override fun toXML(): String { return buildRequest("wpf_payment")!!.toXML() } @@ -415,6 +428,20 @@ open class PaymentRequest : Request, PaymentAttributes, CustomerInfoAttributes, .addElement("threeds_v2_params", buildThreeDsV2Attributes().toXML()) .addElement("dynamic_descriptor_params", buildDescriptorParams().toXML()) + val transactionTypesList = transactionTypes.transactionTypesList + + if (transactionTypesList.contains("authorize") + || transactionTypesList.contains("authorize3d") + || transactionTypesList.contains("sale") + || transactionTypesList.contains("sale3d")) { + recurringType?.let { + paymentRequestBuilder?.addElement("recurring_type", it) + } + recurringCategory?.let { + paymentRequestBuilder?.addElement("recurring_category", it) + } + } + consumerId = getConsumerId() when { diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/request/TransactionTypesRequest.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/request/TransactionTypesRequest.kt index 4b2fa70..1058b2f 100644 --- a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/request/TransactionTypesRequest.kt +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/request/TransactionTypesRequest.kt @@ -2,12 +2,13 @@ package com.emerchantpay.gateway.genesisandroid.api.internal.request import com.emerchantpay.gateway.genesisandroid.api.constants.WPFTransactionTypes +import com.emerchantpay.gateway.genesisandroid.api.interfaces.recurring.CommonManagedRecurringAttributes import com.emerchantpay.gateway.genesisandroid.api.internal.validation.GenesisValidator import com.emerchantpay.gateway.genesisandroid.api.util.Request import com.emerchantpay.gateway.genesisandroid.api.util.RequestBuilderWithAttribute import java.util.* -class TransactionTypesRequest : Request { +class TransactionTypesRequest : Request, CommonManagedRecurringAttributes { private var parent: PaymentRequest? = null val transactionTypesList = ArrayList() @@ -97,6 +98,13 @@ class TransactionTypesRequest : Request { return buildRequest(root).toQueryString() } + private fun isManagedRecurringEnabled(): Boolean { + return (transactionTypesList.contains(WPFTransactionTypes.AUTHORIZE.value) + || transactionTypesList.contains(WPFTransactionTypes.AUTHORIZE3D.value) + || transactionTypesList.contains(WPFTransactionTypes.SALE.value) + || transactionTypesList.contains(WPFTransactionTypes.SALE3D.value)) + } + protected fun buildRequest(root: String): RequestBuilderWithAttribute { val builder = RequestBuilderWithAttribute(root, "") @@ -105,6 +113,9 @@ class TransactionTypesRequest : Request { builder.addElement("", attribute) } + if (isManagedRecurringEnabled()) + builder!!.addElement("managed_recurring", buildManagedRecurringAttributes()) + return builder } } diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/validation/GenesisValidator.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/validation/GenesisValidator.kt index 0e60173..a9f652c 100644 --- a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/validation/GenesisValidator.kt +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/validation/GenesisValidator.kt @@ -143,7 +143,7 @@ open class GenesisValidator { val errorMessage = requiredParametersValidator!!.error!!.message val errorTechnicalMessage = requiredParametersValidator!!.error!!.technicalMessage error = GenesisError("is required for $transactionType transaction type", - "$errorTechnicalMessage parameter ") + "$errorTechnicalMessage parameter ") } } } @@ -160,7 +160,7 @@ open class GenesisValidator { orderTaxAmount: BigDecimal?): Boolean? { when { klarnaRequest != null -> requiredParametersValidator = RequiredParametersValidator(requiredParameters - .getRequiredParametersForKlarnaItem(klarnaRequest)) + .getRequiredParametersForKlarnaItem(klarnaRequest)) else -> { error = GenesisError(ErrorMessages.REQUIRED_PARAMS, "items") return false @@ -209,7 +209,7 @@ open class GenesisValidator { fun isValidAddress(address: PaymentAddress): Boolean? { // Init Required Params Validator requiredParametersValidator = RequiredParametersValidator(requiredParameters - .getRequiredParametersForAddress(address)) + .getRequiredParametersForAddress(address)) return requiredParametersValidator!!.isValidRequiredParams!! } @@ -259,9 +259,9 @@ open class GenesisValidator { companion object { // Regular expressions val VALID_EMAIL_REGEX = Pattern - .compile("[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}", Pattern.CASE_INSENSITIVE) + .compile("[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}", Pattern.CASE_INSENSITIVE) val VALID_PHONE_REGEX = Pattern.compile("^[0-9\\+]{1,}[0-9\\\\-]{3,15}$") val VALID_URL_REGEX = Pattern - .compile("\\b(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]") + .compile("\\b(https?)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]") } -} +} \ No newline at end of file diff --git a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/validation/RequiredParameters.kt b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/validation/RequiredParameters.kt index 6557ea8..5ee7664 100644 --- a/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/validation/RequiredParameters.kt +++ b/GenesisAndroid/src/main/java/com/emerchantpay/gateway/genesisandroid/api/internal/validation/RequiredParameters.kt @@ -49,7 +49,7 @@ class RequiredParameters { else -> "" } requiredParamsMap[customerGender] = when { - transactionParams[orderTaxAmount] != null -> transactionParams[customerGender].toString() + transactionParams[customerGender] != null -> transactionParams[customerGender].toString() else -> "" } return requiredParamsMap @@ -80,6 +80,7 @@ class RequiredParameters { return requiredParamsMap } + fun getRequiredParametersForRequest(paymentRequest: PaymentRequest): HashMap? { requiredParamsMap[transactionId] = paymentRequest.transactionId requiredParamsMap[amount] = paymentRequest.amount.toString() @@ -87,11 +88,11 @@ class RequiredParameters { requiredParamsMap[transactionTypes] = paymentRequest.transactionTypes.transactionTypesList.toString() requiredParamsMap[returnSuccessUrl] = paymentRequest.returnSuccessUrl requiredParamsMap[returnCancelUrl] = paymentRequest.returnCancelUrl - when { - !paymentRequest.customerEmail.isNullOrBlank() - && paymentRequest.consumerId?.isEmpty() == true -> - requiredParamsMap[consumerId] = paymentRequest.consumerId as String - } + + if (!paymentRequest.customerEmail.isNullOrBlank() + && paymentRequest.consumerId?.isEmpty() == true) + requiredParamsMap[consumerId] = paymentRequest.consumerId as String + requiredParamsMap[notificationUrl] = paymentRequest.notificationUrl requiredParamsMap[billingAddress] = paymentRequest.getBillingAddress().toXML() @@ -107,7 +108,9 @@ class RequiredParameters { const val returnSuccessUrl = "return_success_url" const val returnFailureUrl = "return_failure_url" const val returnCancelUrl = "return_cancel_url" + const val customerEmail = "customer_email" const val consumerId = "consumer_id" + const val customerPhone = "customer_phone" const val billingAddress = "billing_address" const val shippingAddress = "shipping_address" const val notificationUrl = "notification_url" @@ -118,6 +121,10 @@ class RequiredParameters { const val lifetime = "lifetime" const val firstName = "firstname" const val lastName = "lastname" + const val address1 = "address1" + const val address2 = "address2" + const val zipCode = "zip_code" + const val city = "city" const val country = "country" const val state = "state" const val customerAccountId = "customer_account_id" @@ -128,6 +135,7 @@ class RequiredParameters { const val cardType = "card_type" const val redeemType = "redeem_type" + // Klarna const val orderTaxAmount = "order_tax_amount" const val customerGender = "customer_gender" @@ -137,5 +145,8 @@ class RequiredParameters { const val quantity = "quantity" const val unitPrice = "unitPrice" const val totalAmount = "total_amount" + + // Managed recurring + const val managedRecurring = "managed_recurring" } } diff --git a/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/internal/CommonManagedRecurringAttributesUnitTest.kt b/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/internal/CommonManagedRecurringAttributesUnitTest.kt new file mode 100644 index 0000000..4dce286 --- /dev/null +++ b/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/internal/CommonManagedRecurringAttributesUnitTest.kt @@ -0,0 +1,52 @@ +package com.emerchantpay.gateway.genesisandroid.internal + +import com.emerchantpay.gateway.genesisandroid.api.constants.RecurringInterval +import com.emerchantpay.gateway.genesisandroid.api.constants.RecurringMode +import com.emerchantpay.gateway.genesisandroid.api.interfaces.recurring.CommonManagedRecurringAttributes +import org.junit.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.DisplayName +import java.text.SimpleDateFormat +import java.util.* + +internal class CommonManagedRecurringAttributesUnitTest : CommonManagedRecurringAttributes { + @Test + @DisplayName("Given attributes with assigned values, When serialized to XML, Then should be valid") + fun testValidXmlIsGeneratedOnSerialization() { + setMode(RecurringMode.AUTOMATIC) + setInterval(RecurringInterval.DAYS) + setFirstDate(FIRST_DATE) + setTimeOfDay(7) + setPeriod(7) + setAmount(500) + setMaxCount(10) + + val generatedXml = buildManagedRecurringAttributes().toXML() + + assertEquals(EXPECTED_XML, generatedXml) + } + + @Test + @DisplayName("Given required attributes with assigned values, When serialized to XML, Then should be valid") + fun testValidXmlIsGeneratedOnSerializationWithRequiredParams() { + setMode(RecurringMode.AUTOMATIC) + setInterval(RecurringInterval.DAYS) + + val generatedXml = buildManagedRecurringAttributes().toXML() + + assertEquals(EXPECTED_XML_REQUIRED, generatedXml) + } + + companion object { + private const val FIRST_DATE_TEXT = "2018-02-14" + private val FIRST_DATE = SimpleDateFormat("yyyy-MM-dd").parse(FIRST_DATE_TEXT) + private val MODE = RecurringMode.AUTOMATIC.value + private val INTERVAL = RecurringInterval.DAYS.value + + private val EXPECTED_XML = + "$MODE$INTERVAL$FIRST_DATE_TEXT7750010" + + private val EXPECTED_XML_REQUIRED = + "$MODE$INTERVAL" + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/internal/PaymentRequestUnitTest.kt b/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/internal/PaymentRequestUnitTest.kt index f5a6bf6..50a4b79 100644 --- a/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/internal/PaymentRequestUnitTest.kt +++ b/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/internal/PaymentRequestUnitTest.kt @@ -3,6 +3,8 @@ package com.emerchantpay.gateway.genesisandroid.internal import android.content.Context import com.emerchantpay.gateway.genesisandroid.api.constants.ReminderConstants import com.emerchantpay.gateway.genesisandroid.api.constants.WPFTransactionTypes +import com.emerchantpay.gateway.genesisandroid.api.constants.recurring.RecurringCategory +import com.emerchantpay.gateway.genesisandroid.api.constants.recurring.RecurringType import com.emerchantpay.gateway.genesisandroid.api.internal.request.PaymentRequest import com.emerchantpay.gateway.genesisandroid.api.internal.request.TransactionTypesRequest import com.emerchantpay.gateway.genesisandroid.api.models.* @@ -35,8 +37,8 @@ class PaymentRequestUnitTest { // Address address = PaymentAddress("John", "Doe", "Berlin street 1", - "Berlin street 1", "10000", "Berlin", - "Berlin state", Country.Germany) + "Berlin street 1", "10000", "Berlin", + "Berlin state", Country.Germany) // Transaction types // Create Transaction types @@ -45,9 +47,9 @@ class PaymentRequestUnitTest { // Payment paymentRequest paymentRequest = PaymentRequest(context!!, uniqueId, - BigDecimal("2.00"), Currency.USD, - "john@example.com", "+55555555", address!!, - "https://example.com", transactionTypes!!) + BigDecimal("2.00"), Currency.USD, + "john@example.com", "+55555555", address!!, + "https://example.com", transactionTypes!!) paymentRequest?.setConsumerId("123456") } @@ -121,9 +123,9 @@ class PaymentRequestUnitTest { address?.let { it1 -> transactionTypes?.let { it2 -> PaymentRequest(it, uniqueId, - BigDecimal("2.00"), Currency.USD, - "john@example.com", "+55555555", it1, - "", it2) + BigDecimal("2.00"), Currency.USD, + "john@example.com", "+55555555", it1, + "", it2) } } } @@ -168,8 +170,8 @@ class PaymentRequestUnitTest { @Test fun testRemindersSuccess() { paymentRequest!!.setPayLater(true) - .addReminder(ReminderConstants.REMINDERS_CHANNEL_EMAIL, 1) - .addReminder(ReminderConstants.REMINDERS_CHANNEL_SMS, 1).done() + .addReminder(ReminderConstants.REMINDERS_CHANNEL_EMAIL, 1) + .addReminder(ReminderConstants.REMINDERS_CHANNEL_SMS, 1).done() assertNotNull(paymentRequest!!.reminders) } @@ -177,7 +179,7 @@ class PaymentRequestUnitTest { @Test fun testRemindersFailure() { paymentRequest!!.setPayLater(true) - .addReminder("test", 1).done() + .addReminder("test", 1).done() assertEquals(paymentRequest!!.reminders.remindersList, ArrayList()) } @@ -185,4 +187,18 @@ class PaymentRequestUnitTest { fun testBuildRequest() { assertEquals(paymentRequest!!.toXML(), paymentRequest!!.request.toXML()) } -} + + @Test + fun testWithoutRecurringParams() { + mockParams() + paymentRequest!!.isValidData?.let { assertTrue(it) } + } + + + @Test + fun testRecurringParams() { + paymentRequest?.setRecurringType(RecurringType.INITIAL) + paymentRequest?.setRecurringCategory(RecurringCategory.SUBSCRIPTION) + paymentRequest!!.isValidData?.let { assertTrue(it) } + } +} \ No newline at end of file diff --git a/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/validation/GenesisValidatorUnitTest.kt b/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/validation/GenesisValidatorUnitTest.kt index ea29932..8af8ddd 100644 --- a/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/validation/GenesisValidatorUnitTest.kt +++ b/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/validation/GenesisValidatorUnitTest.kt @@ -4,6 +4,8 @@ import android.content.Context import com.emerchantpay.gateway.genesisandroid.api.constants.ErrorMessages import com.emerchantpay.gateway.genesisandroid.api.constants.ReminderConstants import com.emerchantpay.gateway.genesisandroid.api.constants.WPFTransactionTypes +import com.emerchantpay.gateway.genesisandroid.api.constants.recurring.RecurringCategory +import com.emerchantpay.gateway.genesisandroid.api.constants.recurring.RecurringType import com.emerchantpay.gateway.genesisandroid.api.internal.request.PaymentRequest import com.emerchantpay.gateway.genesisandroid.api.internal.request.TransactionTypesRequest import com.emerchantpay.gateway.genesisandroid.api.internal.validation.GenesisValidator @@ -246,4 +248,17 @@ class GenesisValidatorUnitTest { fun testIsValidData() { assertTrue(request?.let { validator!!.isValidRequest(it) }!!) } + + @Test + fun testValidDataWithoutRecurring() { + setup() + assertTrue(request?.let { validator!!.isValidRequest(it) }!!) + } + + @Test + fun testValidDataWithRecurring() { + request?.setRecurringType(RecurringType.INITIAL) + request?.setRecurringCategory(RecurringCategory.SUBSCRIPTION) + assertTrue(request?.let { validator!!.isValidRequest(it) }!!) + } } diff --git a/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/validation/RequiredParametersValidatorUnitTest.kt b/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/validation/RequiredParametersValidatorUnitTest.kt index fdc6afb..3d31f5d 100644 --- a/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/validation/RequiredParametersValidatorUnitTest.kt +++ b/GenesisAndroid/src/test/java/com/emerchantpay/gateway/genesisandroid/validation/RequiredParametersValidatorUnitTest.kt @@ -3,6 +3,8 @@ package com.emerchantpay.gateway.genesisandroid.validation import android.content.Context import com.emerchantpay.gateway.genesisandroid.api.constants.KlarnaItemTypes import com.emerchantpay.gateway.genesisandroid.api.constants.WPFTransactionTypes +import com.emerchantpay.gateway.genesisandroid.api.constants.recurring.RecurringCategory +import com.emerchantpay.gateway.genesisandroid.api.constants.recurring.RecurringType import com.emerchantpay.gateway.genesisandroid.api.internal.request.PaymentRequest import com.emerchantpay.gateway.genesisandroid.api.internal.request.TransactionTypesRequest import com.emerchantpay.gateway.genesisandroid.api.internal.validation.RequiredParameters @@ -60,8 +62,8 @@ class RequiredParametersValidatorUnitTest { // Address billingAddress = PaymentAddress("John", "Doe", - "address1", "", "10000", "New York", - "state", Country().getCountry("United States")!!) + "address1", "", "10000", "New York", + "state", Country().getCountry("United States")!!) // Transaction types list transactionTypes = TransactionTypesRequest() @@ -71,7 +73,7 @@ class RequiredParametersValidatorUnitTest { // Payment request request = context?.let { PaymentRequest(it, transactionId!!, amount!!, Currency.USD, - customerEmail!!, customerPhone!!, billingAddress!!, notificationUrl, transactionTypes!!) + customerEmail!!, customerPhone!!, billingAddress!!, notificationUrl, transactionTypes!!) } request!!.consumerId = "123456" @@ -102,7 +104,7 @@ class RequiredParametersValidatorUnitTest { billingAddress?.let { it1 -> transactionTypes?.let { it2 -> PaymentRequest(it, transactionId, amount, Currency.USD, - customerEmail, customerPhone, it1, notificationUrl, it2) + customerEmail, customerPhone, it1, notificationUrl, it2) } } } @@ -151,8 +153,8 @@ class RequiredParametersValidatorUnitTest { fun testWithMissingAddressParams() { // Address billingAddress = PaymentAddress("John", "Doe", - "", "", "", "", - "", Country().getCountry("United States")!!) + "", "", "", "", + "", Country().getCountry("United States")!!) requiredParamsMap = requiredParameters.getRequiredParametersForAddress(billingAddress!!) @@ -177,7 +179,7 @@ class RequiredParametersValidatorUnitTest { customerEmail?.let { it4 -> customerPhone?.let { it5 -> PaymentRequest(it1, it2, it3, Currency.USD, - it4, it5, it, notificationUrl, transactionTypes!!) + it4, it5, it, notificationUrl, transactionTypes!!) } } } @@ -203,7 +205,7 @@ class RequiredParametersValidatorUnitTest { // Payment request request = PaymentRequest(context, transactionId, amount, Currency.USD, - customerEmail, customerPhone, billingAddress, notificationUrl, transactionTypes!!) + customerEmail, customerPhone, billingAddress, notificationUrl, transactionTypes!!) var map: HashMap @@ -225,7 +227,7 @@ class RequiredParametersValidatorUnitTest { // Payment request request = PaymentRequest(context, transactionId, amount, Currency.USD, - customerEmail, customerPhone, billingAddress, notificationUrl, transactionTypes!!) + customerEmail, customerPhone, billingAddress, notificationUrl, transactionTypes!!) request!!.rememberCard = true @@ -244,7 +246,7 @@ class RequiredParametersValidatorUnitTest { @Test fun testWithKlarnaItems() { val item = KlarnaItem("TICKET", KlarnaItemTypes.DISCOUNT, 10, - BigDecimal(10.00), BigDecimal(2.00)) + BigDecimal(10.00), BigDecimal(2.00)) request!!.addKlarnaItem(item) @@ -257,7 +259,7 @@ class RequiredParametersValidatorUnitTest { @Test fun testWithMissingKlarnaItems() { val item = KlarnaItem("", KlarnaItemTypes.DISCOUNT, 10, - BigDecimal(10.00), BigDecimal(2.00)) + BigDecimal(10.00), BigDecimal(2.00)) request!!.addKlarnaItem(item) diff --git a/README.md b/README.md index abf9548..8d1e2a7 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ cd GenesisAndroid * Add the dependency in your build.gradle: ``` dependencies { - implementation 'com.emerchantpay.gateway:genesis-android:1.3.3' + implementation 'com.emerchantpay.gateway:genesis-android:1.3.4' } ``` @@ -462,6 +462,58 @@ ThreeDsV2Params threeDsV2Params=threeDsV2ParamsBuilder.build(); paymentRequest.setThreeDsV2Params(threeDsV2Params); ``` +Set Recurring Params + +```kotlin + // Create Transaction types +val transactionTypes = TransactionTypesRequest() +transactionTypes.addTransaction(WPFTransactionTypes.SALE) + +transactionTypes.setMode(RecurringMode.AUTOMATIC) + .setInterval(RecurringInterval.DAYS) + .setFirstDate(FIRST_DATE) + .setTimeOfDay(7) + .setPeriod(7) + .setAmount(500) + .setMaxCount(10) + + // Init WPF API request +val paymentRequest = PaymentRequest(this, uniqueId, + BigDecimal("2.00"), Currency.USD, + "john@example.com", "+555555555", billingAddress, + "https://example.com", transactionTypes) + +paymentRequest?.setRecurringType(RecurringType.INITIAL) +paymentRequest?.setRecurringCategory(RecurringCategory.SUBSCRIPTION) + +// ... +``` + +```java +// Create Transaction types +TransactionTypesRequest transactionTypes = new TransactionTypesRequest(); +transactionTypes.addTransaction(WPFTransactionTypes.SALE); + +transactionTypes.setMode(RecurringMode.AUTOMATIC) + .setInterval(RecurringInterval.DAYS) + .setFirstDate(FIRST_DATE) + .setTimeOfDay(7) + .setPeriod(7) + .setAmount(500) + .setMaxCount(10); + +// Init WPF API request +PaymentRequest paymentRequest = new PaymentRequest(this, uniqueId, + new BigDecimal("2.00"), new Currency().Companion.getUSD(), + "john@example.com", "+555555555", billingAddress, + "https://example.com", transactionTypes); + +paymentRequest.setRecurringType(RecurringType.INITIAL); +paymentRequest.setRecurringCategory(RecurringCategory.SUBSCRIPTION); + +// ... +``` + Running Tests --------------