3DS - Pagseguro

Complete PagSeguro 3DS authentication flow

Overview

Complete 3DS integration flow:

  1. [Manual action] Generate API credentials in your logged-in area (client ID/secret and Store ID).
  2. [Backend] Create a session access_token via OAuth2 (backend).
  3. [Frontend] Load and configure the JavaScript SDKs.
  4. [Frontend] Execute PSI.threeds.authenticate(...) to obtain the auth.id.
  5. [Backend] Use that ID in your Create Transaction API call.
  6. [Frontend] Simulating sandbox scenarios.
  7. [Frontend/Backend] Extras success and error scenarios properly.

Reference: Create Transaction API


1. Credential Generation - [Logged-in Area]

  1. Access your account through the MyAccount link.

  2. Navigate to Account Settings > Config & Key.
    On the Config & Key page, go to the Credentials section and click the Generate button.

  3. A modal will appear with credential type options.
    Select Public Key and click Generate.

  4. The modal will close after loading, and you will return to the Config & Key page with the newly generated credential.

  5. Click Reveal secret key to access your API key.


⚠️

Use the secret key as the authentication token to generate the 3DS authentication session.

This Secret Key will be referred to as api_token_public from now on. You will use it to generate Session Tokens in the next integration step.


2. Generate Access Token - [Backend]

Use the OAuth2 Client Credentials flow securely in your backend. Never expose credentials to the frontend.

Example:

curl -v --request 
POST \ 
	--url https://api.sandbox.international.pagseguro.com/sessions \
  --header 'Authorization: Basic {{api_token_public}}' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --header 'X-Store-Id: {{you_store_id}}' \
  --data grant_type=client_credentials

Typical response:

{
  "access_token": "eJd61f1fZzSDWKT2Jl4Rmchjee8Q20...",
  "token_type": "Bearer",
  "expires_in": 3599,
  "scopes": [
    "sdk.*"
  ]
}

Tips:

  • Cache tokens until expiration.
  • Renew ~5 minutes before expiry.
  • Always send the correct X-Store-Id matching your environment.

3. Frontend Setup (SDKs) - [Frontend]

Include the required scripts in your checkout page:

<script src="https://stc.international.pagseguro.com/sdk/1.0/threeds.js"></script>
<script src="https://stc.international.pagseguro.com/sdk/1.0/main.js"></script>

Important: The SDK address is unique. You must use the environment variable set during the script initialization to target the desired environment.

The available options are sandbox, or production.


4. SDK Initialization and 3DS Authentication - [Frontend]

Example implementation:

<script>
(async function () {
  try {
    const accessToken = "{{your_access_token_session}}";

    const PSI = PagSeguroInternational({
      accessToken: accessToken,
      environment: "sandbox" // or "production"
    });

    const auth = await PSI.threeds.authenticate(
{
  payer: {
    name: "João de Oliveira",
    email: "[email protected]",
    phones: [
      {
        country: "55",
        area: "21",
        number: "912345678",
        type: "MOBILE"
      }
    ]
  },
  charge: {
    country: "BR",
    amount: {
      currency: "BRL",
      value: 125075
    },
    paymentMethod: {
      type: "CARD",
      card: {
        number: "4000000000001091",
        expirationMonth: "08",
        expirationYear: "2027",
        holderName: "JOAO C OLIVEIRA"
      },
      installments: 1
    }
  },
  address: {
    billing: {
      street: "Avenida Paulista",
      number: "1578",
      complement: "Conjunto 142",
      city: "São Paulo",
      regionCode: "SP",
      postalCode: "01310200",
      country: "BR"
    },
    shipping: {
      street: "Rua das Acácias",
      number: "456",
      complement: "Apt 301",
      city: "Rio de Janeiro",
      regionCode: "RJ",
      postalCode: "22071900",
      country: "BR"
    }
  }
}
);

    console.info(auth); // Contains 3DS authentication result (auth.id)

  } catch (error) {
    switch (error.type) {
      case 'SDKError':
        console.error({ module: error.module, code: error.code });
        break;
      case 'ProcessingError':
        console.error({ code: error.code, errors: error.errors });
        break;
      default:
        console.error(error);
    }
  }
})();
</script>

Key Output: On success, the property auth.id — this value must be used when creating the payment transaction.

{
  id: "3DS_7bc0be8c-3601-46cf-a291-a8a15666395d",
  status: "AUTHENTICATED",
  authentication: {
    eci: "05",
    pares_status: "Y",
    version: "2.2.0"
  }
}
{
  code: "API_INTERNAL_SERVER_ERROR",
  module: "THREEDS",
  name: "SDKError",
  type: "SDKError"
}
{
  code: "PAYLOAD_INVALID",
  errors: [
    {
      location: "charge.paymentMethod.card.number",
      message: "Invalid card number"
    }
  ],
  module: "THREEDS",
  name: "ProcessingError",
  type: "ProcessingError"
}

