- Minimum Java 17 or Android 5.1
 targetSdkandcompileSdkshould be set to 36.
Include the following dependency in your project:
implementation 'com.paytabs:payment-sdk:6.8.1'If you encounter a "Duplicated class" dependency conflict with the coroutine API, add the following to your app's Gradle file:
configurations.all {
    resolutionStrategy {
        exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug"
    }
}If you are using ProGuard, you may need to exclude the library classes:
-keep public class com.payment.paymentsdk.**{*;}
val profileId = "PROFILE_ID"
val serverKey = "SERVER_KEY"
val clientKey = "CLIENT_KEY"
val locale =
    PaymentSdkLanguageCode.EN or PaymentSdkLanguageCode.AR or PaymentSdkLanguageCode.FR or PaymentSdkLanguageCode.TR or PaymentSdkLanguageCode.UR
val screenTitle = "Test SDK"
val cartId = "123456"
val cartDesc = "Cart description"
val currency = "AED"
val amount = 20.0
val tokeniseType = PaymentSdkTokenise.NONE
// Options: 
// PaymentSdkTokenise.USER_OPTIONAL 
// PaymentSdkTokenise.USER_MANDATORY 
// PaymentSdkTokenise.MERCHANT_MANDATORY 
// PaymentSdkTokenise.USER_OPTIONAL_DEFAULT_ON 
val transType = PaymentSdkTransactionType.SALE
// or PaymentSdkTransactionType.AUTH
// or PaymentSdkTransactionType.REGISTER
val tokenFormat = PaymentSdkTokenFormat.Hex32Format()
// Options: 
// PaymentSdkTokenFormat.NoneFormat 
// PaymentSdkTokenFormat.AlphaNum20Format 
// PaymentSdkTokenFormat.Digit22Format 
// PaymentSdkTokenFormat.Digit16Format 
// PaymentSdkTokenFormat.AlphaNum32Format 
val billingData = PaymentSdkBillingDetails(
    "City",
    "2-digit ISO country code",
    "email1@domain.com",
    "Name",
    "Phone",
    "State",
    "Address street",
    "ZIP"
)
val shippingData = PaymentSdkShippingDetails(
    "City",
    "2-digit ISO country code",
    "email1@domain.com",
    "Name",
    "Phone",
    "State",
    "Address street",
    "ZIP"
)
val configData = PaymentSdkConfigBuilder(profileId, serverKey, clientKey, amount ?: 0.0, currency)
    .setCartDescription(cartDesc)
    .setLanguageCode(locale)
    .setMerchantIcon(resources.getDrawable(R.drawable.bt_ic_amex))
    .setBillingData(billingData)
    .setMerchantCountryCode("AE") // ISO Alpha-2 code
    .setShippingData(shippingData)
    .setCartId(cartId)
    .setTransactionType(transType)
    .showBillingInfo(false)
    .showShippingInfo(true)
    .forceShippingInfo(true)
    .setScreenTitle(screenTitle)
    .isDigitalProduct(false)
    .build()
startCardPayment(this, configData, callback = this)
// or 
startSamsungPayment(this, configData, "samsungpay token", callback = this)
override fun onError(error: PaymentSdkError) {
    Log.d(TAG_PAYTABS, "onError: $error")
    Toast.makeText(this, "${error.msg}", Toast.LENGTH_SHORT).show()
}
override fun onPaymentFinish(paymentSdkTransactionDetails: PaymentSdkTransactionDetails) {
    Toast.makeText(
        this,
        "${paymentSdkTransactionDetails.paymentResult?.responseMessage}",
        Toast.LENGTH_SHORT
    ).show()
    Log.d(TAG_PAYTABS, "onPaymentFinish: $paymentSdkTransactionDetails")
}
override fun onPaymentCancel() {
    Toast.makeText(this, "Cancelled", Toast.LENGTH_SHORT).show()
    Log.d(TAG_PAYTABS, "onPaymentCancel:")
}/** To set a timeout of 2 minutes (120 seconds).
 * Set to 0 to deactivate the timeout feature.
 * The expiryTime cannot be set to less than 60 seconds.
 */
