Handling Paystack transactions using webhooks
Published: 2023-04-17 08:09:03

[Paystack](https://paystack.com/) is a popular payment processing platform used by businesses and individuals in Nigeria and other African countries. One of the key features of Paystack is its ability to process transactions using webhooks. Webhooks are HTTP callbacks that enable the automatic transfer of transaction data from Paystack to your application in real-time. Webhooks are useful for a variety of reasons. They can automate tasks and streamline workflows by eliminating the need for manual intervention. For example, when a customer places an order on an e-commerce website, a webhook can trigger an automated process that sends a confirmation email to the customer, updates the inventory system, and notifies the shipping department to prepare the order for delivery.

Overall, webhooks are a flexible and powerful way to enable real-time communication and automation between web applications, making them a valuable tool for developers and businesses alike.

In this article, we will explore how to implement Paystack transactions using webhooks with TypeScript. We will cover the steps involved in setting up the Paystack API, creating a webhook endpoint, handling Paystack webhook events, and testing the webhook integration.


### Setting up the Paystack API
To use the Paystack API, you will need to create a Paystack account and obtain the API keys needed for transaction processing. 

Here are the steps involved:

- **Create a Paystack account**: Go to https://dashboard.paystack.com/#/signup and follow the instructions to create an account. After getting access to the dashboard, on the left-hand navigation bar, you click on settings.

<img width="90%" alt="Screenshot 2023-04-16 at 17 06 37" src="https://user-images.githubusercontent.com/47679952/232330124-e323d039-a6e5-4a8b-9987-5e86a5f377fd.png">

- **Obtain the API keys**: Go to the API section of your dashboard and copy the secret and public keys.

<img width="90%" alt="Screenshot 2023-04-16 at 17 08 01" src="https://user-images.githubusercontent.com/47679952/232330173-7a5e02dd-1536-4595-9ddf-c4f2cfb14e10.png">

You can use the Paystack API to initiate transactions by sending a POST request to the API endpoint with the necessary transaction details. Here is an example of how to initiate a transaction in TypeScript:

```typescript
import axios from 'axios';

const API_SECRET_KEY = 'yoursecretkey';//Test Secret Key for Test mode on

const transactionDetails = {
  email: 'customer@email.com',
  amount: 10000,
  metadata: {
    custom_fields: [
      {
        display_name: "Customer's name",
        variable_name: "customer_name",
        value: "John Doe"
      }
    ]
  }
};

axios.post('https://api.paystack.co/transaction/initialize', transactionDetails, {
  headers: {
    Authorization: `Bearer ${API_SECRET_KEY}`
  }
})
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.log(error);
  });

```
**NOTES:**
- `amount: 10000`, Paystack divides the amount by 100 to have value for kobo which sets the current amount to 100 in naira.
- In transactionDetails, metadata value don't necessarily have to be set.
```bash
{
  status: true,
  message: 'Authorization URL created',
  data: {
    authorization_url: 'https://checkout.paystack.com/tqvqyiwxlxm54cg',
    access_code: 'tqvqyiwxlxm54cg',
    reference: 'xrmihwxzv9'
  }
}
```
Let's breakdown the response from the Paystack API after initiating a transaction:

`status`: A boolean value indicating whether the request was successful (true) or not (false)

`message`: A message indicating the result of the request. In this case, the message is 'Authorization URL created', which means that the Paystack API was able to create an authorization URL for the transaction.

`data`: An object containing the data returned by the Paystack API. In this case, the data object contains three properties:

`authorization_url`: The URL that the user should be redirected to in order to authorize the transaction.

`access_code`: A code that is used to authorize the transaction.

`reference`: A unique reference code that identifies the transaction.

On following the authorization url, you redirected to a similar webpage like the one below where you can simulate different transaction scenarios.

<img width="700" alt="Screenshot 2023-04-16 at 17 50 59" src="https://user-images.githubusercontent.com/47679952/232330201-2a5092e3-6568-4faf-a764-5279b12a2c2c.png">

<img width="700" alt="Screenshot 2023-04-16 at 17 51 15" src="https://user-images.githubusercontent.com/47679952/232330226-b34ebbf0-c6f3-4923-9aa1-529101b39c22.png">

### Setting up the webhook endpoint
To receive and process transaction data from Paystack in real-time, you will need to set up a webhook endpoint. Here are the steps involved:

- **Create a webhook endpoint**: You can create a webhook endpoint using an HTTP framework like Express. Here is an example of how to create a webhook endpoint in TypeScript:

```typescript
import express from 'express';
import { json } from 'body-parser';

const app = express();

app.use(json());

app.post('/paystack/webhook', (req, res) => {
  const eventData = req.body;
  console.log(eventData);
  res.sendStatus(200);
});

app.listen(3000, () => {
  console.log('Webhook server started on port 3000');
});
```

- **Register the webhook endpoint with Paystack**: Go to the Webhooks section of your Paystack dashboard and add your webhook URL. Paystack will send transaction data to this URL whenever a transaction event occurs.

  To receive webhook events from Paystack, your endpoint needs to be accessible from the internet. Paystack does not allow to register localhost as webhook URL, however you can expose your local enpoint to the internet. One way to achieve this in a local development environment is to use a tool like [ngrok](https://ngrok.com/), which exposes your local endpoint to a public URL that can be accessed from the internet.
  Here is how to use ngrok to expose your local endpoint:

  - [Download](https://ngrok.com/download) and install ngrok from the official website.
  - Start ngrok by running the command ngrok http 3000 (replace 3000 with the port number of your local endpoint).
  - Ngrok will generate a public URL that you can use as your webhook endpoint in the Paystack dashboard.

### Handling the Paystack webhook events
Paystack sends different types of webhook events to your webhook endpoint, depending on the status of the transaction. Here are the steps involved in handling Paystack webhook events in TypeScript:

- **Verify the webhook event**: Paystack sends a signature with each webhook event that you can use to verify the authenticity of the event. Here is how to verify the signature:

```typescript
import crypto from 'crypto';

const API_SECRET_KEY = 'yoursecretkey';

function verify(eventData: any, signature: string): boolean {
    const hmac = crypto.createHmac('sha512', API_SECRET_KEY);
    const expectedSignature = hmac.update(JSON.stringify(eventData)).digest('hex');
    return expectedSignature === signature;
}
```

- **Handle the webhook event**: Once you have verified the signature, you can process the webhook event based on the event type. Here is how to handle a successful transaction event:

```typescript
app.post('/paystack/webhook', (req, res) => {
  const eventData = req.body;
  const signature = req.headers['x-paystack-signature'];

  if (!verify(eventData, signature)) {
    return res.sendStatus(400);
  }

  if (eventData.event === 'charge.success') {
    const transactionId = eventData.data.id;
    // Process the successful transaction to maybe fund wallet and update your WalletModel
    console.log(`Transaction ${transactionId} was successful`);
  }

  return res.sendStatus(200);
});
```


### Testing the webhook integration
To test your webhook integration, you can use the Paystack Test Mode to simulate different transaction scenarios. Here are the steps involved:

- **Switch to Test Mode**: Go to your Paystack dashboard and switch to Test Mode.
- **Initiate a test transaction**: Use the Paystack API to initiate a test transaction with the necessary test parameters.
- **Check the webhook response**: Once the test transaction is complete, check the webhook response to ensure that the transaction data was received and processed correctly.

To test your webhook processing logic thoroughly, you can simulate different webhook events by sending different test parameters to the Paystack API. For example, you can simulate a failed transaction, a disputed transaction, or a successful refund.

By following these steps, you can thoroughly test your Paystack webhook integration in a local development environment and ensure that your application can handle real-time transactions correctly

### Conclusion
In this article, we explored how to implement Paystack transactions using webhooks with TypeScript. We covered the steps involved in setting up the Paystack API, creating a webhook endpoint, handling Paystack webhook events, and testing the webhook integration. By following these steps, you can easily integrate Paystack transactions into your TypeScript application and process transactions in real-time.

Further reading: [Paystack API documentation](https://paystack.com/docs/api), [ngrok docs](https://ngrok.com/docs)