❗️

Important: A challenge may be requested.

3DS authentication may open an iframe to present a challenge request required by the cardholder’s issuing bank.

The experience and the method by which the challenge is carried out are entirely orchestrated by the issuer. PagSeguro has no control over this step.

4.1 SDK Field Validations

Below is a detailed table of all validation rules enforced by the PagSeguro International 3DS SDK. Use this section to ensure your payload meets the requirements before invoking PSI.threeds.authenticate().


PAYER Object

FieldTypeRequiredConstraintsValidation Rules
payer.namestringYes1–100 charsMust include at least two words (first and last name).
payer.emailstringYesMust be a valid email format.
payer.phonesarrayYes≥1 itemMust include at least one phone with type = MOBILE.

PHONE Object (within payer.phones)

FieldTypeRequiredConstraintsValidation Rules
phone.areastringYes≥1 digitDigits only (^\d+$).
phone.typeenumYesAllowed: MOBILE, HOME, BUSINESS.
phone.numberstringYes6–9 digitsDigits only (^\d+$).
phone.countrystringYes1–3 digitsDigits only; transformed to uppercase.

CHARGE Object

FieldTypeRequiredConstraintsValidation Rules
charge.amount.valueintegerYes≥100Positive integer (e.g., 1550 = $15.50).
charge.amount.currencyenumYesMust match country (see cross-validations). Allowed: BRL, CLP, COP, MXN, PEN, USD.
charge.countryenumYesAllowed: BR, CO, CL, MX, PE.
charge.paymentMethod.typeenumYesMust be CARD.
charge.paymentMethod.installmentsintegerYes1–18Max 18 (Mexico), 12 (others).

CARD Object (Option 1 – Tokenized Card)

FieldTypeRequiredConstraintsValidation Rules
card.idstringYes≥1 charStrict mode — no extra fields allowed.

CARD Object (Option 2 – Raw Card)

FieldTypeRequiredConstraintsValidation Rules
card.numberstringYes13–19 digitsMust pass Luhn check.
card.holderNamestringYes1–50 charsMust contain first and last name.
card.expirationYearstringYes4 digitsCombined with month → must be in the future.
card.expirationMonthstringYes2 digits (01–12)Combined with year → must be in the future.

ADDRESS Object (Optional)

FieldTypeRequiredConstraintsValidation Rules
address.billingobjectNoMust follow Address Item rules if provided.
address.shippingobjectNoMust follow Address Item rules if provided.

ADDRESS ITEM (Billing/Shipping)

FieldTypeRequiredConstraintsValidation Rules
citystringConditional≥1 charRequired if address provided.
streetstringConditional≥1 charRequired if address provided.
numberstringConditional≥1 charRequired if address provided.
countrystringConditional2 charsISO code, uppercase.
complementstringNo≥1 charOptional field.
regionCodestringConditional≥1 charRequired if address provided.
postalCodestringConditional≥1 charMust NOT contain hyphens.

Cross-Field Validations

RuleDescription
Currency–Country MatchBR → BRL, CO → COP, CL → CLP, MX → MXN, PE → PEN
Installment LimitsMX → up to 18, others → up to 12
Mobile RequirementAt least one phone with type = MOBILE required
Card Type ExclusivityUse either Tokenized OR Raw card — never both
Expiration ValidityCombined month/year must be a future date

Validation Error Handling

TypeCauseAction
SDKErrorInvalid field format, missing parametersFix validation issue before retry.
ProcessingErrorInvalid transaction context or backend failureReview SDK response and logs.

5. Create the Transaction with 3DS - [Backend]

5.1: Create the authorization

Use the Create Transaction API.

Add the following fields inside the charge object:

FieldDescription
charge.authentication_method.type"3DS"
charge.authentication_methodtype.id"auth.id" returned of SDK

Example:

curl -X POST https://api.sandbox.international.pagseguro.com/v3/transactions \
  -H "Authorization: Basic <base64(client_id:secret)>" \
  -H "Content-Type: application/json" \
  -d '{
  "reference_id": "order-123",
  "customer": {
    "name": "John Doe",
    "email": "[email protected]"
  },
  "charge": {
    "amount": {
      "value": 125075,
      "currency": "MXN"
    },
    "payment_method": {
      "type": "CARD",
      "card": {
        "token": "eyJkbmEiOiIiLCJ0b2tlbiI6IjYzZDk1NGZlN2Y4ZjQyNDhhN2U1Ym...."
      },
      "installments": 3
    },
    "country": "MX",
    "authentication_method": {
      "type": "3DS",
      "id": "3DS_9596a062-2ec6-4c60-8a63-4cb9aa130508" // From the SDK response
    }
  }
}'
{
  "code": "25a58ef1-3755-476b-b2f6-e445b170a849",
  "reference": "REF-XXX-1234567890",
  "status": "PENDING",
  "amount": 101.1,
  "currency": "BRL",
  "country": "BR",
  "created_at": "2021-04-12T12:43:13Z"
}

