Xpend

Email Multibanco

Depois de gerares uma referência Multibanco, envia ao cliente um email HTML profissional com os dados necessários para pagar. Este guia mostra o template recomendado e como integrá-lo em Node.js ou PHP.

Fluxo

  1. POST /api/v1/payments/init — cria a transacção com orderId e amount.
  2. POST /api/v1/payments/multibanco — devolve entity, reference, expiresAt.
  3. Constrói o HTML do email com os 4 campos: entidade, referência, montante e validade.
  4. Envia via SMTP (nodemailer / PHPMailer / qualquer cliente SMTP).

Campos obrigatórios no email

Estes valores vêm directamente da Xpend e não devem ser alterados. Se mudares a entidade, referência ou montante, o cliente não consegue pagar — qualquer transacção que não bata certo com a referência emitida fica por reconciliar.

CampoOrigemObrigatório
entityAPI XpendSim
referenceAPI XpendSim
amountAPI Xpend — idêntico ao valor da transacçãoSim
expiresAtAPI Xpend (default 72h)Sim

O que podes personalizar

Tudo o resto é livre. Podes mudar:

  • Nome e logo da tua loja
  • Assunto do email
  • Texto de saudação e corpo
  • Cores, fontes e layout
  • Adicionar foto do produto ou imagens de marca
  • Footer com links para redes sociais
  • Texto do aviso (mas mantém o conteúdo: "montante tem de ser exacto")

O que é opcional

  • supportEmail — email de contacto da loja
  • orderDetails — descrição do que o cliente encomendou
  • Links para redes sociais
  • Rodapé com termos e condições
  • Foto do produto inline

Template HTML

Recomendamos um email de fundo branco, com uma tabela de 4 linhas (Entidade / Referência / Montante / Válido até) e um aviso amarelo a sublinhar que o montante tem de ser exacto.

A função buildMultibancoEmailHtml() em lib/email-templates/multibanco-reference.ts do nosso código aberto serve como referência. Renderiza identicamente em Gmail, Outlook, Apple Mail e clientes móveis.

Usa o SDK oficial. Os exemplos abaixo usam lib/xpend.js do ZIP em Integrações — não uses fetch directo (403).

Exemplo · Node.js

require('dotenv').config()
const nodemailer = require("nodemailer")
const xpend = require("./lib/xpend")

async function sendMultibancoEmail({ customerEmail, customerName, orderId, amount, customer, items }) {
  const payment = await xpend.createPayment(orderId, amount, customer, items)
  const mb = await xpend.generateMultibanco(payment.transactionId)
  const refFmt   = String(mb.reference).replace(/(\d{3})(\d{3})(\d{3})/, "$1 $2 $3")
  const amountFmt = new Intl.NumberFormat("pt-PT", { style: "currency", currency: "EUR" }).format(amount)
  const expires  = new Date(mb.expiresAt).toLocaleString("pt-PT")

  const html = `<div style="font-family: -apple-system, sans-serif; background:#F4F6F9; padding:24px;">
    <div style="max-width:520px; margin:0 auto; background:#fff; border-radius:14px; padding:28px;">
      <h2 style="margin:0 0 8px; color:#0F172A;">Paga com Referência Multibanco</h2>
      <p style="color:#475569;">Olá ${customerName}, obrigado pela encomenda <strong>#${orderId}</strong>.</p>
      <table width="100%" style="border:1px solid #E2E8F0; border-radius:10px; margin-top:16px; border-collapse:collapse;">
        <tr style="background:#F8FAFC;"><td style="padding:10px 14px; font-size:11px; text-transform:uppercase; color:#64748B;">Entidade</td>
          <td align="right" style="padding:10px 14px; font-family:monospace; font-weight:700; font-size:18px; color:#0F172A;">${mb.entity}</td></tr>
        <tr><td style="padding:10px 14px; font-size:11px; text-transform:uppercase; color:#64748B; border-top:1px solid #E2E8F0;">Referência</td>
          <td align="right" style="padding:10px 14px; font-family:monospace; font-weight:700; font-size:18px; color:#0F172A; border-top:1px solid #E2E8F0;">${refFmt}</td></tr>
        <tr style="background:#F8FAFC;"><td style="padding:10px 14px; font-size:11px; text-transform:uppercase; color:#64748B; border-top:1px solid #E2E8F0;">Montante</td>
          <td align="right" style="padding:10px 14px; font-weight:700; font-size:18px; color:#00A86B; border-top:1px solid #E2E8F0;">${amountFmt}</td></tr>
        <tr><td style="padding:10px 14px; font-size:11px; text-transform:uppercase; color:#64748B; border-top:1px solid #E2E8F0;">Válido até</td>
          <td align="right" style="padding:10px 14px; color:#0F172A; border-top:1px solid #E2E8F0;">${expires}</td></tr>
      </table>
      <div style="background:#FEF3C7; border:1px solid #FCD34D; padding:10px 14px; margin-top:14px; border-radius:8px; font-size:13px; color:#854D0E;">
        ⚠ <strong>O montante tem de ser exacto.</strong>
      </div>
    </div></div>`

  const transporter = nodemailer.createTransport({
    host: "smtp.gmail.com", port: 587,
    auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS },
  })
  await transporter.sendMail({
    from: `"A tua loja" <${process.env.SMTP_USER}>`,
    to: customerEmail,
    subject: `Referência Multibanco — Pedido ${orderId}`,
    html,
  })
}

Exemplo · PHP

require 'vendor/autoload.php';
require 'xpend.php';
use PHPMailer\PHPMailer\PHPMailer;

function sendMultibancoEmail($email, $name, $orderId, $amount, $customer, $items) {
  $payment = xpendCreatePayment($orderId, $amount, $customer, $items);
  $mb = xpendMultibanco($payment['transactionId']);
  // ... constrói o HTML e envia via PHPMailer (ver painel Integrações)
}

Boas práticas

  • Assunto claro: Referência Multibanco — Pedido #ORDER-123 é mais reconhecível do que algo genérico como "A tua encomenda".
  • Montante exacto: pagamentos com valor diferente do gerado ficam por reconciliar. Inclui sempre o aviso amarelo no email.
  • Validade: a referência expira após 72h por defeito. Mostra a data formatada e considera enviar um lembrete antes do prazo.
  • Fundo branco: evita gradientes ou imagens de fundo — não renderizam consistentemente entre clientes de email. Tabelas com inline styles é o mais seguro.
  • Webhook: assim que o cliente paga, recebes payment.successno teu webhook. Usa-o para disparar o email de confirmação de pagamento (separado deste).

Geradores prontos no painel

No teu backoffice tens uma aba Email Multibanco em Integrações com 5 snippets prontos para Node.js, PHP, Claude Code, Replit e Lovable — com as tuas API keys já injectadas.