# TAP-Inlinejs

Popup Library for loading TAP's payment checkout gateway. It makes it easy to accept payments from a web application and to create custom, secure payment experiences for merchant apps and websites

### Requirements

```js
node >= 12.0.1
npm >= 6.0.0
```

## Introduction

This documentation provides an overview of the TouchandPay Payment Popup **(TAPPaymentPop)** JavaScript library that facilitates payment integration with the TAP payment gateway. It explains how to use the library, describes its main features and provides an example of how to integrate it with a web page.

---

## Version 2.0.5 (Latest)

Version 2.0.5 introduces a `superMerchantFee` parameter for advanced fee management and continues to use the `env` parameter to simplify environment selection (production or sandbox) with a single script URL.

### Getting Started (v2.0.5)

To use the TAPPaymentPop JavaScript library (v2.0.5), include the following script tag in your HTML code:

```html
<script src="https://unpkg.com/tap-payment-popupjs@2.0.5/dist/umd/index.js"></script>
```

You can now use the `TAPPaymentPop.setup()` method to create an instance of the payment gateway, passing in the required configuration parameters, including the new `superMerchantFee` parameter.

### API (v2.0.5)

The `TAPPaymentPop` object provides the following methods:

-   `initialize(transactionDefaults)`: Initializes or re-initializes the payment gateway with specified default transaction parameters. Typically called by `setup()` if the gateway isn't already initialized.
-   `setup(transactionDetails, setupCallback)`: Configures and returns an instance of the payment gateway. `transactionDetails` is an object with configuration parameters. `setupCallback` is an optional function that receives the gateway instance.
-   `destroy()`: Cleans up the current payment gateway instance, removing its iframes and event listeners. Call this if you need to remove the payment popup functionality from the page or before re-initializing with a completely new configuration.

The instance returned by `TAPPaymentPop.setup()` has the following method:

-   `openIframe()`: Displays the payment gateway iframe to start the payment process.

### Configuration Parameters (v2.0.5)

The `TAPPaymentPop.setup()` method requires a `transactionDetails` object with the following parameters:

| Parameter           | Required                                         | Description                                                                                                                               |
| ------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`            | yes                                              | Your TAP API key.                                                                                                                         |
| `env`               | yes                                              | Environment to use: `"production"` for production or `"sandbox"` for testing.                                                                   |
| `transID`           | yes                                              | A unique transaction ID for this payment attempt.                                                                                         |
| `amount`            | yes                                              | The amount of the transaction (e.g., in Kobo for NGN).                                                                                    |
| `email`             | yes                                              | The email address of the customer.                                                                                                        |
| `phone`             | if `savePaymentDetails` is `true`, then yes; else no | The customer's phone number. Required if `savePaymentDetails` is true.                                                                    |
| `savePaymentDetails`| no                                               | Boolean (true/false). Set to `true` if you want to enable saving payment details for the customer. Defaults to `false`.                     |
| `customerReference` | if `savePaymentDetails` is `true`, then yes; else no | A unique reference for the customer, used when `savePaymentDetails` is `true`.                                                            |
| `superMerchantFee`  | no                                               | Optional fee amount for super merchant transactions. Used for advanced fee management scenarios.                                           |
| `customPayload`     | no                                               | An object for any other custom data you want to send with the transaction. This data will be nested under `customPayload` in the backend. |
| - `billerID`        | no (within `customPayload`)                      | The biller ID (Special Usecase, include in `customPayload`).                                                                              |
| - `productID`       | no (within `customPayload`)                      | The product ID (Special Usecase, include in `customPayload`).                                                                             |
| - ...               | no (within `customPayload`)                      | Other custom data relevant to your application.                                                                                           |
| `onClose`           | no                                               | A function to call when the payment gateway popup is closed by the user before completion.                                                |
| `callback`          | no                                               | A function to call when the payment has been successfully completed. It receives the transaction response object as an argument.           |

### Example Usage (v2.0.5)

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>TAP Payment Gateway Example (v2.0.5)</title>
  </head>
  <body>
    <form id="pay-form">
      <div class="form-group">
        <label for="amount">Amount (Kobo)</label>
        <input type="number" id="amount" name="amount" class="form-control" required />
      </div>
      <div class="form-group">
        <label for="email">Email</label>
        <input type="email" id="email" name="email" class="form-control" required />
      </div>
      <div class="form-group">
        <label for="phone">Phone</label>
        <input type="text" id="phone" name="phone" class="form-control" /> <!-- Made not required in form for example flexibility -->
      </div>
      <div class="form-group">
        <label for="customerReference">Customer Reference (Optional)</label>
        <input type="text" id="customerReference" name="customerReference" class="form-control" />
      </div>
      <div class="form-group">
        <label>
          <input type="checkbox" id="savePaymentDetails" name="savePaymentDetails" />
          Save Payment Details
        </label>
      </div>
      <div class="form-group">
        <label for="superMerchantFee">Super Merchant Fee (Optional)</label>
        <input type="number" id="superMerchantFee" name="superMerchantFee" class="form-control" />
      </div>
      <div class="form-group">
        <label for="billerID">Biller ID (Optional)</label>
        <input type="text" id="billerID" name="billerID" class="form-control" />
      </div>
      <div class="form-group">
        <label for="productID">Product ID (Optional)</label>
        <input type="text" id="productID" name="productID" class="form-control" />
      </div>
      <button id="pay-btn" type="button" onclick="validateAndPay()" class="btn btn-primary">
        Pay
      </button>
    </form>
    <div id="alert-holder"></div>

    <script type="module" src="https://unpkg.com/tap-payment-popupjs@2.0.5/dist/umd/index.js"></script>
    <script>
      const api_key = "YOUR_API_KEY"; // Replace with your actual API key

      function validateAndPay() {
        const email = document.getElementById("email").value;
        const amount = document.getElementById("amount").value;
        const phone = document.getElementById("phone").value;
        const savePaymentDetails = document.getElementById("savePaymentDetails").checked;
        const customerReference = document.getElementById("customerReference").value;
        const superMerchantFee = document.getElementById("superMerchantFee").value;
        
        const billerID = document.getElementById("billerID").value;
        const productID = document.getElementById("productID").value;

        if (!email || !amount) { // Phone is conditionally required by the library
          alert("Please fill in Email and Amount.");
          return;
        }

        payWithTAP(email, amount, phone, savePaymentDetails, customerReference, superMerchantFee, billerID, productID);
      }

      function payWithTAP(email, amount, phone, savePaymentDetails, customerReference, superMerchantFee, billerID, productID) {
        const transactionDetails = {
          apiKey: api_key,
          env: "sandbox", // "production" or "sandbox"
          amount: parseFloat(amount),
          transID: `TAP-${Date.now()}-${Math.random().toString(36).slice(2)}`,
          email: email,
          phone: phone, 
          savePaymentDetails: savePaymentDetails,
          customerReference: customerReference,
          superMerchantFee: superMerchantFee ? parseFloat(superMerchantFee) : undefined,
          customPayload: {
            // phone: phone, // phone is a top-level param
            billerID: billerID || undefined,
            productID: productID || undefined,
          },
          callback: function (response) {
            console.log("Payment successful:", response);
            const msg = 'Success. The transaction id is <b>"' + response.transID + '"</b>. Full response: ' + JSON.stringify(response);
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-success" role="alert">' + msg + "</div>";
            document.getElementById("pay-form").reset();
          },
          onClose: function () {
            console.log("Payment popup closed by user.");
            const msg = "Payment popup closed. Please click the 'Pay' button to try again.";
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-info" role="alert">' + msg + "</div>";
          }
        };

        try {
            const handler = TAPPaymentPop.setup(transactionDetails);
            if (handler) {
                 handler.openIframe();
            } else {
                console.error("Failed to setup TAPPaymentPop. Check console for errors.");
                // Error messages from setup will be more specific if thrown by the library
            }
        } catch (error) {
            console.error("Error during TAPPaymentPop setup:", error);
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-danger" role="alert">' + error.message + "</div>";
        }
      }
    </script>
  </body>
</html>
```

---

## Version 2.0.x (Previous)

Version 2.0.x introduces an `env` parameter to simplify environment selection (production or sandbox) and uses a single script URL.

### Getting Started (v2.0.x)

To use the TAPPaymentPop JavaScript library (v2.0.x), include the following script tag in your HTML code:

```html
<script src="https://unpkg.com/tap-payment-popupjs@2.0.2/dist/umd/index.js"></script>
```

You can now use the `TAPPaymentPop.setup()` method to create an instance of the payment gateway, passing in the required configuration parameters, including the new `env` parameter.

### API (v2.0.x)

The `TAPPaymentPop` object provides the following methods:

-   `initialize(transactionDefaults)`: Initializes or re-initializes the payment gateway with specified default transaction parameters. Typically called by `setup()` if the gateway isn't already initialized.
-   `setup(transactionDetails, setupCallback)`: Configures and returns an instance of the payment gateway. `transactionDetails` is an object with configuration parameters. `setupCallback` is an optional function that receives the gateway instance.
-   `destroy()`: Cleans up the current payment gateway instance, removing its iframes and event listeners. Call this if you need to remove the payment popup functionality from the page or before re-initializing with a completely new configuration.

The instance returned by `TAPPaymentPop.setup()` has the following method:

-   `openIframe()`: Displays the payment gateway iframe to start the payment process.

### Configuration Parameters (v2.0.x)

The `TAPPaymentPop.setup()` method requires a `transactionDetails` object with the following parameters:

| Parameter           | Required                                         | Description                                                                                                                               |
| ------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`            | yes                                              | Your TAP API key.                                                                                                                         |
| `env`               | yes                                              | Environment to use: `"production"` for production or `"sandbox"` for testing.                                                                   |
| `transID`           | yes                                              | A unique transaction ID for this payment attempt.                                                                                         |
| `amount`            | yes                                              | The amount of the transaction (e.g., in Kobo for NGN).                                                                                    |
| `email`             | yes                                              | The email address of the customer.                                                                                                        |
| `phone`             | if `savePaymentDetails` is `true`, then yes; else no | The customer's phone number. Required if `savePaymentDetails` is true.                                                                    |
| `savePaymentDetails`| no                                               | Boolean (true/false). Set to `true` if you want to enable saving payment details for the customer. Defaults to `false`.                     |
| `customerReference` | if `savePaymentDetails` is `true`, then yes; else no | A unique reference for the customer, used when `savePaymentDetails` is `true`.                                                            |
| `customPayload`     | no                                               | An object for any other custom data you want to send with the transaction. This data will be nested under `customPayload` in the backend. |
| - `billerID`        | no (within `customPayload`)                      | The biller ID (Special Usecase, include in `customPayload`).                                                                              |
| - `productID`       | no (within `customPayload`)                      | The product ID (Special Usecase, include in `customPayload`).                                                                             |
| - ...               | no (within `customPayload`)                      | Other custom data relevant to your application.                                                                                           |
| `onClose`           | no                                               | A function to call when the payment gateway popup is closed by the user before completion.                                                |
| `callback`          | no                                               | A function to call when the payment has been successfully completed. It receives the transaction response object as an argument.           |

### Example Usage (v2.0.x)

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>TAP Payment Gateway Example (v2.0.x)</title>
  </head>
  <body>
    <form id="pay-form">
      <div class="form-group">
        <label for="amount">Amount (Kobo)</label>
        <input type="number" id="amount" name="amount" class="form-control" required />
      </div>
      <div class="form-group">
        <label for="email">Email</label>
        <input type="email" id="email" name="email" class="form-control" required />
      </div>
      <div class="form-group">
        <label for="phone">Phone</label>
        <input type="text" id="phone" name="phone" class="form-control" /> <!-- Made not required in form for example flexibility -->
      </div>
      <div class="form-group">
        <label for="customerReference">Customer Reference (Optional)</label>
        <input type="text" id="customerReference" name="customerReference" class="form-control" />
      </div>
      <div class="form-group">
        <label>
          <input type="checkbox" id="savePaymentDetails" name="savePaymentDetails" />
          Save Payment Details
        </label>
      </div>
      <div class="form-group">
        <label for="billerID">Biller ID (Optional)</label>
        <input type="text" id="billerID" name="billerID" class="form-control" />
      </div>
      <div class="form-group">
        <label for="productID">Product ID (Optional)</label>
        <input type="text" id="productID" name="productID" class="form-control" />
      </div>
      <button id="pay-btn" type="button" onclick="validateAndPay()" class="btn btn-primary">
        Pay
      </button>
    </form>
    <div id="alert-holder"></div>

    <script type="module" src="https://unpkg.com/tap-payment-popupjs@2.0.2/dist/umd/index.js"></script>
    <script>
      const api_key = "YOUR_API_KEY"; // Replace with your actual API key

      function validateAndPay() {
        const email = document.getElementById("email").value;
        const amount = document.getElementById("amount").value;
        const phone = document.getElementById("phone").value;
        const savePaymentDetails = document.getElementById("savePaymentDetails").checked;
        const customerReference = document.getElementById("customerReference").value;
        
        const billerID = document.getElementById("billerID").value;
        const productID = document.getElementById("productID").value;

        if (!email || !amount) { // Phone is conditionally required by the library
          alert("Please fill in Email and Amount.");
          return;
        }

        payWithTAP(email, amount, phone, savePaymentDetails, customerReference, billerID, productID);
      }

      function payWithTAP(email, amount, phone, savePaymentDetails, customerReference, billerID, productID) {
        const transactionDetails = {
          apiKey: api_key,
          env: "sandbox", // "production" or "sandbox"
          amount: parseFloat(amount),
          transID: `TAP-${Date.now()}-${Math.random().toString(36).slice(2)}`,
          email: email,
          phone: phone, 
          savePaymentDetails: savePaymentDetails,
          customerReference: customerReference,
          customPayload: {
            // phone: phone, // phone is a top-level param
            billerID: billerID || undefined,
            productID: productID || undefined,
          },
          callback: function (response) {
            console.log("Payment successful:", response);
            const msg = 'Success. The transaction id is <b>"' + response.transID + '"</b>. Full response: ' + JSON.stringify(response);
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-success" role="alert">' + msg + "</div>";
            document.getElementById("pay-form").reset();
          },
          onClose: function () {
            console.log("Payment popup closed by user.");
            const msg = "Payment popup closed. Please click the 'Pay' button to try again.";
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-info" role="alert">' + msg + "</div>";
          }
        };

        try {
            const handler = TAPPaymentPop.setup(transactionDetails);
            if (handler) {
                 handler.openIframe();
            } else {
                console.error("Failed to setup TAPPaymentPop. Check console for errors.");
                // Error messages from setup will be more specific if thrown by the library
            }
        } catch (error) {
            console.error("Error during TAPPaymentPop setup:", error);
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-danger" role="alert">' + error.message + "</div>";
        }
      }
    </script>
  </body>
</html>
```