configuration.setPaymentExpiry(120)To close the payment screen if there are no ongoing transactions:
PaymentSdkActivity.cancelPayment()Normal Card Payment:
startCardPayment(context = this, ptConfigData = configData, callback = this)Recurring Payment:
startTokenizedCardPayment(
    context = this,
    ptConfigData = configData,
    token = yourToken,
    transactionRef = yourTransactionReference,
    callback = this
)Recurring Payment with 3DS Feature Enabled (Request CVV):
start3DSecureTokenizedCardPayment(
    context = this,
    ptConfigData = configData,
    savedCardInfo = PaymentSDKSavedCardInfo("Masked card", "Visa or MC or card type"),
    token = token!!,
    callback = this
)Create a Query Configuration:
val queryConfig = PaymentSDKQueryConfiguration(
    "ServerKey",
    "ClientKey",
    "Country ISO 2",
    "Profile Id",
    "Transaction Reference"
)Execute the Query:
QuerySdkActivity.queryTransaction(
    this,
    queryConfig,
    this
)String profileId = "PROFILE_ID";
String serverKey = "SERVER_KEY";
String clientKey = "CLIENT_KEY";
PaymentSdkLanguageCode locale = PaymentSdkLanguageCode.EN;
String screenTitle = "Test SDK";
String cartId = "123456";
String cartDesc = "Cart description";
String currency = "AED";
double amount = 20.0;
PaymentSdkTokenise tokeniseType = PaymentSdkTokenise.NONE;
// Options:
// PaymentSdkTokenise.USER_OPTIONAL 
// PaymentSdkTokenise.USER_MANDATORY 
// PaymentSdkTokenise.MERCHANT_MANDATORY
PaymentSdkTransactionType transType = PaymentSdkTransactionType.SALE;
// or PaymentSdkTransactionType.AUTH
// or PaymentSdkTransactionType.REGISTER
PaymentSdkTokenFormat tokenFormat = new PaymentSdkTokenFormat.Hex32Format();
// Options:
// new PaymentSdkTokenFormat.NoneFormat() 
// new PaymentSdkTokenFormat.AlphaNum20Format() 
// new PaymentSdkTokenFormat.Digit22Format()
// new PaymentSdkTokenFormat.Digit16Format()
// new PaymentSdkTokenFormat.AlphaNum32Format()
PaymentSdkBillingDetails billingData = new PaymentSdkBillingDetails(
        "City",
        "2-digit ISO country code",
        "email1@domain.com",
        "Name",
        "Phone",
        "State",
        "Address street",
        "ZIP"
);
PaymentSdkShippingDetails shippingData = new PaymentSdkShippingDetails(
        "City",
        "2-digit ISO country code",
        "email1@domain.com",
        "Name",
        "Phone",
        "State",
        "Address street",
        "ZIP"
);
PaymentSdkConfigurationDetails configData = new PaymentSdkConfigBuilder(profileId, serverKey, clientKey, amount, currency)
        .setCartDescription(cartDesc)
        .setLanguageCode(locale)
        .setBillingData(billingData)
        .setMerchantCountryCode("AE") // ISO Alpha-2 code
        .setShippingData(shippingData)
        .setCartId(cartId)
        .setTransactionType(transType)
        .showBillingInfo(false)
        .showShippingInfo(true)
        .forceShippingInfo(true)
        .setScreenTitle(screenTitle)
        .build();
PaymentSdkActivity.
startCardPayment(this,configData, this);
@Override
public void onError(@NotNull PaymentSdkError paymentSdkError) {
    // Handle error
}
@Override
public void onPaymentCancel() {
    // Handle cancellation
}
@Override
public void onPaymentFinish(@NotNull PaymentSdkTransactionDetails paymentSdkTransactionDetails) {
    // Handle payment completion
}Normal Card Payment:
PaymentSdkActivity.startCardPayment(
    this,
    configData,
    this);Recurring Payment:
PaymentSdkActivity.startTokenizedCardPayment(
    this,
    configData,
    "Token",
            "TransactionRef",
            this);Recurring Payment with 3DS Feature Enabled (Request CVV):
PaymentSdkActivity.start3DSecureTokenizedCardPayment(
    this,
    configData,
    new PaymentSDKSavedCardInfo("Masked card", "Visa or MC or card type"),
    "Token",
            this);You can use paymentSdkTransactionDetails?.isSuccess to ensure a successful transaction. If the
transaction is not successful, you should check the corresponding failure code, which you will
receive in paymentSdkTransactionDetails?.paymentResult?.responseCode. All codes can be found in
the Payment Response Codes.
To enable tokenization, follow the instructions below:
// Request token and transaction reference by passing tokeniseType and Format
setTokenise(PaymentSdkTokenise.MERCHANT_MANDATORY, PaymentSdkTokenFormat.Hex32Format())
// You will receive token and reference after the first transaction       
// Pass the token and transaction reference returned from the SDK
    .setTokenisationData(token = "", transactionReference = "") The Payment SDK allows you to customize BIN-based discounts through the PaymentSdkCardApproval
class, which collects approval details via an API.
val cardApproval = PaymentSdkCardApproval(
    validationUrl = "Your validation URL. Ex: https://yourdomain.com/validate",
    binLength = 8,
    blockIfNoResponse = false
)
val configData = PaymentSdkConfigBuilder(profileId, serverKey, clientKey, amount ?: 0.0, currency)
    .setCardApproval(cardApproval)
    .build()validationUrl: The endpoint provided by the business where the Payment SDK will pass transaction information and receive a response.binLength: The length of the BIN (default is 6 digits, can be set to 8).blockIfNoResponse: Determines whether to block the transaction if there is no response from the validation endpoint.
