Skip to content

Kenandarabeh/sofizpay-sdk-java

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

2 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

SofizPay SDK for Java/Kotlin

SofizPay Logo

๐Ÿš€ A powerful Java/Kotlin SDK for SofizPay payment processing

Maven Central License: MIT GitHub Stars Issues Java 8+ Kotlin


๐Ÿ“‹ Table of Contents


๐ŸŒŸ Overview

SofizPay SDK is a comprehensive Java/Kotlin library for secure payment processing with real-time transaction monitoring, banking integration, and advanced payment management capabilities.

Key Benefits:

  • ๐Ÿ” Secure payment processing
  • โšก Real-time transaction monitoring with callbacks
  • ๐ŸŽฏ Simple, intuitive API for both Java and Kotlin
  • ๐Ÿฆ Banking transaction support
  • ๐Ÿ“Š Comprehensive transaction history and search
  • ๐Ÿ” Advanced signature verification
  • ๐ŸŒ Testnet and Production environment support

โœจ Features

  • โœ… Send Payments: Secure payment transfers with memo support
  • โœ… Transaction History: Retrieve and filter transaction records with pagination
  • โœ… Balance Checking: Real-time balance queries
  • โœ… Transaction Search: Find transactions by memo, hash, or account
  • โœ… Real-time Streams: Live transaction monitoring with customizable callbacks
  • โœ… Banking Transactions: Create bank transactions for deposits
  • โœ… Account Management: Create new accounts and manage payment credentials
  • โœ… Signature Verification: RSA signature validation for secure communications
  • โœ… Error Handling: Robust error management and detailed reporting
  • โœ… Kotlin Support: Modern Kotlin implementation with data classes and coroutines-ready

๐Ÿ“ฆ Installation

Gradle (Groovy)

dependencies {
    implementation 'io.github.kenandarabeh:sofizpay-sdk-java:1.0.5-SNAPSHOT'
}

Gradle (Kotlin DSL)

dependencies {
    implementation("io.github.kenandarabeh:sofizpay-sdk-java:1.0.5-SNAPSHOT")
}

Maven

<dependency>
  <groupId>io.github.kenandarabeh</groupId>
  <artifactId>sofizpay-sdk-java</artifactId>
  <version>1.0.5-SNAPSHOT</version>
</dependency>

Build from Source

git clone https://github.com/kenandarabeh/sofizpay-sdk-java.git
cd sofizpay-sdk-java
./gradlew build

๐Ÿš€ Quick Start

Java Example

import com.sofizpay.sdk.SofizPayStellarSDK;

public class QuickStart {
    public static void main(String[] args) {
        // Initialize SDK (testnet by default)
        try (SofizPayStellarSDK sdk = new SofizPayStellarSDK(true)) {
            
            // Create payment data
            SofizPayStellarSDK.PaymentData paymentData = new SofizPayStellarSDK.PaymentData();
            paymentData.secret = "YOUR_SECRET_KEY";
            paymentData.destination = "DESTINATION_ADDRESS";
            paymentData.amount = "10.0";
            paymentData.memo = "Payment for services";
            
            // Send payment
            SofizPayStellarSDK.PaymentResult result = sdk.submit(paymentData);
            
            if (result.success) {
                System.out.println("โœ… Payment successful! TX: " + result.transactionId);
            } else {
                System.out.println("โŒ Payment failed: " + result.message);
            }
        }
    }
}

Kotlin Example

import com.sofizpay.sdk.SofizPayStellarSDK

fun main() {
    // Initialize SDK (testnet by default)
    SofizPayStellarSDK(isTestnet = true).use { sdk ->
        
        // Create payment data
        val paymentData = SofizPayStellarSDK.PaymentData(
            secret = "YOUR_SECRET_KEY",
            destination = "DESTINATION_ADDRESS",
            amount = "10.0",
            memo = "Payment for services"
        )
        
        // Send payment
        val result = sdk.submit(paymentData)
        
        if (result.success) {
            println("โœ… Payment successful! TX: ${result.transactionId}")
        } else {
            println("โŒ Payment failed: ${result.message}")
        }
    }
}

๐Ÿ“š API Reference

Core Payment Methods

submit() - Send Payment

Send payments with memo support.

Java:

PaymentData paymentData = new PaymentData();
paymentData.secret = "SECRET_KEY";
paymentData.destination = "DESTINATION_ADDRESS";
paymentData.amount = "10.0";
paymentData.memo = "Payment memo";

PaymentResult result = sdk.submit(paymentData);

Kotlin:

val paymentData = PaymentData(
    secret = "SECRET_KEY",
    destination = "DESTINATION_ADDRESS",
    amount = "10.0",
    memo = "Payment memo"
)

val result = sdk.submit(paymentData)

getBalance() - Check Balance

Get account balance.

BalanceResult balance = sdk.getBalance("ACCOUNT_ADDRESS");
System.out.println("Balance: " + balance.balance);

getPublicKey() - Extract Public Key

Extract public key from secret key.

PublicKeyResult result = sdk.getPublicKey("SECRET_KEY");
String publicKey = result.publicKey;

Transaction Management

getTransactions() - Transaction History

Get paginated transaction history for an account.

TransactionHistoryResult result = sdk.getTransactions("ACCOUNT_ID", 50);
for (TransactionInfo tx : result.transactions) {
    System.out.println("TX: " + tx.hash + " Amount: " + tx.amount);
}

searchTransactionsByMemo() - Search by Memo

Find transactions containing specific memo text.

SearchTransactionsResult result = sdk.searchTransactionsByMemo("ACCOUNT_ID", "invoice-123", 10);

getTransactionByHash() - Get by Hash

Retrieve specific transaction by hash.

TransactionByHashResult result = sdk.getTransactionByHash("TRANSACTION_HASH");
if (result.found) {
    TransactionInfo tx = result.transaction;
    System.out.println("Found transaction: " + tx.amount);
}

Account Management

createAccount() - Create New Account

Generate a new account keypair.

AccountCreationResult result = sdk.createAccount();
System.out.println("Account ID: " + result.accountId);
System.out.println("Secret Key: " + result.secretKey);

fundAccountFromFaucet() - Fund from Testnet Faucet

Fund account with testnet funds (testnet only).

FundResult result = sdk.fundAccountFromFaucet("ACCOUNT_ID");
if (result.success) {
    System.out.println("Account funded successfully");
}

Banking Integration

makeCIBTransaction() - Bank Transaction

Create bank transactions for deposits.

CIBTransactionData cibData = new CIBTransactionData();
cibData.account = "YOUR_SECRET_KEY";
cibData.amount = "150";
cibData.full_name = "Ahmed";
cibData.phone = "+213*********";
cibData.email = "ahmed@sofizpay.com";
cibData.memo = "Payment";
cibData.return_url = "https://yoursite.com/payment-success";
cibData.redirect = true;

CIBTransactionResult result = sdk.makeCIBTransaction(cibData);

Security

verifySignature() - RSA Signature Verification

Verify RSA signatures for secure communication.

boolean isValid = sdk.verifySignature("message", "base64_signature");
if (isValid) {
    System.out.println("Signature is valid");
}

๐Ÿ”„ Real-time Transaction Monitoring

Monitor transactions in real-time with customizable callbacks.

Java Implementation

// Define callback
TransactionCallback callback = new TransactionCallback() {
    @Override
    public void onNewTransaction(TransactionInfo transaction) {
        System.out.println("New transaction: " + transaction.type + 
                          " Amount: " + transaction.amount);
        
        if ("received".equals(transaction.type)) {
            handleIncomingPayment(transaction);
        }
    }
};

// Start monitoring
StreamResult streamResult = sdk.startTransactionStream("ACCOUNT_ID", callback);

// Check status
StreamStatusResult status = sdk.getStreamStatus("ACCOUNT_ID");
System.out.println("Stream active: " + status.active);

// Stop monitoring
StreamResult stopResult = sdk.stopTransactionStream("ACCOUNT_ID");

Kotlin Implementation

// Start monitoring with lambda
val streamResult = sdk.startTransactionStream("ACCOUNT_ID") { transaction ->
    println("New transaction: ${transaction.type} Amount: ${transaction.amount}")
    
    if (transaction.type == "received") {
        handleIncomingPayment(transaction)
    }
}

// Check status
val status = sdk.getStreamStatus("ACCOUNT_ID")
println("Stream active: ${status.active}")