Response: Refer to the API documentation for transaction structure and status codes.

📘

Reason Codes

If the request fails, the API will return an HTTP status code other than 200. The response body will include an errors array with descriptive messages and corresponding error codes.

For the full list of possible error codes, see the Reason Codes reference.


5.2: Processing the API Response

After submitting the request, the API will return a response containing the transaction details. Below is an example of a successful response.

The status field in the response indicates the transaction state.
You can monitor status updates using the notification_url or by querying the transaction status.


6. Sandbox


Use these rules in sandbox/QA to force 3DS outcomes without changing payer/card data. The switches are driven by the amount.value pattern (decimal float, e.g., 1250.75 for $1,250.75).

How to use

  1. Keep your normal 3DS auth flow (Sections 3–5).
  2. Set charge.amount.value to match one of the patterns below.
  3. Run PSI.threeds.authenticate(...) and then create the transaction with authentication_method as usual.
  4. Verify the 3DS internal status and API result.

Scenarios

Scenarioamount.value patternChallenge?3DS Internal ResultFinal Status / Code
Authenticated – no challenge (default)any value not matching the patterns belowNoAuthenticated (internal)status = AUTHENTICATED
Authenticated – with challengeends with **.*1 (e.g., ...0.01, ...1.01)YesAuthenticated (internal)status = AUTHENTICATED
Not authenticated – with challengeends with **.*2 (e.g., ...0.02, ...1.12)YesNot authenticated (internal)status = NOT_AUTHENTICATED
Not authenticated – no challengeends with **.*3 (e.g., ...0.03, ...2.33)NoNot authenticated (internal)status = NOT_AUTHENTICATED

Notes

  • **.*n means any integer whose last three digits end with 00n/* * * n. Examples shown above are illustrative.
  • These rules apply to sandbox only and are ignored in production.
  • Keep authentication_method in the payment request so the gateway ties the 3DS auth to the transaction.
  • For error simulation (**.*4), validate your UI/observability surfaces the SDK error cleanly and that you do not proceed to payment creation when the SDK indicates an integration failure.

Example excerpt

Authenticated – with challenge scenario (**.*1)

{
	/* other parameters */
  charge: {
		/* other parameters */
    amount: {
      currency: "BRL",
      value: 1000.01
    }
  }
}

Validate both SDK errors (SDKError / ProcessingError) and payment API responses to ensure your app handles each branch: successful auth, challenged auth, failed auth, and integration error.


7. Extras

7.1 Error Handling SDK (Frontend)

  • SDKError: Local configuration or validation issue (e.g., missing parameters).
    → Log module and code.
  • ProcessingError: Remote or validation failure during processing.
    → Log code and errors.

7.2 Error Handling API (Backend)

  • Handle HTTP 4xx/5xx responses.
  • Log error code and reason.
  • Map reason codes to friendly user messages (e.g., card declined, fraud suspicion).

7.3. Success Handling

  1. Successful SDK authentication returns auth.id.
  2. Create transaction using that ID.
  3. Evaluate API response: Transaction Status Description

7.4. Security & Compliance

  • Never expose client_secret in the frontend.
  • Manage access_token only via backend.
  • Mask all sensitive data (PAN, CVV) in logs.
  • Only PCI-certified merchants may use raw card data.

7.5. Implementation Checklist

  • API credentials created (client_id, secret, store ID).
  • Backend generates and caches access_token securely.
  • SDK scripts loaded for correct environment.
  • 3DS authentication executed and returning auth.id.
  • Transaction created using authentication_method with type: 3DS and valid id.
  • Error handling implemented.
  • Logs sanitized.
  • End-to-end tests executed.

7.6. Troubleshooting

SymptomLikely CauseFix
401/403 on token requestWrong Authorization or Store IDVerify Basic Auth, Store ID, and host
SDKError on initMissing script or invalid environmentCheck script order and environment param
No auth.id returnedMissing required fields or expired tokenValidate payer/charge payload and token expiry
Payment not authenticatedMissing authentication_method in API payloadAdd type: 3DS and valid id
Environment mismatchToken vs SDK environment conflictAlign both to same env