Consuming a Paystack API using Spring RestTemplate

Last week, I wrote about building a simple Rest Service using Spring Boot. I explained what Spring Boot is and also how to create a Spring Boot Project.

In this article, I will explain how to work with external APIs using Rest Template. I will integrate with Paystack which is a payment gateway, I will show how to initialize a payment transaction and generate a payment URL.

To begin with, I will explain the Paystack Payment Flow, the steps are

  • Register to get an API Key. Its usually of the format “sk_test_xxxxxxxxxxxxxxxxxxxxxxx”
  • Initialize a transaction to generate a payment Url
  • Verify the transaction

Project Setup

I use Spring Initialzr to generate the spring boot project and populate the dependencies.

 

Importing the Project

Initializing a Paystack Transaction

To initialize a Paystack transaction, a post request is sent to the Paystack API then, a payment URL is generated which the payer can use to pay for a product or service.

When using Rest Template to consume an external API, we need to properly model the request and response object of the external API, all the fields and data types have to be the same.

Below is the request expected to be sent to the Paystack API to initialize a transaction

This project is split into four sections:

  • Enums
  • DTO
  • Service
  • Controller

 

1. Enums

A Java Enum is a special Java type used to define collections of constants. Some Enums such as “Channel” and “PaystackBearer” are part of the request object so we have to create them

Channels
public enum Channels 
{ CARD,
 BANK; 
}

PaystackBearer
public enum PaystackBearer

{ ACCOUNT,

SUBACCOUNT;

}


2. DTO

The Data Transfer Object (DTO) is like a data structure. We model our Request and Response Object using the DTO.

InitializeTransactionRequestDTO

The IntitializeTrasactionRequestDTO Class models the Request Object

 

 
public class InitializeTransactionRequestDTO
 {
private String amount;
private String email;
private String reference;
private String callback_url;
private Integer invoice_limit;
private Channels[] channels;
private String subaccount;
private Integer transaction_charge;
// @Enumerated(EnumType.STRING)
 private PaystackBearer
 paystackBearer
 = PaystackBearer.ACCOUNT;
public String getAmount()
 { return amount; }
public void setAmount
(String amount)
 { this.amount = amount; }
public String getEmail()
 { return email; }
public void setEmail(String email)
 { this.email = email; }
public String getReference()
 { return reference; }
public void setReference
(String reference)
 { this.reference = reference; }
public String getCallback_url() 
{ return callback_url; }
public void setCallback_url
(String callback_url)
 { this.callback_url = 
callback_url; }
public Integer getInvoice_limit()
 { return invoice_limit; }
public void setInvoice_limit
(Integer invoice_limit)
 { this.invoice_limit = 
invoice_limit; }
public Channels[] getChannels()
 { return channels; }
public void setChannels
(Channels[] channels)
 { this.channels = channels; }
public String getSubaccount()
 { return subaccount; }
public void setSubaccount
(String subaccount)
 { this.subaccount = subaccount; }
public Integer 
getTransaction_charge()
 { return transaction_charge; }
public void setTransaction_charge
(Integer transaction_charge){ 
this.transaction_charge =
 transaction_charge;}
public PaystackBearer 
getPaystackBearer(){ 
return paystackBearer; }
public void setPaystackBearer
(PaystackBearer paystackBearer)
 { this.paystackBearer = 
paystackBearer; }
}

We also have to model the response object. To do that, we need to create a Data object which is part of the response object.

Data
public class Data
{
private String authorization_url;
private String access_code;
private String reference;
public String 
getAuthorization_url(){
 return authorization_url; 
}
public void setAuthorization_url
(String authorization_url) {
 this.authorization_url =
 authorization_url; 
}
public String getAccess_code()
 { return access_code;
 }
public void setAccess_code
(String access_code){
 this.access_code = access_code; 
}
public String getReference() 
{ return reference; }
public void setReference
(String reference){ 
this.reference = reference; }
}
InitializeTransactionResponseDTO

The IntitializeTrasactionResponseDTO Class is used to model the Request Object

public class InitializeTransactionResponseDTO
{
private String status;
private String message;
private Data data;
public String getStatus() 
{ return status; }
public void setStatus
(String status) { 
this.status = status; }
public String getMessage()
 { return message; }
public void setMessage
(String message){ 
this.message = message; }
public Data getData() 
{ return data; }
public void setData(Data data)
 { this.data = data; }
}

3. Service

The Service implementation is where all of the implementations are done. The Service exposes methods that will be called from the controller. The @Service annotation is used to mark the class as a service provider.

Since we have the request and response accurately modeled, we will call the initialize transaction API. We also have to pass the Bearer test secret key as a header with key ‘authorization’ and the content type which is JSON.

Initialize Transaction Service Implementation
@Service
public class InitializeTransactionServiceImpl
implements 
InitializeTransactionService
{ RestTemplate restTemplate = 
new RestTemplate();
@Override
public 
InitializeTransactionResponseDTO 
initializeTransaction 
(InitializeTransactionRequestDTO 
initializeTransactionRequestDTO){
String url = "https://api.
paystack.co/transaction/
initialize";
HttpHeaders headers = 
new HttpHeaders();
String key = 
"sk_test_b2ffbedf2d7b2cf1022923
5415ba2dac551c684e";
 headers.setContentType
(MediaType.APPLICATION_JSON);
headers.set("Authorization",
 "Bearer " + key);
HttpEntity 
<InitializeTransactionRequestDTO>
entity = new HttpEntity
<InitializeTransactionRequestDTO>
(initializeTransactionRequestDTO,
 headers);
 ResponseEntity
<InitializeTransactionResponseDTO>
 response = 
restTemplate.postForEntity
(url, entity,
 InitializeTransactionResponseDTO.
class);
 return response.getBody(); 
} }

The URL represents the API URL, the headers represent the headers expected to be sent to the API while the restTemplate postForEntity is used to execute a POST request and return a ResponseEntity which contains the status code as well as the resource as an object.

Initialize Transaction Service
public interface 
InitializeTransactionService{ 
InitializeTransactionResponseDTO 
initializeTransaction (
InitializeTransactionRequestDTO 
initializeTransactionRequestDTO
); }

 

4. Controller

Different methods are defined in the controller, these methods will be called by different endpoints. The @RestController annotation is a convenience annotation for creating restful controllers.

Initialize Transaction Controller
@RestController 
@RequestMapping("/v1")
 public class 
InitializeTransactionController { 
@Autowired 
private 
InitializeTransactionService
initializeTransactionService;
@RequestMapping(
path = "/initializetransaction",
method = RequestMethod.POST)
public 
InitializeTransactionResponseDTO
initializeTransaction( 
@RequestBody 
InitializeTransactionRequestDTO
initializeTransactionRequestDTO)
{ 
InitializeTransactionResponseDTO
initializeTransaction = 
initializeTransactionService.
initializeTransaction
(initializeTransactionRequestDTO);
return initializeTransaction; } }

 

Testing the Endpoint

Postman is used for testing the endpoints defined above. The project will be using the default localhost port; 8080.

Let’s start the application by running the main class 

PaystackDemoApplication.java

The expected output looks like this;

application

 

Test Case

Initialize a Transaction

Steps:

  • Open Postman
  • Set Request Type as POST
  • Set Url = http://localhost:8080
  • /v1/initializetransaction
  • Set Request Header = Content-Type:application/json and ‘Authorization: Bearer sk_test_b2ff*************************’
  • Set the Body as {“amount”: “20000”, “email”:”moyin@gmail.com”}.Those are the two compulsory fields, the rest are optional
  • Click Send. In the response, we will get the status, message, and the data object which contains the payment URL

 

Conclusion

In this tutorial, we’ve covered consuming an external REST API using Rest Template. We worked with the Paystack Initialize Transaction API to initialize a transaction and generate a payment URL. The next step would be to verify the payment has paid and apply value to the payment.

Feel free to play around with the code and experiment! Reach out to me on Twitter if you have any questions

No Comments

Post A Comment