Developers | Popup

harrenapay.js, the drop-in escrow popup.

Take bank transfer payments without redirecting your buyer. One script tag, one function call, and funds land in escrow until your customer confirms delivery.

1. Create the charge on your server

Your secret API key never touches the browser. Call our charge endpoint from your backend to get an escrow-backed reference. Pass the same Idempotency-Key if the customer retries, we return the existing charge instead of creating a duplicate.

// Step 1 (your backend) - create the charge with your SECRET key
const res = await fetch("https://harrenapay.com/api/public/v1/charge", {
  method: "POST",
  headers: {
    "Authorization": "Bearer hpay_live_xxx",
    "Content-Type": "application/json",
    "Idempotency-Key": "order_4821",
  },
  body: JSON.stringify({
    reference:      "order_4821",
    amount:         2500000,                // NGN 25,000.00 in kobo
    currency:       "NGN",
    customer_email: "buyer@example.com",
    description:    "Order #4821",
    return_url:     "https://yourstore.com/orders/4821",
    escrow:         true,
  }),
});
const { reference } = await res.json();
// hand "reference" to the browser

2. Open the popup from the browser

Drop our script in your page and call HarrenaPay.setup(...).openPopup() when the buyer clicks pay. We open the branded checkout in a centered window, post a harrenapay:success message back when payment is captured, and close on success.

<!-- Step 2 (browser) - open the branded popup -->
<script src="https://harrenapay.com/harrenapay.js"></script>
<script>
  document.getElementById("pay").addEventListener("click", function () {
    var handler = HarrenaPay.setup({
      reference: "order_4821",
      onSuccess: function (evt) {
        window.location.href = "/orders/4821?status=paid";
      },
      onClose: function () {
        console.log("buyer closed the popup");
      },
    });
    handler.openPopup();
  });
</script>

React / Next.js

// React example
import { useEffect } from "react";

declare global { interface Window { HarrenaPay?: any } }

function PayButton({ reference }: { reference: string }) {
  useEffect(() => {
    if (document.getElementById("harrenapay-js")) return;
    const s = document.createElement("script");
    s.id = "harrenapay-js";
    s.src = "https://harrenapay.com/harrenapay.js";
    s.async = true;
    document.body.appendChild(s);
  }, []);

  function pay() {
    const handler = window.HarrenaPay.setup({
      reference,
      onSuccess: (evt: any) => { window.location.href = "/thanks?ref=" + evt.reference; },
      onClose:   () => console.log("closed"),
    });
    handler.openPopup();
  }

  return <button onClick={pay}>Pay with HarrenaPay</button>;
}

What you can rely on

  • Funds are held in escrow by HarrenaPay by default; pass escrow: false for instant-settle charges.
  • Bank transfers and payouts are processed through our licensed partner bank.
  • If the popup is blocked, the script falls back to a full-page redirect so the customer can still pay.
  • The onSuccess handler fires the moment the transfer is confirmed, but the source of truth is always our signed webhook.