Skip to main content

Java SDK

The BirrLink Java SDK provides a simple interface to interact with the BirrLink API for Java applications.

Installation

Maven

Add the following dependency to your pom.xml:

<dependency>
<groupId>com.birrlink</groupId>
<artifactId>sdk</artifactId>
<version>1.0.0</version>
</dependency>

Gradle

Add the following to your build.gradle:

implementation 'com.birrlink:sdk:1.0.0'

Initialization

import com.birrlink.BirrLink;
import com.birrlink.Environment;

// Initialize with your secret key
BirrLink client = new BirrLink(
System.getenv("BIRR_LINK_SECRET_KEY"),
Environment.SANDBOX // Use Environment.PRODUCTION for live transactions
);

Configuration Options

import com.birrlink.BirrLinkOptions;

BirrLinkOptions options = BirrLinkOptions.builder()
.setApiKey(System.getenv("BIRR_LINK_SECRET_KEY"))
.setEnvironment(Environment.SANDBOX)
.setTimeout(30) // Request timeout in seconds (default: 30)
.setMaxRetries(3) // Number of retry attempts (default: 3)
.setBaseUrl("https://api.birrlink.et/v1") // Override base URL if needed
.build();

BirrLink client = new BirrLink(options);

Payment Operations

Create Payment

import java.util.HashMap;
import java.util.Map;

try {
Map<String, Object> customer = new HashMap<>();
customer.put("email", "customer@example.com");
customer.put("phone", "+251912345678");

Map<String, Object> paymentData = new HashMap<>();
paymentData.put("amount", 100.00);
paymentData.put("currency", "ETB");
paymentData.put("payment_method", "mobile_money");
paymentData.put("customer", customer);
paymentData.put("description", "Payment for order #12345");
paymentData.put("callback_url", "https://yourwebsite.com/payment-callback");

Map<String, Object> payment = client.payments().create(paymentData);

System.out.println("Payment created: " + payment.get("id"));
System.out.println("Payment status: " + payment.get("status"));
} catch (BirrLinkException e) {
if (e.getType().equals("validation_error")) {
System.out.println("Validation failed: " + e.getDetails());
} else {
System.out.println("Payment creation failed: " + e.getMessage());
}
}

Retrieve Payment

try {
Map<String, Object> payment = client.payments().get("pay_123456789");
System.out.println("Payment status: " + payment.get("status"));
} catch (BirrLinkException e) {
System.out.println("Failed to retrieve payment: " + e.getMessage());
}

List Payments

try {
Map<String, Object> params = new HashMap<>();
params.put("limit", 10);
params.put("offset", 0);
params.put("status", "completed");

Map<String, Object> payments = client.payments().list(params);

List<Map<String, Object>> paymentsList = (List<Map<String, Object>>) payments.get("data");
System.out.println("Found " + paymentsList.size() + " payments");
} catch (BirrLinkException e) {
System.out.println("Failed to list payments: " + e.getMessage());
}

Customer Operations

Create Customer

try {
Map<String, Object> customerData = new HashMap<>();
customerData.put("email", "customer@example.com");
customerData.put("phone", "+251912345678");
customerData.put("name", "John Doe");

Map<String, Object> metadata = new HashMap<>();
metadata.put("customer_type", "individual");
customerData.put("metadata", metadata);

Map<String, Object> customer = client.customers().create(customerData);

System.out.println("Customer created: " + customer.get("id"));
} catch (BirrLinkException e) {
System.out.println("Customer creation failed: " + e.getMessage());
}

Update Customer

try {
Map<String, Object> updateData = new HashMap<>();
updateData.put("email", "newemail@example.com");
updateData.put("phone", "+251987654321");

Map<String, Object> customer = client.customers().update("cus_123456789", updateData);

System.out.println("Customer updated: " + customer.get("id"));
} catch (BirrLinkException e) {
System.out.println("Customer update failed: " + e.getMessage());
}

Refund Operations

Create Refund

try {
Map<String, Object> refundData = new HashMap<>();
refundData.put("payment_id", "pay_123456789");
refundData.put("amount", 50.00);
refundData.put("reason", "Customer request");

Map<String, Object> refund = client.refunds().create(refundData);

System.out.println("Refund created: " + refund.get("id"));
} catch (BirrLinkException e) {
System.out.println("Refund creation failed: " + e.getMessage());
}