// Stop monitoring
val stopResult = sdk.stopTransactionStream("ACCOUNT_ID")

๐Ÿฆ Banking Integration

Complete banking integration for payment processing.

public class PaymentProcessor {
    private final SofizPayStellarSDK sdk;
    
    public PaymentProcessor() {
        this.sdk = new SofizPayStellarSDK(false); // Production
    }
    
    public void processDeposit(String account, String amount, String fullName, String phone, String email) {
        CIBTransactionData cibData = new CIBTransactionData();
        cibData.account = account;
        cibData.amount = amount;
        cibData.full_name = fullName;
        cibData.phone = phone;
        cibData.email = email;
        cibData.memo = "Payment deposit";
        cibData.return_url = "https://yoursite.com/payment-success";
        cibData.redirect = true;
        
        CIBTransactionResult result = sdk.makeCIBTransaction(cibData);
        
        if (result.success) {
            System.out.println("Transaction successful");
            Map<String, Object> responseData = result.data;
            // Process response data
        } else {
            System.err.println("Transaction failed: " + result.message);
        }
    }
    
    public void close() {
        sdk.close();
    }
}

๐Ÿ’ก Usage Examples

Complete Payment System (Java)

public class PaymentSystem {
    private final SofizPayStellarSDK sdk;
    
    public PaymentSystem() {
        this.sdk = new SofizPayStellarSDK(true); // Testnet
    }
    
    public void processPayment(String secretKey, String destination, 
                             String amount, String memo) {
        try {
            // Check balance first
            String accountId = sdk.getPublicKey(secretKey).publicKey;
            BalanceResult balance = sdk.getBalance(accountId);
            
            System.out.println("Current balance: " + balance.balance);
            
            // Create payment
            PaymentData paymentData = new PaymentData();
            paymentData.secret = secretKey;
            paymentData.destination = destination;
            paymentData.amount = amount;
            paymentData.memo = memo;
            
            // Submit payment
            PaymentResult result = sdk.submit(paymentData);
            
            if (result.success) {
                System.out.println("โœ… Payment successful!");
                System.out.println("Transaction ID: " + result.transactionId);
                
                // Start monitoring for confirmation
                startPaymentMonitoring(accountId, result.transactionId);
            } else {
                System.err.println("โŒ Payment failed: " + result.message);
            }
            
        } catch (Exception e) {
            System.err.println("Error processing payment: " + e.getMessage());
        }
    }
    
    private void startPaymentMonitoring(String accountId, String expectedTxId) {
        TransactionCallback callback = new TransactionCallback() {
            @Override
            public void onNewTransaction(TransactionInfo transaction) {
                if (expectedTxId.equals(transaction.hash)) {
                    System.out.println("โœ… Payment confirmed!");
                    sdk.stopTransactionStream(accountId);
                }
            }
        };
        
        sdk.startTransactionStream(accountId, callback);
    }
    
    public void close() {
        sdk.close();
    }
}

E-commerce Integration (Kotlin)

class ECommercePaymentProcessor(private val isTestnet: Boolean = true) : AutoCloseable {
    private val sdk = SofizPayStellarSDK(isTestnet)
    
    suspend fun processOrder(order: Order): PaymentResult {
        return try {
            // Validate order
            if (order.amount <= 0) {
                return PaymentResult(false, "Invalid amount", null)
            }
            
            // Create payment
            val paymentData = SofizPayStellarSDK.PaymentData(
                secret = order.customerSecretKey,
                destination = getCompanyAddress(),
                amount = order.amount.toString(),
                memo = "Order #${order.id}"
            )
            
            // Submit payment
            val result = sdk.submit(paymentData)
            
            if (result.success) {
                // Log successful payment
                logPayment(order.id, result.transactionId!!)
                
                // Start monitoring for confirmation
                startOrderMonitoring(order)
            }
            
            result
        } catch (e: Exception) {
            PaymentResult(false, "Payment processing error: ${e.message}", null)
        }
    }
    
    private fun startOrderMonitoring(order: Order) {
        val companyAccountId = getCompanyAddress()
        
        sdk.startTransactionStream(companyAccountId) { transaction ->
            if (transaction.memo == "Order #${order.id}" && transaction.type == "received") {
                println("โœ… Order ${order.id} payment confirmed!")
                fulfillOrder(order)
                sdk.stopTransactionStream(companyAccountId)
            }
        }
    }
    
