-
Notifications
You must be signed in to change notification settings - Fork 0
Let's start
The Paytrail Android SDK provides pre-built solutions that simplify payment integration in your app. Our SDK offers flexibility - use just the payment API definitions with your custom views, or take advantage of our complete SDK experience with our ready-to-use components.
Our MSDK comprises two modules:
-
api-client-retrofit2
- Responsible for server-side operations and hosting all Paytrail API definitions. -
payment-sdk
- Contains ready-to-use views and implements calls from theapi-client-retrofit2
module.
If your app has specific network configurations, logging mechanisms, or security requirements, our SDK easily integrates them. But, if you have no such specifications, our SDK uses a default client for smooth integration. For the SDK to utilize your http client, initialize it through your Application class:
override fun onCreate() {
super.onCreate()
//Your own httpclient
val okHttpClientBuilder = OkHttpClient.Builder()
// Customize your own httpclient
val httpLogger = HttpLoggingInterceptor { Log.i("OkHttp", it) }
httpLogger.level = if (BuildConfig.DEBUG) BODY else BASIC
okHttpClientBuilder.addInterceptor(httpLogger)
}
//Then assign it to our sdk
PaytrailBaseOkHttpClient.install(okHttpClientBuilder.build())
}
Payment APIs
Method | API Call | Description | Parameters | Response Type |
---|---|---|---|---|
POST |
createPayment(@Body paymentRequest: PaymentRequest) |
Create a normal payment transaction. | paymentRequest: PaymentRequest |
PaymentRequestResponse |
GET |
getPaymentByTransactionId(@Path("transactionId") transactionId: UUID) |
Retrieve an existing payment by transaction ID. | transactionId: UUID |
Payment |
GET |
getGroupedPaymentProviders(@Query("amount") amount: Long? = null, @Query("groups") groups: List<Groups>? = null, @Query("language") language: Language? = null,) |
Retrieve payment group data containing localized names, icon URLs, and grouped providers. | amount: Long?, groups: List<Groups>?, language: Language? |
GroupedPaymentProvidersResponse |
Token Payment APIs
API Method Name | Description | Parameters | Expected Response |
---|---|---|---|
requestTokenForTokenizationId |
Request a card token for given tokenization id | checkoutTokenizationId: String |
TokenizationRequestResponse |
tokenCitAuthorizationHold |
Request CIT authorization hold on token | TokenPaymentRequest |
TokenPaymentResponse |
tokenCitCharge |
Request CIT charge on token | TokenPaymentRequest |
TokenPaymentResponse |
tokenMitAuthorizationHold |
Request MIT authorization hold on token | TokenPaymentRequest |
TokenPaymentResponse |
tokenMitCharge |
Request MIT Charge on token | TokenPaymentRequest |
TokenPaymentResponse |
tokenCommit |
Request committing of previously created authorization hold on token | transactionId: UUID, TokenPaymentRequest |
TokenPaymentResponse |
tokenRevert |
Revert of previously created authorization hold on token | transactionId: UUID |
TokenPaymentResponse |
payAndAddCard |
Create a transaction & pay while adding the payment card simultaneously | PaymentRequest |
PayAndAddCardResponse |
Please consult our Detailed API Documentation for further explanations on API definitions. You can download OpenAPI 3 specification for the API from here.
If you want to handle API calls manually:
- Setup the api client
private val apiClient: PaytrailApiClient by lazy { PaytrailApiClient(merchantAccount = YOUR_MERCHANT_ACCOUNT) }
- Create the PaymentApi service
// You can replace tha parameter isnide create Service with your desired Paytrail API, like TokenPaymentsApi::class.java
private val api by lazy { apiClient.createService(PaymentsApi::class.java) }
- Example Call for Creating Payment:
var response = api.createPayment(paymentRequest = "Your payment request"))
The payment-sdk
module offers a suite of pre-built views designed to facilitate seamless payment integration into your app. These views are a reflection of some key features provided by the Paytrail API.
-
PaytrailPayment:
- Description: This view displays available payment providers. Once a user selects a provider, they are directed to the corresponding payment provider's webview.
-
Parameters:
MerchantAccount
,PaymentRequest
, and an optional customOkHttpClient
(defaults to our internal client if not provided). -
Callback:
onPaymentStateChanged
returns aPaytrailPaymentState
.
-
PayAndAddCard:
- Description: An integrated view allowing users to tokenize a card and make a payment in a single step, streamlining the payment and card saving process.
-
Parameters:
MerchantAccount
andPaymentRequest
. -
Callback:
onPaymentStateChanged
returns aPaytrailPaymentState
.
-
AddCardForm:
- Description: This view focuses solely on card tokenization without initiating a payment. It provides a form for users to save their payment card information.
-
Parameters:
MerchantAccount
,AddCardRequest
(which defines success and failure callback URLs), and a callback to captureAddCardResult
. -
Callback: If successful, a
tokenizationId
is provided to save the tokenized card ID. You can refer to theTokenizedCreditCardsScreen
in the demo project for a practical implementation.
-
PayWithTokenizationId:
- Description: This view facilitates payments using a saved card.
-
Parameters:
PaymentRequest
,tokenizationId
(obtained from the selected saved card),paymentType
(CIT/MIT),chargeType
(AUTH_HOLD or CHARGE), andMerchantAccount
. -
Callbacks:
PaytrailPaymentState
andonTokenAvailable
.
For those curious about how card details are stored:
-
Client-side: Your client app only retains the token ID, ensuring minimal data exposure.
-
Server-side: The comprehensive details of the tokenized payment card are stored securely on Paytrail servers. This layered security ensures data integrity and user privacy.
-
Displaying Saved Cards: In your app, when presenting saved cards, you'll see a masked version of the card number. This representation will resemble: "**** **** **** ${card.partialPan}". Additional data, like card type and card image, are also available, enhancing user familiarity without compromising security.
This callback serves as an informant throughout the payment process. It details the different stages, their results, and aids in proactive management and reaction to user actions:
-
State: Reflects the ongoing phase such as:
LOADING_PAYMENT_PROVIDERS
SHOW_PAYMENT_PROVIDERS
PAYMENT_IN_PROGRESS
PAYMENT_OK
PAYMENT_FAIL
PAYMENT_CANCELED
PAYMENT_ERROR
-
PaytrailPaymentRedirect: Contains parameters derived from the checkout redirect link in the webview. Notably, it includes details like
transactionId
,settlementReference
, and more. -
TokenPaymentResponse: This is the response for a successful customer-initiated transaction payment request. It provides the
transactionId
and, if necessary, athreeDSecureUrl
. This URL is for situations when a merchant needs to redirect a customer for 3DS authentication. -
PaytrailApiErrorResponse: Represents error responses when interfacing with the Paytrail API. This is particularly beneficial when using views like
PayWithTokenizationId
orPayAndAddCard
. -
Exception: Captures any exceptions that might emerge during operations, ensuring robust error handling.
The Merchant account information is pivotal across all views. A recommended practice is to formulate a static object that encapsulates merchant account details. This object can then be conveniently passed throughout the app, fostering consistency and ease of access.
val SAMPLE_MERCHANT_ACCOUNT = MerchantAccount(id = 375917, secret = "SAIPPUAKAUPPIAS")
Making payments with MSDK is easy. There are two approaches:
Utilize the PaytrailPayment
view from our MSDK for a simplified payment process. From displaying available payment providers to processing the final payment, everything's handled:
PaytrailPayment(
modifier = Modifier.fillMaxSize().padding(horizontal = 24.dp),
paymentRequest = paymentRequest,
onPaymentStateChanged = { state ->
when (state.state) {
// Navigate to the last screen for success, failure, etc.
PAYMENT_OK, PAYMENT_FAIL, PAYMENT_ERROR, PAYMENT_CANCELED -> {
navController.navigate("Your result screen")
}
else -> {
// Handle other payment progress states.
}
}
},
merchantAccount = SAMPLE_MERCHANT_ACCOUNT
)
Example: Creating a Static Payment Request
/**
* Create a static payment request for demonstration purposes.
*/
fun createStaticPaymentRequest(): PaymentRequest {
return PaymentRequest(
stamp = "your_stamp_here",
reference = "your_reference_here",
amount = 10000L, // Adjust the amount as needed
currency = Currency.EUR, // Set the currency
language = Language.EN, // Set the language
customer = Customer(
// Provide customer details
),
redirectUrls = Callbacks(
// Provide redirect URL details
)
)
}
- Setup the API Client & Create a Payment Request:
private val api by lazy {
PaytrailApiClient(merchantAccount = SAMPLE_MERCHANT_ACCOUNT)
.createService(PaymentsApi::class.java)
}
val createPaymentResponse: LiveData<Response<PaymentRequestResponse>> = liveData {
try {
emit(api.createPayment(paymentRequest = createStaticPaymentRequest()))
} catch (e: Exception) {
paymentError.postValue(e)
}
}
-
Render Payment Providers:
ThecreatePaymentResponse
provides available payment methods. Payments are categorized (e.g., banks, mobile payments, cards). Display them using each method's name and SVG. -
Handle User Selection:
When a user selects a payment method, execute the payment in a webview:
val url = selectedPaymentMethod.paymentMethod.provider.url
val postParameters = selectedPaymentMethod.formParameters.joinToFormBodyString().toByteArray()
webview.postUrl(url, postParameters)
-
Add card form:
Using Jetpack compose code here you can easily call this view in your app by calling :
AddCardForm(
request = AddCardRequest(
redirectUrls = Callbacks(
success = "https://ecom.example.org/success",
cancel = "https://ecom.example.org/cancel",
),
),
onAddCardResult = { result ->
// Call state.redirectRequest.url if necessary.
// The WebView in SDK for adding a card does not follow the final HTTP
// redirect to AddCardRequest.redirectUrls.success/cancel URLs. If your
// system depends on the call to these URLs happening, the application needs to
// make this call. This can be done either by opening a WebView to the URL,
// or using an HTTP client (e.g. OkHttp) to call the URL.
coroutineScope.launch {
if (result.result == AddCardResult.Result.SUCCESS) {
// Store the tokenization ID securely for later use. The tokenization ID
// can be used for retrieving the actual payment token and masked card
// details.
tokenizedCardsRepository.saveTokenizationId(result.redirect!!.tokenizationId!!)
}
// Once the tokenization result is available, remove the view from
// composition/view tree.
navController.navigateUp()
}
},
merchantAccount = SAMPLE_MERCHANT_ACCOUNT,
)
For Your personal implementation
You will have to create a WebView that load add card form url, you will need to pass postParameters that you can get after creating AddCardFormRequest
.
val request = AddCardRequest(
redirectUrls = Callbacks(
success = "https://ecom.example.org/success",
cancel = "https://ecom.example.org/cancel",
)
)
val addCardFormRequest = AddCardFormRequest(
checkoutAccount = "YOUR_MERCHANT_ID",
checkoutMethod = "POST",
checkoutAlgorithm = PaytrailHmacCalculator.ALGORITHM_SHA512,
checkoutRedirectSuccessUrl = request.redirectUrls.success,
checkoutRedirectCancelUrl = request.redirectUrls.cancel,
checkoutCallbackSuccessUrl = request.callbackUrls?.success,
checkoutCallbackCancelUrl = request.callbackUrls?.cancel,
language = request.language,
checkoutNonce = UUID.randomUUID().toString(),
checkoutTimestamp = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.now())
).withSignature(account = merchantAccount)
Then
val url = "https://services.paytrail.com/tokenization/addcard-form"
val postParameters = addCardFormRequest.asPostParams()
webview.postUrl(url, postParameters)
- PayAndAddCard:
// You create a payment request
val paymentRequest = createStaticPaymentRequest()
PayAndAddCard(
modifier = Modifier.fillMaxSize(),
paymentRequest = paymentRequest,
onPaymentStateChanged = YOUR_CALL_BACK,
merchantAccount = SAMPLE_MERCHANT_ACCOUNT
)
For custom implementation
- Create Payment requests as show in previous examples
- Send request this api request
val response = api.payAndAddCard(paymentRequest = paymentRequest)
- If the response is successful, get response.body().redirectUrl that you will pass to your webview
- Note the token is not included in the redirect URL parameters, as we don't want the user to be able to see the token.
This component allows you to process a charge using a token, which you've previously saved after the user added their card. In line with the European PSD2 directive, electronic payments are classified into two categories: MIT (Merchant Initiated Transactions) and CIT (Customer Initiated Transactions). Learn more about charging with a token here.
By using the PayWithTokenizationId
view component, we've made it simple for you to charge your customer based on the charge type and payment type. We also manage the 3D secure authentication process if required.
Example of using PayWithTokenizationId
:
PayWithTokenizationId(
modifier = Modifier.fillMaxSize(),
paymentRequest = paymentRequest,
tokenizationId = tokenizationId,
paymentType = "Either AUTH_HOLD or CHARGE",
chargeType = "Either MIT or CIT",
onPaymentStateChanged = { state -> handlePaymentState(paymentId, state) },
onTokenAvailable = { token -> saveToken(paymentId, token) },
merchantAccount = SAMPLE_MERCHANT_ACCOUNT
)
For Custom Implementations:
- Start by getting the saved card token from your local database.
- Request a usable token for payment with:
val response = api.requestTokenForTokenizationId("CARD_TOKEN")
- Next, set up a token payment request.
- Depending on your needs, call one of these APIs:
// For a CIT charge
api.tokenCitCharge(tokenPaymentRequest)
// For a CIT authorization hold
api.tokenCitAuthorizationHold(tokenPaymentRequest)
// For an MIT charge
api.tokenMitCharge(tokenPaymentRequest)
// For an MIT authorization hold
api.tokenMitAuthorizationHold(tokenPaymentRequest)
- Review the response. If
threeDSecureUrl
is present, redirect the customer to this URL for 3D Secure authentication using a WebView.
Demo application | https://github.com/paytrail/paytrail-android-sdk/tree/main/demo-app
OpenAPI 3 specification | https://docs.paytrail.com/paytrail-api.yaml
Create a normal payment | https://docs.paytrail.com/#/?id=create