> ## Documentation Index
> Fetch the complete documentation index at: https://docs.afarapay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Add the payment widget to your website

> Paste a short piece of code into your website and start accepting card, transfer, USSD and QR payments.

The Afara payment widget is a secure payment window that opens on top of your page. Your customer pays without leaving your site, and you get a payment **reference** back to confirm the order.

> [!NOTE]
>
> **Before you start**, you need an Afara account and your **public key**. Follow [Create your account](https://docs.afarapay.com/guides/create-account.md) and [Get your API keys](https://docs.afarapay.com/guides/api-keys.md) first. Use your **test** public key (it starts with `TPK_`) until you are ready to go live.

## How a payment works

**1. Your customer clicks Pay**

Your page collects the customer's email address and the amount, then opens the Afara widget.

**2. They choose how to pay**

The widget shows the payment methods available to you, such as card, bank transfer, USSD and QR.

**3. The widget tells your page it worked**

When the payment succeeds, the widget closes and your page receives a payment **reference**.

**4. You confirm the payment**

Your server checks the reference with Afara before delivering the order. See [Verify a payment](https://docs.afarapay.com/payments/verify-payments.md).

## Add the widget

Paste the code below into your page and replace the two things marked in the comments. It works on any website, including WordPress, Wix and plain HTML sites that let you add custom code.

```html HTML theme={null}
<form id="paymentForm">
  <label for="email-address">Email address</label>
  <input type="email" id="email-address" required />

  <label for="amount">Amount (in Naira)</label>
  <input type="number" id="amount" min="1" required />

  <button type="submit">Pay now</button>
</form>

<script src="https://sdk.afarapartners.com/omni-payment-gateway-sdk"></script>
<script>
  document.getElementById("paymentForm").addEventListener("submit", function (e) {
    e.preventDefault();

    var handler = AfaraPayPop.setup({
      key: "TPK_your_test_public_key", // 1. Paste your PUBLIC key here
      email: document.getElementById("email-address").value,
      // 2. The amount is in kobo, so multiply Naira by 100
      amount: Math.round(Number(document.getElementById("amount").value) * 100),
      currency: "NGN",
      callback: function (response) {
        // Payment finished. Send the customer to a page that confirms the order.
        window.location.href = "/thank-you?reference=" + response.reference;
      },
      onClose: function () {
        console.log("The customer closed the widget.");
      }
    });

    handler.openIframe();
  });
</script>
```

```jsx React theme={null}
import { useState } from "react";

// Add this once to public/index.html:
// <script src="https://sdk.afarapartners.com/omni-payment-gateway-sdk"></script>

export default function CheckoutForm() {
  const [email, setEmail] = useState("");
  const [amount, setAmount] = useState("");

  const payNow = (e) => {
    e.preventDefault();

    const handler = window.AfaraPayPop.setup({
      key: "TPK_your_test_public_key", // Your PUBLIC key
      email: email,
      amount: Math.round(Number(amount) * 100), // Naira to kobo
      currency: "NGN",
      callback: (response) => {
        window.location.href = "/thank-you?reference=" + response.reference;
      },
      onClose: () => console.log("The customer closed the widget."),
    });

    handler.openIframe();
  };

  return (
    <form onSubmit={payNow}>
      <label>
        Email address
        <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
      </label>
      <label>
        Amount (in Naira)
        <input type="number" min="1" value={amount} onChange={(e) => setAmount(e.target.value)} required />
      </label>
      <button type="submit">Pay now</button>
    </form>
  );
}
```

```typescript Angular theme={null}
// Add this once to src/index.html:
// <script src="https://sdk.afarapartners.com/omni-payment-gateway-sdk"></script>

import { Component } from "@angular/core";

declare const AfaraPayPop: any;

@Component({
  selector: "app-checkout-form",
  template: `
    <form (submit)="payNow($event)">
      <label>Email address <input type="email" [(ngModel)]="email" name="email" required /></label>
      <label>Amount (in Naira) <input type="number" [(ngModel)]="amount" name="amount" min="1" required /></label>
      <button type="submit">Pay now</button>
    </form>
  `,
})
export class CheckoutFormComponent {
  email = "";
  amount = 0;

  payNow(event: Event) {
    event.preventDefault();

    const handler = AfaraPayPop.setup({
      key: "TPK_your_test_public_key", // Your PUBLIC key
      email: this.email,
      amount: Math.round(this.amount * 100), // Naira to kobo
      currency: "NGN",
      callback: (response: any) => {
        window.location.href = "/thank-you?reference=" + response.reference;
      },
      onClose: () => console.log("The customer closed the widget."),
    });

    handler.openIframe();
  }
}
```

> [!WARNING]
>
> Use your **public** key in the widget. Never paste a secret key (`TSK_` or `SK_`) into website code.

> [!NOTE]
>
> **Amounts are in kobo.** NGN 5,000 is `500000`. That is why the examples multiply the Naira amount by 100.

## Widget options

**key** `string` *required*

Your public key. Use `TPK_...` to test and `PK_...` for live payments.

**email** `string` *required*

The customer's email address.

**amount** `integer` *required*

The amount to charge, in kobo. Must be a whole number.

**currency** `string` (default: NGN)

The currency code. Defaults to `NGN`.

**ref** `string`

Your own unique reference for this payment, for example an order number. Use a new one for every payment.

**metadata** `object`

Extra details you want stored with the payment, for example a customer name or an order ID.

**callback** `function`

Runs when the payment succeeds. Receives a `response` object that includes the payment `reference`.

**onClose** `function`

Runs when the customer closes the widget.

## Test it

**1. Open your page**

Load the page, enter any email address and a small amount, and click **Pay now**.

**2. Pay with a test card**

Use a [test card](https://docs.afarapay.com/guides/testing.md). No real money moves in test mode.

**3. Check the dashboard**

Open **Transactions** in the merchant portal. Your test payment appears there.

## If something is not working

> [accordion] Nothing happens when I click Pay
>
> Make sure the script tag that loads the widget is on the page **before** the code that calls it. Open your browser's developer tools and look for red errors in the Console.

> [accordion] I see an error about the key or email
>
> The widget needs a public key and a valid email address. Check that the key is copied in full and starts with `TPK_` or `PK_`.

> [accordion] The amount is wrong
>
> The amount must be a whole number in kobo. If a customer should pay NGN 2,500, send `250000`.

> [accordion] AfaraPayPop is not defined
>
> The widget script has not loaded. Check the script address and that your site allows scripts from `sdk.afarapartners.com`. The name is case sensitive: `AfaraPayPop`.

> [card] [Verify a payment](https://docs.afarapay.com/payments/verify-payments.md)
>
> Confirm the payment on your server before you deliver the order.

> [card] [Test cards](https://docs.afarapay.com/guides/testing.md)
>
> Card numbers to try every outcome.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.