# Platforms

This guide is for a product with many payees\: creators who take donations, shops on a marketplace. Each payee is a Mayarin merchant of its own, settled to its own wallet, so you never hold their money. It uses the [platform module](/sdk/typescript/platform), the [live feed](/sdk/typescript/feed) and [`payment.list`](/sdk/typescript/payments#list-payments).

## 1. Give a key the permission

On the dashboard, open **API keys**, mint a **secret** key and tick **Create and manage merchants for your platform**, together with `payments:read` for the history. Any merchant may do this. Keep the key on your server.

## 2. Create a merchant for each creator

When someone signs up on your product, create their merchant\:

```ts
const creator = await mayarin.platform.merchants.create({
  externalId: user.id,
  name: user.displayName,
  city: user.city,
  countryCode: "ID",
});
```

Save `creator.id` with the user. Your own database holds accounts and passwords; Mayarin holds the payment side.

## 3. Let the creator choose where they are paid

Ask for their wallet address and have them sign a message that names it\:

```ts
const request = mayarin.platform.settlementProofRequest({
  platformMerchantId: process.env.MAYARIN_MERCHANT_ID,
  externalId: user.id,
  address,
});
// show request.message in their wallet, then:
await mayarin.platform.merchants.update(creator.id, { settlement: request.withSignature(signature) });
```

Because the wallet signs, you can never repoint a creator's payout, and neither can anyone who breaches you. Until it is set the creator cannot take a payment.

## 4. Take a donation

Create the payment as the creator, carrying what the donor typed\:

```ts
const intent = await mayarin.forMerchant(creator.id).payment.createIntent({
  merchant: { id: creator.id, name: creator.name, city: creator.city, countryCode: "ID" },
  amount: { amount: "50000.00", asset: "IDR" },
  metadata: { donor: name.slice(0, 40), message: message.slice(0, 280) },
});

redirect(intent.checkoutUrl);
```

Donors need no account. Treat what they typed as untrusted text\: escape it, and validate its length.

## 5. Show it live and keep a history

Mint an alert key for the creator's overlay and give them the URL of your overlay page\:

```ts
const { secret } = await mayarin.platform.keys.create(creator.id, { kind: "alert", name: "OBS overlay" });
```

The page listens with [`feed.stream()`](/guides/livestream-alerts), and the creator's history is `mayarin.forMerchant(creator.id).payment.list()`.

## What you can and cannot do

| You can                                               | You cannot                                       |
| ----------------------------------------------------- | ------------------------------------------------ |
| Create merchants (up to 1000) and rename them         | Repoint a payout without the wallet's signature  |
| Create payments and read history as a creator         | Reach a merchant that is not yours               |
| Mint publishable and alert keys for a creator         | Mint a secret key for a creator                  |
| Deactivate a creator's keys                           | Create merchants while acting as a creator       |

If you stop paying attention to a key, deactivate it from **API keys**\: every call it made stops at once.
