Links de venda
Links fixos por curso e por vendedor com campanhas, para vender em eventos, QR Codes e redes sociais sem criar uma venda por CPF.
O POST /sales cria um link único para um comprador: você precisa do CPF antes de gerar o link. Quando você ainda não conhece o comprador (um evento, um QR Code impresso, um post), use uma campanha: um link fixo, reutilizável por quantos alunos quiser, que já abre o checkout com o curso e o preço definidos.
| Situação | Use |
|---|---|
| Seu sistema já tem o CPF do aluno e quer redirecioná-lo para pagar | POST /sales |
| Link público do curso, igual para todos os alunos | Campanha |
| Link por vendedor, para saber quem fechou cada venda | Campanha com consultant_id, ou link com seller |
Criar a campanha
Crie a campanha com POST /campaigns, a partir de cursos e turmas já cadastrados (veja Cursos e Turmas).
curl -X POST https://app-staging.principia.services/checkout/v4/campaigns \
-H "Api-Token: SEU_TOKEN" \
-H "Content-Type: application/json" \
-d @campanha.json{
"name": "Imersao Vendas - Evento Outubro - Joana",
"checkout_price_in_cents": 1200000,
"courses": [{ "id": 1234, "courseClassId": 5678 }],
"consultant_id": "joana@suaempresa.com.br",
"customIdentifier": "evento-out-joana",
"endsAt": "2026-11-01T02:59:59Z"
}| Campo | Obrigatório | Descrição |
|---|---|---|
name | sim | Nome da campanha. Vira o identificador do link (o slug), então precisa gerar um identificador único entre as suas campanhas, contando também as inativas. |
checkout_price_in_cents | sim | Preço final no checkout, em centavos. Precisa ser maior que zero e não pode passar da soma dos preços das turmas escolhidas; a diferença aparece como desconto. Veja Regras de preço. |
courses | sim | Cursos (id) e turmas (courseClassId) incluídos na campanha. Uma turma por curso; a turma precisa estar ativa e pertencer ao curso. |
consultant_id | não | E-mail de quem vendeu (e-mail válido, até 64 caracteres). Fica registrado como responsável por todas as vendas feitas por este link. |
customIdentifier | não | Um código seu, para cruzar a campanha com o seu sistema. Até 24 caracteres. |
startsAt / endsAt | não | Janela da campanha, em UTC (ISO 8601). Veja Início e fim da campanha. |
payment_methods | não | Restringe as formas de pagamento oferecidas nesta campanha. Valores aceitos: Boleto, CreditCard, Pix e CourseFinancing, só entre as formas habilitadas para a sua conta. |
Campos opcionais aceitos, menos comuns:
| Campo | Descrição |
|---|---|
running_days_to_first_installment | Dias até o vencimento da primeira parcela: de 1 a 5, e não maior que o padrão configurado para a sua conta. |
maxInstallmentsToApply | Número máximo de parcelas oferecidas no financiamento desta campanha. |
running_days_to_expire | Inteiro. Confirme o uso com o time do PrincipiaPay antes de enviar. |
min_days_to_payment | Inteiro. Confirme o uso com o time do PrincipiaPay antes de enviar. |
Início e fim da campanha
- Sem
startsAt(ou comstartsAtaté agora): a campanha nasce ativa na hora. startsAtno passado: aceito com até 5 minutos de atraso; mais do que isso devolve erro.startsAtno futuro: a campanha nasce inativa e é ativada automaticamente quando chega o início, desde que tenhaendsAt. SemendsAt, ela nunca é ativada sozinha. Se você ativar uma campanha dessas antes do início, a ativação é desfeita.endsAt: precisa ser depois do início. Ao passar do fim, a campanha é inativada automaticamente. SemendsAt, a campanha fica ativa até você inativá-la.
Com início no futuro, envie sempre endsAt
Uma campanha agendada (startsAt no futuro) sem endsAt fica inativa para sempre. Se não houver data de fim, use uma data bem distante.
Regras de preço
checkout_price_in_centsprecisa ser maior que zero e menor ou igual à soma dos preços das turmas (courseClassId) da campanha.- Em contas do plano Flex, o mínimo é R$ 180,00.
- Se a sua conta oferece financiamento, o valor precisa gerar ao menos uma condição de parcelamento válida; um valor muito baixo, que resultaria em parcelas menores que o mínimo, é recusado.
Resposta
A resposta traz o link pronto em redirect_url:
{
"content": {
"id": "66f1c0a2e4b0c1a2b3c4d5e6",
"name": "Imersao Vendas - Evento Outubro - Joana",
"slug": "Imersao-Vendas-Evento-Outubro-Joana",
"redirect_url": "https://pay.principia.net/checkout/sua-empresa?campaign=Imersao-Vendas-Evento-Outubro-Joana",
"checkout_price_in_cents": 1200000,
"consultant_id": "joana@suaempresa.com.br",
"active": true
}
}Use sempre o redirect_url
O formato do link depende da configuração da sua conta. Copie o redirect_url devolvido pela API em vez de montar a URL na mão. Para gerar o QR Code, use esse mesmo link.
Um link por vendedor
Há duas formas de saber qual vendedor fechou cada venda. As duas preenchem o mesmo campo: o responsável registrado na venda.
1. Uma campanha por vendedor (recomendado para eventos). Crie uma campanha por combinação de curso e vendedor, com o consultant_id de cada um. Cada vendedor recebe o próprio link ou QR Code. O consultant_id precisa ser um e-mail válido, mas não exige que o vendedor tenha usuário no painel.
2. Parâmetro seller no link. Acrescente seller=<ID do vendedor> ao redirect_url:
https://pay.principia.net/checkout/sua-empresa?campaign=Imersao-Vendas&seller=4321O seller precisa ser o ID de um usuário ativo do painel do parceiro, da sua empresa. Cada vendedor encontra o próprio "link de vendedor", já com o seller, no painel do parceiro. Se o ID não for de um usuário ativo, a venda segue normalmente, só que sem vendedor. Quando o link traz seller, ele tem prioridade sobre o consultant_id da campanha.
Gerar vários links de uma vez
Para um evento com muitos cursos e vendedores, gere as campanhas em lote a partir de uma planilha, uma chamada por linha:
# links.csv: curso_id,turma_id,preco_centavos,vendedor_email
while IFS=, read -r curso turma preco vendedor; do
curl -s -X POST https://app.principia.services/checkout/v4/campaigns \
-H "Api-Token: SEU_TOKEN" -H "Content-Type: application/json" \
-d "{\"name\":\"Evento Out - $curso - $vendedor\",\"checkout_price_in_cents\":$preco,
\"courses\":[{\"id\":$curso,\"courseClassId\":$turma}],
\"consultant_id\":\"$vendedor\",\"customIdentifier\":\"evento-out\",
\"endsAt\":\"2026-11-01T02:59:59Z\"}" \
| jq -r --arg v "$vendedor" '[$v, .content.redirect_url] | @csv'
done < links.csv > links-gerados.csvFaça isso primeiro em homologação e confira um link de ponta a ponta antes de gerar os de produção.
Acompanhar e encerrar
GET /campaignslista as campanhas eGET /campaigns/:iddevolve uma delas.PATCH /campaigns/active/:idativa ou inativa a campanha (active) e também pode trocar ocustomIdentifier(de 4 a 24 caracteres). Responde 204, sem corpo: consulte a campanha comGET /campaigns/:idpara ver o resultado. Com a campanha inativa, o link deixa de aplicar os cursos e o preço dela.- Inativar uma campanha que tem
endsAtantecipa o fim para o momento da inativação. Reativar uma campanha comendsAtremove a data de fim: ela passa a valer até você inativá-la de novo. - Cada venda feita pelo link segue o fluxo normal: acompanhe pelos webhooks ou pela lista de vendas.
Não gere um token novo durante a operação
Gerar um novo Api-Token no painel desativa o anterior na hora. Se a sua integração estiver rodando, reutilize o token atual. Veja Autenticação.