---

## Version 1.0.x (Deprecated)

**Note: Version 1.0.x is deprecated. Please upgrade to Version 2.0.5 for the latest features and a simplified environment setup.**

### Getting Started (v1.0.x - Deprecated)

To use the TAPPaymentPop JavaScript library, you need to first include the following script tag in your HTML code:

```html
<!-- Production -->
<script src="https://unpkg.com/tap-payment-popupjs@1.0.4/dist/umd/index.js"></script>

<!-- Staging/Test -->
<script src="https://unpkg.com/tap-payment-popupjs@1.0.3/dist/umd/index.js"></script>
```

You can now use the `TAPPaymentPop.setup()` method to create an instance of the payment gateway, passing in the required configuration parameters.

### API (v1.0.x - Deprecated)

The `TAPPaymentPop` object provides the following methods:

-   `initialize(transactionDefaults)`: Initializes or re-initializes the payment gateway with specified default transaction parameters. Typically called by `setup()` if the gateway isn't already initialized.
-   `setup(transactionDetails, setupCallback)`: Configures and returns an instance of the payment gateway. `transactionDetails` is an object with configuration parameters. `setupCallback` is an optional function that receives the gateway instance.
-   `destroy()`: Cleans up the current payment gateway instance, removing its iframes and event listeners. Call this if you need to remove the payment popup functionality from the page or before re-initializing with a completely new configuration.

The instance returned by `TAPPaymentPop.setup()` has the following method:

-   `openIframe()`: Displays the payment gateway iframe to start the payment process.

### Configuration Parameters (v1.0.x - Deprecated)

The `TAPPaymentPop.setup()` method requires a `transactionDetails` object with the following parameters:

| Parameter           | Required | Description                                                                                                                               |
| ------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `apiKey`            | yes      | Your TAP API key.                                                                                                                         |
| `transID`           | yes      | A unique transaction ID for this payment attempt.                                                                                         |
| `amount`            | yes      | The amount of the transaction (e.g., in Kobo for NGN).                                                                                    |
| `email`             | yes      | The email address of the customer.                     |
| `customPayload`     | no       | An object for any other custom data you want to send with the transaction. This data will be nested under `customPayload` in the backend. |
| - `billerID`        | no (within `customPayload`) | The biller ID (Special Usecase, include in `customPayload`).                                                                              |
| - `productID`       | no (within `customPayload`) | The product ID (Special Usecase, include in `customPayload`).                                                                             |
| - ...               | no (within `customPayload`) | Other custom data relevant to your application.                                                                                           |
| `onClose`           | no       | A function to call when the payment gateway popup is closed by the user before completion.                                                |
| `callback`          | no       | A function to call when the payment has been successfully completed. It receives the transaction response object as an argument.           |

