Primeira recusa depois de achar o produto: 403 quando a comunidade não tem informações comerciais `APPROVED`, para **todo** produto (antes só quando `requiresApproval` era verdadeiro), antes de gravar qualquer coisa — inclusive o `saveDocument` — ou chamar o provedor. Produto avulso (`ONE_TIME`/`INSTALLMENT`) só é comprável quando aparece num space Loja (`storefront`) que o comprador enxerga, ou quando tem `directLinkEnabled`. Fora disso responde 403 com `errors[0].param = productId`, antes de criar a compra ou chamar o provedor. Assinaturas não mudam. Também antes de gravar qualquer coisa: 403 (`param = X-CommunityId`) para quem não tem perfil na comunidade; 400 (`param = paymentMethod` ou `installments`) quando o método não está em `allowedPaymentMethods` ou as parcelas passam de `maxInstallments`; 400 (`param = customerData`) sem nome e e-mail do comprador (os da conta valem quando o corpo não traz). CPF/CNPJ: sem `customerData.document`, vale o salvo na conta (`document` de `GET /api/auth/me`). Campo opcional `saveDocument` (boolean): `true` grava `customerData.document` na conta, substituindo o salvo (ex.: comprar como empresa); CPF/CNPJ com dígito verificador errado responde 400 (`param = customerData.document`) sem criar nada. Sem `saveDocument`, o documento e o telefone do pedido são gravados no primeiro pagamento confirmado só se a conta não tiver (telefone existente nunca é trocado). Plano já assinado: 409 (`param = productId`, mensagem "Você já assina este plano") quando o comprador tem assinatura `ACTIVE`, `TRIALING` ou `PAST_DUE` de qualquer opção do mesmo plano (grupo); `data: { subscriptionId, subscriptionStatus, productId }` para o app levar a Cobrança. PIX ou boleto do mesmo plano ainda em aberto: 409 (`param = productId`) sem criar outro pedido, com `data.openPayment: { purchaseId, orderId, productId, paymentMethod, status, amount, currency, qrCode, pixCode, expiresAt, boletoUrl, boletoBarcode, boletoDueAt }` para mostrar o mesmo QR (ou cancelar em `POST /checkout/{purchaseId}/cancel`). O pedido aberto é lido na Stone antes: pago vira o 409 de plano assinado; expirado ou falho deixa seguir. Outro plano da comunidade não é bloqueado. A resposta 201 traz os campos opcionais `thankYouMessage` e `redirectUrl` do produto. O valor cobrado (`amount`) é o preço, mais a taxa da plataforma quando `feePayer = BUYER`. Quando o provedor recusa o pagamento, a compra fica `FAILED` e a resposta é 402, com o motivo do provedor em `errors[].param = provider`; provedor fora do ar responde 502. Parcelas (`installments`, 1–12, até `maxInstallments`) só valem no cartão de crédito: PIX e boleto são à vista, e a resposta e a compra trazem `installments = 1`. Assinatura `YEARLY` vende o ano em parcelas, com os juros de parcelamento da Memberfy (F-43) pagos por quem o produto diz (`installmentInterestPayer`), e a renovação anual cobra o ano de novo no cartão salvo, nas mesmas parcelas da compra, com a tabela vigente. A resposta ganha os campos opcionais `installmentInterestPayer`, `installmentInterestPercent`, `installmentInterest`, `totalWithInterest` e `installmentAmount` (`amount` já é o total cobrado). O cartão com que uma assinatura é paga vira o cartão padrão do membro (`/payment-methods`), para a renovação. Adicional (produto com `prerequisiteGroupIds`) só é vendido a quem tem assinatura ACTIVE ou TRIALING num dos grupos exigidos, inclusive por link direto: sem isso, 403 com `errors[0].param = productId` (`monetization.purchase.prerequisiteRequired`), antes de criar a compra ou chamar o provedor. F-37: `addOnProductIds` (array de UUID, opcional) compra a opção de plano e os adicionais da lista do plano num pedido só, numa cobrança (um PIX, um boleto ou uma transação no cartão, nas parcelas da opção). É o que permite comprar o adicional sem ainda ter o plano. Cada adicional vira uma compra própria ligada à do plano e, pago o pedido, uma assinatura cobrada junto com a do plano (`billedWithId`), no ritmo da opção (o mensal, ou 12 × o mensal no anual). A taxa fixa da plataforma entra uma vez, na compra do plano. Recusas com 400 e `param = addOnProductIds`, antes de gravar: adicional fora da lista do plano, que não é `SUBSCRIPTION` `MONTHLY` à venda, repetido, já assinado pelo comprador, ou opção que não aceita adicional (intervalo sem fator, ou com teste). Com o campo, a resposta ganha `items` (`[{ purchaseId, productId, title, amount, feeBreakdown }]`, o plano primeiro), `amount` passa a ser o total do pedido e `feeBreakdown` a soma; `purchaseId` continua sendo o da compra do plano. FIN-7: `couponCode` (opcional) aplica o cupom antes da taxa: a taxa da plataforma, o valor cobrado (`pricePaid`), o ledger e um reembolso seguem o valor com desconto. Com cupom, a resposta ganha `coupon` (`code`, `type`, `discountValue`, `duration`, `durationInMonths`), `discountAmount` (do pedido) e `items` mesmo sem adicionais, cada item com `baseAmount` (antes do desconto) e `discountAmount`. O uso do cupom (`CouponUsage`, `currentUses`) só é registrado quando o pagamento é confirmado; até lá o pedido em aberto segura um dos `maxUses`. Na renovação, `ONCE` vale só na primeira cobrança, `REPEATING` enquanto o período começa dentro de `durationInMonths` desde o início da assinatura, `FOREVER` sempre. Recusas com `param = couponCode`, antes de cobrar: 404 cupom inexistente; 400 inativo, fora da validade, sem usos, limite por pessoa, só primeira compra, pedido abaixo do mínimo, produto fora da lista, cupom `FREE_TRIAL`, ou desconto que zera um item. Depois de 10 códigos recusados em 15 minutos, 429.