Pular para o conteúdo principal

Seller onboarding

Bob precisa de um lugar para a Ishtaran mandar o dinheiro dele. A Mercatto poderia criar um para ele — mas em vez disso convida Bob a criar o dele próprio, para que a mesma identidade possa funcionar depois em outros marketplaces também, nunca presa dentro dos sistemas da própria Mercatto. Alice recebe o mesmo tratamento.

Mercattotoken de convite"resgato commeu próprio email+ senha"🔑Bobpróprio AccountHolder
O login de Bob pertence a Bob — a Mercatto emite o convite, mas nunca vê sua senha.

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

Três Accounts reais, cada uma autorizada para a Application da Mercatto — um passo fácil de esquecer e que falha ruidosamente se pulado (veja Failure scenarios) — e cada uma com uma ExecutionDestination registrada, sem a qual um Settlement real on-chain não consegue pagá-las de jeito nenhum (veja Settlement and Split).

O que aconteceu por baixo dos panos

createAccountHolderInvitation não cria uma Account sozinha — a Account só existe depois que o convite é resgatado. Existem dois métodos diferentes de resgate por um motivo: signUpAndClaimInvitation é para quem nunca teve uma identidade na Ishtaran antes (Bob e Alice aqui); um claimInvitation simples (sem cadastro) é para quem já tem uma sessão de AccountHolder de um marketplace diferente, reutilizando a mesma Account subjacente — esse é o verdadeiro motivo de dar a Bob o próprio login dele em primeiro lugar. A Mercatto nunca vê nenhuma das duas senhas.

Alternativa coberta em outro lugar: um pagador avulso que nunca precisa do próprio login recebe uma Account provisionada pela Organization no lugar (accounts.create, sem convite) — veja Failure scenarios.

Um limite que vale conhecer agora, não depois: authorizeApplication exige a sessão de Member da Mercatto (owner), não sua API Key — a chamada com API Key é rejeitada. O mesmo vale para tudo sob workflows.* no próximo capítulo. Uma vez que Bob e Alice resgatam seus convites, porém, os próprios logins deles deixam de ser úteis para o resto desta história — toda chamada financeira posterior (saldo, saque) é a Mercatto agindo em nome deles com suas próprias credenciais, nunca a sessão deles diretamente. Veja Known Limitations para entender exatamente o porquê.

Registrar uma ExecutionDestination não é a mesma coisa que ter uma Account. Uma Account pode ter saldo sem nunca ter um endereço real de recebimento on-chain registrado — é para isso que existe a ExecutionDestination (DEC-037): o endereço para onde o execution leg de um Settlement efetivamente paga, primeiro-a-registrar-vence, nunca sobrescrito silenciosamente. É deliberadamente um mecanismo diferente da WithdrawalDestination (sem whitelist/cooldown) — isso é um beneficiário declarando onde ele recebe como vendedor de um marketplace, não um saque iniciado por um integrador. Antes deste capítulo rodar, a Mercatto também registra sua própria execution wallet (examples/marketplace-mercatto/register-execution-wallet.ts) — uma wallet que a Mercatto gera e assina inteiramente na própria máquina (só a chave pública estendida chega até a Ishtaran); essa wallet é o que depois assina cada leg de Settlement em Settlement and Split.