API v1FiatPe Home
FiatPeDocs
WEB INTEGRATION

Collect payments with Checkout.js

Add FiatPe Checkout to your website and open a secure payment popup when the customer clicks your payment button.

Include the Checkout SDK

Load Checkout.js before creating a FiatPe instance.

HTML
<script src="https://checkout.fiatpe.com/v1/checkout.js"></script>
Copy

Complete popup example

Create the options object, initialise FiatPe, and call open() from a customer action.

HTML
Copy
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>FiatPe Checkout Example</title>
</head>
<body>
  <!-- FiatPe Checkout SDK -->
  <script src="https://checkout.fiatpe.com/v1/checkout.js"></script>

  <button type="button" onclick="openFiatPeCheckout()">
    Pay Now
  </button>

  <script>
    function openFiatPeCheckout() {
      const options = {
        api_key: "ak_test_xxxxxxxxxxxxxxxx",
        order_id: "order_xxxxxxxxxxxxxxxx",

        image: null,

        theme: {
          color: "#fcd008"
        },

        customer: {
          name: "Customer Name",
          email: "customer@mail.com",
          contact: "9960245621"
        },

        onSuccess: function (response) {
          console.log("Payment successful:", response);

          /*
           * IMPORTANT:
           * Verify the payment signature on your server using HMAC SHA-512
           * and your FiatPe Salt Key before marking the payment successful.
           *
           * Never verify the signature in frontend code and never expose
           * your Salt Key in the browser.
           *
           * Example response:
           * {
           *   "payment_id": "FIATPEXXXXXXXXXXXX",
           *   "order_id": "order_xxxxxxxxxxxxxxxx",
           *   "signature": "xxxxxxxxxxxxxxxxxxxxxxxx"
           * }
           */
        },

        onFailure: function (error) {
          console.error("Payment failed:", error);
        }
      };

      const fiatPe = new FiatPe(options);
      fiatPe.open();
    }
  </script>
</body>
</html>

Checkout options

OptionTypeDescription
api_keystringYour FiatPe Test or Live API key.
order_idstringThe order ID created securely from your server.
imagestring | nullOptional merchant logo displayed in Checkout.
theme.colorstringCheckout accent color in hexadecimal format.
customerobjectOptional name, email, and contact prefill values.
onSuccessfunctionRuns after Checkout returns a successful payment result.
onFailurefunctionRuns when payment fails or cannot be completed.

Verify payment on your server

Never fulfil an order from the frontend callback alone.

Send payment_id, order_id, and signature to your backend. Verify the signature there with HMAC SHA-512 and your FiatPe Salt Key, then confirm the authoritative payment status before fulfilment.

  • Keep the Salt Key exclusively on your server.
  • Use an ak_test_ key while testing and an ak_live_ key in production.
  • Create and validate the order on your backend.
  • Handle duplicate callbacks and webhooks idempotently.

Node.js

JavaScript
Copy
import crypto from "node:crypto";

export function verifyFiatPeSignature({ orderId, paymentId, signature }) {
  const saltKey = process.env.FIATPE_SALT_KEY;

  if (!saltKey || !orderId || !paymentId || !signature) {
    return false;
  }

  // The field order and separator must remain exactly the same.
  const payload = `${orderId}|${paymentId}`;
  const expectedSignature = crypto
    .createHmac("sha512", saltKey)
    .update(payload, "utf8")
    .digest("hex");

  const receivedSignature = signature.trim().toLowerCase();

  // A hexadecimal SHA-512 digest contains exactly 128 characters.
  if (!/^[a-f0-9]{128}$/.test(receivedSignature)) {
    return false;
  }

  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, "hex"),
    Buffer.from(receivedSignature, "hex")
  );
}

Django / Python

Python
Copy
import hashlib
import hmac
import os


def verify_fiatpe_signature(*, order_id, payment_id, signature):
    salt_key = os.environ.get("FIATPE_SALT_KEY")

    if not all([salt_key, order_id, payment_id, signature]):
        return False

    # The field order and separator must remain exactly the same.
    payload = f"{order_id}|{payment_id}".encode("utf-8")
    expected_signature = hmac.new(
        salt_key.encode("utf-8"),
        payload,
        hashlib.sha512,
    ).hexdigest()

    return hmac.compare_digest(
        expected_signature,
        signature.strip().lower(),
    )
Build the signature from trusted values.

Read the expected order_id from your database instead of trusting the value returned by the browser. The signed payload is order_id|payment_id, and the generated hexadecimal signature is compared in constant time.