Webhook Verification

Verify webhook signatures to ensure authenticity:

import com.birrlink.Webhook;
import spark.Spark;

public class WebhookHandler {
public static void setupWebhookHandler(BirrLink client) {
Spark.post("/webhooks/birrlink", (request, response) -> {
String payload = request.body();
String signature = request.headers("BirrLink-Signature");
String secret = System.getenv("WEBHOOK_SECRET");

try {
Map<String, Object> event = Webhook.constructEvent(payload, signature, secret);

// Process the event
String eventType = (String) event.get("type");
if ("payment.completed".equals(eventType)) {
System.out.println("Payment completed");
} else if ("payment.failed".equals(eventType)) {
System.out.println("Payment failed");
} else {
System.out.println("Unhandled event type: " + eventType);
}

response.status(200);
return "OK";
} catch (BirrLinkException e) {
System.out.println("Webhook verification failed: " + e.getMessage());
response.status(400);
return "Invalid signature";
}
});
}
}

Error Handling

The SDK provides detailed error information:

try {
Map<String, Object> payment = client.payments().create(paymentData);
} catch (ValidationError e) {
System.out.println("Validation error: " + e.getMessage());
System.out.println("Invalid fields: " + e.getDetails());
} catch (AuthenticationException e) {
System.out.println("Authentication failed: " + e.getMessage());
} catch (CardException e) {
System.out.println("Card processing error: " + e.getMessage());
System.out.println("Card code: " + e.getCode());
} catch (PaymentException e) {
System.out.println("Payment error: " + e.getMessage());
} catch (BirrLinkException e) {
System.out.println("Unexpected error: " + e.getMessage());
}

Asynchronous Operations

The Java SDK also supports async operations:

import java.util.concurrent.CompletableFuture;

// Create payment asynchronously
CompletableFuture<Map<String, Object>> futurePayment = client.payments().createAsync(paymentData);

futurePayment
.thenAccept(payment -> System.out.println("Payment created: " + payment.get("id")))
.exceptionally(throwable -> {
System.out.println("Payment creation failed: " + throwable.getMessage());
return null;
});

Custom Requests

For advanced use cases, you can make custom API requests:

try {
Map<String, Object> response = client.request("GET", "/custom-endpoint",
Collections.singletonMap("param", "value"));

System.out.println("Custom response: " + response);
} catch (BirrLinkException e) {
System.out.println("Custom request failed: " + e.getMessage());
}

Version Information

Check the SDK version:

String version = client.getVersion();
System.out.println("SDK Version: " + version);

Spring Boot Integration

For Spring Boot applications, you can configure the SDK as a bean:

// BirrLinkConfig.java
@Configuration
public class BirrLinkConfig {

@Bean
public BirrLink birrLinkClient(@Value("${birrlink.api.key}") String apiKey) {
return new BirrLink(apiKey, Environment.SANDBOX);
}
}

// PaymentService.java
@Service
public class PaymentService {

private final BirrLink client;

public PaymentService(BirrLink client) {
this.client = client;
}

public Map<String, Object> createPayment(double amount, String currency, String description)
throws BirrLinkException {

Map<String, Object> paymentData = new HashMap<>();
paymentData.put("amount", amount);
paymentData.put("currency", currency);
paymentData.put("description", description);

return client.payments().create(paymentData);
}
}

Testing Considerations

When testing, use test API keys and enable debug mode:

BirrLinkOptions options = BirrLinkOptions.builder()
.setApiKey(System.getenv("BIRR_LINK_TEST_KEY"))
.setEnvironment(Environment.SANDBOX)
.setDebug(true) // Enable debug logging
.build();

BirrLink client = new BirrLink(options);

Connection Pooling

For high-traffic applications, configure connection pooling:

BirrLinkOptions options = BirrLinkOptions.builder()
.setApiKey(System.getenv("BIRR_LINK_SECRET_KEY"))
.setEnvironment(Environment.PRODUCTION)
.setConnectionPoolSize(20) // Size of the connection pool
.setMaxRetries(3)
.build();

BirrLink client = new BirrLink(options);

For comprehensive testing, use the SDK in combination with BirrLink's sandbox environment to simulate various payment scenarios without real money transfers. The SDK handles connection management and request/response formatting automatically, allowing you to focus on implementing payment functionality in your application.