# Zapier

> Payments into Google Sheets, Notion, your CRM or Discord without code: triggers for paid invoices, refunds, subscriptions and customers; actions to make invoices and payment links.

The Perly Pay app connects your payments to the thousands of apps on Zapier. A paid invoice can add a row to a sheet, a member to a CRM or a role in Discord; a form can create an invoice and email its payment page. Nothing to host and no code.

> **Note:** A test key and a live key are two connections. A Zap 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 Zap** — The app is on its way to Zapier's directory. Until it is listed, [write to us](https://pay.perly.io/contact) for an invite link; then search **Perly Pay** in a Zap.
3. **Connect** — Paste the key. The connection is named by its mode and the key's last four, like **Test mode · …4f2a**.

## Triggers

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

Turning a Zap on adds a webhook in Dashboard → Developers → Webhooks, named like **Zapier: Invoice Paid**; turning it off removes it. Leave those webhooks as they are: Zapier keeps their secret and checks every delivery's [signature](https://pay.perly.io/docs/webhooks.md) with it. Each Zap's trigger uses one of the 16 webhooks a mode may have.

Each trigger gives the object it is about — the invoice, refund, subscription or customer — with every field the [API](https://pay.perly.io/docs/api.md) has. Amounts come twice: as the API keeps them, in cents (`total` 4900), and ready for a sheet (`total_decimal` 49.00). **Items** says what was bought.

## Actions

| Action | Give it | You get |
| --- | --- | --- |
| Create 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 Payment Link | A price, or a new product's name and amount | A page that sells it, to share anywhere |
| Find Customer | An email | The customer, or nothing |

## Recipes

### Payment → row in Google Sheets

1. **Trigger** — Perly Pay → **Invoice Paid**. Test it: Zapier shows your last paid invoices (in test mode, pay one first).
2. **Action** — Google Sheets → **Create Spreadsheet Row**, in a sheet with columns like Date, Email, Items, Amount, Coin.
3. **Map** — Date → Paid At, Email → Customer Email, Items → Items, Amount → Total, Coin → 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. **Zap 1: the invoice** — Trigger: your sign-up form (Typeform, Google Forms, Tally) asking for email and Discord user id. Action: Perly Pay → **Create Invoice**, metadata `discord_user_id` = the form's answer. Action: email the buyer the **Payment Page URL**.
2. **Zap 2: the role** — Trigger: Perly Pay → **Invoice Paid**. Action: Discord → **Add Role to User**: your server, the role, and User = the invoice's metadata `discord_user_id`.
3. **Take it back** — For a subscription, a third Zap on **Subscription Ended** removes the role the same way.

## Test

With a test connection, create an invoice (by the action, 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 **Invoice Paid** runs. Zap History shows each run and what it sent.

## Go live

- Turn on live mode in Perly Pay and connect your wallet's public keys.
- In each Zap, switch the Perly Pay step to a new connection with a `sk_live_…` key, and turn the Zap off and on so its webhook moves to live mode.
- Pay one small real invoice and watch it arrive.
