Seller onboarding
Bob needs a place for Ishtaran to send his money. Mercatto could create one for him — but instead it invites Bob to create his own, so the same identity could later work with other marketplaces too, never trapped inside Mercatto's own systems. Alice gets the same treatment.
Code
const bobInvitation = await mercatto.accounts.createAccountHolderInvitation(organizationId, `bob-${runId}`);
const bob = createClient();
const bobClaim = await bob.accountHolders.signUpAndClaimInvitation(bobInvitation.plainTextToken, emails.bob, STORY_PASSWORD);
const bobAccountId = (await bob.accountHolders.me()).accountId;
// Alice, the buyer, gets the identical treatment — not an "anonymous" payer.
const aliceInvitation = await mercatto.accounts.createAccountHolderInvitation(organizationId, `alice-${runId}`);
// … same claim flow …
// Mercatto's own commission lands in an Account it owns directly — no invitation needed.
const mercattoRevenueAccountId = (await mercatto.accounts.create(organizationId, `mercatto-revenue-${runId}`)).accountId;
await owner.accounts.authorizeApplication(organizationId, bobAccountId, applicationId);
await owner.accounts.authorizeApplication(organizationId, aliceAccountId, applicationId);
await owner.accounts.authorizeApplication(organizationId, mercattoRevenueAccountId, applicationId);
// DEC-037 — where does Ishtaran actually send Bob's money? Bob's own wallet, entirely outside
// Ishtaran (Mercatto never touches his private key). Mercatto's own commission, by contrast, lands
// on an address of Mercatto's OWN execution wallet — registered just before this chapter runs
// (`register-execution-wallet.ts`), the same wallet that later signs every Settlement leg.
const bobsOwnWallet = wallet.generate();
const bobDestinationAddress = deriveTronAddress(bobsOwnWallet.wallet.accountExtendedPublicKey, 0);
await mercatto.executionDestinations.register(organizationId, bobAccountId, assetNetworkId, bobDestinationAddress);
const mercattoRevenueAllocation = await mercatto.wallets.allocateDepositAddress(applicationId, networkId);
await mercatto.executionDestinations.register(organizationId, mercattoRevenueAccountId, assetNetworkId, mercattoRevenueAllocation.address);
Result
Three real Accounts, each authorized for Mercatto's Application — a step that's easy to forget and
fails loudly if skipped (see Failure scenarios) — and each with a registered
ExecutionDestination, without which a real on-chain Settlement can't pay them at all (see
Settlement and Split).
What happened under the hood
createAccountHolderInvitation doesn't create an Account by itself — the Account only exists once
the invitation is claimed. Two different claim methods exist for a reason: signUpAndClaimInvitation
is for someone who's never had an Ishtaran identity before (Bob and Alice here); a plain
claimInvitation (no signup) is for someone who already has an AccountHolder session from a
different marketplace, reusing the same underlying Account — the actual point of giving Bob his
own login in the first place. Mercatto never sees either password.
Alternative covered separately: a one-off payer who never needs their own login gets an
Organization-provisioned Account instead (accounts.create, no invitation) — see
Failure scenarios.
A limit worth knowing now, not later: authorizeApplication requires Mercatto's Member session
(owner), not its API Key — the API Key call is rejected. Same for everything under workflows.*
in the next chapter. Once Bob and Alice have claimed their invitations, though, their own logins
are done being useful for the rest of this story — every later financial call (balance, withdrawal)
is Mercatto acting on their behalf with its own credentials, never their session directly. See
Known Limitations for exactly why.
Registering an ExecutionDestination is not the same as having an Account. An Account can hold
a balance without ever having a real on-chain receiving address on file — that's what
ExecutionDestination is for (DEC-037): the address a Settlement's execution leg actually pays
out to, first-registration-wins, never silently overwritten. It's deliberately not the same
mechanism as WithdrawalDestination (no whitelist/cooldown) — this is a beneficiary declaring
where they get paid as a marketplace seller, not an integrator-initiated withdrawal. Before this
chapter runs, Mercatto also registers its own execution wallet
(examples/marketplace-mercatto/register-execution-wallet.ts) — a wallet Mercatto generates and
signs with entirely on its own machine (only the public extended key ever reaches Ishtaran); that
wallet is what later signs every Settlement leg in Settlement and Split.