This SDK allows your app to make payments with Tpay.
Tpay SDK is available on Maven Central.
// Add Maven Central repository to root level build.gradle or settings.gradle file
repositories {
mavenCentral()
}
// Add Tpay SDK dependency to app level build.gradle
dependencies {
implementation "com.tpay:sdk:<version>"
}
Tpay SDK contains UI module that users can interact with and exposes a possibility to make screenless payments.
To configure Tpay SDK use TpayModule class.
Configure information about merchant.
TpayModule.configure(
Merchant(
merchantId = "YOUR_MERCHANT_ID",
authorization = Merchant.Authorization(
clientId = "YOUR_CLIENT_ID",
clientSecret = "YOUR_CLIENT_SECRET"
)
)
)
Configure Tpay environment
TpayModule.configure(Environment.PRODUCTION)
Configure languages that customer will see when using Tpay UI module.
TpayModule.configure(
preferredLanguage = Language.PL,
supportedLanguages = listOf(Language.PL, Language.EN)
)
Configure payment methods that customer will be able to use.
TpayModule.configure(
paymentMethods = listOf(
PaymentMethod.Card,
PaymentMethod.Blik,
PaymentMethod.Pbl,
PaymentMethod.DigitalWallets(
wallets = listOf(DigitalWallet.GOOGLE_PAY)
)
)
)
Configure merchant details provider to make sure information is correctly displayed for selected language.
TpayModule.configure(object : MerchantDetailsProvider {
override fun merchantDisplayName(language: Language): String {
return when (language) {
Language.PL -> "polish name"
Language.EN -> "english name"
}
}
override fun merchantCity(language: Language): String {
return when (language) {
Language.PL -> "Warszawie"
Language.EN -> "Warsaw"
}
}
override fun regulationsLink(language: Language): String {
return when (language) {
Language.PL -> "polish regulation url"
Language.EN -> "english regulation url"
}
}
})
Configure public key that will be used to encrypt credit card data.
TpayModule.configure(object : SSLCertificatesProvider {
override var apiConfiguration: CertificatePinningConfiguration =
CertificatePinningConfiguration(publicKeyHash = "PUBLIC_KEY")
})
Tpay UI sheets need to handle system back press events.
override fun onBackPressed() {
sheet.onBackPressed()
}
Configure activity result handling when using Google Pay.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Where paymentSheet is a object of Payment.Sheet class
paymentSheet.onActivityResult(requestCode, resultCode, data)
}
Payment flow opens a UI module and allows customer to pick one of defined payment methods.
// Create payment
val paymentSheet = Payment.Sheet(
object : Transaction {
override val amount: Double = 29.99
override val description: String = "transaction description"
override val payerContext: PayerContext = PayerContext(
payer = Payer(
name = "Jan Kowalski",
email = "[email protected]",
phone = null,
address = null
),
automaticPaymentMethods = AutomaticPaymentMethods(
blikAlias = BlikAlias.Registered(value = "alias value", label = "alias label"),
tokenizedCards = listOf(
TokenizedCard(token = "card token 1", cardTail = "1234", brand = CreditCardBrand.VISA),
TokenizedCard(token = "card token 2", cardTail = "1234", brand = CreditCardBrand.MASTERCARD)
)
)
)
override val notifications: Notifications = Notifications(
notificationEmail = "[email protected]",
notificationUrl = "https://yourstore.com"
)
},
activity = activity,
supportFragmentManager = activity.supportFragmentManager
)
// Add payment observer
paymentSheet.addObserver(object : PaymentDelegate {
override fun onPaymentCreated(transactionId: String?) { }
override fun onPaymentCompleted(transactionId: String?) { }
override fun onPaymentCancelled(transactionId: String?) { }
override fun onModuleClosed() { }
})
// Open UI module
val result = paymentSheet.present()
if (result is SheetOpenResult.Success) {
// Module opened successfully
}
Token payment allows for making credit card token payments with Tpay UI.
// Create payment
val tokenPaymentSheet = CardTokenPayment.Sheet(
transaction = CardTokenTransaction(
amount = 29.99,
description = "transaction description",
payer = Payer(
name = "Jan Kowalski",
email = "[email protected]",
phone = null,
address = null
),
cardToken = "card token",
notifications = "https://yourstore.com"
),
activity = activity,
supportFragmentManager = activity.supportFragmentManager
)
// Add payment observer
tokenPaymentSheet.addObserver(object : PaymentDelegate {
override fun onPaymentCreated(transactionId: String?) { }
override fun onPaymentCompleted(transactionId: String?) { }
override fun onPaymentCancelled(transactionId: String?) { }
override fun onModuleClosed() { }
})
// Open UI module
val result = tokenPaymentSheet.present()
if (result is SheetOpenResult.Success) {
// Module opened successfully
}
Tpay SDK allows customers to tokenize credit cards to save them for future payments.
// Create tokenization
val tokenizationSheet = AddCard.Sheet(
tokenization = Tokenization(
payer = Payer(
name = "Jan Kowalski",
email = "[email protected]",
phone = null,
address = null
),
notificationUrl = "https://yourstore.com"
),
activity = activity,
supportFragmentManager = activity.supportFragmentManager
)
// Add tokenization observer
tokenizationSheet.addObserver(object : AddCardDelegate {
override fun onAddCardSuccess(tokenizationId: String?) { }
override fun onAddCardFailure() { }
override fun onModuleClosed() { }
})
// Open UI module
val result = tokenizationSheet.present()
if (result is SheetOpenResult.Success) {
// Module opened successfully
}
GetPaymentMethods class allows you to get payment methods that you can use within your app. It takes a common part of payment methods available on Tpay backend and payment methods that you configured using TpayModule.
GetPaymentMethods().execute { result ->
if (result is GetPaymentMethodsResult.Success) {
if (result.isCreditCardPaymentAvailable) {
// show credit card
}
if (result.isBLIKPaymentAvailable) {
// show BLIK
}
if (result.availableTransferMethods.isNotEmpty()) {
// show transfers
// each transfer object contains
// groupId, name and image url
}
if (result.availableDigitalWallets.isNotEmpty()) {
// show digital wallets
}
}
}
All screenless payments require payment details and payer information, you can also pass redirects and notifications.
val payer = Payer(
name = "Jan Kowalski",
email = "[email protected]",
phone = null,
address = null
)
val paymentDetails = PaymentDetails(
amount = 29.99,
description = "transaction description",
hiddenDescription = "hidden description",
language = Language.PL
)
val redirects = Redirects(
successUrl = "https://yourstore.com/success",
errorUrl = "https://yourstore.com/error"
)
val notifications = Notifications(
notificationEmail = "[email protected]",
notificationUrl = "https://yourstore.com"
)
CreditCardPayment allows you to create payments with credit card data or credit card token (for returning customers) and can also create recursive payments.
val calendar = Calendar.getInstance()
calendar.set(2024, 6, 1)
CreditCardPayment.Builder()
.setRecursive(
Recursive(
frequency = Frequency.MONTHLY,
quantity = Quantity.Specified(3),
expirationDate = calendar.time
)
)
.setCallbacks(redirects, notifications)
.setPayer(payer)
.setCreditCard(
CreditCard("1111111111111111", "02/29", "123"),
domain = "https://yourstore.com"
)
.setCreditCardToken("card token")
.setPaymentDetails(paymentDetails)
.build()
.execute { result ->
// handle payment create result
}
BLIKPayment allows you to create payments with BLIK code or alias (for returning customers).
BLIKPayment.Builder()
.setBLIKCode(code = "123456")
.setBLIKCodeAndRegisterAlias(
code = "123456",
blikAlias = BlikAlias.NotRegistered(value = "value", label = "label")
)
.setBLIKAlias(BlikAlias.Registered(value = "value", label = "label"))
.setPayer(payer)
.setPaymentDetails(paymentDetails)
.setCallbacks(redirects, notifications)
.build()
.execute { result ->
// handle payment create result
}
BLIKPayment can return a result of type CreateBLIKTransactionResult.AmbiguousBlikAlias. In this case you need to display result.aliases to the user and then use BLIKAmbiguousAliasPayment class to continue the payment.
if (result is CreateBLIKTransactionResult.AmbiguousBlikAlias) {
// display result.aliases
// continue with BLIKAmbiguousAliasPayment if user selected a alias
BLIKAmbiguousAliasPayment
.from(
transactionId = result.transactionId, // id of transaction created with BLIKPayment
blikAlias = BlikAlias.Registered(value = "value", label = "label"), // blik alias used to create payment with BLIKPayment
ambiguousAlias = AmbiguousAlias(...) // ambiguous alias selected by user
)
.execute { result ->
// handle result
}
}
TransferPayment allows you to create payment with bank selected by user identified by groupId.
TransferPayment.Builder()
.setGroupId(102)
.setPayer(payer)
.setPaymentDetails(paymentDetails)
.setCallbacks(redirects, notifications)
.build()
.execute { result ->
// handle payment create result
}
GooglePayPayment allows you to create payments with credit card data provided by Google Pay.
GooglePayPayment.Builder()
.setGooglePayToken("GOOGLE_PAY_TOKEN")
.setPayer(payer)
.setPaymentDetails(paymentDetails)
.setCallbacks(redirects, notifications)
.build()
.execute { result ->
// handle payment create result
}
To make things easier you can use GooglePayUtil class.
val googlePayUtil = GooglePayUtil(
activity = requireActivity(),
googlePayRequest = GooglePayRequest(
price = 19.99, // Final price
merchantName = "Your Store",
merchantId = "YOUR_MERCHANT_ID" // Tpay merchant id
),
googlePayEnvironment = GooglePayEnvironment.PRODUCTION
)
// Check if Google Pay is available to use on the device
googlePayUtil.checkIfGooglePayIsAvailable { isAvailable ->
if (isAvailable) {
// show Google Pay button
}
}
// Opens the Google Pay module with data specified in GooglePayRequest
googlePayUtil.openGooglePay()
// Google Pay requires your app to override onActivityResult method in Activity
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
googlePayUtil.handleActivityResult(requestCode, resultCode, data) { result ->
when (result) {
is OpenGooglePayResult.Success -> {
// Payer selected credit card
// use result.token with GooglePayPayment.Builder
// to create payment
}
is OpenGooglePayResult.Cancelled -> {
// Google Pay request was cancelled
}
is OpenGooglePayResult.UnknownError -> {
// Unknown error occurred
}
}
}
}
Screenless payments can be instantly paid when creating payment (it can happen with credit card payment) but most likely the payment will be created and you will have to display payment url received via result to the user. BLIK payment doesn't receive payment url because user has to accept payment in bank app so it's recommended to use long polling mechanism in that case.
Screenless payments give you a option to use long polling mechanism. You have to pass LongPollingConfig object as a first parameter of execute function as shown on BLIKPayment. Note that long polling mechanism will start only when it's needed:
- CreditCardPayment: when payment is created and you have to display payment url.
- BLIKPayment or BLIKAmbiguousAliasPayment: when payment is created and payer has to accept payment in bank app.
- TransferPayment: when payment is created and you have to display payment url.
- GooglePayPayment: when payment is created and you have to display payment url.
val config = LongPollingConfig(
delayMillis = 4000, // delay between requests
maxRequestCount = 10,
stopOnFirstRequestError = false,
onTransactionState = {
// this function is called on each response
// with new transaction state
// long polling keeps running if transaction
// state is PENDING
},
onRequestError = {
// request error
},
onMaxRequestCount = {
// maximum request count was reached
// long polling stops and you can show timeout to user
// this means that we don't know if payment was successful
}
)
BLIKPayment.Builder()
.setBLIKCode("123456")
.setPayer(payer)
.setPaymentDetails(paymentDetails)
.setCallbacks(redirects, notifications)
.build()
.execute(config) { result ->
// handle payment create result
}
This library is released under the MIT License.