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>Complete popup example
Create the options object, initialise FiatPe, and call open() from a customer action.
HTML
<!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
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 anak_live_key in production. - Create and validate the order on your backend.
- Handle duplicate callbacks and webhooks idempotently.
Node.js
JavaScript
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
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.