Introduction
Businesses that need to accept in-person credit card payments from their custom Point of Sale (POS) applications are responsible for keeping their customers’ payment information secure and meeting lengthy Payment Card Industry (PCI) regulations—unless they use a Semi-Integrated payment solution.
With a Semi-Integrated (SI) solution, the credit card terminal communicates sensitive transaction information directly to the payment processor, keeping that data out of the business’s systems. This shifts most of the responsibility of PCI compliance away from your POS application and the merchant’s environment, and onto the payment provider.
In Part 1 of this article, you’ll learn how to build a simple POS app, and Part 2 will explain how to add credit card payment functionality to it using the C#/.NET PAX SI SDK.
Prerequisites
- Review the North Developer Integration Guide and follow the instructions in the Setup section.
- Install Visual Studio Community or use your preferred IDE with support for C#/.NET projects. VS Community will be used for this tutorial.
- Create a new VS Community project. Select the “Windows Forms App (.NET Framework)” template. This tutorial assumes little or no prior knowledge, so using this template makes it quick and easy to create a simple POS UI for instructional purposes. Install the POSLink.dll provided in PAX’s POSLink .NET package.
Building a Simple Point of Sale Application
This tutorial will explain each step in detail, both in the article text and the code comments. Because the app in this tutorial is for educational purposes, the code may not be as minimized as possible so that all aspects of each step are clearly illustrated.
The POS will have two pages:
- Order Summaries: This is the default page that will be displayed when the application is started. It will display a list of all orders with high-level information about each record, including the order number, the employee assigned to the order, the table number, the order total, and the order status (eg., Open, Refunded, Voided, etc.). It will also provide buttons to create a new order and submit the current batch of orders to the processor for settlement and funding.

- Order Details: This page will be displayed when the user clicks on an existing record in the Order Summaries list or the “Start New Order” button is clicked. The Order Details page will display information about the selected order or the new order, and provide buttons to add items to the order and perform a variety of payment functions.
The payment buttons will be created in this part of the tutorial, and payment functionality will be added in Part 2.

Get in Touch
Talk to us about using the PAX SDK to accept in-person payments with your Point of Sale application.
Creating the Class Files
Form1
Form2
FormProvider
The FormProvider static class will be used to implement a version of the Singleton Design Pattern so that only one instance of each Form class can be created when the app is running, while providing a simple method of accessing that instance.
Add a new class file named “FormProvider.cs” (or any meaningful name of your choice) to the project, and add the following code to it.
The Form1 object will be named OrderSummaries, and the Form2 object will be named OrderDetail. In the Solution Explorer, open Program.cs and update the Application.Run method to the following:
Setting Up a Flat-File Database
In real contexts, each business’s database will be setup differently, so this tutorial will use a CSV in place of a database for simplicity, with the expectation that in real-world scenarios, each business will connect their own secure database based on their specific business requirements.
In the Solution Explorer, locate your project, right click, select Add, then New Folder. Name the new folder App_Data. Right click on the App_Data folder, select Add New Item, then name the file orders.csv. Open orders.csv and insert the following in the first row.
These are the column headers, or data attributes, for your flat-file database. They indicate the types of data that the app will be writing and reading for each record.
POS Page 1: Order Summaries
If the Design View of Form1.cs is displayed by default (tab name is “Form1.cs [Design]”), use the Solution Explorer to locate Form1.cs, right click, and select “View Code” to view the Form1 code.
At the beginning of the file, add the following Using statements to access the required .NET namespaces. If your environment is missing any, select Project from the top menu, then Manage NuGet Packages, search for the necessary package, and install.
Within the Form1 class definition that’s provided by default, add the code below to initialize class-level variables.
Accessing the Database
Within the Form1 class definition, add the following method to access the orders.csv file.
Next, add the function below to parse the CSV data.
Displaying Order Summaries
On the OrderSummaries page, two tables will display a summary of each order.
- One table will include open orders, or orders with payments that have only been authorized.
- The other table will include closed orders, or orders with payments that have been authorized and a subsequent action has also been performed, such as a void, capture, refund, etc.
To add the graphical table elements to the page, in the Solution Explorer right click on Form1.cs, and select View Designer. In the top navigation menu, select View, then Toolbox. In the Toolbox panel, select DataGridView, drag it onto Form1, and if prompted to add a data source, click on the background of the form to hide the prompt window because a data source won’t be added at this time. In the Properties panel, you can see that the DataGridView object was given a default name dataGridView1. From the Toolbox, select TextBox, drag it onto Form1 directly above dataGridView1, and in the Properties panel, update the Text property to “Open Orders”. You can see that the TextBox object was given a default name textBox1.
Follow the process described in the previous paragraph again, and place the second DataGridView and TextBox objects to the right of the first ones. Update the TextBox’s Text property to “Closed Orders”.
Navigate back to the Code View of Form1.cs and below the parseCsv method, add the following code.
The updateOrders method populates each of the DataGridView tables with the current data from the database.
Creating a New Order
In addition to displaying order information, the OrderSummaries page will include a “Start New Order” button that generates a new, empty record in the database and opens the OrderDetails page, where users can add items to the order.
Open Form1.cs in Design View, and from the Toolbox, drag a Button onto the page in any location you choose. Update the button’s Text property to “Start New Order”. Double click on the button, and a new method will be added automatically in Code View. Rename the method newOrderButtonClick and leave the default definition for now.
After the newOrderButtonClick method, add the following code.
The createNewOrder method adds a new, empty record to the database, generates a new order number by incrementing the previous order number by 1, calls updateOrders to refresh the data displayed in the DataGridView tables, and returns the new order number.
Add the following code to the newOrderButtonClick method definition that was created previously.
When the “Start New Order” button is clicked, the createNewOrder method is called, and the new order number that’s returned is used in a linq query to select that record from the database and create a new DataView with that record’s data. The DataView is passed to the OrderDetail instance of the Form2 class, OrderDetail is displayed, and OrderSummaries is hidden.
Displaying a Selected Order
Clicking an existing order on the OrderSummaries page will open the OrderDetails page and display all data for that order. To add this functionality, place the following code below the newOrderButtonClick method definition.
In the Design View of Form1.cs, double-click on dataGridView1 to generate a new method definition in Code View named dataGridView1_CellContentClick. Do the same for dataGridView2. Add the following code to each, changing dataGridView1 to dataGridView2 in that definition.
Adding a Batch Close Button
The last functionality that the OrderSummaries page will handle is closing a batch of transactions. In Design View, drag a new Button from the Toolbox onto the UI near the “Start New Order” button and update the Text property to “Close Batch”. Double-click it to generate a new method definition in Code View and leave the default definition for now.
POS Page 2: Order Details
At the beginning of the file, add the following Using statements to access the required .NET namespaces. If your environment is missing any, select Project from the top menu, then Manage NuGet Packages, search for the necessary package, and install.
Within the Form2 class definition that’s provided by default, add the following code to initialize class-level variables.
Setting Up the UI
On the OrderDetails page, all information related to a record will be displayed, and users will be able to add items to the order and perform various payment functions. To organize this functionality, the left half of the page will display information about the order and the right half will include the buttons to add items and perform payment functions.
Open Form2.cs in Design View and drag and drop tools from the Toolbox onto the UI to build a page with the following elements. Tool suggestions and the corresponding names that are used in this tutorial are shown in red text below. After adding the buttons to the UI, double-click each to generate a new method definition in Code View and leave the default definitions for now.


Reading and Writing Order Details
Open Form2.cs in Code View and below the class-level variables, add the following method definition. When called, this method will display the selected order’s data in the TextBoxes on the UI.
Next, add the following method to edit database records. It accepts three parameters:
- The updated text that will replace the existing text
- The name of the database file
- The index of the database record that will be edited
The editRecord method will be called in the next method, updateDb.
Next, add a method to update the order details on the UI. For this tutorial, the logic to update the order on the UI and update the database are separate.
The next methods are used to add and remove items from the itemDictionary. They accept two parameters:
- Item name
- Item cost
In the addItem method, if itemDictionary already includes the item to be added, only the cost will be updated. In the removeItem method, if itemDictionary doesn’t include the item to be removed, the method is exited without taking any action.
Notice that once an item is added, the authId is displayed on the UI, indicating that a payment method can now be performed on the order.
For each of the buttons that add or remove items on an order, add the relevant call to addItem or removeItem with the required arguments. For example:
Finally, add the updateOrderStatus method, which will be called from the CommonPayment class that will be created in Part 2 of this tutorial. The updateOrderStatus method will be used to update the status of an order after a transaction has been processed.
Demonstrating the POS App


Conclusion
In Part 1 of this tutorial, you learned how to build a simple POS application to create and update customer orders using C# with the .NET framework. In Part 2, you’ll learn how to use the PAX Semi-Integrated SDK to integrate credit card acceptance into the POS.
How To Get Started
North’s Sales Engineering team provides support to developers and business decision-makers to help select the best possible payment system. Contact us to learn more about how to connect your system to the North ecosystem.