A modern, easy-to-use Java library for integrating Paystack payment gateway with split payment support.
✅ Transaction Initialization - Create payment links for customers
✅ Payment Verification - Verify completed transactions
✅ Subaccount Management - Create and manage seller subaccounts
✅ Split Payments - Automatically split payments between platform and sellers
✅ Webhook Support - Secure webhook handling with signature verification
✅ Type-Safe - Full type safety with enums and models
✅ Java 21+ Compatible - Works with Java 21 and above
✅ Builder Pattern - Easy-to-use fluent API
✅ Transfer API - Send Money to Bank Accounts
- Java 21 or higher
- Gradle (for building)
Add JitPack repository to your build.gradle:
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}Add the dependency:
dependencies {
implementation 'com.github.justme8code:paystack4j:1.2.0'
}Replace YOUR_USERNAME with your GitHub username.
Add JitPack repository to your pom.xml:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>Add the dependency:
<dependency>
<groupId>com.github.justme8code</groupId>
<artifactId>paystack4j</artifactId>
<version>1.2.0</version>
</dependency>Until published to JitPack, you can install locally:
- Clone this repository
- Run
./gradlew publishToMavenLocal - Add
mavenLocal()to your repositories
PaystackClient client = new PaystackClient("sk_test_your_secret_key");TransactionInitRequest request = TransactionInitRequest.builder()
.email("[email protected]")
.amount(10000.00) // ₦10,000
.currency(Currency.NGN)
.reference("TXN_" + System.currentTimeMillis())
.build();
PaystackResponse<TransactionInitData> response = client.transactions().initialize(request);
// Redirect customer to payment page
String paymentUrl = response.getData().getAuthorizationUrl();PaystackResponse<TransactionData> verification =
client.transactions().verify("transaction_reference");
if (verification.getData().getStatusEnum() == TransactionStatus.SUCCESS) {
// Payment successful - deliver value
}Use this when you want to automatically split payments between your platform and sellers.
Scenario: Customer pays ₦10,000, your platform takes 10% (₦1,000), seller gets ₦9,000
SubaccountCreateRequest subRequest = SubaccountCreateRequest.builder()
.businessName("Seller Shop")
.settlementBank("058") // Bank code
.accountNumber("0123456789")
.percentageCharge(10.0) // Default split
.build();
PaystackResponse<SubaccountData> subResponse =
client.subaccounts().create(subRequest);
String subaccountCode = subResponse.getData().getSubaccountCode();
// Save this code to your database linked to the sellerTransactionInitRequest request = TransactionInitRequest.builder()
.email("[email protected]")
.amount(10000.00) // Total amount
.subaccount("ACCT_xxxxxxxxx") // Seller's subaccount
.transactionCharge(1000.00) // Your platform fee (₦1,000)
.bearer(Bearer.SUBACCOUNT) // Seller pays Paystack fees
.build();
PaystackResponse<TransactionInitData> response =
client.transactions().initialize(request);Result:
- Seller receives ₦9,000 in their bank account
- You receive ₦1,000 in your main Paystack account
- Automatic settlement - no manual transfers needed!
Main entry point for the library.
PaystackClient client = new PaystackClient(secretKey);
client.transactions() // Access transaction operations
client.subaccounts() // Access subaccount operationsCreate a new payment transaction.
Parameters:
email(required) - Customer's emailamount(required) - Amount in major currency units (e.g., 100.50)currency- Currency code (default: NGN)reference- Unique transaction referencesubaccount- Subaccount code for split paymentstransactionCharge- Platform fee amountbearer- Who pays Paystack fees (ACCOUNT or SUBACCOUNT)callbackUrl- URL to redirect customer after paymentmetadata- Custom data to attach to transaction
Returns: PaystackResponse<TransactionInitData>
authorizationUrl- Redirect customer here to payaccessCode- Payment access codereference- Transaction reference
Verify a transaction status.
Parameters:
reference- Transaction reference to verify
Returns: PaystackResponse<TransactionData>
- Contains complete transaction details including status
Create a new subaccount for a seller.
Parameters:
businessName(required) - Seller's business namesettlementBank(required) - Bank code (e.g., "058" for GTBank)accountNumber(required) - Bank account numberpercentageCharge- Default percentage splitprimaryContactEmail- Contact emailprimaryContactName- Contact nameprimaryContactPhone- Contact phone
Returns: PaystackResponse<SubaccountData>
subaccountCode- Use this for split payments
Fetch subaccount details.
The library automatically handles currency conversion:
// All these work:
.amount(100.50) // Double
.amount(new BigDecimal("100.50")) // BigDecimal (recommended)
.amountInKobo(10050) // Direct kobo (if needed)Note: Paystack requires amounts in kobo (smallest unit). ₦100 = 10,000 kobo
try {
PaystackResponse<TransactionInitData> response =
client.transactions().initialize(request);
} catch (PaystackApiException e) {
// API returned an error
System.out.println("Error: " + e.getMessage());
System.out.println("Status Code: " + e.getStatusCode());
} catch (PaystackAuthException e) {
// Authentication failed (invalid API key)
System.out.println("Auth Error: " + e.getMessage());
} catch (PaystackException e) {
// General error (network, etc.)
System.out.println("Error: " + e.getMessage());
}TransactionData transaction = verifyResponse.getData();
// Check status
if (transaction.getStatusEnum() != TransactionStatus.SUCCESS) {
return; // Don't deliver value
}
// Check amount matches expected
long expectedKobo = expectedAmount.multiply(new BigDecimal("100")).longValue();
if (transaction.getAmount() != expectedKobo) {
// Amount mismatch - investigate!
}
// Check you haven't already processed this transaction
// (prevents double fulfillment)String reference = "TXN_" + userId + "_" + System.currentTimeMillis();Save the subaccountCode in your database linked to each seller. You'll need it for every transaction.
For production, implement Paystack webhooks to get real-time payment notifications instead of relying only on callback URLs.
Use test API keys (start with sk_test_) during development. Paystack provides test cards for testing.
Paystack provides test cards you can use:
Success: 4084084084084081
Declined: 5060666666666666666
Common Nigerian bank codes:
- Access Bank:
044 - GTBank:
058 - Zenith Bank:
057 - First Bank:
011 - UBA:
033
PaystackConfig config = new PaystackConfig("sk_test_xxx", "https://custom-url.com");
PaystackClient client = new PaystackClient(config);OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.build();
PaystackClient client = new PaystackClient(config, httpClient);See the PaymentExample.java file for complete working examples including:
- Creating subaccounts
- Initializing split payments
- Verifying transactions
- Handling callbacks
- See the example page https://github.com/justme8code/paystack4jexamples
- See documentations https://github.com/justme8code/documentation
- Paystack Documentation: https://paystack.com/docs/api/
- Paystack Support: [email protected]
MIT License
Contributions are welcome! Please feel free to submit a Pull Request.
Future features planned:
- Transfer API (send money to customers)
- Customer management
- Plans and Subscriptions
- Refunds
- Bulk charges
- Async API support
- Webhook signature verification
Thompson - paystack4j
Note: This library is not officially affiliated with Paystack. It's a community-built integration library.
