Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xpepper/8057b8034a54085e77046e21794bc2f0 to your computer and use it in GitHub Desktop.
Save xpepper/8057b8034a54085e77046e21794bc2f0 to your computer and use it in GitHub Desktop.
tags
Kotlin

A Kotlin type-safe DSL to create payment transactions

See https://kotlinlang.org/docs/type-safe-builders.html for more info.

import com.transactions.Authentication.*
import com.transactions.Authentication.Bank.BANK_OF_AMERICA
import com.transactions.Authentication.ChallengeType.NONE
import com.transactions.Authentication.RiskDecision.FRICTIONLESS
import com.transactions.Authentication.Status.SUCCESS
import java.util.*

fun authentication(addDetails: AuthenticationBuilder.() -> Unit = {}): Authentication {
    return AuthenticationBuilder().apply(addDetails).build()
}

@AuthenticationDsl
class AuthenticationBuilder {
    internal var id: String = "12345"
    internal var pan = Pan("6409430199901944")
    internal var userAccount: UserAccount = UserAccount.empty()
    internal var riskDecision: RiskDecision = FRICTIONLESS
    internal var challengeType: ChallengeType = NONE
    internal var status: Status = SUCCESS
    internal var bank: Bank = BANK_OF_AMERICA
    internal var acsTransactionId: String? = null

    fun build() = Authentication(id, pan, userAccount, riskDecision, challengeType, status, acsTransactionId)

    fun userAccount(addDetails: UserAccountBuilder.() -> Unit = {}) {
        userAccount = UserAccountBuilder().apply(addDetails).build()
    }
}

fun authenticationWithUserId(userId: String): Authentication {
    return authentication {
        userAccount {
            id = userId
        }
    }
}

fun userAccount(addDetails: UserAccountBuilder.() -> Unit = {}): UserAccount {
    return UserAccountBuilder().apply(addDetails).build()
}

@AuthenticationDsl
data class UserAccountBuilder(
    internal var id: String = "anyId",
    internal var abi: String = "anyAbi",
    internal var cardType: CardType = CardType.PRIVATE,
    internal var taxCode: String = "anyTaxCode",
    internal var posizioneCarta: String = "anyPosizioneCarta",
    internal var userType: UserType = UserType.PRIVATE,
    internal var bank: Bank = BANK_OF_AMERICA
) {

    fun build() = UserAccount(id, abi, cardType, userType, taxCode, posizioneCarta, bank)

    fun withId(id: String): UserAccountBuilder {
        this.id = id
        return this
    }

    fun withAbi(abi: String): UserAccountBuilder {
        this.abi = abi
        return this
    }

    fun withTaxCode(taxCode: String): UserAccountBuilder {
        this.taxCode = taxCode
        return this
    }

    fun withPosizioneCarta(posizioneCarta: String): UserAccountBuilder {
        this.posizioneCarta = posizioneCarta
        return this
    }

    fun withCardType(cardType: CardType): UserAccountBuilder {
        this.cardType = cardType
        return this
    }

    fun withUserType(userType: UserType): UserAccountBuilder {
        this.userType = userType
        return this
    }

    companion object {
        fun aUserAccount() = UserAccountBuilder().build()
    }
}

fun transaction(addDetails: TransactionBuilder.() -> Unit = {}): Transaction {
    return TransactionBuilder().apply(addDetails).build()
}

@AuthenticationDsl
class TransactionBuilder {
    internal var date = Date()
    internal var amount = Amount.euro(10)
    internal var authenticationId = "123"
    internal var merchant: Merchant = Merchant("merchantName")

    fun build() = Transaction(authenticationId, amount, date, merchant)
}

@DslMarker
annotation class AuthenticationDsl
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment