> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tagada.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Merchant-of-Record sub-merchants

> Provision sub-merchants under your OWN payfac umbrella — shared account holder + settlement balance account, per-sub-merchant statement descriptors, no KYB pipeline. Returned active immediately.

# Merchant-of-Record sub-merchants

<Note>
  **Beta.** The Merchant-of-Record sub-merchant system is in **beta**: it is rolled out to selected partners case by case, and its API surface and behavior may still change. Coordinate with your account manager before using it in production.
</Note>

Some partners are the **Merchant-of-Record (MoR)** for the businesses they serve: they hold the acquiring contract, funds settle to **them**, and they redistribute to their sub-merchants off-platform. For that model, spinning up a full KYB'd payfac tree per sub-merchant is wrong — the sub-merchant is not the legal merchant, you are.

`partners.processing.subMerchants.create()` provisions a sub-merchant **under your own Adyen umbrella**: it reuses your legal entity, account holder and **settlement balance account**, and only creates a dedicated acquiring point (its own store + statement descriptor). It is returned **`active` immediately** — no requirements, no `provision()`.

<Warning>
  **This is opt-in per partner.** The MoR sub-merchant system must be enabled for your partner account (ask your account manager). Until then, `subMerchants.create()` returns `403 mor_sub_merchant_not_enabled`.
</Warning>

<Note>
  **Not a MoR?** If each of your merchants is the legal merchant (their own KYB, their own payouts), use [Processing provisioning (TPAs)](/developer-tools/partners/accounts) instead — **payfac:** `tpas.create()` + requirements + `provision()`; **CRM-only:** `applications.create({ accountId })` or embed. Don't use this page.
</Note>

***

## Two provisioning models, side by side

