ExactJS is client-side JavaScript library that can be used with eCommerce merchant web applications to accept online payments from customers without the PCI compliance requirements. This is an implementation of a Java Spring Boot application that is common among many eCommerce websites on how to integrate ExactJS.
More information about ExactJS can be found in the following guide: https://developer.exactpay.com/docs/Payment-Forms
- Java version 17
- Suitable version of Maven for building and running the application
- This application uses Thymeleaf for the server-side rendering of HTML pages: https://www.thymeleaf.org/
- Clone the repository
git clone https://github.com/exact-payments/merchant-demo-exactjs-spring-boot.git
- Move to the directory of the source code of the application
cd merchant-demo-exactjs-spring-boot
- Build and run the application
./mvnw spring-boot:run
- Open the browser and load the following URL
http://localhost:8080
You will see the home page of a eCommerce website. Add the products to the shopping cart and checkout.
The integration of ExactJS library involves HTML/JavaScript frontend changes as well a backend changes in your Spring Boot application. The following steps outline how these changes are implemented in this sample application.
Please review the contents of the application.properties
file in the src/main/resources
directory. This file contains the following properties:
exact.url
- This is the Exact Payments API URLapplication.token
- This is the identity and authorization token with the necessary permissions to use ExactJS. The application token must have at leastcharges.create
andcharges.read
permissions.account.id
- This is the merchant account ID for a specific merchant.
HomeController.java
This is a Spring MVC controller class to deliver the home page of the sample eCommerce merchant page. This simply returns an index.html file that is the sample product page of the online plant shop.
This is the home page of the online plant shop. The most important code to review
in this page are the two JavaScript functions: updateTotal()
and pay()
.
The updateTotal()
is a simple Javascript code to capture the events of the
shopper adding items to their shopping cart and calculating the total amount
before checkout. The pay()
is the JavaScript code that POSTs to the
CheckoutController
that renders the payment page powered by ExactJS.
The HTML code required for rendering the ExactJS powered payment page is in the pay.html
file.
The loading of this page is controlled by the Sprint Boot backend controller
CheckoutController.java.
The business logic coded in this controller is as follows:
First create an Order for the total sale amount coming in as the request parameter amountStr
.
This class makes a POST request to the endpoint:
https://api.exactpaysandbox.com/account/{accountId}/orders
Please note that the URI contains the accountID
in the URI path. This
implies that this call is made from the partner context with you as a
software platform partner to Exact Payments by explicitly specifying the merchant
account ID of your customer. The response to this call will fetch two important
data that is required to be passed on your payment page. The first one is the
accessToken
which is required to securely initialize the ExactJS component
in the payment form (pay.html
in this sample application). The second one is the
orderID
which represents the payment intent of the eCommerce customer in
fulfilling their shopping order.
The controller is setting three model attributes that are required in the payment page
for completing the payment: accessToken
, orderId
, and amount
. These are
set as session attributes that Thymeleaf can interpret and render appropriately
on the payment form page next.
Please start with the pay.html
page included in this project.
At the top of the page you will see the following JavaScript link included
that is essential to initialize your payment page to work with ExactJS in a
way that does removes your PCI compliance overhead.
<script src="https://api.exactpaysandbox.com/js/v1/exact.js"></script>
Notice that, in the body of the pay.html
page you have a HTML snippet:
<p style="text-align: center"> Your Order total is: <strong th:text="${amount}"></strong></p>
This is about informing your eCommerce customer about their payment amount
that is coming through the order they just placed. The syntax of how you capture
from the model attributes we set in the Spring Controller backend should be
fairly self-explanatory. For more information on this, please refer to the Thymeleaf templating engine documentation.
https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html
The most important part of building the payment page with the help of ExactJS is to embed a few lines of JavaScript code into your HTML page. Take a look at the the following JavaScript code snippet:
const exact = ExactJS([[${accesstoken}]]);
const components = exact.components({orderId: [[${orderid}]]});
components.addCard('cardElement', {
billingAddress: {
type: "full"
},
style: {
default: {
backgroundColor: "white",
padding: "3px"
},
error: {
backgroundColor: "blue",
border: "2px dashed deeppink",
borderRadius: "10px"
}
}
});
The above JavaScript code will render the required payment fields inside the
following <div>
element you will see inside the <form>
element
<div id="cardElement">
<!-- our credit card UI component will be attached here -->
</div>
Please note that the accessToken
and orderId
are carried through from the backend
as model attributes and rendered in the HTML page with the rendering
capabilities of Thymeleaf. Please note that, we have done some minimal styling
for the look and feel of the payment page leaving out the option to customize by
the merchants as they see fit for their business.
To complete the payment, the JavaScript below that is present in the pay.html
page is invoked:
document.getElementById("myForm").addEventListener('submit', (event) => {
event.preventDefault();
const form = event.target.closest("form");
exact.payOrder()
.then(payment_id => {
// add the payment id to your form
document.getElementById('payment_id').value = payment_id
// submit your form to your backend
form.submit()
})
.catch(err => console.error(err));
});
Please note that the above JavaScript code is also populating the value for thw following hidden input element in the form which is required for any post-payment flows such as generating a confirmation page.
ExactJS generates Javascript events such as payment-completed
and payment-failed
for the application to handle and communicate to the user the state of the
payment. For example, as shown in the JavaScript code below, the payment-completed
event handler can call an endpoint to show a confirmation page. In this sample application
we use the same Spring Boot controller class, CheckoutController
with a
new method mapping for /confirm
in the URI with the paymentID
as a request parameter.