# Platform

A platform is a merchant that creates merchants of its own\: a creator on a donation page, a shop on a marketplace. Each one is a real Mayarin merchant with its own settlement address, so the money goes to them and not through you. `mayarin.platform` creates and manages them; `mayarin.forMerchant(id)` acts for one.

It needs a **secret key that holds `merchants:provision`**, a permission you give the key on the dashboard's **API keys** page. It only ever reaches merchants you created.

| Method                                    | Returns                    | Use it for                                          |
| ----------------------------------------- | -------------------------- | --------------------------------------------------- |
| `platform.merchants.create(body)`         | `PlatformMerchantDto`      | Make a merchant of your own.                        |
| `platform.merchants.get(id)`              | `PlatformMerchantDto`      | Read one.                                           |
| `platform.merchants.list(filter?)`        | `PlatformMerchantListDto`  | One page, newest first.                             |
| `platform.merchants.listAll(filter?)`     | `AsyncGenerator`           | Every merchant, page after page.                    |
| `platform.merchants.update(id, body)`     | `PlatformMerchantDto`      | Rename, edit the profile, or repoint the payout.    |
| `platform.keys.create(id, body)`          | `CreatedPlatformKeyDto`    | Mint a `publishable` or `alert` key. Secret shown once. |
| `platform.keys.list(id)`                  | `PlatformKeyDto[]`         | The keys, never their secrets.                      |
| `platform.keys.deactivate(id, keyId)`     | `PlatformKeyDto`           | Stop a key at once.                                 |
| `platform.settlementProofRequest(input)`  | `SettlementProofRequest`   | The message a creator signs to set their payout.    |
| `forMerchant(id)`                         | `MayarinClient`            | Act as one of your merchants.                       |

```ts
const creator = await mayarin.platform.merchants.create({
  externalId: "creator_8841", // your own id, unique among your merchants
  name: "Warung Kopi Live",
  city: "Jakarta",
  countryCode: "ID",
});

creator.id; // "mrc_01KZ…"
creator.settlementAddress; // null: it cannot take a payment yet
```

## Where the creator is paid

**The creator decides, not you.** An address is set or changed only with a proof signed by a wallet at that address. A platform that is breached, or turns bad, cannot repoint a payout; it can only ask the creator to sign.

`settlementProofRequest` builds what they sign\: a message naming you, the creator, the address, an expiry and a one-time nonce.

```ts
const request = mayarin.platform.settlementProofRequest({
  platformMerchantId: "mrc_your_own_id",
  externalId: creator.externalId,
  address: creatorWallet, // an EVM address they control
});

// In the creator's browser, with their wallet (viem):
const signature = await walletClient.signMessage({ account: creatorWallet, message: request.message });

await mayarin.platform.merchants.update(creator.id, {
  settlement: request.withSignature(signature),
});
```

The proof is valid for 15 minutes by default and at most an hour (`ttlMinutes`). The signature must be a plain wallet signature (EIP-191 personal sign) from an externally owned account\: a smart-contract wallet such as a Safe cannot sign this way yet. Create the merchant with `settlement` set to do both in one call.

## Acting for a merchant

`forMerchant(id)` returns a client that does everything as that merchant\: it sends the `Mayarin-Merchant` header, so a payment it creates belongs to the creator, and `payment.list` lists theirs.

```ts
const asCreator = mayarin.forMerchant(creator.id);

const intent = await asCreator.payment.createIntent({
  merchant: { id: creator.id, name: creator.name, city: "Jakarta", countryCode: "ID" },
  amount: { amount: "50000.00", asset: "IDR" },
  metadata: { donor: "Budi", message: "Semangat!" },
});

const history = await asCreator.payment.list({ status: "COMPLETED" });
```

You keep one secret key, not one per creator. The client has your key's other permissions (`payments:read`, `catalog:manage`, …) and **not** `merchants:provision`\: acting as a creator cannot create more merchants. A key that does not hold the permission, or a merchant that is not yours, is refused (`403`, and `404` for a merchant that is another platform's, as if it did not exist).

## Keys for the creator

A creator's checkout page and overlay need keys of their own\:

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

A `publishable` key is for a checkout page and an `alert` key is for a livestream overlay, which reads the [live feed](/sdk/typescript/feed). A secret key is never minted for a creator. Deactivate a key with `keys.deactivate`, and a merchant may hold 20 active keys.

## Limits

* A platform may create 1000 merchants.
* `externalId` is unique among your merchants (`409`, with the existing merchant's id in `details`).
* Mayarin can turn a merchant off; it then takes no new payment, and `disabled` is `true`.
* Every change you make to a merchant is written to its change history under your platform.

The wire format is in the [API reference](/api-reference/platform), and a walk-through is in [Platforms](/guides/platforms).
