Skip to main content



The following prerequisites are required for the Exact Payments API:

  • You have been onboarded and given an account Id
  • You have generated or been given access to an Application Token
  • You will need a list of test cards

Creating an Order

Before rendering your payment form for the customer, you need to send the details of the order to our servers. From your server, send a POST request to our Orders with the details of your customer's order.

You will need to use your API key to authenticate this request. Include it as an Authorization header.

POST /orders
amount: 1123
reference: {referenceNo: "sample for demo"}

The above example is the bare minimum required to create an order. Please see the Orders API reference for the various other options available when creating an Order.

This will return an order ID and an access token which you will need to include on your payment form.

You can also use the ID with the Orders API to update the order as many times as you need until the customer has paid. Once the order has been paid, further updates will be rejected.

Access Tokens

The access token you received when you created the Order will allow your customers to access our APIs from their browser for a limited time period. It is valid for 15 minutes and, once it has expired, further API requests will be rejected.

You can optionally re-generate an access token if you want to allow your customer more time to complete their payment.

Building Your Form

When building your payment form, you first need to add our ExactJS library.

For the sandbox environment, you should load the file from the domain.

For production, load it from the domain.

<script src=""></script>

You then need to initialize the library with the access token - do not use your secret API key!!

const exact = ExactJS("the_access_token");

Create your payment form, including an element to which we will attach our credit card UI. Here's a simple example:

<form id="myForm" action="your_form_url" method="post">
<label for="email-address">Email address</label>
<input type="email" id="email-address" name="email-address" autocomplete="email">

<div id="cardElement">
<!-- our credit card UI component will be attached here -->

<label for="address">Address</label>
<input type="text" id="address" name="address" autocomplete="street-address">

<label for="apartment">Apartment, suite, etc.</label>
<input type="text" id="apartment" name="apartment">

<label for="city">City</label>
<input type="text" id="city" name="city">

<label for="province">Province</label>
<input type="text" id="province" name="province">

<label for="postal-code">Postal code</label>
<input type="text" id="postal-code" name="postal-code" autocomplete="postal-code">


<input type="submit" name="commit" value="Pay Now" data-disable-with="Pay Now">

Tell ExactJS to add the credit card UI to your form. You will also need to provide your Order ID at this stage.

const components = exact.components({orderId: "the_order_id"});

Pay for Order

Configure your payment form so that your customers pay for the order directly from their browser. The ID of the completed payment will be returned to you. This ID can then be used with our Payments API to look up further details of the payment for example, or to capture an authorization.

For this option, you need to add an element to your form to accept the payment ID returned by ExactJS, so insert the following snippet into your form in place of the comment in the sample form above.

Add Payment ID Element
<input type="hidden" name="payment_id" id="payment_id">

Now add a listener to tell ExactJS to pay for the order when the customer submits the form.

document.getElementById("myForm").addEventListener('submit', (event) => {

Once the customer clicks your form's submit button, ExactJS will gather the payment details they have entered and will use that to pay for the order. The payment can succeed or fail, so you will need to provide handlers for each of those conditions.

If the payment did not complete, we will want to handle the payment-failed condition. For this condition, the payload will consist of an array of error strings, which we can display to the customer.

Failed Payment Handler
exact.on("payment-failed", (payload) => {
const errorElem = document.getElementById("errors");
Array.from(payload).forEach(err => {
const pElem = document.createElement("p");
pElem.textContent = err;

Succesful Payment Handler
exact.on("payment-complete", (payload) => {
// add the payment id to your form
document.getElementById('payment_id').value = payload.paymentId;
// submit your form to your backend

You should save the payment ID on your server as it will allow you to use the Payments API to get more details about the payment, or to perform follow-up transactions such as captures, refunds or voids.

User Flow Diagram