# Blesta

> A payment gateway for Blesta: clients pay invoices in bitcoin or USDC/USDT straight to your wallet, recorded by a signed webhook.

The Perly Pay gateway adds crypto to your Blesta invoices. The client chooses **Perly Pay** under Pay or in the order form; on "Review and confirm" the gateway makes an invoice in Perly Pay for exactly the amount Blesta worked out, and **Pay with crypto** opens it. A signed webhook records the payment in Blesta. Blesta 6, or Blesta 5 on PHP 8.1 or later, with PHP's `curl` and `json`. Nothing to install with Composer: the [PHP SDK](https://pay.perly.io/docs/sdks.md) is inside.

> **Note:** Perly Pay bills in USD or EUR, and the gateway says so to Blesta, so Blesta offers it only on payments in those two currencies.

## Install

1. **Get the gateway** — Download `perly-pay-blesta.zip` from the latest release on [GitHub](https://github.com/volodymyrslipak/perly-pay-blesta/releases/latest).
2. **Upload** — Unzip it over your Blesta folder. It adds `components/gateways/nonmerchant/perly_pay/`.
3. **Install** — Settings → Company → Payment Gateways → Available, find **Perly Pay** and press **Install**. It makes one table, `perly_pay_invoices`.

## Settings

| Setting | What to put |
| --- | --- |
| Secret key | From Dashboard → Developers → API keys. `sk_test_…` for [test mode](https://pay.perly.io/docs/test-mode.md), `sk_live_…` for real money. Full access, or Restricted with **Webhook endpoints** ticked: **Test connection** reads your webhooks. |
| Webhook signing secret | `whsec_…`, from the webhook you add for this Blesta (below). Until it is saved, clients see no button. |
| Payment page | **Over the Blesta page (overlay)** opens the checkout over Blesta's page. **On pay.perly.io (redirect)** sends the client to it. Phones always get the page itself. |

1. **Paste the key** — Save, then press **Test connection**: it says whether the key works, its mode, and whether this Blesta's webhook is in Perly Pay.
2. **Add the webhook** — In Dashboard → Developers → Webhooks, add the address the settings show, `https://your-blesta/callback/gw/1/perly_pay/` (`1` is the company), with the invoice and refund events. Paste its secret and save.
3. **Allow the overlay** — For the overlay, add your Blesta address in Dashboard → Settings → Checkout → **Sites that may embed the checkout**.

Running several companies? Each has its own gateway, its own callback address (`/callback/gw/<company id>/perly_pay/`) and its own webhook in Perly Pay.

## What clients pay with

The client picks a coin and network on the payment page and pays from any wallet. The money goes straight to yours.

| Coin | Networks |
| --- | --- |
| BTC | Bitcoin |
| USDC | Base, Arbitrum, Optimism and Ethereum |
| USDT0 | Arbitrum and Optimism |
| USDT | Ethereum and TRON |

> **Note:** The gateway is free and open source (MIT). Perly Pay costs 2.5¢ a payment, never more than 0.5% of it, billed after the month. A month of up to 21 payments costs $0. Nothing is taken from the payment: see [Pricing](https://pay.perly.io/pricing).

## Test

With a `sk_test_…` key, pay an invoice in the client area with **Perly Pay**. Pay it with test coins, or from the API — the invoice id `inv_…` is on the checkout page:

```bash
curl -X POST https://pay.perly.io/api/v1/invoices/inv_…/simulate \
  -H "Authorization: Bearer $PERLY_PAY_SECRET_KEY" -H "Content-Type: application/json" -d '{}'
```

Within seconds the Blesta invoice is **Paid**.

## How invoices follow payments

| In Perly Pay | In Blesta |
| --- | --- |
| Paid and the sender checked (`invoice.fulfilled`) | A transaction for the amount billed, applied to the invoices it pays, and the client is emailed, as for any payment. The transaction id is the Perly Pay invoice (`inv_…`), its reference the first transfer (`pay_…`), its note the coin and network. |
| Part paid, expired, held for [review](https://pay.perly.io/docs/screening.md) | A line in the gateway log (Tools → Logs → Gateway). No payment. |
| Refund events | A line in the gateway log, from the refund as Perly Pay's API returns it. |

A payment Blesta already has is never handed over again, so a replayed webhook records nothing twice and sends no second email. When the client comes back, Blesta's "payment received" page shows the payment as approved or pending; the webhook records it. Crypto cannot be pulled from a wallet, so there are no automatic recurring charges: each invoice is paid when the client pays it.

## Refunds

Refund the transaction in Blesta as usual: the gateway opens a [refund](https://pay.perly.io/docs/refunds.md) in Perly Pay, in the coin that was paid (the same share of it for part). Perly Pay emails the client for an address; you send from your wallet and paste the transaction id in Perly Pay. Blesta marks the transaction refunded once the refund is open. Blesta refunds a transaction once: refund the rest of the same payment from the Perly Pay dashboard.

## Go live

- Turn on live mode in Perly Pay and connect your wallet's public keys.
- Paste a `sk_live_…` key. Live keys and webhooks are separate from test ones: add the callback address again as a live webhook and paste its secret.
- For the overlay, add your Blesta's https address to **Sites that may embed the checkout** in live mode too: test and live keep separate lists.
- Pay one small real invoice and refund it.
