Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developer.pagou.ai/llms.txt

Use this file to discover all available pages before exploring further.

Use this page when you need the exact browser SDK contract for Payment Element v3.

Load the SDK

<script src="https://js.pagou.ai/payments/v3.js"></script>
The script exposes window.Pagou.
Pagou.setEnvironment("sandbox");
Supported environments:
EnvironmentUse
productionDefault. Uses production collection endpoints.
sandboxUse for test public keys and sandbox transactions.
localInternal development only.

Initialize Elements

const elements = Pagou.elements({
  publicKey: "pk_test_your_public_key",
  locale: "en",
  origin: window.location.origin,
});
Options:
OptionRequiredDescription
publicKeyYes before submitCompany public key. Use pk_test_* in sandbox and pk_live_* in production.
localeNoLocale forwarded to the hosted card field. Defaults to pt-BR.
originNoCheckout origin stored on the Element session. Defaults to window.location.origin.
You can update an existing instance before submit:
elements.update({
  publicKey: "pk_live_your_public_key",
  locale: "en",
});

Create and mount the card field

<div id="card-element"></div>
const card = elements.create("card", {
  theme: "default",
  locale: "en",
});

card.mount("#card-element");
elements.create("card") creates one hosted card field. If a card field already exists on the same elements instance, the SDK unmounts it before creating the new one. Card options:
OptionDescription
themedefault, night, or flat.
localeOverrides the Elements locale for this card field.
styleStyle object forwarded to the hosted field.
mountTimeoutMsMount timeout in milliseconds. Defaults to 8000.
telemetrySends best-effort mount failure telemetry when supported. Defaults to true.

Card events

card.on("ready", () => {
  messageEl.textContent = "";
});

card.on("change", (event) => {
  submitButton.disabled = !event.valid;
  brandEl.textContent = event.brand ?? "";
  errorEl.textContent = Object.values(event.errors ?? {})[0] ?? "";
});

card.on("error", (event) => {
  errorEl.textContent = event.message;
});
Supported events:
EventPayloadUse
ready{}Hosted iframe loaded and completed the SDK handshake.
change{ valid, brand, errors }Enable submit only when valid is true.
error{ code, message }Show initialization, mount, or card field errors.
Remove handlers during component teardown when the same card instance can stay alive:
card.off("change", handleCardChange);

Submit a payment

elements.submit(...) is the main SDK action. It creates an Element session, tokenizes the hosted card field, calls your createTransaction callback, and continues 3DS when the transaction response includes next_action.
const result = await elements.submit({
  createTransaction: async (tokenData) => {
    const response = await fetch("/api/pay", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        external_ref: "order_2001",
        amount: 2490,
        currency: "BRL",
        method: "credit_card",
        token: tokenData.token,
        installments: 1,
      }),
    });

    const payload = await response.json();
    return payload.data ?? payload;
  },
});
createTransaction receives:
{
  "token": "pgct_token_from_browser",
  "brand": "visa",
  "last4": "4242",
  "exp_month": "12",
  "exp_year": "2029"
}
Only send token to your backend as the payment credential. Treat brand, last4, exp_month, and exp_year as display or bookkeeping metadata.

Submit result

{
  "status": "pending",
  "transaction": {
    "id": "tr_2001",
    "status": "pending"
  }
}
Possible status values include:
StatusMeaning
Transaction statusIf there is no next_action, the SDK returns the transaction status from your backend response.
completedFallback when the backend response has no status.
requires_actionA next_action exists and automatic 3DS modal handling is disabled for the Element session.
succeeded3DS challenge completed successfully.
failed3DS challenge or payment failed.
canceledBuyer closed the 3DS modal.
timed_out3DS challenge did not finish within the SDK timeout.
errorTokenization, session creation, callback, or SDK flow failed.
Do not fulfill an order from the browser status alone. Use webhook delivery or server-side reconciliation as the final source of truth.

3D Secure

When your backend returns a transaction with next_action, the SDK can open the challenge modal automatically.
{
  "id": "tr_2001",
  "status": "three_ds_required",
  "next_action": {
    "type": "three_ds_challenge",
    "challenge_session_id": "3ds_1001",
    "client_secret": "sec_1001",
    "expires_at": "2026-03-16T14:20:00.000Z"
  }
}
If you already created the transaction server-side and only need to continue an existing action, call:
const result = await Pagou.handleNextAction(transaction.next_action);
Or pass the transaction to an Elements instance:
const result = await elements.submit({
  transaction,
  createTransaction: async () => transaction,
});

Reusable token for upsells

For one-click upsell flows, request a reusable token:
const result = await elements.submit({
  saveForUpsell: true,
  createTransaction: async (tokenData) => {
    return createPaymentWithToken(tokenData.token);
  },
});
This requests a pgpm_* token that can be consumed twice within 5 minutes. Use it only when the same card must be charged for the initial purchase and a follow-up upsell offer.

Cleanup

Unmount a card field when leaving the checkout screen:
card.unmount();
Destroy the Elements instance when the entire payment flow is gone:
elements.destroy();

Production rules

  • Use pk_test_* only with Pagou.setEnvironment("sandbox").
  • Use pk_live_* with the default production environment.
  • Never send raw card data to your backend.
  • Never log pgct_*, pgpm_*, client_secret, or card data.
  • Disable duplicate submits while elements.submit(...) is running.
  • Return your transaction payload from the backend without removing id, status, or next_action.
  • Treat browser status as provisional until webhook or reconciliation confirms the final payment state.