# Make

> Payments into any Make scenario: instant triggers for paid invoices, refunds, subscriptions and customers; modules to make invoices and payment links and to look them up.

The Perly Pay app brings your payments to Make. A paid invoice can fill a sheet, update a CRM or give a Discord role; a form can create an invoice and send its payment page. Nothing to host and no code.

> **Note:** A test key and a live key are two connections. A scenario on a test connection only ever sees test payments.

## Connect

1. **Get a key** — In Perly Pay, Dashboard → Developers → API keys. `sk_test_…` for [test mode](https://pay.perly.io/docs/test-mode.md), `sk_live_…` for real money.
2. **Add Perly Pay to a scenario** — The app is on its way to Make's app list. Until it is listed, [write to us](https://pay.perly.io/contact) for its invite link; open it once, then search **Perly Pay** when you add a module.
3. **Connect** — **Add** a connection and paste the key. Name it so you can tell test from live.

## Instant triggers

| Module | When | Event |
| --- | --- | --- |
| Watch Paid Invoices | Paid in full and the sender checked. The moment to give access or ship. | `invoice.fulfilled` |
| Watch Underpaid Payments | The buyer sent less than the invoice asks. | `invoice.underpaid` |
| Watch Opened Refunds | You opened a [refund](https://pay.perly.io/docs/refunds.md). | `refund.requested` |
| Watch Confirmed Refunds | The refund you sent is confirmed on chain. | `refund.confirmed` |
| Watch Started Subscriptions | A [subscription](https://pay.perly.io/docs/subscriptions.md) starts. | `subscription.created` |
| Watch Renewed Subscriptions | A subscriber paid for the next period. | `subscription.renewed` |
| Watch Ended Subscriptions | It ended. The moment to take access away. | `subscription.ended` |
| Watch New Customers | A new buyer. | `customer.created` |

Adding a trigger's webhook in Make adds one in Dashboard → Developers → Webhooks, named like **Make: Paid Invoices**; deleting it in Make removes it. Make reads every delivery back from Perly Pay with your key before the scenario runs, so a request that did not come from Perly Pay runs nothing. Each webhook is one of the 16 a mode may have.

Each trigger gives the event and the object it is about — the invoice, refund, subscription or customer — as the [API](https://pay.perly.io/docs/api.md) has it. Fiat amounts are in cents (`total` 4900 is 49.00): divide by 100 in a mapping. Coin amounts are in the coin's smallest unit, with its `decimals`.

## Modules

| Module | Give it | You get |
| --- | --- | --- |
| Create an Invoice | Amount (like 49.00), description; optional currency, customer email, return URL, metadata | The invoice, with its payment page (**Payment page URL**) to send the buyer |
| Create a Payment Link | A price, or a new product's name and amount | A page that sells it, to share anywhere |
| Get an Invoice | An invoice ID | Its status, what arrived, its payment page |
| Search Customers | An email, or nothing for all | Customers, newest first |

## Recipes

### Payment → row in Google Sheets

1. **Trigger** — Perly Pay → **Watch Paid Invoices**. Add the webhook; run the scenario once and pay a test invoice so Make learns the fields.
2. **Action** — Google Sheets → **Add a Row**, in a sheet with columns like Date, Email, Amount, Coin.
3. **Map** — Date → Invoice: Paid at, Email → Customer email, Amount → `Total (cents) / 100`, Coin → Payment: Coin. Turn it on.

### Payment → Discord role

Discord needs to know who paid. Put the buyer's Discord user id on the invoice when you make it, and read it back when it is paid.

1. **Scenario 1: the invoice** — Trigger: your sign-up form asking for email and Discord user id. Perly Pay → **Create an Invoice**, metadata key `discord_user_id`, value the form's answer. Then email the buyer the **Payment page URL**.
2. **Scenario 2: the role** — Perly Pay → **Watch Paid Invoices**. Discord → **Add a Role to a Member** (or **Make an API Call** to Discord): your server, the role, and the member = Invoice: Metadata → `discord_user_id`.
3. **Take it back** — For a subscription, **Watch Ended Subscriptions** removes the role the same way.

## Test

With a test connection, create an invoice (by the module, or in the dashboard) and pay it with test coins, or from the API with the invoice's id:

```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 scenario runs. Its History shows each run and what came in.

## Go live

- Turn on live mode in Perly Pay and connect your wallet's public keys.
- Add a connection with a `sk_live_…` key. In each scenario, add a new webhook on it for the trigger, and switch the other Perly Pay modules to it.
- Pay one small real invoice and watch it arrive.
