Merchants
Onboard and manage the merchants under your organization — create, update, deactivate, or delete merchants, review their activity trail, and manage their members and invitations.
A merchant is a business you onboard under your organization. Every payment-facing resource in Tokeflow — customers, transactions, orders, catalog, connectors — belongs to exactly one merchant, so the merchant is the unit of isolation for data, routing configuration, and API key scoping.
This page covers the organization-level merchant surface: listing and onboarding merchants, updating their details, retiring them, reading their activity trail, and managing the members (dashboard users) of each merchant. Creating a merchant also provisions its first owner: you supply a primary_email, and Tokeflow sends that person an invitation to the merchant dashboard.
These endpoints accept Organization API keys only. Merchant keys are scoped to a single merchant and cannot manage the merchant roster — calls with a Merchant key return 403. See Authentication.
Merchant lifecycle
Two moments in the lifecycle deserve attention. First, once a merchant is enrolled with the card networks (for network token provisioning), the fields sent at enrollment — name, website, mcc, and the address — are fixed at the networks and can no longer be changed through PATCH. Second, deletion is reserved for merchants created in error: a merchant with any activity is kept for reporting and reconciliation, and DELETE refuses it with 409. Deactivate it instead.
The merchant object
| Field | Type | Description |
|---|---|---|
id | string | Unique merchant ID, prefixed mrc_. |
organization_id | string | Organization this merchant belongs to, prefixed org_. |
name | string | Merchant name. |
slug | string | Merchant slug — unique, URL-safe identifier. Auto-generated at creation when not provided. |
external_reference | string | null | Your own reference/ID for this merchant, echoed back for reconciliation. |
business_registration_number | string | Business registration number (tax ID — CNPJ, EIN, VAT). |
mcc | string | Merchant Category Code (MCC), four digits. |
phone_number | string | Contact phone number, in E.164. Input is accepted in any human format and normalized before storage, so responses always carry the canonical form. |
address | object | Merchant address. See The address object. |
website | string | null | Official website URL. |
network_tokens_enabled | boolean | Whether network-token provisioning is switched on for cards saved under this merchant. Explicit opt-in, false by default; see Network tokens. |
saved_card_checkout_enabled | boolean | Whether this merchant's server may pay a checkout session with a customer's saved card (stored provider credential, no CVV). Explicit opt-in, false by default; see Saved-card checkout. |
status | string | One of active, inactive, suspended. |
created_at | string | Timestamp when the merchant was created (ISO 8601 UTC). |
updated_at | string | Timestamp when the merchant was last updated (ISO 8601 UTC). |
Merchant status
| Value | Meaning |
|---|---|
active | Operating normally. New merchants are created in this status. |
inactive | Deactivated. Use this to retire a merchant while keeping its records for reporting. |
suspended | Temporarily blocked by the organization. |
Network tokens
Tokeflow can provision a network token for each card saved under a merchant, so stored credentials keep working across reissues and expiries. Provisioning is an explicit, per-merchant opt-in: network_tokens_enabled is false for a new merchant and nothing is provisioned until you set it to true through PATCH. Tokens are billed per provision, and the merchant must be enrolled with the card networks first (the enrollment happens automatically once website, mcc and the address are complete). Turning the flag off stops new provisioning; saved cards keep working through the provider credentials kept at enrollment, which is also what one-click charges use.
Saved-card checkout
saved_card_checkout_enabled lets your server pay a checkout session with a card the customer saved earlier — checkout_session_id plus payment_instrument_id and credential_on_file: true on POST /transactions — instead of asking for the card again. It is false for every merchant until you set it to true through PATCH. Turning it on is a statement that your server authenticates the customer before identifying them on a session: on a session Tokeflow never sees the cardholder, so the charge relies on your login. While it is off, any saved-card use on a session without a fresh card_ciphertext_id is refused with 400.
Settings Tokeflow can override
network_tokens_enabled and saved_card_checkout_enabled are the merchant's own settings. Tokeflow can also switch either feature on or off for a whole organization or for a single merchant — for example while a feature is rolling out — and that setting wins. The value you read on the merchant is therefore the one you chose, and the effective behavior can differ from it. A request refused because of a Tokeflow setting says so in its error message; to have it reviewed, contact the Tokeflow team.
The address object
| Field | Type | Description |
|---|---|---|
line_1 | string | Street and number. |
line_2 | string | Apartment, suite, etc. Optional. |
zip_code | string | ZIP/postal code. |
city | string | City. |
state | string | State/province code. |
country | string | ISO 3166-1 alpha-2 country code, e.g. BR. |
The member object
Members are the users of a merchant's dashboard. A member is a membership: the link between a user identity (unique by email within your organization) and one merchant, with a role. The same person can hold memberships on several merchants.
| Field | Type | Description |
|---|---|---|
membership_id | string | Membership ID — identifies this user-on-this-merchant link. |
user_id | string | User ID — the underlying identity, shared across the user's memberships. |
email | string | User email. |
name | string | User display name. |
role | string | Role within the merchant: owner, admin, or viewer. |
joined_at | string | Date the user joined the merchant. |
status | string | active once the invitation has been accepted, pending until then. |
invitation_expires_at | string | null | When the pending invitation expires; null when the member is active. |
Endpoints
GET/api/v1/merchants
Auth: Organization key only. Scope: merchants:read.
Returns a paginated list of the merchants belonging to the authenticated organization. Supports filtering by status.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by status: active, inactive, or suspended. |
page | integer | No | Page number, 1-indexed (default 1, min 1). |
limit | integer | No | Items per page (default 20, max 100). |
Example request
curl -G https://api.tokeflow.com/api/v1/merchants \
-H "Authorization: Bearer sk_live_org_…" \
--data-urlencode "status=active" \
--data-urlencode "page=1" \
--data-urlencode "limit=20"Example response — 200 OK
{
"data": [
{
"id": "mrc_123",
"organization_id": "org_123",
"name": "John's Store",
"slug": "johns-store",
"external_reference": "internal_id_99",
"business_registration_number": "12345678000199",
"mcc": "5732",
"phone_number": "+5511999990000",
"address": {
"line_1": "Av Paulista, 1000",
"line_2": "Conj 42",
"zip_code": "01310-100",
"city": "São Paulo",
"state": "SP",
"country": "BR"
},
"website": "https://johnsstore.com.br",
"network_tokens_enabled": false,
"saved_card_checkout_enabled": false,
"status": "active",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-11-28T12:10:00Z"
}
],
"meta": {
"pagination": {
"page": 1,
"limit": 20,
"total": 6,
"total_pages": 1,
"has_next": false,
"has_prev": false
}
}
}See Pagination & filtering for how to iterate every page.
POST/api/v1/merchants
Auth: Organization key only. Scope: merchants:write.
Onboards a new merchant under your organization. The merchant is created in active status, and the person at primary_email becomes its first owner: if a user with that email already exists in your organization, they gain a membership on the new merchant; otherwise an identity is provisioned and an invitation email is sent so they can set a password. Emails are matched case-insensitively.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Merchant business name. Must contain at least one alphanumeric character. |
primary_email | string | Yes | Email of the initial merchant owner. The address is the identity — see above. |
primary_name | string | No | Optional display name for the merchant owner. |
external_reference | string | No | Your own reference/ID for this merchant. |
business_registration_number | string | No | Business registration number (CNPJ, EIN, VAT). |
mcc | string | No | Merchant Category Code (MCC), four digits (e.g. 5732). |
website | string | No | Merchant website URL. Required before 3DS sessions can be created for the merchant. |
phone_number | string | No | Business phone number in international format. |
address | object | No | Business address. See The address object. |
slug | string | No | Unique slug for the merchant. Auto-generated when not provided. |
Example request
curl -X POST https://api.tokeflow.com/api/v1/merchants \
-H "Authorization: Bearer sk_live_org_…" \
-H "Content-Type: application/json" \
-d '{
"name": "John'\''s Store",
"primary_email": "owner@johnsstore.com",
"primary_name": "John Smith",
"external_reference": "internal_id_99",
"business_registration_number": "12345678000199",
"mcc": "5732",
"website": "https://johnsstore.com.br",
"phone_number": "+55 11 99999-0000",
"address": {
"line_1": "Av Paulista, 1000",
"zip_code": "01310-100",
"city": "São Paulo",
"state": "SP",
"country": "BR"
}
}'Example response — 201 Created
{
"id": "mrc_123",
"organization_id": "org_123",
"name": "John's Store",
"slug": "johns-store",
"external_reference": "internal_id_99",
"status": "active",
"created_at": "2025-11-28T12:10:00Z"
}The creation response is a compact receipt. Fetch the full merchant object with GET /api/v1/merchants/:id. The owner you provisioned via primary_email appears in the merchant's member list with role owner and status pending until the invitation is accepted.
GET/api/v1/merchants/:id
Auth: Organization key only. Scope: merchants:read.
Retrieves a single merchant belonging to the authenticated organization. Returns the full merchant object.
Example request
curl https://api.tokeflow.com/api/v1/merchants/mrc_123 \
-H "Authorization: Bearer sk_live_org_…"Example response — 200 OK
{
"id": "mrc_123",
"organization_id": "org_123",
"name": "John's Store",
"slug": "johns-store",
"external_reference": "internal_id_99",
"business_registration_number": "12345678000199",
"mcc": "5732",
"phone_number": "+5511999990000",
"address": {
"line_1": "Av Paulista, 1000",
"line_2": "Conj 42",
"zip_code": "01310-100",
"city": "São Paulo",
"state": "SP",
"country": "BR"
},
"website": "https://johnsstore.com.br",
"network_tokens_enabled": false,
"saved_card_checkout_enabled": false,
"status": "active",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}A 404 (not_found_error) is returned if the merchant does not exist or does not belong to the authenticated organization.
PATCH/api/v1/merchants/:id
Auth: Organization key only. Scope: merchants:write.
Updates a merchant. All body fields are optional; only the fields you send are changed.
Once the merchant is enrolled with the card networks, the fields sent at enrollment — name, website, mcc, and the address — are fixed at the networks and can no longer be changed; attempting to returns 409 (conflict_error). status, phone_number, business_registration_number, and external_reference remain editable for the merchant's whole life.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Merchant name. Must contain at least one alphanumeric character. Locked after card-network enrollment. |
status | string | No | One of active, inactive, suspended. |
external_reference | string | No | Your own reference/ID for this merchant. |
business_registration_number | string | No | Business registration number (CNPJ, EIN, VAT). |
mcc | string | No | Merchant Category Code (MCC), four digits. Locked after card-network enrollment. |
website | string | No | Merchant website URL. Required before 3DS sessions can be created for the merchant. Locked after card-network enrollment. |
phone_number | string | No | Business phone number in international format. |
address | object | No | Business address. See The address object. Locked after card-network enrollment. |
network_tokens_enabled | boolean | No | Opt this merchant in (true) or out (false) of network-token provisioning for its saved cards. See Network tokens. |
saved_card_checkout_enabled | boolean | No | Opt this merchant in (true) or out (false) of paying checkout sessions with a customer's saved card. Must be a JSON boolean — the string "false" is rejected. See Saved-card checkout. |
Example request — deactivate a merchant
curl -X PATCH https://api.tokeflow.com/api/v1/merchants/mrc_123 \
-H "Authorization: Bearer sk_live_org_…" \
-H "Content-Type: application/json" \
-d '{ "status": "inactive" }'Example response — 200 OK
{
"id": "mrc_123",
"organization_id": "org_123",
"name": "John's Store",
"slug": "johns-store",
"external_reference": "internal_id_99",
"business_registration_number": "12345678000199",
"mcc": "5732",
"phone_number": "+5511999990000",
"address": {
"line_1": "Av Paulista, 1000",
"line_2": "Conj 42",
"zip_code": "01310-100",
"city": "São Paulo",
"state": "SP",
"country": "BR"
},
"website": "https://johnsstore.com.br",
"network_tokens_enabled": false,
"saved_card_checkout_enabled": false,
"status": "inactive",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-11-28T14:00:00Z"
}DELETE/api/v1/merchants/:id
Auth: Organization key only. Scope: merchants:write.
Permanently deletes a merchant that has never been used — no transactions, orders, customers, catalog, saved payment methods, live API keys, or card-network enrollment. Anything else is refused with 409, because merchants with activity are kept for reporting and reconciliation.
This endpoint exists for a merchant created in error — expect refusal to be the common outcome. To retire a merchant that has history, set its status to inactive with PATCH instead.
Example request
curl -X DELETE https://api.tokeflow.com/api/v1/merchants/mrc_123 \
-H "Authorization: Bearer sk_live_org_…"Response codes
| Code | When |
|---|---|
204 No Content | Merchant deleted. No response body. |
404 Not Found | Merchant does not exist or is not yours. |
409 Conflict | Merchant has activity or is enrolled with the card networks. Deactivate it instead. |
GET/api/v1/merchants/:id/activity
Auth: Organization key only. Scope: merchants:read.
Retrieves the paginated activity trail for a merchant belonging to the authenticated organization. Each record describes an administrative action taken on the merchant — what changed, by whom, and when — which makes this the audit companion to the endpoints above.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number, 1-indexed (default 1, min 1). |
limit | integer | No | Items per page (default 20, max 100). |
Example request
curl -G https://api.tokeflow.com/api/v1/merchants/mrc_123/activity \
-H "Authorization: Bearer sk_live_org_…" \
--data-urlencode "page=1" \
--data-urlencode "limit=20"Returns 200 OK with a paginated list of activity records, or 404 if the merchant does not exist or does not belong to your organization.
GET/api/v1/merchants/:merchant_id/members
Auth: Organization key only. Scope: merchants:read.
Lists the users scoped to a specific merchant. Returns a paginated array of member objects, including pending invitations.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
page | integer | No | Page number, 1-indexed (default 1, min 1). |
limit | integer | No | Items per page (default 20, max 100). |
Example request
curl -G https://api.tokeflow.com/api/v1/merchants/mrc_123/members \
-H "Authorization: Bearer sk_live_org_…" \
--data-urlencode "page=1" \
--data-urlencode "limit=20"Example response — 200 OK
{
"data": [
{
"membership_id": "mum_5e8d21",
"user_id": "usr_3c9f10",
"email": "owner@johnsstore.com",
"name": "John Smith",
"role": "owner",
"joined_at": "2025-11-28T12:10:00Z",
"status": "active",
"invitation_expires_at": null
},
{
"membership_id": "mum_7a4b90",
"user_id": "usr_b81c22",
"email": "team@johnsstore.com",
"name": "team@johnsstore.com",
"role": "admin",
"joined_at": "2025-12-01T09:00:00Z",
"status": "pending",
"invitation_expires_at": "2025-12-08T09:00:00Z"
}
],
"meta": {
"pagination": {
"page": 1,
"limit": 20,
"total": 2,
"total_pages": 1,
"has_next": false,
"has_prev": false
}
}
}POST/api/v1/merchants/:merchant_id/members
Auth: Organization key only. Scope: merchants:write.
Invites a user to a merchant by email. Tokeflow finds or creates the user identity within your organization and adds a membership on the merchant with the given role, then sends an invitation email so the recipient can set a password. If the person already has an identity in your organization (from another merchant, for example), that identity is reused — the email address is the identity.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Email of the user to invite to the merchant. |
role | string | Yes | Role to assign within the merchant: owner, admin, or viewer. |
name | string | No | Optional display name (defaults to the email). |
Example request
curl -X POST https://api.tokeflow.com/api/v1/merchants/mrc_123/members \
-H "Authorization: Bearer sk_live_org_…" \
-H "Content-Type: application/json" \
-d '{
"email": "team@johnsstore.com",
"name": "Store Team",
"role": "admin"
}'Example response — 201 Created
{
"membership_id": "mum_7a4b90",
"user_id": "usr_b81c22",
"email": "team@johnsstore.com",
"name": "Store Team",
"role": "admin",
"joined_at": "2025-12-01T09:00:00Z",
"status": "pending",
"invitation_expires_at": "2025-12-08T09:00:00Z"
}The member stays pending until the invitation is accepted. If it expires first, resend it.
PATCH/api/v1/merchants/:merchant_id/members/:membership_id
Auth: Organization key only. Scope: merchants:write.
Updates the role of a user within a merchant.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Yes | New role for the member: owner, admin, or viewer. |
Example request
curl -X PATCH https://api.tokeflow.com/api/v1/merchants/mrc_123/members/mum_7a4b90 \
-H "Authorization: Bearer sk_live_org_…" \
-H "Content-Type: application/json" \
-d '{ "role": "viewer" }'Returns 204 No Content on success. No response body.
DELETE/api/v1/merchants/:merchant_id/members/:membership_id
Auth: Organization key only. Scope: merchants:write.
Removes a user from a merchant. Only the membership is removed — the underlying user identity keeps any memberships it holds on other merchants in your organization.
Example request
curl -X DELETE https://api.tokeflow.com/api/v1/merchants/mrc_123/members/mum_7a4b90 \
-H "Authorization: Bearer sk_live_org_…"Returns 204 No Content on success. No response body.
POST/api/v1/merchants/:merchant_id/members/:membership_id/resend
Auth: Organization key only. Scope: merchants:write.
Resends a pending merchant invitation. The invitation token and its expiry are rotated — the old email link stops working — and the invitation email is sent again. Returns 409 (conflict_error) if the user has already accepted.
Example request
curl -X POST https://api.tokeflow.com/api/v1/merchants/mrc_123/members/mum_7a4b90/resend \
-H "Authorization: Bearer sk_live_org_…"Example response — 200 OK
{
"membership_id": "mum_7a4b90",
"user_id": "usr_b81c22",
"email": "team@johnsstore.com",
"name": "Store Team",
"role": "admin",
"joined_at": "2025-12-01T09:00:00Z",
"status": "pending",
"invitation_expires_at": "2025-12-15T10:00:00Z"
}Note the refreshed invitation_expires_at — the countdown restarts from the resend.
Errors
Every error uses the standard envelope. The most common cases for this resource:
| HTTP | type | Typical cause |
|---|---|---|
400 | validation_error | Missing required field, malformed mcc, or a name without alphanumeric characters. |
401 | authentication_error | Missing or invalid API key. |
403 | authorization_error | A Merchant key was used — this surface requires an Organization key — or the key lacks the required scope. |
404 | not_found_error | Merchant (or membership) not found or not owned by your organization. |
409 | conflict_error | Deleting a merchant with activity, changing a network-locked field after enrollment, or resending an accepted invitation. |
See Errors for the full envelope and type catalog.
Related
- Authentication — Organization vs. Merchant keys and scopes.
- Pagination & filtering — iterate list endpoints safely.
- Customers — buyer records scoped to a merchant.
- Transactions — charges processed on behalf of a merchant.