    private fun getCompanyAddress(): String = "COMPANY_ADDRESS"
    private fun logPayment(orderId: String, txId: String) { /* Log to database */ }
    private fun fulfillOrder(order: Order) { /* Fulfill order */ }
    
    override fun close() = sdk.close()
}

data class Order(
    val id: String,
    val customerSecretKey: String,
    val amount: Double,
    val items: List<String>
)

Transaction Analytics

public class TransactionAnalytics {
    private final SofizPayStellarSDK sdk;
    
    public TransactionAnalytics() {
        this.sdk = new SofizPayStellarSDK(false); // Production
    }
    
    public void generateReport(String accountId, int days) {
        try {
            // Get recent transactions
            TransactionHistoryResult result = sdk.getTransactions(accountId, 200);
            
            double totalReceived = 0;
            double totalSent = 0;
            int receivedCount = 0;
            int sentCount = 0;
            
            for (TransactionInfo tx : result.transactions) {
                if ("received".equals(tx.type)) {
                    totalReceived += Double.parseDouble(tx.amount);
                    receivedCount++;
                } else if ("sent".equals(tx.type)) {
                    totalSent += Double.parseDouble(tx.amount);
                    sentCount++;
                }
            }
            
            System.out.println("=== Transaction Report ===");
            System.out.println("Total Received: " + totalReceived + " (" + receivedCount + " transactions)");
            System.out.println("Total Sent: " + totalSent + " (" + sentCount + " transactions)");
            System.out.println("Net Flow: " + (totalReceived - totalSent));
            
        } catch (Exception e) {
            System.err.println("Error generating report: " + e.getMessage());
        }
    }
    
    public void close() {
        sdk.close();
    }
}

โš ๏ธ Error Handling

All methods return structured response objects with consistent error handling:

// Java
PaymentResult result = sdk.submit(paymentData);
if (result.success) {
    System.out.println("Success: " + result.transactionId);
} else {
    System.err.println("Error: " + result.message);
}
// Kotlin
val result = sdk.submit(paymentData)
if (result.success) {
    println("Success: ${result.transactionId}")
} else {
    println("Error: ${result.message}")
}

Common Error Messages

  • "Secret key is required."
  • "Destination address is required."
  • "Amount is required."
  • "Bad request: Invalid destination address"
  • "Network error: Connection timeout"
  • "Insufficient balance for transaction"

Exception Handling

try (SofizPayStellarSDK sdk = new SofizPayStellarSDK()) {
    // SDK operations
} catch (Exception e) {
    System.err.println("SDK error: " + e.getMessage());
    e.printStackTrace();
}

๐Ÿ† Best Practices

Security

// โœ… Store secret keys securely
String secretKey = System.getenv("SECRET_KEY"); // From environment
// โŒ Never hardcode secret keys in source code

// โœ… Validate inputs
if (amount == null || amount.isEmpty()) {
    throw new IllegalArgumentException("Amount is required");
}

// โœ… Use try-with-resources for automatic cleanup
try (SofizPayStellarSDK sdk = new SofizPayStellarSDK()) {
    // Use SDK
} // Automatically closed

Performance

// โœ… Reuse SDK instances
private static final SofizPayStellarSDK sdk = new SofizPayStellarSDK();

// โœ… Use reasonable limits for transaction queries
TransactionHistoryResult result = sdk.getTransactions(accountId, 50); // Not 1000+

// โœ… Stop streams when no longer needed
sdk.stopTransactionStream(accountId);

Error Resilience

// โœ… Always check success status
if (result.success) {
    // Process successful result
} else {
    // Handle error gracefully
    logError("Payment failed", result.message);
}

// โœ… Implement retry logic for network operations
public PaymentResult submitWithRetry(PaymentData data, int maxRetries) {
    for (int i = 0; i < maxRetries; i++) {
        PaymentResult result = sdk.submit(data);
        if (result.success || !isRetryableError(result.message)) {
            return result;
        }
        try {
            Thread.sleep(1000 * (i + 1)); // Exponential backoff
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            break;
        }
    }
    return new PaymentResult(false, "Max retries exceeded", null);
}

