Build Stripe Refund App: issue refunds and send notifications
Tags: beginners, webdev, tutorial, showdev
Published: 2022-05-23 14:40:32

> In this tutorial, We will build a Stripe Refund Application for looking up all customers' data, all payments, issuing refunds to customers and sending them confirmation email/sms notifications.

The Stripe refund application will allow you to go through all the customers, payments, and issue and check refunds within a single dashboard. You will be able to send email/SMS notifications to your customers directly from the dashboard.

Check the application in action here: https://app.tooljet.com/applications/stripe-refund-tool

## Prerequisites
- **ToolJet** (https://github.com/ToolJet/ToolJet): A free and open-source low-code platform that allows you to quickly build applications. Sign up [here](https://tooljet.com/).
- **Stripe**: For Stripe, it's recommended to use the active account or if you're just getting started with Stripe then you can use it in **Test Mode**. For this tutorial, I have used the Stripe account in Test mode.
- **SendGrid/Twilio**: For implementing the send SMS or email feature you'll need to have a Twilio or SendGrid account. In this tutorial, I have used Twilio for sending SMS notifications.

Let's take a look at the UI of the application:
![UI](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-11-at-3.51.18-PM.png)

**The tutorial is divided into the following parts:**
- **Build the app UI**
- **Create the queries**
- **Edit widgets and connect queries**

---
Let's jump right into the ToolJet and click on **Create new application** button on the top-right corner of the dashboard. Once entered the app editor, you'll be asked to create a version - enter a version name and click **Create**.

Let me give you a quick walkthrough of the **ToolJet app editor**:

![app-editor](https://blog.tooljet.com/content/images/size/w1600/2022/03/Screenshot-2022-03-25-at-4.02.40-PM.png)

> 💡 Need help with building your own application or just want to hang out in the community of low-code application builders? Feel free to join our [Slack community](https://join.slack.com/t/tooljet/shared_invite/zt-r2neyfcw-KD1COL6t2kgVTlTtAV5rtg) 🚀

---

## Build the app UI
Let's get straight into building the user interface of our application. The UI will consist of the following sections:

### Header
For building the header I have used the image widget, and two text widgets with different font sizes.

- Drag the **image** widget to the top left corner of the canvas, and click on the handle to open properties in the right sidebar. In the **URL** field, enter the URL of the image or logo that you want to display. You can adjust the height and width of the image according to your choice.
- The first **text** widget includes the text **Refund Tool** and to make it look like a heading I have wrapped it inside the HTML &lt;h2>&lt;/h2> tags. Yes, you can use HTML inside text widgets!!!
- The second **text** widget includes a short description of the application.

![Header](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-18-at-12.56.15-AM.png)

## Payments
For building this section, we will use the containers, text, listview, and inside list view, we will use button and text.

- Let's drag a **container**, scale it to its full width on the canvas, and set the height as shown in the image. You can edit its properties to change the background color or change the border radius of the container.
- Drag a **text** widget inside the container and place it on the top left. Edit its properties and enter the text as **Payments** and wrap it in HTML &lt;h2> tags.
- Now drag a **containers** within the container, scale its width the same as the parent container and height should be just enough to place text widgets inside it. We'll make this container look like a row that will have column titles. You can also change the color of the container according to your choice.
- Let's **drag** text widgets inside the child container and use HTML <b> tags to bold the font in the text widget. The quickest method to do this is just to drag one text widget edit its properties and then use **cmnd/ctrl+d to duplicate** that widget 5 times and then change the text of duplicate widgets.
- Finally, drag a **list view** widget inside the container and place it below the child container. We'll edit the list view later in the tutorial once we have added our data in the list view.

![payments](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-18-at-12.56.15-AM-copy.png)

### Customers
For this section, we will be using the container, text, and a table widget.

- Drag the **container** and place it as shown in the image. You can edit its properties to change the background color or change the border radius of the container.
- Drag a **text** widget inside the container and place it on the top left. Edit its properties and enter the text as **Customers** and wrap it in HTML &lt;h2> tags.
- Finally, drag a **table** widget inside the container and place it accordingly.

![customer](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-18-at-12.56.15-AM-copy-2.png)

### Refund Notification

For this section, we will use the text, text area, and button widgets.

- Drag a **text** widget and use the HTML tag to add a title **Refund Notification** to this section as we did in the last two sections.
- Add another text widget to display a short description of the section below the Title. This is not mandatory.
- Now, whenever a customer will be selected on the table their customer ID, Name, Email, and contact will be displayed in this section. To do this we will use a **text** widget and use the table's `selectedRow` variable. Since we haven't added any data to the table yet. So, let's add a text widget inside the container and enter: **`<b>Customer ID:<b> Random ID <br><b>Customer Name:<b>  Random Name <br><b>Email:<b>  abc@xyz.com <br><b>Contact:<b> +91-9834856044 <br>`**
- Drag a **text area** inside the container that will be used to frame the message to send to the customers. 
- Drag a **button** that will be used to trigger the Send SMS or Email query that we will create later. Click on the handle to edit its properties to change the button text, color, and border-radius.

![Refund Notification](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-18-at-12.56.15-AM-copy-3.png)

### Check Refunds

This section will be triggered through a button and will include a modal, and a table widget.

- Drag a **modal** somewhere below in the canvas (empty space below the Customers and Refund Notification section).
- Drag a **button** on the top right of the canvas. Edit its properties - change the button text to **Check Refunds**, change button color and border-radius. Go to the **Events**, add a handler for the **On-click** event to perform **Show modal** action, and select the **modal1** in the dropdown. This will show up in the modal every time the button is clicked.
- Click on the button to show up the modal. Once the modal shows up, you can drag and drop widgets from the right sidebar to the modal. Drag a **table** widget inside the modal, and change the modal title to **Recent Refunds**.

![refunds](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-18-at-12.57.18-AM.png)

---

## Create the queries

Now that we have built the UI, we need to build the queries for getting the data. But before creating queries we need to add the data sources to the application in ToolJet. We will be using:

### Twilio

This data source will be used to send the SMS to the selected customer. You need to have a paid Twilio account if you want to send SMS to unregistered customers, if you're using a free account then you'll have to register the number in your Twilio dashboard before sending SMS. For connecting data source, you'll require:

- **Auth token & Account SID**: You can find your Account SID and Auth Token under the "API Credentials" in your Twilio account settings dashboard.
- **Messaging service SID**: Create a messaging service from the Service tab under Messaging in the left sidebar to get the Messaging service SID.

### Stripe

As mentioned earlier, you'll need to have an active Stripe account and if you don't have one then you can create a new one to use the Stripe app in Test mode. Once enabled in the Test mode, you can get the Secret key from the Developers tab. Click on the reveal secret key, copy it, and then paste it into the ToolJet.

![stripe](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-18-at-11.55.38-PM.png)

---

Now once you have successfully added the data sources, you can go to the query panel at the bottom of the editor and click on the + button to create a new query. We will be building the following queries:

![queries](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-19-at-12.35.52-AM.png)

### allRefunds
This query will return a list of all refunds you’ve previously created. The query will return a dictionary with a `data` property that contains an array all refunds.

- Create a new query and select the **Stripe** data source.
- Select `get,/v1/refunds` from the **Operation's** dropdown.
- Leave all other query parameters blank as we won't need any filtering in the data returned by the query.
- Toggle on the **Transformations** and enter `return data.data;`
- Rename the query to **allRefunds** in the field next to the Preview button and click **Save**.

Check Stripe's doc for this query [here](https://stripe.com/docs/api/refunds/list).

![allrefunds](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-19-at-1.33.59-AM.png)

### listCustomers
This query will get the list of all the customers and their details from Stripe. The query will return an object with a `data` property that contains an array of customers.

- Create a new query and select the **Stripe** data source.
- Select `get,/v1/customers` from the **Operation's** dropdown.
- Go to the **Advanced** tab, and add an **event handler**. Select **Run Query** action for **Query Success** event, and choose **allRefunds** query from the query dropdown. This will fire up the allRefunds query(list of refunds) every time whenever this query is successful.
- Rename the query to **listCustomers** in the field next to the Preview button and click **Save**.

Check Stripe's doc for this query [here](https://stripe.com/docs/api/customers/list).

![listCustomers](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-19-at-12.47.46-AM.png)

### charges
This query will return a list of all charges(payments). The query will return an object with a data property that contains an array of charges.

- Create a new query and select the **Stripe** data source.
- Select `get,/v1/charges` from the **Operation's** dropdown.
- Leave all other query parameters blank as we won't need any filtering in the data returned by the query.
- Toggle on the **Transformations** and enter `return data.data;`
- Go to the **Advanced** tab, and add an **event handler**. Select **Run Query** action for Query Success event, and choose listCustomers query from the query dropdown. This will fire up the listCustomers(list of customers) query whenever this query is successful.
- Rename the query to **charges** in the field next to the Preview button and click **Save**.

Check Stripe's doc for this query [here](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-19-at-1.24.50-AM.png).

![charges](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-19-at-1.24.50-AM.png)

### processRefund
This query will create a new refund for the particular Charge/PaymentIntent specified in the query. This query will return the `Refund` object if the refund succeeded, and will return [an error](https://stripe.com/docs/api/refunds/create#errors) if the Charge/PaymentIntent has already been refunded, or if an invalid identifier was provided.

- Create a new query and select the **Stripe** data source.
- Select `post,/v1/refunds` from the **Operation's** dropdown.
- For this query the **charge** or **payment_intent** parameter is required to identify the payment, we will leave the fields empty for now.
- Go to the **Advanced** tab, and add an **event handler**. Select **Run Query** action for **Query Success** event, and choose charges query from the query dropdown. This will reload the **charges** query everytime a refund will be processed and the list of **Payments** will get refreshed.
- Rename the query to **processRefund** in the field next to the Preview button and click **Save**.

Check Stripe's doc for this query [here](https://stripe.com/docs/api/refunds/create).

![processRefund](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-19-at-1.41.55-AM.png)

### sendSMS
This query will send the SMS to the number provided in query parameters with the body provided.

- Create a new query and select the **Twilio** data source.
- Select **Send SMS** from the **Operation's** dropdown.
- We will use the table's `selectedRow` property to get the phone number of the customer selected in the table. Enter `{{components.table1.selectedRow.phone}}` in the **To Number** field.
- Since we have used a **text area** widget in the Refund Notification section of the UI for entering a message we will be using the value provided in the text area widget as the body for SMS. To do this, enter `{{components.textarea1.value}}` in the **Body** field.
- Go to the **Advanced** tab, and select add an **event handler**. Select **Show Alert** action for **Query Success** event, add a **Message** and choose **Alert type** as success. This will show a notification whenever a message is sent to a customer.
- Rename the query to **sendSMS** in the field next to the Preview button and click **Save**.

![sendsms](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-21-at-5.43.43-PM.png)

---

## Edit widgets and connect queries

Finally, we have come to the last section of the tutorial. We built the UI, then created the queries, and now we will be connecting both of them. Let's go from top to bottom in the UI to connect the queries:

### Check Refunds

- Click on the **Check Refunds button** to open up the **modal** that has table to display all the refunds.
- When the modal is open, click on the handle of the **table** to open its properties on the right sidebar.
- In the table data field, we will get the data from the **allRefunds** query using: `{{queries.allRefunds.data}}` (You'll see all the data from the query in a green box below the field)
- Now you can go to the columns section to add the columns that you want to display in Recent Refunds table. While adding the columns make sure that the key for columns is same as returned in the query data.

![uicheckrefunds](https://blog.tooljet.com/content/images/size/w1600/2022/05/Screenshot-2022-05-21-at-8.27.56-PM.png)

### Payments
- Click the handle of the **list view** widget to open its properties and the add the data to list view from the **charges** query.
  ![Screenshot-2022-05-21-at-8.55.01-PM](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-21-at-8.55.01-PM.png)
- Once we have added the data to the list view widget, it's time to add widgets in the first row of the list view.
  - Drag a button below the **Action** and the click on the handle to edit its properties. You can change the color and border radius of the button. Add a **event handler** to button to run the **processRefund** query for **On Click** event.
  ![Screenshot-2022-05-21-at-9.01.40-PM](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-21-at-9.01.40-PM.png)
  - Similarly, add the **text widgets** below the **Customer ID, Transaction ID, Amount, Transaction Date, and Status**. For the text widgets under each column use the following values respectively: `{{{{listItem.customer}}}}`,`{{{{listItem.id}}}}`,`{{{{listItem.id}}}}`,`{{listItem.amount/100}}`,`{{moment.unix(listItem.created).format("DD/MM/YYYY")}}` (the date returned by Stripe query is in Unix format so we used Moment.js library to convert it into the give format), `{{listItem.status}}`
  ![Screenshot-2022-05-21-at-9.10.39-PM](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-21-at-9.10.39-PM.png)
- Once done, all the rows will be populated will the data.

### Customers

- Go to the **Customers** container, click on the handle of the **table** and edit it properties.
- In the **table data** field, set the value to `{{queries.listCustomers.data.data}}` . You'll see the all the data in the green box below the field.
- Now add the columns that you want to display in the table. I have added the **Customer ID, Customer, Email, and Contact**. Make sure to add the correct key while adding column.
- Go to the **Options**, and enable the **highlight selected row** option.

![uicustomer](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-21-at-9.13.29-PM.png)

### Refund Notification
Now for refund notification all we need to do is just add a event handler to the button. 

- Click on the handle of the **Send SMS** button to open the properties
- Now **add a handler** to run the **twilio1** query for **On Click** event.

![uisendsms](https://blog.tooljet.com/content/images/2022/05/Screenshot-2022-05-21-at-9.20.32-PM.png)

And now FINALLY just go ahead and **Release** your application from the top right corner. 

You have successfully created an application for issuing refunds directly to your customer using Stripe and Twilio data source in ToolJet. 🎉

---

If you have any queries related to building applications with ToolJet or just want to hangout in the community of low-code application developers the just drop us a Hi in our [Slack Communiy](https://join.slack.com/t/tooljet/shared_invite/zt-r2neyfcw-KD1COL6t2kgVTlTtAV5rtg). 🚀