To apply a discount on a card payment, use the following method:
// List of card discounts
val cardDiscount = listOf(
    PaymentSdkCardDiscount(
        // List of card prefixes from 4 to 10 digits
        listOf("40001"),
        // Discount percentage or value
        10.0,
        // Discount description
        "β 10% discount on VISA cards starting with 40001",
        // Discount type: percentage or value
        true
    )
)
...setCardDiscount(cardDiscount)- 
To enable payments with Samsung Pay, first integrate with the Samsung Pay API. Follow the Samsung Pay Integration Guide.
 - 
Pass the returned JSON token from Samsung Pay to the following method:
 
startSamsungPayment(this, configData, "samsungpay token", callback = this)Add your custom font files with the following names:
payment_sdk_primary_font.ttfpayment_sdk_secondary_font.ttf
To override strings, colors, or dimens, add the resource you need to override from the resources below:
<resources>
    <!-- Override colors -->
    <color name="payment_sdk_primary_color">#ffffff</color>
    <color name="payment_sdk_secondary_color">#0073bc</color>
    <color name="payment_sdk_status_bar_color">#444647</color>
    <color name="payment_sdk_primary_font_color">#4c4c4c</color>
    <color name="payment_sdk_secondary_font_color">#0073bc</color>
    <color name="payment_sdk_hint_font_color">#a5a5a5</color>
    <color name="payment_sdk_stroke_color">#e1e1e1</color>
    <color name="payment_sdk_button_text_color">#FFF</color>
    <color name="payment_sdk_title_text_color">#1e1e1e</color>
    <color name="payment_sdk_button_background_color">#0073bc</color>
    <color name="payment_sdk_background_color">#F9FAFD</color>
    <color name="payment_sdk_blue_F2FAFD">#F2FAFD</color>
    <color name="payment_sdk_error_text_color">#EC2213</color>
    <color name="payment_sdk_back_black_dim">#4D6E6E6E</color>
    <color name="payment_sdk_input_field_background_color">#FFFFFFFF</color>
    <color name="payment_sdk_enabled_switch_track_color">#00000000</color>
    <color name="payment_sdk_enabled_switch_handle_color">#3db39e</color>
    <color name="payment_sdk_disabled_switch_track_color">#00000000</color>
    <color name="payment_sdk_disabled_switch_handle_color">#c7c7c7</color>
    <color name="payment_sdk_switch_stroke_color">#4c4c4c</color>
    <color name="payment_sdk_amount_font_color">#4c4c4c</color>
    <color name="payment_sdk_original_amount_font_color">#a5a5a5</color>
    <color name="payment_sdk_billing_header_background_color">#0073bc</color>
    <color name="payment_sdk_billing_text_color">#FFF</color>
    <!-- Override dimens -->
    <dimen name="payment_sdk_title_font_size">18sp</dimen>
    <dimen name="payment_sdk_title_margin">24dp</dimen>
    <dimen name="payment_sdk_primary_font_size">16sp</dimen>
    <dimen name="payment_sdk_secondary_font_size">16sp</dimen>
    <dimen name="payment_sdk_button_font_size">16sp</dimen>
    <dimen name="payment_sdk_separator_thickness">1dp</dimen>
    <dimen name="payment_sdk_stroke_thickness">.5dp</dimen>
    <dimen name="payment_sdk_input_corner_radius">8dp</dimen>
    <dimen name="payment_sdk_card_corner_radius">8dp</dimen>
    <dimen name="payment_sdk_card_margin">16dp</dimen>
    <dimen name="payment_sdk_billing_header_corner_radius">0dp</dimen>
    <dimen name="payment_sdk_billing_header_margin">0dp</dimen>
    <dimen name="payment_sdk_button_corner_radius">8dp</dimen>
    <dimen name="payment_sdk_error_font_size">12sp</dimen>
    <dimen name="payment_sdk_amount_font_size">16sp</dimen>
    <!-- Override styles -->
    <style name="PaymentSdkTheme" parent="Theme.MaterialComponents.NoActionBar">
        <!-- Hides the payment screen title background -->
        <item name="payment_sdk_hideScreenTitleBackground">true</item>
        <!-- Sets the alignment of the payment screen title [start-end-center] -->
        <item name="payment_sdk_screenTitleAlignment">start</item>
        <!-- Hides the card and button shadows -->
        <item name="payment_sdk_hideViewsShadow">true</item>
    </style>
</resources>You can find the keys with the default values here:
To override the back button icon, add your drawable file with the name:
payment_sdk_back_arrow.xml
For a list of common issues, refer to Common Issues.
For licensing information, see License.


