Pular para o conteúdo principal
Preços dinâmicos permitem que você ofereça preços variáveis para seus produtos sem criar várias entradas de produtos. Ao ativar Pague o Que Quiser (PWYW) em um único produto, você pode definir limites de preço mínimo e máximo e, em seguida, passar valores dinâmicos ao criar links de sessão de checkout. Essa abordagem é ideal quando você precisa:
  • Preços variáveis sem gerenciar vários produtos
  • Preços impulsionados pelo cliente onde os compradores escolhem seu valor
  • Controle de preço programático onde você define o valor dinamicamente via API
  • Modelos de preços flexíveis para produtos digitais, doações ou lançamentos experimentais
Pay What You Want está disponível apenas para produtos Single Payment (pagamento único). Não pode ser usado com produtos de assinatura.

Como Funciona

Com Pague o Que Quiser ativado, você pode:
  1. Defina limites de preço: Especifique um preço mínimo (obrigatório) e, opcionalmente, um preço máximo
  2. Envie valores dinâmicos: Inclua um campo amount no carrinho do produto ao criar sessões de checkout
  3. Deixe os clientes escolherem: Se nenhum valor for fornecido, os clientes podem inserir o próprio preço (dentro dos limites definidos)
Quando você envia um amount no carrinho do produto, esse valor é usado no checkout. Se você omitir o campo amount, os clientes podem escolher o próprio preço durante o checkout (conforme seus limites mínimo/máximo).

Passo 1: Criar um Produto com Pague o Que Quiser

Primeiro, crie um produto de pagamento único no seu painel do Dodo Payments e ative a precificação Pague o Que Quiser.
1

Create a new product

Navegue até Products no seu painel Dodo Payments e clique em Add Product.
2

Configure product details

Preencha as informações obrigatórias do produto:
  • Product Name: Nome exibido para o seu produto
  • Product Description: Descrição clara do que os clientes estão comprando
  • Product Image: Faça upload de uma imagem (PNG/JPG/WebP, até 3 MB)
  • Tax Category: Selecione a categoria tributária apropriada
3

Set pricing type

Selecione Pricing Type como Single Payment (pagamento único).
4

Enable Pay What You Want

Na seção Pricing, habilite o interruptor Pay What You Want.
5

Set minimum price

Digite o Minimum Price que os clientes devem pagar. Isso é obrigatório e garante que você mantenha um piso de receita.Exemplo: Se o seu mínimo for $5,00, digite 5.00 (ou 500 centavos).
6

Set maximum price (optional)

Opcionalmente, defina um Maximum Price para limitar o valor que os clientes podem pagar.
7

Set suggested price (optional)

Opcionalmente, insira um Suggested Price que será exibido para orientar os clientes. Isso ajuda a ancorar expectativas e pode melhorar o ticket médio.
8

Save the product

Clique em Add Product para salvar. Anote o ID do produto (por exemplo, pdt_123abc456def) para usar nas sessões de checkout.
Você pode encontrar o ID do produto no painel em ProductsView Details, ou usando o List Products API.

Passo 2: Criar Sessões de Checkout com Preços Dinâmicos

Depois que seu produto estiver configurado com Pay What You Want, você pode criar sessões de checkout com valores dinâmicos. O campo amount no carrinho do produto permite definir o preço programaticamente para cada sessão de checkout.

Entendendo o Campo de Valor

Ao criar uma sessão de checkout, você pode incluir um campo amount em cada item do carrinho do produto:
  • Se amount for fornecido: O checkout usa esse valor exato (deve estar dentro dos seus limites mínimo/máximo)
  • Se amount for omitido: Os clientes podem inserir seu próprio preço durante o checkout (dentro dos seus limites)
O campo amount é aplicável apenas a produtos Pay What You Want. Para produtos comuns, esse campo é ignorado.

Exemplos de Código

import DodoPayments from 'dodopayments';

// Initialize the Dodo Payments client
const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
});

async function createDynamicPricingCheckout(
  productId: string,
  amountInCents: number,
  returnUrl: string
) {
  try {
    const session = await client.checkoutSessions.create({
      product_cart: [
        {
          product_id: productId,
          quantity: 1,
          // Dynamic amount in cents (e.g., 1500 = $15.00)
          amount: amountInCents
        }
      ],
      return_url: returnUrl,
      // Optional: Pre-fill customer information
      customer: {
        email: 'customer@example.com',
        name: 'John Doe'
      },
      // Optional: Add metadata for tracking
      metadata: {
        order_id: 'order_123',
        pricing_tier: 'custom'
      }
    });

    console.log('Checkout URL:', session.checkout_url);
    console.log('Session ID:', session.session_id);
    
    return session;
  } catch (error) {
    console.error('Failed to create checkout session:', error);
    throw error;
  }
}

// Example: Create checkout with $25.00 (2500 cents)
const session = await createDynamicPricingCheckout(
  'prod_123abc456def',
  2500, // $25.00 in cents
  'https://yoursite.com/checkout/success'
);

// Example: Create checkout with $10.00 (1000 cents)
const session2 = await createDynamicPricingCheckout(
  'prod_123abc456def',
  1000, // $10.00 in cents
  'https://yoursite.com/checkout/success'
);
Formato do valor: O campo amount deve estar na menor denominação da moeda. Para USD, isso significa centavos (por exemplo, $25,00 = 2500). Para outras moedas, use a menor unidade (por exemplo, paise para INR).

