Skip to content

Develop #52

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 87 commits into from
Dec 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
8933f93
configure scm
Oct 16, 2023
007b032
setup dependency management
Oct 16, 2023
ca2abd5
[maven-release-plugin] prepare release PaystackJavaClient-1.0
Oct 16, 2023
43d0c39
[maven-release-plugin] prepare for next development iteration
Oct 16, 2023
2c37ce7
cleanup
Oct 16, 2023
9bfc855
cleanup
Oct 16, 2023
7ab5d9b
Merge branch 'main' into develop
chriseteka Oct 16, 2023
69948fa
cleanup
Oct 16, 2023
959697b
Merge branch 'main' into develop
chriseteka Oct 16, 2023
7dcbb7a
cleanup
Oct 16, 2023
7575348
Develop (#5) (#6)
chriseteka Oct 16, 2023
ba09fa5
Merge branch 'main' into develop
chriseteka Oct 16, 2023
e1046cc
cleanup
Oct 16, 2023
c4dd3bc
Merge branch 'main' into develop
chriseteka Oct 16, 2023
03193b0
cleanup
Oct 16, 2023
22aeafe
Merge branch 'main' into develop
chriseteka Oct 16, 2023
d28dbc6
cleanup
Oct 16, 2023
e4d85fc
Merge branch 'main' into develop
chriseteka Oct 16, 2023
e4b7b6b
cleanup
Oct 16, 2023
3fec30a
Merge branch 'main' into develop
chriseteka Oct 16, 2023
55ab281
cleanup
Oct 16, 2023
2d26904
Merge branch 'main' into develop
chriseteka Oct 16, 2023
cd26cc0
cleanup
Oct 16, 2023
da0b498
Merge branch 'main' into develop
chriseteka Oct 16, 2023
a8bc385
cleanup
Oct 16, 2023
c53ec39
Merge branch 'main' into develop
chriseteka Oct 16, 2023
c9c7233
cleanup
Oct 16, 2023
a9c7334
Merge branch 'main' into develop
chriseteka Oct 16, 2023
766f298
Merge branch 'main' into develop
Oct 16, 2023
faefaaa
cleanup
Oct 16, 2023
4d0ecc1
[maven-release-plugin] prepare release PaystackJavaClient-1.0.5
Oct 16, 2023
ebcb439
[maven-release-plugin] prepare for next development iteration
Oct 16, 2023
3b6aec2
cleanup
Oct 16, 2023
b2eddc3
Merge remote-tracking branch 'origin/develop' into develop
Oct 16, 2023
f8a6253
cleanup
Oct 16, 2023
cf8dcf9
[maven-release-plugin] prepare release PaystackJavaClient-1.0.6
Oct 16, 2023
9b27795
Merge branch 'main' into develop
Oct 16, 2023
0174758
Merge branch 'main' into develop
Oct 16, 2023
4c8e7e6
cleanup
Oct 16, 2023
66ff352
Merge branch 'main' into develop
Oct 16, 2023
f0f9309
cleanup
Oct 16, 2023
f6ea5ff
cleanup
Oct 16, 2023
08e0b03
cleanup
Oct 16, 2023
5be4fb7
Merge branch 'main' into develop
Oct 16, 2023
8a63c4e
Restructure to return execution spec
Oct 19, 2023
8edbe24
Merge branch 'main' into develop
Oct 19, 2023
961a334
cleanup
Oct 19, 2023
3f7ef3b
Merge branch 'main' into develop
Oct 19, 2023
54f8757
cleanup
Oct 19, 2023
e7e6a70
Merge branch 'main' into develop
Oct 19, 2023
2383700
cleanup
Oct 19, 2023
bb69a1f
Merge branch 'main' into develop
Oct 19, 2023
4f5ef71
cleanup
Oct 19, 2023
1bfed1c
Merge branch 'main' into develop
Oct 19, 2023
b734114
cleanup
Oct 19, 2023
f512544
Merge branch 'main' into develop
Oct 19, 2023
e8335cd
cleanup
Oct 19, 2023
cb2737f
[maven-release-plugin] prepare release PaystackJavaClient-1.0.5
Oct 19, 2023
688617a
cleanup
Oct 19, 2023
652ddfd
Merge branch 'main' into develop
Oct 19, 2023
3b599f0
cleanup
Oct 19, 2023
33a249b
Merge branch 'main' into develop
Oct 21, 2023
f643ce1
cleanup
Oct 21, 2023
c357227
Merge branch 'main' into develop
Oct 21, 2023
88d172a
Merge branch 'main' into develop
Oct 21, 2023
a115b94
cleanup and example
Oct 21, 2023
f70947a
Merge branch 'main' into develop
Oct 29, 2023
1f08aa0
Remove unnecessary super class
Nov 1, 2023
71174d6
Introduce the use of declarative http client for paystack client spri…
Nov 1, 2023
7caef0a
cleanup to allow build
Nov 14, 2023
b3e8fd0
Merge branch 'main' into develop
Nov 14, 2023
4c1d75a
Merge branch 'main' into develop
Nov 15, 2023
1d213ac
cleanup
Nov 15, 2023
65a2ea5
❇️ Create classes and interfaces for the Product submodule (#46)
Doctor-Vee Nov 28, 2023
6d316a4
Bump jackson.version from 2.15.3 to 2.16.0 (#45)
dependabot[bot] Nov 28, 2023
f86da5d
Add customer client and fixes some serialization bugs
Nov 28, 2023
fe01994
Merge branch 'main' into develop
Nov 28, 2023
6fb3c0d
Bump actions/setup-java from 3 to 4 (#48)
dependabot[bot] Dec 10, 2023
a2b14b5
Bump jackson.version from 2.16.0 to 2.16.1 (#51)
dependabot[bot] Dec 27, 2023
a4bc119
Bump com.squareup.okhttp3:okhttp from 5.0.0-alpha.11 to 5.0.0-alpha.1…
dependabot[bot] Dec 27, 2023
ed3431c
✨ Create classes and update code for the subaccount module (#49)
Doctor-Vee Dec 27, 2023
5a58c34
Cleanup client's spring boot starter, add readme and example
Dec 27, 2023
b2fb478
Merge remote-tracking branch 'origin/develop' into develop
Dec 27, 2023
fbdbfdb
Cleanup client's spring boot starter
Dec 27, 2023
ad66861
Cleanup
Dec 27, 2023
285ff33
Configure jackson serialization to match similar settings used in okhttp
chriseteka Dec 27, 2023
6c2e147
Cleanup
chriseteka Dec 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/maven-action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
restore-keys: ${{ runner.os }}-maven-

- name: Step 3 - Setup JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
Expand Down
7 changes: 6 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
restore-keys: ${{ runner.os }}-maven-

- name: Setup JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
Expand All @@ -47,5 +47,10 @@ jobs:

- name: Publish Client Package
run: mvn versions:set -DnewVersion=${{ github.event.client_payload.version }} versions:commit -pl paystack-clients && mvn -B deploy -pl paystack-clients
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}

- name: Publish Client SpringBoot Starter Package
run: mvn versions:set -DnewVersion=${{ github.event.client_payload.version }} versions:commit -pl paystack-clients-spring-boot-starter && mvn -B deploy -pl paystack-clients-spring-boot-starter
env:
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
74 changes: 63 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,8 @@ The Client comes in 3 flavors:
3. Reactive - Responses in Mono and Flux

## Setup
1. Add the dependency to your project
```xml
<dependency>
<groupId>com.chrisworks.paystackclient</groupId>
<artifactId>paystack-clients</artifactId>
<version>${VERSION}</version>
</dependency>
```
2. Add GitHub Maven Package Repository to your POM

1. Add GitHub Maven Package Repository to your POM
```xml
<repositories>
<repository>
Expand All @@ -29,8 +22,66 @@ The Client comes in 3 flavors:
</repositories>
```

## usage
### 1. When Using SpringBoot
- Add the dependency to your spring boot project:
```xml
<dependency>
<groupId>com.chrisworks.paystackclient</groupId>
<artifactId>paystack-clients-spring-boot-starter</artifactId>
<version>${VERSION}</version>
</dependency>
```

- Add the following property to you `applications.properties` file
```properties
paystack-client.secret-key=INPUT_YOUR_PAYSTACK_SECRET_KEY_HERE
paystack-client.definition-type=(REACTIVE|NON_REACTIVE) #This property is optional, it defaults to 'NON_REACTIVE' if not specified
```

- Usage
```java
// Imports here

import com.chrisworks.paystackclient.definitions.simple.PlanClient; //When using the non-reactive type
import com.chrisworks.paystackclient.definitions.reactive.PlanClient; //When using the reactive type

@Service
class Example {

private final PlanClient planClient;

public Example(PlanClient planClient) {
this.planClient = planClient;
}

public void yourMethodThatDoesAndReturnsSomething() {

//A.
PlanResponse.Single nonReactiveRes = planClient
.createPlan(new CreatePlanRequest("Sample Plan 9", Interval.DAILY,
Amount.actualValue(BigDecimal.valueOf(10_000)).ofCurrency(Currency.NGN)));

//Or B.
Mono<PlanResponse.Single> reactiveRes = planClient
.createPlan(new CreatePlanRequest("Sample Plan 9", Interval.DAILY,
Amount.actualValue(BigDecimal.valueOf(10_000)).ofCurrency(Currency.NGN)));
}
}
```
NB: During injection of the client, you can only inject either the REACTIVE type or the NON_REACTIVE type and never both.
The implementation here is powered by the popular Spring WebClient which is part of the Spring Framework Project Reactor.

### 2. Java/Maven Project without SpringBoot
- Add the dependency to your project
```xml
<dependency>
<groupId>com.chrisworks.paystackclient</groupId>
<artifactId>paystack-clients</artifactId>
<version>${VERSION}</version>
</dependency>
```

- usage
```java
// Imports here

Expand Down Expand Up @@ -82,4 +133,5 @@ class Example {
.executeAsync();
}
}
```
```
NB: The implementation here is powered by the popular OkHttp library.
6 changes: 6 additions & 0 deletions paystack-clients-spring-boot-starter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
<artifactId>paystack-domain</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>3.1.4</version>
<optional>true</optional>
</dependency>
</dependencies>

<repositories>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.chrisworks.paystackclient;

import com.chrisworks.paystackclient.definitions.DefinitionType;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("paystack-client")
public class PaystackClientsProperties {

private String secretKey;
private DefinitionType definitionType = DefinitionType.NON_REACTIVE;

public String getSecretKey() {
return secretKey;
}

public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}

public DefinitionType getDefinitionType() {
return definitionType;
}

public void setDefinitionType(DefinitionType definitionType) {
this.definitionType = definitionType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.chrisworks.paystackclient;

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.lang.NonNull;

import java.util.Objects;
import java.util.Properties;

@Configuration
public class YamlPropertySourceFactory implements PropertySourceFactory {
@NonNull
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource encodedResource) {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(encodedResource.getResource());

Properties properties = factory.getObject();

assert properties != null;
return new PropertiesPropertySource(Objects.requireNonNull(encodedResource.getResource().getFilename()), properties);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.chrisworks.paystackclient.autoconfigure;

import com.chrisworks.paystackclient.PaystackClientsProperties;
import com.chrisworks.paystackclient.YamlPropertySourceFactory;
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

@Configuration
@EnableConfigurationProperties(PaystackClientsProperties.class)
@ConditionalOnProperty(prefix = "paystack-client", name = "secret-key")
@PropertySource(value = "classpath:application-paystack-clients-config.yml", factory = YamlPropertySourceFactory.class)
public class PaystackClientsAutoConfiguration {

/**
* Non Reactive Client configuration
*/
@Configuration
@ConditionalOnProperty(prefix = "paystack-client", name = "definition-type", havingValue = "NON_REACTIVE", matchIfMissing = true)
@AutoConfigurationPackage(basePackages = "com.chrisworks.paystackclient.definitions.simple")
public static class NonReactiveClientConfiguration {}

/**
* Reactive Client configuration
*/
@Configuration
@ConditionalOnProperty(prefix = "paystack-client", name = "definition-type", havingValue = "REACTIVE")
@AutoConfigurationPackage(basePackages = "com.chrisworks.paystackclient.definitions.reactive")
public static class ReactiveClientConfiguration {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.chrisworks.paystackclient.definitions;

public final class Constants {

private Constants() {}

public static final String PLAN_CLIENT = "plan-client";
public static final String APPLE_PAY_CLIENT = "apple-pay-client";
public static final String TRANSACTION_CLIENT = "transaction-client";
public static final String PRODUCT_CLIENT = "product-client";
public static final String SUB_ACCOUNT_CLIENT = "sub-account-client";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.chrisworks.paystackclient.definitions;

public enum DefinitionType {
REACTIVE,
NON_REACTIVE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.chrisworks.paystackclient.definitions.reactive;

import com.chrisworks.paystackclient.domain.applepay.ApplePayRequest;
import com.chrisworks.paystackclient.domain.applepay.ApplePayResponse;
import com.chrisworks.paystackclient.domain.request.QueryParamConstants;
import com.chrisworks.paystackclient.domain.response.EmptyDataResponse;
import com.chrisworks.paystackclient.definitions.Constants;
import com.maciejwalkowiak.spring.http.annotation.HttpClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.DeleteExchange;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.PostExchange;
import reactor.core.publisher.Mono;

@HttpClient(Constants.APPLE_PAY_CLIENT)
public interface ApplePayClient {

@PostExchange
Mono<EmptyDataResponse> register(@RequestBody ApplePayRequest request);

@DeleteExchange
Mono<EmptyDataResponse> unregister(@RequestBody ApplePayRequest request);

@GetExchange
Mono<ApplePayResponse.Multiple> list(
@RequestParam(name = QueryParamConstants.NEXT, required = false) String next,
@RequestParam(name = QueryParamConstants.PREVIOUS, required = false) String previous,
@RequestParam(name = QueryParamConstants.USE_CURSOR, required = false) Boolean useCursor
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.chrisworks.paystackclient.definitions.reactive;

import com.chrisworks.paystackclient.domain.plan.CreatePlanRequest;
import com.chrisworks.paystackclient.domain.plan.PlanResponse;
import com.chrisworks.paystackclient.domain.plan.UpdatePlanRequest;
import com.chrisworks.paystackclient.domain.request.QueryParamConstants;
import com.chrisworks.paystackclient.definitions.Constants;
import com.maciejwalkowiak.spring.http.annotation.HttpClient;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.PostExchange;
import org.springframework.web.service.annotation.PutExchange;
import reactor.core.publisher.Mono;

import java.math.BigInteger;

@HttpClient(Constants.PLAN_CLIENT)
public interface PlanClient {

@PostExchange
Mono<PlanResponse.Single> createPlan(@RequestBody CreatePlanRequest body);

@GetExchange
Mono<PlanResponse.Multiple> listPlans(
@RequestParam(name = QueryParamConstants.PAGE) @NonNull BigInteger page,
@RequestParam(name = QueryParamConstants.PER_PAGE) @NonNull BigInteger perPage,
@RequestParam(name = QueryParamConstants.STATUS, required = false) String status,
@RequestParam(name = QueryParamConstants.INTERVAL, required = false) String interval,
@RequestParam(name = QueryParamConstants.AMOUNT, required = false) String amount
);

@GetExchange("/{idOrCode}")
Mono<PlanResponse.Single> fetchPlan(@PathVariable String idOrCode);

@PutExchange("/{idOrCode}")
Mono<PlanResponse.Single> updatePlan(@PathVariable String idOrCode, @RequestBody UpdatePlanRequest body);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.chrisworks.paystackclient.definitions.reactive;

import com.chrisworks.paystackclient.domain.product.CreateOrUpdateProductRequest;
import com.chrisworks.paystackclient.domain.product.ProductResponse;
import com.chrisworks.paystackclient.domain.request.QueryParamConstants;
import com.chrisworks.paystackclient.definitions.Constants;
import com.maciejwalkowiak.spring.http.annotation.HttpClient;
import org.springframework.lang.NonNull;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.service.annotation.GetExchange;
import org.springframework.web.service.annotation.PostExchange;
import org.springframework.web.service.annotation.PutExchange;
import reactor.core.publisher.Mono;

import java.math.BigInteger;
import java.time.ZonedDateTime;

@HttpClient(Constants.PRODUCT_CLIENT)
public interface ProductClient {

@PostExchange
Mono<ProductResponse.Single> createProduct(@RequestBody CreateOrUpdateProductRequest body);

@GetExchange
Mono<ProductResponse.Multiple> listProducts(
@RequestParam(name = QueryParamConstants.PAGE) @NonNull BigInteger page,
@RequestParam(name = QueryParamConstants.PER_PAGE) @NonNull BigInteger perPage,
@RequestParam(name = QueryParamConstants.FROM, required = false)ZonedDateTime from,
@RequestParam(name = QueryParamConstants.TO, required = false)ZonedDateTime to
);

@GetExchange("/{id}")
Mono<ProductResponse.Single> fetchProduct(@PathVariable String id);

@PutExchange("/{id}")
Mono<ProductResponse.Multiple> updateProduct(@PathVariable String id);
}
Loading