๐Ÿ”„ Java vs Kotlin

This SDK provides both Java and Kotlin implementations with identical functionality:

Java Strengths

  • Familiar Syntax: Traditional Java patterns
  • Enterprise Ready: Mature ecosystem
  • Explicit Types: Clear type declarations
  • Wide Adoption: Large developer community

Kotlin Advantages

  • Concise Syntax: Less boilerplate code
  • Null Safety: Compile-time null checks
  • Data Classes: Built-in equals/hashCode/toString
  • Lambda Support: Modern functional programming

Migration Path

You can easily migrate from Java to Kotlin implementation:

// Java
PaymentData data = new PaymentData();
data.secret = "SECRET";
data.destination = "DEST";
data.amount = "10.0";
// Kotlin
val data = PaymentData(
    secret = "SECRET",
    destination = "DEST", 
    amount = "10.0"
)

๐Ÿงช Testing

Unit Tests

./gradlew test

Integration Tests

./gradlew integrationTest

Test Example

@Test
public void testPaymentSubmission() {
    SofizPayStellarSDK sdk = new SofizPayStellarSDK(true); // Testnet
    
    // Create test account
    AccountCreationResult account = sdk.createAccount();
    
    // Fund account
    FundResult fundResult = sdk.fundAccountFromFaucet(account.accountId);
    assertTrue(fundResult.success);
    
    // Test payment
    PaymentData paymentData = new PaymentData();
    paymentData.secret = account.secretKey;
    paymentData.destination = "DESTINATION_ADDRESS";
    paymentData.amount = "1.0";
    paymentData.memo = "Test payment";
    
    PaymentResult result = sdk.submit(paymentData);
    assertTrue(result.success);
    assertNotNull(result.transactionId);
    
    sdk.close();
}

๐Ÿค Contributing

We welcome contributions! Here's how to get started:

Development Setup

# Clone repository
git clone https://github.com/kenandarabeh/sofizpay-sdk-java.git
cd sofizpay-sdk-java

# Build project
./gradlew build

# Run tests
./gradlew test

# Run examples
./gradlew runJavaExample
./gradlew runKotlinExample

Contribution Guidelines

  1. Fork the repository
  2. Create feature branch: git checkout -b feature/amazing-feature
  3. Write tests for new functionality
  4. Ensure all tests pass: ./gradlew test
  5. Commit changes: git commit -m 'Add amazing feature'
  6. Push to branch: git push origin feature/amazing-feature
  7. Open a Pull Request

Code Style

  • Follow Java/Kotlin conventions
  • Add Javadoc/KDoc for public methods
  • Include unit tests for new features
  • Use meaningful variable names
  • Handle errors gracefully

๐Ÿ“ž Support

Getting Help

  1. Check the documentation above
  2. Search existing issues on GitHub
  3. Join our community discussions
  4. Contact support for enterprise needs

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License

Copyright (c) 2025 SofizPay

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

๐Ÿ™ Acknowledgments

  • Open Source Community - For continuous improvement and feedback
  • Java/Kotlin Ecosystem - For providing robust development tools
  • OkHttp - Reliable HTTP client for network operations
  • Gson - JSON serialization and deserialization
  • Gradle - Build automation and dependency management
  • JetBrains - Kotlin language development

๐Ÿ”ฎ Roadmap

Upcoming Features

  • WebSocket Streams - Real-time WebSocket transaction monitoring
  • Multi-signature Support - Advanced security with multiple signatures
  • Advanced Analytics - Built-in transaction analytics and reporting
  • Spring Boot Integration - Auto-configuration for Spring applications
  • Reactive Streams - RxJava/Reactor support for reactive applications
  • Mobile SDK - Android and iOS native SDKs

Version History

  • v1.0.5-SNAPSHOT - Latest development version with enhanced features
  • v1.0.0 - Initial release with core payment functionality
  • v1.0.0-kotlin - Kotlin implementation with modern language features

๐Ÿš€ Ready to integrate secure payments?

Start building with SofizPay SDK today!

GitHub โ€ข Maven Central โ€ข Support โ€ข Contact

Made with โค๏ธ by the SofizPay Team

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages