API Reference

Android Native

EdfaPay SoftPos SDK

Installation

[!IMPORTANT]

Configure Repository

Its is important to add the gradlePluginPortal and maven jipack with authorization repositories to your project, It's allows the gradle to download edfapay plugin from gradlePluginPortal the native dependency from jitpack.

If your project build was configured to prefer settings repositories, Place the below maven block to project ./settings.gradle

pluginManagement {
    repositories {
        
        // Add below at same
        gradlePluginPortal()
    }
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        mavenCentral()

        // Add below at same
        maven {
            url "https://jitpack.io"
            credentials { username "jp_dtett6nt05eqiekvc4hp4og128" }
        }
    }
}
pluginManagement {
        repositories {
                // Add below at same
                gradlePluginPortal()
        }
}

dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
            repositories {
                mavenCentral()

                    // Add below at same
                    maven {
                        url = uri("https://jitpack.io") credentials {
                                username = "jp_dtett6nt05eqiekvc4hp4og128"
                        }
                }
        }
}

If your project build was configured to prefer traditional build.gradle repositories, Place the below maven block to project ./build.gradle

allprojects {
  repositories {

    // Add below at same
    gradlePluginPortal()
    maven{
      url "https://jitpack.io"
      credentials{
        username "jp_dtett6nt05eqiekvc4hp4og128"
      }
    }
  }
}

[!IMPORTANT]

Adding Edfapay Gradle plugin

It is important to apply edfapay plugin to your app module build.gradle

Usingplugin DSL:

plugins {
  id("com.edfapay.softpos.tools") version "1.0.1"
}

Usinglegacy plugin application:

Add the classpath to the project build.gradle

buildscript {
  dependencies {
    classpath("com.edfapay.softpos:plugin:1.0.1") // add this line
  }
}

apply(plugin = "com.edfapay.softpos.tools")

Learn how to apply plugins to subprojects

[!IMPORTANT]

Adding dependency

It is important to add dependency to your project modulebuild.gradle

  • Provide your partner code to the script below at install method like: install("xyz...")
  • If you provide the null in install method like: install(null), The plugin will look for the value from variable EDFAPAY_PARTNER at gradle.properties of your project and apply it to the script.
dependencies {
    .
    .
    .
    //add below at same
    edfapay{
        softpos{
            install(null)
        }
    }
}


// Also add below at same
configurations.configureEach {
    exclude group: "com.github.edfapay.emv", module: "mastercard-debug"
    exclude group: "com.github.edfapay.emv", module: "discovery-corec-release"
    exclude group: "com.github.edfapay.emv", module: "discovery-readerc-release"
}
dependencies {
    .
    .
    .
    //add below at same
    SoftPosToolsExtension(project).apply {
        install(null)
    }
}


// Also add below at same
configurations.configureEach {
    exclude(group="com.github.edfapay.emv", module="mastercard-debug"
    exclude(group="com.github.edfapay.emv", module="discovery-corec-release"
    exclude(group="com.edfapay.emv", module="discovery-readerc-release"
}

Define the following in your gradle.properties file:

EDFAPAY_PARTNER = 706172746E65727E73612D656466617061792D726576616D70
EDFAPAY_SDK_VERSION = r0.0.5


Usage

This section guides you through the essential steps to integrate and utilize the EdfaPay SoftPos SDK in your Android application.

Importing the SDK

import com.edfapay.paymentcard.EdfaPayPlugin
import com.edfapay.paymentcard.Env
import com.edfapay.paymentcard.model.TransactionType
import com.edfapay.paymentcard.model.TxnParams
import com.edfapay.paymentcard.EdfaPayPlugin
import com.edfapay.paymentcard.Env
import com.edfapay.paymentcard.model.TransactionType
import com.edfapay.paymentcard.model.TxnParams

Authenticating with EdfaPay

// 1. Direct auto-fill email/password
val credentials = EdfaPayCredentials(
environment = Env.REVAMP, // For production use Env.PRODUCTION
email = "[email protected]",
password = "yourPassword123"
)

// 2. Enable email/password (without providing credentials immediately)
val credentials = EdfaPayCredentials(
environment = Env.REVAMP // For production use Env.PRODUCTION
)

// 3. Using Token (Auth Code) from the Dashboard / Backend
val credentials = EdfaPayCredentials(
environment = Env.REVAMP, // For production use Env.PRODUCTION
authCode = "AUTH - CODE - FROM - BACKEND"
)
// 1. Direct auto-fill email/password
EdfaPayCredentials credentials1 = new EdfaPayCredentials(
    Env.REVAMP, // For production use Env.PRODUCTION
    "[email protected]",
    "yourPassword123"
);

// 2. Enable email/password (without providing credentials immediately)
EdfaPayCredentials credentials2 = new EdfaPayCredentials(
    Env.REVAMP // For production use Env.PRODUCTION
);

// 3. Using Token (Auth Code) from the Dashboard / Backend
EdfaPayCredentials credentials3 = new EdfaPayCredentials(
    Env.REVAMP, // For production use Env.PRODUCTION
    "AUTH-CODE-FROM-BACKEND"
);

Initializing the Plugin

EdfaPayPlugin.initiate(
context = this,
credentials = credentials,
onSuccess ={plugin,sessionId - > 
Toast.makeText(requireContext(),"SDK Initialized Successfully",
Toast.LENGTH_SHORT).show()
}
){err - > 
err.printStackTrace()
Toast.makeText(requireContext(),"Error Initializing : ${err.message}",
Toast.LENGTH_SHORT).show()
}
EdfaPayPlugin.initiate(
    this,
    credentials,
    new EdfaPayPlugin.OnSuccessCallback() {
        @Override
        public void onSuccess(EdfaPayPlugin plugin, String sessionId) {
            Toast.makeText(
                getApplicationContext(),
                "SDK Initialized Successfully",
                Toast.LENGTH_SHORT
            ).show();
        }
    },
    new EdfaPayPlugin.OnErrorCallBack() {
        @Override
        public void onError(Throwable err) {
            err.printStackTrace();
            Toast.makeText(
                getApplicationContext(),
                "Error Initializing: " + err.getMessage(),
                Toast.LENGTH_SHORT
            ).show();
        }
    }
);

Transaction Operations

Performing a Purchase Transaction

val params = 
TxnParams(
amount = amount, // String
orderId = "INV - 1234" // This is optional
transactionType = TransactionType.PURCHASE
)
EdfaPayPlugin.purchase(
requireActivity(),
flowType = FlowType.DETAIL,
txnParams = params,
onRequestTimerEnd ={Toast
.makeText(requireContext(),
"Server Request Timeout",
Toast.LENGTH_SHORT)
.show()},
onCardScanTimerEnd ={Toast
.makeText(requireContext(),
"Card Scan Timeout",
Toast.LENGTH_SHORT)
.show()},
onPaymentProcessComplete = 
{
    status,_,transaction,
    _
     - > if(transaction ! = null){
        TransactionStorage.addTransaction(transaction)
        val rrn = transaction.rrn
         ? : "Unknown" val amount = transaction.amount
         ? : "0"
        Toast
        .makeText(requireContext(),
        "Transaction saved. RRN : $rrn,"
         + "Amount : $amount",
        Toast.LENGTH_SHORT)
        .show()}Toast
        .makeText(requireContext(),
        if(status)"Success" else "Failure",
        Toast.LENGTH_SHORT)
        .show()
    },
    onCancelByUser ={Toast
    .makeText(requireContext(),
    "Cancelled by User",Toast.LENGTH_SHORT)
    .show()},
    onError ={e
     - > Toast
    .makeText(requireContext(),"Error : ${e.message}",
    Toast.LENGTH_SHORT)
    .show()})
TxnParams params = new TxnParams(
        amount,                 // String
        "INV - 1234",           // Optional orderId
        TransactionType.PURCHASE,
);

EdfaPayPlugin.purchase(
        requireActivity(),
        FlowType.DETAIL,
        params,
        new EdfaPayPlugin.TimeOutCallBack() {
            @Override
            public void onTimeout() {
                Toast.makeText(requireContext(), "Server Request Timeout", Toast.LENGTH_SHORT).show();
            }
        },
        new EdfaPayPlugin.TimeOutCallBack() {
            @Override
            public void onTimeout() {
                Toast.makeText(requireContext(), "Card Scan Timeout", Toast.LENGTH_SHORT).show();
            }
        },
        new EdfaPayPlugin.ProcessCompleteCallback() {
            @Override
            public void onComplete(boolean status, String code, Transaction transaction, boolean isProcessComplete) {
                if (transaction != null) {
                    // Save transaction
                    TransactionStorage.addTransaction(transaction);

                    String rrn = transaction.getRrn() != null ? transaction.getRrn() : "Unknown";
                    String txnAmount = transaction.getAmount() != null ? transaction.getAmount() : "0";

                    Toast.makeText(
                            requireContext(),
                            "Transaction saved. RRN: " + rrn + ", Amount: " + txnAmount,
                            Toast.LENGTH_SHORT
                    ).show();
                }

                Toast.makeText(
                        requireContext(),
                        status ? "Success" : "Failure",
                        Toast.LENGTH_SHORT
                ).show();
            }
        },
        new EdfaPayPlugin.CancelByUserCallBack() {
            @Override
            public void onCancel() {
                Toast.makeText(requireContext(), "Cancelled by User", Toast.LENGTH_SHORT).show();
            }
        },
        new EdfaPayPlugin.OnErrorCallBack() {
            @Override
            public void onError(Throwable e) {
                Toast.makeText(requireContext(), "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
);

Performing a Refund Transaction

// Create the original transaction reference using RRN
val originalTxnReference = Transaction.withRRN(
rrn = originalTransaction.rrn ? : "",
txnDate = formattedTxnDate, // Date in format: "yyyyMMdd"
type = TransactionType.PURCHASE // This must be the type of the original
)

 // Or create using transaction number
val originalTxnReference = Transaction.withTxnNumber(
txnNumber = originalTransaction.transactionNumber ? : "",
txnDate = formattedTxnDate, // Date in format: "yyyyMMdd"
type = TransactionType.PURCHASE // The type of the original transaction
)

 // Build TxnParams for refund
val params = TxnParams(
amount = amount, // String
transactionType = TransactionType.REFUND,
originalTransaction = originalTxnReference
)
EdfaPayPlugin.refund(
requireActivity(),
flowType = FlowType.DETAIL,
txnParams = params,
onRequestTimerEnd ={
    Log.e(TAG,"Server Request Timeout")
    Toast.makeText(requireContext(),"Server Request
    Timeout",Toast.LENGTH_SHORT).show()
},
onCardScanTimerEnd ={
    Log.e(TAG,"Card Scan Timeout")
    Toast.makeText(requireContext(),"Card Scan
    Timeout",Toast.LENGTH_SHORT).show()
},
onPaymentProcessComplete ={status,code,transaction,isProcessComplete - > 
Log.d(TAG,"onPaymentProcessComplete called")
Log.d(TAG,"Status : $status")
Log.d(TAG,"Code : $code")
Log.d(TAG,"Transaction : $transaction")
Log.d(TAG,"Is Process Complete : $isProcessComplete")
if(status){
    Toast.makeText(requireContext(),"Refund
    Successful",Toast.LENGTH_SHORT).show()
    TransactionStorage.removeTransaction(rrnInput)
    Log.d(TAG,"Refund successful,transaction removed from storage.")
}else{
    Toast.makeText(requireContext(),"Refund
    Failed",Toast.LENGTH_SHORT).show()
    Log.e(TAG,"Refund failed with code : $code and transaction : 
    $transaction")
}
},
onCancelByUser ={
    Log.w(TAG,"Refund cancelled by user")
    Toast.makeText(requireContext(),"Cancelled by
    User",Toast.LENGTH_SHORT).show()
},
onError ={e - > 
Log.e(TAG,"Refund error occurred",e)
Toast.makeText(requireContext(),"Error : 
${e.message}",Toast.LENGTH_SHORT).show()
}
)
// Create the original transaction reference using RRN
Transaction originalTxnReference = Transaction.withRRN(
        originalTransaction.getRrn() != null ? originalTransaction.getRrn() : "",
        formattedTxnDate, // Date in format: "yyyyMMdd"
        TransactionType.PURCHASE // Must be the type of the original transaction
);

// Or create using transaction number
Transaction originalTxnReferenceByNumber = Transaction.withTxnNumber(
        originalTransaction.getTransactionNumber() != null ? originalTransaction.getTransactionNumber() : "",
        formattedTxnDate,
        TransactionType.PURCHASE
);

// Build TxnParams for refund
TxnParams params = new TxnParams(
        amount,                   // String
        TransactionType.REFUND,
        originalTxnReference       // Or originalTxnReferenceByNumber
);

// Call refund
EdfaPayPlugin.refund(
        requireActivity(),
        FlowType.DETAIL,
        params,
        new EdfaPayPlugin.TimeOutCallBack() {
            @Override
            public void onTimeout() {
                Log.e(TAG, "Server Request Timeout");
                Toast.makeText(requireContext(), "Server Request Timeout", Toast.LENGTH_SHORT).show();
            }
        },
        new EdfaPayPlugin.TimeOutCallBack() {
            @Override
            public void onTimeout() {
                Log.e(TAG, "Card Scan Timeout");
                Toast.makeText(requireContext(), "Card Scan Timeout", Toast.LENGTH_SHORT).show();
            }
        },
        new EdfaPayPlugin.ProcessCompleteCallback() {
            @Override
            public void onComplete(boolean status, String code, Transaction transaction, boolean isProcessComplete) {
                Log.d(TAG, "onPaymentProcessComplete called");
                Log.d(TAG, "Status: " + status);
                Log.d(TAG, "Code: " + code);
                Log.d(TAG, "Transaction: " + transaction);
                Log.d(TAG, "Is Process Complete: " + isProcessComplete);

                if (status) {
                    Toast.makeText(requireContext(), "Refund Successful", Toast.LENGTH_SHORT).show();
                    TransactionStorage.removeTransaction(rrnInput);
                    Log.d(TAG, "Refund successful, transaction removed from storage.");
                } else {
                    Toast.makeText(requireContext(), "Refund Failed", Toast.LENGTH_SHORT).show();
                    Log.e(TAG, "Refund failed with code: " + code + " and transaction: " + transaction);
                }
            }
        },
        new EdfaPayPlugin.CancelByUserCallBack() {
            @Override
            public void onCancel() {
                Log.w(TAG, "Refund cancelled by user");
                Toast.makeText(requireContext(), "Cancelled by User", Toast.LENGTH_SHORT).show();
            }
        },
        new EdfaPayPlugin.OnErrorCallBack() {
            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "Refund error occurred", e);
                Toast.makeText(requireContext(), "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        }
);

Performing a Reversal Transaction

EdfaPayPlugin.reversal(
    this, 
    transaction = transaction,
    onSuccess = {model -> 
        Log.d(TAG, "onSuccessReconcile: $model")
    },
    onError = { e -> 
        Toast.makeText(this, "Error: ${e.message}", Toast.LENGTH_SHORT).show() 
        Log.d(TAG, "onPaymentError: " + e.message)
        
    }, 
)
EdfaPayPlugin.INSTANCE.reversal(this, // Activity
    transaction, // Transaction object
    new Function1<Transaction, Unit>() { // onSuccess
      @Override
      public Unit invoke(Transaction model) {
        Log.d(TAG, "onSuccessReconcile: " + model);
        return Unit.INSTANCE;
      }
    },
    new Function1<Throwable, Unit>() { // onError
      @Override
      public Unit invoke(Throwable e) {
        Toast
            .makeText(MainActivity.this, "Error: " + e.getMessage(),
                Toast.LENGTH_SHORT)
            .show();
        Log.d(TAG, "onPaymentError: " + e.getMessage());
        return Unit.INSTANCE;
      }
    });

Reconciling Transactions

EdfaPayPlugin.reconcile(
    onSuccess = {model -> 
        Log.d(TAG, "onSuccessReconcile: $model")
        
    },
    onError = {exception -> 
        Log.d(TAG, "onErrorReconcile: $exception")
        
    }
)
EdfaPayPlugin.INSTANCE.reconcile(
    new Function1<com.edfapay.paymentcard.model.responses.revamp.Reconcile,
        Unit>() { // onSuccess
            @Override
            public Unit invoke(com.edfapay.paymentcard.model.responses.revamp
                                   .Reconcile model) {
                    Log.d(TAG, "onSuccessReconcile: " + model);
                    return Unit.INSTANCE;
            }
    },
    new Function1<Throwable, Unit>() { // onError
            @Override
            public Unit invoke(Throwable exception) {
                    Log.d(TAG, "onErrorReconcile: " + exception);
                    return Unit.INSTANCE;
            }
    });

Reconcile History

EdfaPayPlugin.reconciliationHistory( 
 onSuccess = { historyList:
List<com.edfapay.paymentcard.model.responses.revamp.ReconciliationHistory> -
>
 Log.d("EdfaPay", "Reconciliation History:")
 historyList.forEach { history ->
 Log.d("EdfaPay", "ID: ${history.id}, Date: ${history.date},
Amount: ${history.amount}")
 }
 Toast.makeText(requireContext(), "Fetched ${historyList.size}
reconciliation records", Toast.LENGTH_SHORT).show()
 },
 onError = { error ->
 Log.e("EdfaPay", "Failed to fetch reconciliation history:
${error.message}", error)
 Toast.makeText(requireContext(), "Failed: ${error.message}",
Toast.LENGTH_SHORT).show()
 }
)
EdfaPayPlugin.reconciliationHistory(
        new EdfaPayPlugin.ReconciliationHistoryCallback() {
            @Override
            public void onSuccess(List<ReconciliationHistory> historyList) {
                Log.d("EdfaPay", "Reconciliation History:");
                for (ReconciliationHistory history : historyList) {
                    Log.d("EdfaPay", "ID: " + history.getId() +
                            ", Date: " + history.getDate() +
                            ", Amount: " + history.getAmount());
                }
                Toast.makeText(requireContext(),
                        "Fetched " + historyList.size() + " reconciliation records",
                        Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onError(Throwable error) {
                Log.e("EdfaPay", "Failed to fetch reconciliation history: " + error.getMessage(), error);
                Toast.makeText(requireContext(),
                        "Failed: " + error.getMessage(),
                        Toast.LENGTH_SHORT).show();
            }
        }
);

Reconcile Detail

EdfaPayPlugin.reconciliationDetail(
 id = reconciliationId,
 onSuccess = { detail:
com.edfapay.paymentcard.model.responses.revamp.ReconciliationDetail ->
Edfapay SoftPOS SDK – Integration Guide
 Log.d("EdfaPay", "Reconciliation Detail for $reconciliationId:")
 Log.d("EdfaPay", "Total Amount: ${detail.totalAmount}")
 Log.d("EdfaPay", "Transactions: ${detail.transactions}")
 Toast.makeText(requireContext(), "Reconciliation detail fetched",
Toast.LENGTH_SHORT).show()
 },
 onError = { error ->
 Log.e("EdfaPay", "Failed to get reconciliation detail:
${error.message}", error)
 Toast.makeText(requireContext(), "Error: ${error.message}",
Toast.LENGTH_SHORT).show()
 }
)
EdfaPayPlugin.reconciliationDetail(
        reconciliationId,
        new EdfaPayPlugin.ReconciliationDetailCallback() {
            @Override
            public void onSuccess(ReconciliationDetail detail) {
                Log.d("EdfaPay", "Reconciliation Detail for " + reconciliationId + ":");
                Log.d("EdfaPay", "Total Amount: " + detail.getTotalAmount());
                Log.d("EdfaPay", "Transactions: " + detail.getTransactions());
                
                Toast.makeText(requireContext(),
                        "Reconciliation detail fetched",
                        Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onError(Throwable error) {
                Log.e("EdfaPay", "Failed to get reconciliation detail: " + error.getMessage(), error);
                Toast.makeText(requireContext(),
                        "Error: " + error.getMessage(),
                        Toast.LENGTH_SHORT).show();
            }
        }
);

[!TIP]

Enabling and Disabling Logs

The developer can enable or disable logging at the SDK

EdfaPayPlugin.enableLogs = true
EdfaPayPlugin.INSTANCE.setEnableLogs(true);

Setting Animation Speed

The developer can set the speed for animations for status and card scheme. It will control the process speed.

EdfaPayPlugin.animationSpeedX = 2.0f
EdfaPayPlugin.INSTANCE.setAnimationSpeedX(2.0f);

Customizing the Theme

EdfaPayPlugin.theme
    .setButtonBackgroundColor("#06E59F")
    .setButtonTextColor("#000000")
    .setHeaderImage(this, R.drawable.logo)
    .setPoweredByImage(this, R.drawable.ogo);
EdfaPayPlugin.INSTANCE.setTheme(EdfaPayPlugin.INSTANCE.getTheme()
                 .setButtonBackgroundColor("#06E59F")
                 .setButtonTextColor("#000000")
                 .setHeaderImage(this, R.drawable.logo)
                 .setPoweredByImage(this, R.drawable.ogo));

License

MIT