Skip to content

Commit

Permalink
Revert "Enhance Chapa Client with Retrofit2 Integration, Comprehensiv…
Browse files Browse the repository at this point in the history
…e Testing, and Resilience Features"
  • Loading branch information
isrugeek authored Jun 9, 2024
1 parent 26aab68 commit 4f207d5
Show file tree
Hide file tree
Showing 151 changed files with 4,756 additions and 12,736 deletions.
226 changes: 91 additions & 135 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,109 +6,77 @@
`-----' `--' `--' `--`--' | |-' `--`--' `-----' `--`--' `--' `--`--'
```

Unofficial Java package for Chapa Payment Gateway.
[![BUILD](https://github.com/yaphet17/chapa-java/actions/workflows/maven.yml/badge.svg)](https://github.com/yaphet17/chapa-java/actions/workflows/maven.yml/) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.github.yaphet17/Chapa/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.github.yaphet17/Chapa) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## Features
- You can now implement `IChapaClient` interface and create your own custom implementation
to use your favorite HTTP client.
- Includes split payment feature added by Chapa. You can now get list of supported banks, create
sub-account and perform a split payment. See [Split Payment](https://developer.chapa.co/docs/split-payment/) documentation for more details.
- Additional utility methods to help you to generate a convenient token for your transactions, to map json string
to `PostData` object etc.
Unofficial Java SDK for Chapa Payment Gateway.

## What's new in this version
- You no longer need to deal with `JSON` or `Map<String, Object>` responses. You can just treat response data as a Java object using specific response classes for each request type (e.g. payment initialization, payment verification).
- Better exception handling. The SDK will throw the newly added `ChapaException` on failed requests to Chapa API.
- Bug fixes and design improvements.
- Well-tested and documented code. Check out the Javadoc [here](https://yaphet17.github.io/chapa-java/).

## Table of Contents
1. [Documentation](#documentation)
2. [Installation](#installation)
3. [Usage](#usage)
4. [Contribution](#contribution)
5. [Example](#example)
6. [License](#license)
4. [Javadoc](https://yaphet17.github.io/chapa-java/)
5. [Contribution](#contribution)
6. [Example](#example)
7. [License](#license)

## Documentation
Visit official [Chapa's API Documentation](https://developer.chapa.co/docs)
## Installation
Add the below maven dependency to your `pom.xml` file.
```xml
<dependency>
<groupId>com.github.amenski</groupId>
<artifactId>chapa</artifactId>
<version>1.0.0</version>
<groupId>io.github.yaphet17</groupId>
<artifactId>Chapa</artifactId>
<version>1.2.2</version>
</dependency>
```
Or add the below gradle dependency to your `build.gradle` file.
```groovy
implementation 'com.github.amenski:chapa:1.0.0'
implementation 'io.github.yaphet17:Chapa:1.2.2'
```

## Usage

> **Note** : This doc might not fully cover chapa-api. Please refer to the chapa developer doc for more. And contributions are welcome too. Thanks.

Instantiate a `Chapa` class.
```java
Chapa chapa = new Chapa.ChapaBuilder()
.client(new ChapaClient()) // --> default implementation
.secretKey("secret-key")
.build();
Chapa chapa = new Chapa("your-secrete-key");
```
Or if you want to use your own implementation, implement the methods from `IChapaClient` interface.
Or if you want to use your own implementation of `ChapaClient` interface.
```java
import com.github.amenski.client.ChapaClient;

public class MyCustomChapaClient implements IChapaClient {
...
}


Chapa chapa = new Chapa(new MyCustomChapaClient(), "secrete-key");
Chapa chapa = new Chapa("your-secrete-key", new MyCustomChapaClient());
```
Note: `MyCustomChapaClient` must implement `ChapaClient` interface.

## Retries (with ExponentialBackoff)
To add retries to clients, use `RetrierRetrofitClientProvider`. This class allows configuring 3 retries if a call fails.
Provides retrofit client to make calls to chapa api. <br>
Retry will be done with an <a href="https://en.wikipedia.org/wiki/Exponential_backoff">ExponentialBackoff</a> strategy.<br>
<pre>
Example usage:
public class CustomChapaClient implements IChapaClient {
private String baseUrl = "https://api.chapa.co/v1/";
private ChapaClientApi chapaClientApi;
.
.
private void buildApiClient() {
if (isBlank(baseUrl)) throw new ChapaException("Unable to create a client. Api baseUrl can't be empty");
chapaClientApi = new RetrierRetrofitClientProvider().buildClient(ChapaClientApi.class, baseUrl);
}
}
</pre>


To initialize a transaction, you simply need to specify your information by either using our `PostData` class.
To initialize a transaction, you can specify your information by either using our `PostData` class.

Note: Starting from version 1.1.0 you have to specify customization fields as a `Map<String, String>` object.

```java
Customization customization = new Customization()
.setTitle("E-commerce")
.setDescription("It is time to pay")
.setLogo("https://mylogo.com/log.png");
.setTitle("E-commerce")
.setDescription("It is time to pay")
.setLogo("https://mylogo.com/log.png");
PostData postData = new PostData()
.setAmount(new BigDecimal("100"))
.setCurrency("ETB")
.setFirstName("Abebe")
.setLastName("Bikila")
.setEmail("abebe@bikila.com")
.setTxRef(UUID.randomUUID().toString())
.setCallbackUrl("https://chapa.co")
.setReturnUrl("https://chapa.co")
.setSubAccountId("testSubAccountId")
.setCustomization(customization);

...

chapa.initialize(postData);
.setAmount(new BigDecimal("100"))
.setCurrency("ETB")
.setFirstName("Abebe")
.setLastName("Bikila")
.setEmail("abebe@bikila")
.setTxRef(Util.generateToken())
.setCallbackUrl("https://chapa.co")
.setReturnUrl("https://chapa.co")
.setSubAccountId("testSubAccountId")
.setCustomization(customization);
```
Or, as a string JSON data.
Or, you can use a string JSON data.
```java
String postDataString = " { " +
String formData = " { " +
"'amount': '100', " +
"'currency': 'ETB'," +
"'email': 'abebe@bikila.com'," +
Expand All @@ -123,34 +91,35 @@ String postDataString = " { " +
" 'customization[logo]':'https://mylogo.com/log.png'" +
" }" +
" }";

chapa.initialize(postDataString)
```
Intitialize payment
Initialize payment
```java
InitializeResponseData responseData = chapa.initialize(postData)
InitializeResponseData responseData = chapa.initialize(postData);
// Get the response message
System.out.println(responseData.getMessage());
// Get the checkout URL from the response JSON
System.out.println(responseData.getData().getCheckOutUrl());
// Get the raw response JSON
System.out.println(responseData.getRawJson());
```
Verify payment
```java
VerifyResponseData actualResponseData = chapa.verify("tx-ref");
// Get the verification response data
VerifyResponseData verifyResponseData = chapa.verify("tx-myecommerce12345");
```
Get list of banks
Get the list of banks
```java
List<Bank> banks = chapa.getBanks();
```
To create a subaccount, you can specify your information by either using our `Subaccount` class.
```java
SubAccount subAccount = new SubAccountDto()
.setBusinessName("Abebe Suq")
.setAccountName("Abebe Bikila")
.setAccountNumber("0123456789")
.setBankCode("001")
.setSplitType(SplitTypeEnum.PERCENTAGE)
.setSplitValue(0.2);

...

SubAccountResponseData response = chapa.createSubAccount(subAccountDto);
SubAccount subAccount = new SubAccount()
.setBusinessName("Abebe Suq")
.setAccountName("Abebe Bikila")
.setAccountNumber("0123456789")
.setBankCode("96e41186-29ba-4e30-b013-2ca36d7e7025")
.setSplitType(SplitType.PERCENTAGE)
.setSplitValue(0.2);
```
Or, you can use a string JSON data.
```java
Expand All @@ -162,81 +131,68 @@ String subAccount = " { " +
"'split_type': 'percentage'," +
"'split_value': '0.2'" +
" }";