### Example Usage (v1.0.x - Deprecated)

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>TAP Payment Gateway Example (v1.0.x - Deprecated)</title>
  </head>
  <body>
    <form id="pay-form">
      <div class="form-group">
        <label for="amount">Amount (Kobo)</label>
        <input type="number" id="amount" name="amount" class="form-control" required />
      </div>
      <div class="form-group">
        <label for="email">Email</label>
        <input type="email" id="email" name="email" class="form-control" required />
      </div>
      <div class="form-group">
        <label for="phone">Phone</label>
        <input type="text" id="phone" name="phone" class="form-control" required />
      </div>
      <div class="form-group">
        <label for="billerID">Biller ID (Optional)</label>
        <input type="text" id="billerID" name="billerID" class="form-control" />
      </div>
      <div class="form-group">
        <label for="productID">Product ID (Optional)</label>
        <input type="text" id="productID" name="productID" class="form-control" />
      </div>
      <button id="pay-btn" type="button" onclick="validateAndPay()" class="btn btn-primary">
        Pay
      </button>
    </form>
    <div id="alert-holder"></div>

    <!-- Ensure you are using the correct version (e.g., Staging/Test for v1.0.3) -->
    <script type="module" src="https://unpkg.com/tap-payment-popupjs@1.0.3/dist/umd/index.js"></script>
    <script>
      const api_key = "TkdLb2VUMk46ZXRoWEdJSEF0Z24xOnB1WVUzd3dvS1c4bw=="; // Replace with your actual API key

      function validateAndPay() {
        const email = document.getElementById("email").value;
        const amount = document.getElementById("amount").value;
        const phone = document.getElementById("phone").value;
        
        const billerID = document.getElementById("billerID").value;
        const productID = document.getElementById("productID").value;

        if (!email || !amount || !phone) {
          alert("Please fill in all required fields: Email, Amount, and Phone.");
          return;
        }

        payWithTAP(email, amount, phone, billerID, productID);
      }

      function payWithTAP(email, amount, phone, billerID, productID) {
        const transactionDetails = {
          apiKey: api_key,
          amount: parseFloat(amount),
          transID: `TAP-${Date.now()}-${Math.random().toString(36).slice(2)}`,
          email: email,
          customPayload: {
            phone: phone,
            billerID: billerID || undefined,
            productID: productID || undefined,
          },
          callback: function (response) {
            console.log("Payment successful:", response);
            const msg = 'Success. The transaction id is <b>"' + response.transID + '"</b>. Full response: ' + JSON.stringify(response);
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-success" role="alert">' + msg + "</div>";
            document.getElementById("pay-form").reset();
          },
          onClose: function () {
            console.log("Payment popup closed by user.");
            const msg = "Payment popup closed. Please click the 'Pay' button to try again.";
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-info" role="alert">' + msg + "</div>";
          }
        };

        try {
            const handler = TAPPaymentPop.setup(transactionDetails);
            if (handler) {
                 handler.openIframe();
            } else {
                console.error("Failed to setup TAPPaymentPop. Check console for errors.");
                document.getElementById("alert-holder").innerHTML = '<div class="alert alert-danger" role="alert">Could not initialize payment. Please check configuration.</div>';
            }
        } catch (error) {
            console.error("Error during TAPPaymentPop setup:", error);
            document.getElementById("alert-holder").innerHTML = '<div class="alert alert-danger" role="alert">' + error.message + "</div>";
        }
      }
    </script>
  </body>
</html>
```

### Deployment (v1.0.x - Deprecated)

Inline JS is deployed to:

---

-   Production: `https://unpkg.com/tap-payment-popupjs@1.0.4/dist/umd/index.js` (Deprecated)
-   Staging / Test: `https://unpkg.com/tap-payment-popupjs@1.0.3/dist/umd/index.js` (Deprecated)
-   npm: <https://www.npmjs.com/package/tap-payment-popupjs> (Check for latest v2.0.5)
-   Test Sample (for v1.0.x): <https://tap-sdk-demo-staging.netlify.app/>

---

### Live Checkout

Checkout Interface is deployed to:

---

-   Live URL: <https://checkout.touchandpay.me>
-   Sandbox URL: (The main checkout URL will adapt based on the `env` parameter in v2.0.5 For v1.0.x, use the Staging/Test script for a sandbox-like environment.)