|                                     | `tpas.create()` (standalone) | `subMerchants.create()` (MoR)         |
| ----------------------------------- | ---------------------------- | ------------------------------------- |
| Adyen legal entity / account holder | **its own** (KYB'd)          | **shared** — yours                    |
| Settlement balance account          | its own                      | **shared** — yours                    |
| Statement descriptor                | per account holder           | **per sub-merchant** (own store)      |
| KYB requirements + documents        | required                     | **none** (you are the MoR)            |
| `provision()` step                  | required to go live          | **none** — returned `active`          |
| Payouts                             | Tagada pays the merchant     | **Tagada pays you**; you redistribute |
| `payfacMode`                        | `non_mor`                    | `mor`                                 |
| `parentTpaId`                       | `null`                       | your root TPA                         |

Everything **downstream of provisioning is identical**: mint a processing key on the sub-merchant, tokenize with `core-js`, and `payments.process()`. The [Quick Start](/developer-tools/partners/quick-start) charge flow works unchanged on a sub-merchant key.

***

## What gets created

```
Your partner root TPA (tpa_root)          ← your KYB'd Adyen tree
  │  legal entity · account holder · settlement balance account
  │
  └── Sub-merchant (tpa_child, payfacMode: 'mor')
        ├── Adyen business line   ← the sub-merchant's MCC + storefront URL
        └── Adyen store           ← its own statementDescriptor
```

Only the **business line + store** are new on Adyen. The account holder and balance account are yours — that's why funds settle to you. The sub-merchant's CRM store (`store_xxx`, for checkout & payment routing) comes with its CRM merchant — it is auto-provisioned by `partners.crm.merchants.create()` in step 1 below.

On the Tagada side, `subMerchants.create()` also wires the **charge routing** for you: a router processor pointing at the sub-merchant, a default payment flow, and the link to its CRM store. The sub-merchant is chargeable as soon as the call returns — no extra setup.

***

## Prerequisites

1. **A provisioned root TPA** — your own `tpa_xxx`, fully `active` on Adyen (legal entity + account holder + balance account). This is the umbrella every sub-merchant nests under. Provision it the normal way once ([Processing provisioning](/developer-tools/partners/accounts)).
2. **MoR enabled** for your partner account, with your root TPA set as the default parent (optional — you can also pass `parentTpaId` on every call).

***

## Provision a sub-merchant

Each sub-merchant needs **its own CRM merchant** (`acc_xxx`) — sub-merchants share your balance account, so the `(account, balance-account)` pair must stay unique. Create the merchant first, then the sub-merchant.

```ts theme={null}
const partner = new Tagada(process.env.TAGADA_PARTNER_KEY!);

// 1. The sub-merchant's own CRM account (idempotent on externalRef).
const acc = await partner.partners.crm.merchants.create({
  legalName: 'Boutique Zoé',
  externalRef: 'zoe',
});

// 2. Provision the sub-merchant under your umbrella.
const sub = await partner.partners.processing.subMerchants.create({
  parentTpaId: 'tpa_your_root',       // omit to use your configured default
  accountId: acc.id,                   // required — its own acc_xxx
  legalName: 'Boutique Zoé',
  statementDescriptor: 'ZOE PARIS',    // ≤ 22 chars — what the cardholder sees
  webAddress: 'https://zoe.example',
  industryCode: '4431A',               // Adyen industry code — omit to inherit the parent's
  storePhone: '+33170700000',          // required — store contact phone (E.164)
  address: {                           // required — Adyen needs a full store address
    street: '12 rue de la Paix',
    city: 'Paris',
    postalCode: '75002',
    country: 'FR',
  },
  externalRef: 'zoe',                  // idempotency
});

// →
// {
//   object: 'tpa',
//   id: 'tpa_child',
//   accountId: 'acc_child',
//   parentTpaId: 'tpa_your_root',
//   payfacMode: 'mor',
//   status: 'active',        // ← live immediately, no provision()
//   ...
// }
```

<Note>
  **Idempotent.** A second call with the same `externalRef` returns the same sub-merchant (`created=false`, `X-Tpa-Idempotent-Replay: 1`). Safe to retry.
</Note>

### Charge on it — same as any TPA

```ts theme={null}
// A processing key scoped to the sub-merchant.
const key = await partner.partners.processing.tpas.keys.create(sub.id);

// The charge targets the sub-merchant's CRM store. Resolve it once with a
// CRM key minted on the merchant (stores are account-scoped):
const crmKey = await partner.partners.crm.merchants.keys.create(acc.id);
const merchantClient = new Tagada(crmKey.token);
const { data: stores } = await merchantClient.stores.list();
const storeId = stores[0].id; // auto-created with the CRM merchant

// then tokenize (core-js) + payments.process({ storeId, ... }) with the
// processing key — exactly as in the Quick Start.
```

<Note>
  **Card scheme activation is asynchronous on Adyen's side.** The store is `active` immediately, but Visa/Mastercard/Amex enablement on a brand-new store can take a short while to propagate (typically minutes). If a first charge declines right after provisioning, retry after a few minutes before digging further.
</Note>

***

## Statement descriptor

`statementDescriptor` is the **only** per-sub-merchant branding on the cardholder's statement (Adyen `shopperStatement`, capped at **22 chars**). Because each sub-merchant gets its own Adyen store, two sub-merchants under the same umbrella show **different** descriptors — even though they settle to the same balance account.

***

## Settlement & payouts

<Warning>
  **Funds settle to YOU, not the sub-merchant.** Every charge on a sub-merchant lands in your (the partner's) settlement balance account. Tagada does **not** pay out to sub-merchants in MoR mode — redistributing to them is your responsibility, off-platform. The split stays as configured: Tagada's commission and your markup are kept as separate legs; the remainder settles into your balance account.
</Warning>

For the same reason, sub-merchant balance/ledger views in reporting reflect the **shared** (partner) balance account — treat the partner account as the source of truth for money movement.

To observe payouts and the balance ledger over the API (always on your **root** TPA), see [Payouts, balances & fees](/developer-tools/partners/payouts).

***

## What you cannot do on a sub-merchant

| Action                                             | Why                                                                                                 |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| `tpas.provision()`                                 | No payfac tree of its own — it reuses yours. Returns an error.                                      |
| `tpas.requirements.*` / `documents.*` (to go live) | No Adyen KYB — you are the MoR.                                                                     |
| Generate a hosted onboarding (KYC) link            | No legal entity of its own.                                                                         |
| Trigger a payout / debt collection / FX sweep      | Money movement runs on the parent only — blocked on children to protect the shared balance account. |

These are enforced server-side: dangerous operations on a sub-merchant **child** (`parentTpaId` set) are refused so they can never mutate or drain the shared parent tree.

***

## Errors

| HTTP | Code                               | When                                                                                                                     |
| ---- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| 403  | `partner_scope_required`           | The API key is not partner-scoped                                                                                        |
| 403  | `mor_sub_merchant_not_enabled`     | The system isn't enabled for your partner account                                                                        |
| 400  | `missing_parent_tpa`               | No `parentTpaId` and no configured default                                                                               |
| 404  | `parent_not_found`                 | `parentTpaId` doesn't exist                                                                                              |
| 403  | `parent_not_owned`                 | The parent TPA belongs to another partner                                                                                |
| 422  | `parent_is_sub_merchant`           | You pointed at a child — nest under a **root** TPA                                                                       |
| 422  | `parent_not_adyen`                 | MoR sub-merchants are Adyen-only                                                                                         |
| 422  | `parent_not_provisioned`           | The parent's Adyen tree isn't fully provisioned yet                                                                      |
| 404  | `merchant_not_found`               | `accountId` doesn't exist — create it first via `partners.crm.merchants.create()`                                        |
| 403  | `merchant_access_denied`           | `accountId` belongs to another partner                                                                                   |
| 409  | `account_balance_collision`        | That `acc_xxx` already has a TPA on this balance account — use a distinct account                                        |
| 422  | `sub_merchant_provisioning_failed` | The Adyen leg failed (e.g. incomplete store address, missing `storePhone`, invalid industry code) — the message says why |

***

## Next step

<Card title="Charge a sub-merchant" icon="credit-card" href="/developer-tools/partners/payments">
  The card flow, instruments, 3DS, APMs and refunds are identical to any TPA — mint a processing key on the sub-merchant and go.
</Card>
