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

# Payment Buttons

> Add a checkout button to any website with a single script tag - no backend required.

Payment buttons are embeddable checkout widgets that let customers pay directly from your website. You configure everything in the [dashboard](https://dashboard.paybridgenp.com) and embed a single `<script>` tag - the button fetches its settings live from PayBridgeNP, so changes you make in the dashboard take effect on the next page load without re-embedding.

<Note>
  Payment buttons require a **Growth plan or higher**. They are not available on the Free plan.
</Note>

## Use cases

* **E-commerce** - add a Buy Now button to a product page
* **Donations** - accept fixed or custom-amount contributions
* **SaaS** - quick one-time payments from a landing page
* **Invoicing** - embed a Pay button in an email template or hosted invoice

## How it works

<Steps>
  <Step title="Create a button in the dashboard">
    Configure the label, amount, color, customer fields, and return URL.
  </Step>

  <Step title="Copy the embed snippet">
    You get a single `<script>` tag containing only a button ID.
  </Step>

  <Step title="Paste it on your site">
    The script loads the button, which fetches its latest config from the API automatically.
  </Step>

  <Step title="Customer clicks and pays">
    A secure modal opens, collects any required information, creates a checkout session, and redirects to the provider (eSewa, Khalti, or Fonepay).
  </Step>
</Steps>

## Creating a button

1. Go to **Buttons** in the [dashboard](https://dashboard.paybridgenp.com)
2. Click **New button**
3. Configure the button:

| Field                | Required | Description                                                                            |
| -------------------- | -------- | -------------------------------------------------------------------------------------- |
| **Internal name**    | Yes      | For your reference only - not shown to customers                                       |
| **Button label**     | Yes      | Text displayed on the button (e.g. "Pay Now", "Donate", "Buy")                         |
| **Color**            | No       | Hex color for the button background (default: `#5C2D91`)                               |
| **Amount**           | Yes      | Fixed amount in NPR, or "Customer enters amount" for open-amount                       |
| **Description**      | No       | Shown on the checkout page                                                             |
| **Return URL**       | Yes      | Where the customer is redirected after payment                                         |
| **Cancel URL**       | No       | Where the customer is redirected if they cancel                                        |
| **Provider**         | No       | Pre-select a payment provider (eSewa, Khalti, or Fonepay) - or let the customer choose |
| **Collect name**     | No       | Show a "Full name" field before checkout                                               |
| **Collect email**    | No       | Show an "Email address" field before checkout                                          |
| **Collect phone**    | No       | Show a "Phone number" field before checkout                                            |
| **Shipping address** | No       | Ask for a delivery address at checkout                                                 |

4. Click **Create button** - you will see an embed snippet.

## Embedding the button

Copy the snippet and paste it anywhere inside your page's `<body>`:

```html theme={null}
<script
  src="https://api.paybridgenp.com/js/v1/button.js"
  data-button-id="btn_xxx">
</script>
```

The button renders inline, right where the script tag is placed. No additional CSS or JavaScript is required.

<Tip>
  The snippet only contains a button ID. All configuration (label, color, amount, collect fields) is fetched live from the API on each page load. If you change a setting in the dashboard, every page using that button updates automatically - you never need to re-embed.
</Tip>

### Multiple buttons on one page

You can embed multiple buttons on the same page. Each script tag renders independently:

```html theme={null}
<!-- Product A -->
<script
  src="https://api.paybridgenp.com/js/v1/button.js"
  data-button-id="btn_aaa">
</script>

<!-- Product B -->
<script
  src="https://api.paybridgenp.com/js/v1/button.js"
  data-button-id="btn_bbb">
</script>
```

### Inline overrides

In rare cases, you may want the same button to behave differently on different pages (e.g. different amounts for different products). You can override settings with `data-*` attributes on the script tag:

```html theme={null}
<script
  src="https://api.paybridgenp.com/js/v1/button.js"
  data-button-id="btn_xxx"
  data-amount="150000"
  data-label="Buy Premium">
</script>
```

| Attribute                   | Description                                                  |
| --------------------------- | ------------------------------------------------------------ |
| `data-amount`               | Override the amount (in paisa, e.g. `150000` = NPR 1,500.00) |
| `data-label`                | Override the button label text                               |
| `data-color`                | Override the button color (hex, e.g. `#1e00ff`)              |
| `data-collect-name`         | Override collect name setting (`"true"` or `"false"`)        |
| `data-collect-email`        | Override collect email setting (`"true"` or `"false"`)       |
| `data-collect-phone`        | Override collect phone setting (`"true"` or `"false"`)       |
| `data-customer-name`        | Prefill the customer's name                                  |
| `data-customer-email`       | Prefill the customer's email                                 |
| `data-customer-phone`       | Prefill the customer's phone                                 |
| `data-customer-line1`       | Prefill address line 1 (needs `data-customer-city` too)      |
| `data-customer-city`        | Prefill the city (needs `data-customer-line1` too)           |
| `data-customer-line2`       | Prefill address line 2                                       |
| `data-customer-state`       | Prefill the province or state                                |
| `data-customer-postal-code` | Prefill the postal code                                      |
| `data-customer-country`     | Prefill the country (defaults to Nepal)                      |

Inline overrides take precedence over dashboard settings. If an attribute is not present, the dashboard setting is used.

## Prefilling for a customer who is already signed in

If your site already knows who the shopper is, pass it and they will not retype
it:

```html theme={null}
<script
  src="https://api.paybridgenp.com/js/v1/button.js"
  data-button-id="btn_xxx"
  data-customer-name="Ramesh Shrestha"
  data-customer-email="ramesh@example.com"
  data-customer-phone="9812345678">
</script>
```

Render those values from your own session, the same way you would prefill any
other form on your site.

A few things worth knowing:

* **The customer can still edit every field.** These are a starting point, not a
  lock. A stale entry in your customer table has to be fixable at the moment of
  payment.
* **A value we cannot use is dropped, not fatal.** An email that does not parse
  means the customer types that one field. It never fails the checkout.
* **Only fields the button collects are used.** A button that does not ask for a
  phone ignores `data-customer-phone`.
* **An address needs line 1 and the city together.** Either both or neither is
  used, because that is the pair we treat as a usable address. Sending half of
  one would look like it worked and then quietly vanish.
* **This is not a sign-in.** Prefilled details are treated exactly like typed
  ones. They never link a [PayBridgeNP ID](/guides/paybridgenp-id) or mark
  contact details as verified — that still needs a one-time code from the
  customer.

<Note>
  These values are read from your page, so treat them as a convenience for the
  customer rather than a record of who paid. The payment record is what your
  webhook and the API return, not what the page sent.
</Note>

## Customer experience

When a customer clicks the button:

1. A secure modal opens with the PayBridgeNP branding and the button's color
2. If collect fields are enabled, the customer fills in their name, email, or phone
3. For custom-amount buttons, the customer enters the amount in NPR
4. The customer clicks the pay button inside the modal
5. A checkout session is created and the customer is redirected to the selected payment provider
6. After payment, the customer is redirected to your return URL with `session_id`, `status`, and `payment_id` query parameters

### Return URL parameters

After payment, your return URL receives these query parameters:

```
https://yoursite.com/thank-you?session_id=cs_xxx&status=success&payment_id=pay_xxx
```

| Parameter    | Description                              |
| ------------ | ---------------------------------------- |
| `session_id` | The checkout session ID                  |
| `status`     | `success` or `failed`                    |
| `payment_id` | The payment ID (only present on success) |

<Warning>
  Do not rely solely on the return URL parameters to confirm payment. A customer can modify the URL. Always verify payment status server-side with a [webhook](/guides/webhook-verification). See [Confirming a payment](/guides/confirming-payments) for the full pattern.
</Warning>

## Validation

The payment button validates customer input before submitting:

| Field           | Validation                                   |
| --------------- | -------------------------------------------- |
| Full name       | At least 2 characters                        |
| Email           | Valid email format (e.g. `user@example.com`) |
| Phone           | 7-15 digits, optional `+` prefix             |
| Amount (custom) | Positive number in NPR                       |

These rules are enforced both in the client-side modal and on the API. Invalid input will not create a checkout session.

## Webhooks

Payment button transactions fire the same webhooks as API-created checkout sessions. The payload is identical - it does not carry a dedicated payment-button identifier.

Set up a webhook endpoint in the dashboard to receive `payment.succeeded` events. See [Webhook verification](/guides/webhook-verification) for details.

## Managing buttons

### Enable / disable

Toggle a button on or off from the dashboard table. Disabled buttons are invisible - the script tag renders nothing on your page, so visitors see a blank space instead of a broken button.

### Editing

Click the edit icon on any button to change its settings. Since the button fetches config live, changes take effect on the next page load. No action is needed on your website.

### Deleting

Deleting a button is permanent. Any pages still using its embed snippet will render nothing.

### Stats

The dashboard table shows per-button stats:

| Column       | Description                                       |
| ------------ | ------------------------------------------------- |
| **Payments** | Number of successful payments through this button |
| **Volume**   | Total NPR amount collected through this button    |

## Sandbox testing

Payment buttons are scoped to the API key used to create them. A button created with a `sk_test_…` key uses sandbox credentials and test payment flows. A button created with a `sk_live_…` key processes real payments.

See [Sandbox testing](/guides/sandbox-testing) for provider-specific test credentials.

## Limitations

* Payment buttons are created and managed from the dashboard only - there is no API to create them programmatically
* Each project can have up to 200 buttons
* The button script requires JavaScript to be enabled in the customer's browser
* The button renders as an inline-block element with a max width of 340px
* Custom CSS cannot be applied to the button (styling is self-contained to prevent conflicts with your site)