...

SubAccountResponseData actualResponse = chapa.createSubAccount(subAccount);
```
Create subaccount
```java
SubAccountResponseData actualResponse = chapa.createSubAccount(subAccountDto);
SubAccountResponseData subAccountResponseData = chapa.createSubAccount(subAccount);
// Get SubAccount id from the response JSOn
System.out.println(subAccountResponseData.getData().getSubAccountId());
```
## Example
```java
package com.github.amenski.chapa;

import com.github.amenski.Chapa;
import com.github.amenski.client.ChapaClient;
import com.github.amenski.ChapaException;
import com.github.amenski.model.Customization;
import com.github.amenski.model.PostData;
import com.github.amenski.model.ResponseBanks;
import com.github.amenski.model.SplitTypeEnum;
import com.github.amenski.model.SubAccountDto;

import java.math.BigDecimal;
import java.util.UUID;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ChapaExample {
import io.github.yaphet17.chapa.Chapa;
import io.github.yaphet17.chapa.PostData;
import io.github.yaphet17.chapa.SubAccount;
import io.github.yaphet17.chapa.SplitType;
import io.github.yaphet17.chapa.Bank;

public static void main(String[] args) throws ChapaException {
Chapa chapa = new Chapa.ChapaBuilder()
.client(new ChapaClient())
.secretKey("CHASECK_TEST-...")
.build();
public class ChapaExample {

Customization customization = new Customization()
public static void main(String[] args) {
Chapa chapa = new Chapa("your-secrete-key");

Customization customization = new Customization()
.setTitle("E-commerce")
.setDescription("It is time to pay")
.setLogo("https://mylogo.com/log.png");
PostData postData = new PostData()

PostData postData = new PostData()
.setAmount(new BigDecimal("100"))
.setCurrency("ETB")
.setFirstName("Abebe")
.setLastName("Bikila")
.setEmail("abebe@bikila.com")
.setTxRef(UUID.randomUUID().toString())
.setEmail("abebe@bikila")
.setTxRef(Util.generateToken())
.setCallbackUrl("https://chapa.co")
.setReturnUrl("https://chapa.co")
.setSubAccountId("testSubAccountId")
.setCustomization(customization);

SubAccountDto subAccountDto = new SubAccountDto()
SubAccount subAccount = new SubAccount()
.setBusinessName("Abebe Suq")
.setAccountName("Abebe Bikila")
.setAccountNumber("0123456789")
.setBankCode("853d0598-9c01-41ab-ac99-48eab4da1513")
.setSplitType(SplitTypeEnum.PERCENTAGE)
.setBankCode("96e41186-29ba-4e30-b013-2ca36d7e7025")
.setSplitType(SplitType.PERCENTAGE)
.setSplitValue(0.2);

// list of banks
ResponseBanks banks = chapa.getBanks();
if ((banks == null || banks.getData() == null)) {
System.out.println("Create SubAccount response: " + banks);
} else {
banks.getData().forEach(System.out::println);
}
// create subaccount
System.out.println("Create SubAccount response: " + chapa.createSubAccount(subAccountDto));
// initialize payment
System.out.println("Initialize response: " + chapa.initialize(postData));
// verify payment
System.out.println("Verify response: " + chapa.verify(postData.getTxRef()));
}
}

InitializeResponseData responseData = chapa.initialize(postData);
VerifyResponseData verifyResponseData = chapa.verify("tx-myecommerce12345");
SubAccountResponseData subAccountResponseData = chapa.createSubAccount(subAccount);

}
}
```
## Contribution
Please feel free to open an issue or pull request.
If you find any bugs or have any suggestions, please feel free to open an issue or pull request.

## License
MIT
This open-source library is licensed under the terms of the MIT License.

Enjoy!
41 changes: 0 additions & 41 deletions doc/allclasses-frame.html

This file was deleted.

Loading

0 comments on commit 4f207d5

Please sign in to comment.