Passo 3: Deixar os Clientes Escolherem Seu Preço

Se quiser que os clientes escolham o próprio preço durante o checkout, basta omitir o campo amount do carrinho do produto. A página de checkout exibirá um campo de entrada onde os clientes poderão inserir qualquer valor dentro dos seus limites mínimo e máximo.
async function createCustomerChoiceCheckout(
  productId: string,
  returnUrl: string
) {
  try {
    const session = await client.checkoutSessions.create({
      product_cart: [
        {
          product_id: productId,
          quantity: 1
          // No amount field - customer will choose their price
        }
      ],
      return_url: returnUrl,
      customer: {
        email: 'customer@example.com',
        name: 'John Doe'
      }
    });

    return session;
  } catch (error) {
    console.error('Failed to create checkout session:', error);
    throw error;
  }
}

Casos de Uso Comuns

Caso de Uso 1: Preços em Camadas com Base no Tipo de Usuário

Ofereça preços diferentes para diferentes segmentos de clientes usando o mesmo produto:
// Student discount: $10.00
const studentSession = await createDynamicPricingCheckout(
  'prod_123abc456def',
  1000, // $10.00
  'https://yoursite.com/success'
);

// Regular price: $25.00
const regularSession = await createDynamicPricingCheckout(
  'prod_123abc456def',
  2500, // $25.00
  'https://yoursite.com/success'
);

// Premium price: $50.00
const premiumSession = await createDynamicPricingCheckout(
  'prod_123abc456def',
  5000, // $50.00
  'https://yoursite.com/success'
);

Caso de Uso 2: Preços Dinâmicos com Base na Quantidade

Ajuste o preço com base na quantidade comprada:
async function createQuantityBasedCheckout(
  productId: string,
  quantity: number
) {
  // Base price: $20.00 per unit
  // Discount: 10% for 2+ items, 20% for 5+ items
  const basePrice = 2000; // $20.00 in cents
  let discount = 0;
  
  if (quantity >= 5) {
    discount = 0.20; // 20% off
  } else if (quantity >= 2) {
    discount = 0.10; // 10% off
  }
  
  const totalAmount = Math.round(basePrice * quantity * (1 - discount));
  
  const session = await client.checkoutSessions.create({
    product_cart: [
      {
        product_id: productId,
        quantity: quantity,
        amount: totalAmount
      }
    ],
    return_url: 'https://yoursite.com/success'
  });
  
  return session;
}

Caso de Uso 3: Preços Baseados em Tempo ou Promoções

Aplique preços promocionais durante períodos específicos:
async function createPromotionalCheckout(productId: string) {
  const isPromoActive = checkIfPromotionActive(); // Your logic
  const regularPrice = 3000; // $30.00
  const promoPrice = 2000; // $20.00
  
  const amount = isPromoActive ? promoPrice : regularPrice;
  
  const session = await client.checkoutSessions.create({
    product_cart: [
      {
        product_id: productId,
        quantity: 1,
        amount: amount
      }
    ],
    return_url: 'https://yoursite.com/success',
    metadata: {
      pricing_type: isPromoActive ? 'promotional' : 'regular'
    }
  });
  
  return session;
}

Melhores Práticas

Set Reasonable Bounds

Escolha um preço mínimo que cubra seus custos e ainda seja acessível. Use um preço sugerido para orientar as expectativas dos clientes.

Validate Amounts

Sempre valide se os valores dinâmicos estão dentro dos limites mínimo e máximo do seu produto antes de criar sessões de checkout.

Track Pricing Decisions

Use metadata para rastrear por que valores específicos foram escolhidos (por exemplo, pricing_tier, discount_code, user_segment).

Handle Edge Cases

Certifique-se de que sua aplicação trate com elegância os casos em que os valores ultrapassam os limites máximos ou ficam abaixo dos mínimos.

Validação e Tratamento de Erros

Sempre valide os valores em relação às configurações mínimas e máximas do seu produto:
async function createValidatedCheckout(
  productId: string,
  amountInCents: number,
  minAmount: number,
  maxAmount: number | null
) {
  // Validate minimum
  if (amountInCents < minAmount) {
    throw new Error(
      `Amount ${amountInCents} is below minimum ${minAmount}`
    );
  }
  
  // Validate maximum (if set)
  if (maxAmount !== null && amountInCents > maxAmount) {
    throw new Error(
      `Amount ${amountInCents} exceeds maximum ${maxAmount}`
    );
  }
  
  // Create checkout session
  return await client.checkoutSessions.create({
    product_cart: [
      {
        product_id: productId,
        quantity: 1,
        amount: amountInCents
      }
    ],
    return_url: 'https://yoursite.com/success'
  });
}

Referência da API

Solução de Problemas

Se o seu campo amount estiver sendo ignorado, verifique se:
  • O produto tem o Pay What You Want ativado no painel
  • O produto é um Single Payment (pagamento único), não uma assinatura
  • O valor está no formato correto (menor denominação da moeda, por exemplo, centavos para USD)
A API rejeitará sessões de checkout em que o valor viole os limites de preço do seu produto. Sempre valide os valores antes de criar sessões de checkout ou permita que os clientes escolham o próprio preço omitindo o campo amount.
Se os clientes não estiverem vendo o campo de entrada de preço, certifique-se de ter omitido o campo amount do carrinho do produto. Quando o amount é fornecido, o checkout usa esse valor exato.