Saltar al contenido principal

Seller onboarding

Bob necesita un lugar al que Ishtaran pueda enviar su dinero. Mercatto podría crear uno por él — pero en cambio lo invita a crear el suyo propio, para que la misma identidad pueda funcionar después con otros marketplaces también, nunca atrapada dentro de los sistemas de Mercatto. Alice recibe el mismo tratamiento.

Mercattotoken de invitación"la reclamo conmi propio email+ contraseña"🔑Bobsu propio AccountHolder
El login de Bob le pertenece a Bob — Mercatto emite la invitación, pero nunca ve su contraseña.

Código

examples/marketplace-mercatto/seller-onboarding.ts
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);

Resultado

Tres Accounts reales, cada una autorizada para la Application de Mercatto — un paso fácil de olvidar y que falla de forma ruidosa si se omite (ver Failure scenarios) — y cada una con un ExecutionDestination registrado, sin el cual un Settlement real on-chain no puede pagarles en absoluto (ver Settlement and Split).

Qué pasó por debajo

createAccountHolderInvitation no crea una Account por sí sola — la Account solo existe una vez que la invitación es reclamada. Existen dos métodos de reclamo distintos por una razón: signUpAndClaimInvitation es para alguien que nunca tuvo una identidad en Ishtaran (Bob y Alice aquí); un simple claimInvitation (sin registro) es para alguien que ya tiene una sesión de AccountHolder de un marketplace distinto, reutilizando la misma Account subyacente — ese es el verdadero propósito de darle a Bob su propio login desde el principio. Mercatto nunca ve ninguna de las dos contraseñas.

Alternativa cubierta por separado: un pagador ocasional que nunca necesita su propio login recibe en cambio una Account provisionada por la Organization (accounts.create, sin invitación) — ver Failure scenarios.

Un límite que conviene conocer ahora, no después: authorizeApplication requiere la sesión de Member de Mercatto (owner), no su API Key — la llamada con API Key es rechazada. Lo mismo aplica a todo lo que esté bajo workflows.* en el próximo capítulo. Sin embargo, una vez que Bob y Alice reclamaron sus invitaciones, sus propios logins dejan de ser útiles para el resto de esta historia — cada llamada financiera posterior (balance, retiro) la hace Mercatto en su nombre con sus propias credenciales, nunca con la sesión de ellos directamente. Ver Known Limitations para entender exactamente por qué.

Registrar un ExecutionDestination no es lo mismo que tener una Account. Una Account puede tener balance sin tener nunca en registro una dirección real de recepción on-chain — para eso existe ExecutionDestination (DEC-037): la dirección a la que realmente paga la execution leg de un Settlement, primer registro gana, nunca se sobrescribe en silencio. Deliberadamente no es el mismo mecanismo que WithdrawalDestination (sin whitelist ni cooldown) — esto es un beneficiario declarando dónde le pagan como vendedor de un marketplace, no un retiro iniciado por el integrador. Antes de que corra este capítulo, Mercatto también registra su propia execution wallet (examples/marketplace-mercatto/register-execution-wallet.ts) — una wallet que Mercatto genera y con la que firma enteramente en su propia máquina (solo la extended public key llega alguna vez a Ishtaran); esa wallet es la que más adelante firma cada leg de Settlement en Settlement and Split.