As mesmas recusas de `POST /api/checkout` para o `productId`: adicional (400, `param = productId`), opção de cobrança fora de qualquer plano (400, `param = productId`) e produto avulso esgotado (409, `param = productId`, mensagem "Esgotado" traduzida). O adicional entra em `addOnProductIds` junto da opção do plano. As mesmas recusas de `POST /api/checkout` quando as vendas da comunidade estão desligadas (interruptor `payoutEnabled` falso, a pausa do dono ou o desligamento do sistema) ou, em BRL, o recebedor é conhecido fora de `active`: 400 com `param = productId` e a mensagem `monetization.salesDisabled`, antes de gravar qualquer coisa ou chamar o provedor. Endpoint público — não exige autenticação. Cota só produto da comunidade do `X-CommunityId`; sem comunidade, 400 com `param = X-CommunityId`; produto de outra comunidade, 404. Com token de quem já assina o plano, a resposta traz o campo opcional `alreadySubscribed: { subscriptionId, status, productId, paidByCompany }` (`paidByCompany: true` quando quem assina é a empresa da pessoa). `allowedPaymentMethods` do produto é lido tanto como array quanto como string JSON; método fora da lista ou parcelas acima de `maxInstallments` respondem 400 com `errors[].param`. Parcelas só valem no cartão de crédito (PIX e boleto respondem `installments = 1`). Juros de parcelamento da Memberfy (% total por número de parcelas, da tabela de taxas da plataforma ou da comunidade), depois dos descontos e da taxa da plataforma, que não muda: com `installmentInterestPayer = BUYER` somam ao preço; com `ORGANIZATION` o comprador paga o preço e a comunidade recebe menos. Campos novos e opcionais: `installmentInterestPayer`, `installmentInterestPercent`, `installmentInterest` (juros pagos pelo comprador; `0.00` quando a comunidade absorve), `totalWithInterest` (o que o cartão cobra), `installmentAmount` e, no cartão, `installmentOptions` (`[{ installments, percent, totalAmount, installmentAmount }]`, de 1 até `maxInstallments`). `totalAmount` segue sendo o valor antes dos juros. Com adicionais, os mesmos campos em cada item. `addOnProductIds` (array de UUID, opcional) cota a opção de plano com adicionais, como `POST /checkout` cobraria num pedido só. A resposta ganha `items` (`productId`, `title`, `basePrice`, `feePayer`, `fees` quando o comprador paga a taxa, `totalAmount`), e `totalAmount` e `breakdown.total` passam a ser o total do pedido; os demais campos continuam descrevendo a opção do plano. A taxa fixa entra uma vez, no plano. Recusas com 400 e `param = addOnProductIds`: adicional fora da lista do plano, que não é `SUBSCRIPTION` `MONTHLY` à venda, repetido, ou opção que não aceita adicional (intervalo sem fator, ou com teste). `couponCode` (string, opcional) aplica o cupom da comunidade do produto antes da taxa, como `POST /checkout` cobraria: a taxa da plataforma é calculada sobre o valor com desconto. Com cupom, a resposta ganha `coupon` (`code`, `type`, `discountValue`, `duration`, `durationInMonths`), `discountAmount` (o desconto do pedido), `breakdown.discount` (o da opção) e `items` mesmo sem adicionais, cada item com `discountAmount`; `basePrice` e `breakdown.product` continuam sendo o preço cheio, e `totalAmount`/`breakdown.total` já vêm com o desconto. `PERCENTAGE` (limitado por `maxDiscount`) e `FIXED` valem uma vez para o pedido, divididos entre os itens a que o cupom se aplica. Recusas com `param = couponCode`: 404 cupom inexistente; 400 inativo, fora da validade, sem usos (`maxUses`, contando pedidos ainda em aberto), pedido abaixo do mínimo, produto fora da lista, cupom `FREE_TRIAL`, ou desconto que deixa um item entre 0 e 1,00. **Cupom que zera um produto avulso (`ONE_TIME`) ou, com cupom `FOREVER`, uma opção de plano sem período de teste, sem adicionais:** responde como a compra gratuita do `POST /checkout`: `free: true`, `totalAmount` e `breakdown.total` `"0.00"`, sem `fees` nem parcelas (com `companyId`, ecoado na resposta). Nesse caso, como no `POST /checkout`, `paymentMethod` é opcional (ecoado só quando enviado) e não valem os métodos aceitos pelo produto, os dados da empresa, o repasse nem o interruptor de vendas. Em qualquer outro caso, `paymentMethod` ausente responde 400 com `param = paymentMethod`. Com login (opcional), também o limite por pessoa e a restrição de primeira compra. Depois de 10 códigos recusados em 15 minutos, 429 por quem chama (conta ou IP). **Empresa:** `companyId` cota para a empresa; sem login, 403 (`param = X-CommunityId`); quem não é admin da empresa, 403 (`param = companyId`). **Economia (campo novo e opcional):** numa opção de plano (`SUBSCRIPTION`), `savingsPercentage`, o mesmo "Economize X%" de `GET /api/checkout/subscription-groups` (preço cheio, antes do cupom), contado no primeiro plano da opção; null quando não há.