API Reference

3D Secure (3DS)

Summary: This guide shows how to enable and operate 3D Secure (3DS) in Host‑to‑Host (H2H) mode, including Challenge vs. Frictionless, the threeds_authentication toggle, DataOnly notes, Device Data Collection (DDC) with the A55Pay SDK, example payloads, responses, and a secure redirect pattern.

🔎 Overview

Why 3DS?When it triggers?What you implement?
Liability shift & higher approval with issuers when authenticated.Based on issuer/provider rules and risk; can be Challenge or Frictionless.Send a charge request with the correct 3DS flags & device data, render url_3ds when returned, handle webhook & postMessage events.
🔒

Security: Use HTTPS end‑to‑end, never log sensitive data, and validate cross‑window message origins.


🧭 High‑Level Flow (H2H)

sequenceDiagram
autonumber
participant P as Payer (Merchant Checkout)
participant SDK as A55Pay SDK (DDC)
participant M as Merchant Backend
participant A as A55 API
participant I as Issuer/ACS


%% 1) Checkout start + DDC
P->>SDK: A55Pay.authentication()

SDK-->>P: Returns sessionId
P->>M: Sends sessionId


%% 2) Charge with device_info
M->>A: POST /bank/wallet/charge (device_info.session_id=sessionId)


%% 3) 3DS branching
alt 3DS Challenge required
A-->>M: status=pending + url_3ds
M-->>P: Open modal/iframe or redirect to url_3ds
P->>I: Completes challenge at url_3ds
I-->>A: Challenge result
A-->>M: Webhook with final status (confirmed/error)
M-->>P: Show final result
else No challenge
A-->>M: Immediate status (confirmed/error)
M-->>P: Show result
end

⚙️ Enabling & Forcing 3DS

  • threeds_authentication: trueforces 3DS; transaction only proceeds if it is successfully authenticated.
  • threeds_authentication: false (or omitted) → do not force; the provider may still apply 3DS or DataOnly depending on risk.
📝

Mandatory payload for 3DS: rich customer, address and device_info. Missing details reduce approval and may block 3DS.


🧾 Field Reference (3DS‑Relevant)

FieldScopeRequired for 3DSNotes
payer_cell_phoneCustomerUsed for step‑ups/issuer contact.
items[]OrderName/description/quantity/amount required.
payer_address{...}AddressStreet/city/state/postal_code/country.
device_info.ip_addressDevicePublic IP.
device_info.user_agentDeviceBrowser UA string.
device_info.http_*DeviceAccept headers, language, etc.
device_info.http_browser_*DeviceJava, JS enabled, screen size, color depth, time diff.
redirect_urlFlowWhere to send the customer after 3DS.
webhook_urlFlowReceives all status updates.
💡

Tip: Collect device data with A55Pay SDK (DDC) to improve approval and reduce friction (see below).


📡 Example Requests

1) Do not force 3DS (provider may decide)

{
  "wallet_uuid": "00000000-0000-0000-0000-000000000000",
  "merchant_id": "11111111-1111-1111-1111-111111111111",
  "payer_name": "John Doe",
  "payer_email": "[email protected]",
  "payer_cell_phone": "+5511999999999",
  "items": [
    { "name": "Sample Product", "description": "Description", "quantity": 1, "total_amount": 100, "unit_amount": 100, "sku": "SAMPLE-SKU-123", "code": "SAMPLE-CODE-456" }
  ],
  "payer_address": {
    "street": "Sample Street", "address_number": "123", "complement": "Apt 101",
    "neighborhood": "Sample Neighborhood", "city": "Sample City", "state": "SP",
    "postal_code": "00000-000", "country": "BR"
  },
  "currency": "BRL",
  "installment_value": 100,
  "installment_count": 1,
  "due_date": "2025-12-31",
  "description": "Sample transaction",
  "type_charge": "credit_card",
  "card_name": "John Doe",
  "card_number": "4111111111111111",
  "card_expiry_month": "12",
  "card_expiry_year": "2030",
  "card_cvv": "123",
  "threeds_authentication": false,
  "device_info": {
    "ip_address": "192.168.0.1",
    "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
    "http_accept_content": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
    "http_browser_language": "en-US",
    "http_browser_java_enabled": true,
    "http_browser_javascript_enabled": true,
    "http_browser_color_depth": "24",
    "http_browser_screen_height": "1080",
    "http_browser_screen_width": "1920",
    "http_browser_time_difference": "-180",
    "http_accept_browser_value": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
  },
  "webhook_url": "https://webhook.example.com/status",
  "redirect_url": "https://merchant.example.com/thank-you"
}

2) Force 3DS

{
  "wallet_uuid": "00000000-0000-0000-0000-000000000000",
  "merchant_id": "11111111-1111-1111-1111-111111111111",
  "payer_name": "John Doe",
  "payer_email": "[email protected]",
  "payer_cell_phone": "+5511999999999",
  "items": [
    { "name": "Sample Product", "description": "Description", "quantity": 1, "total_amount": 100, "unit_amount": 100, "sku": "SAMPLE-SKU-123", "code": "SAMPLE-CODE-456" }
  ],
  "payer_address": { "street": "Sample Street", "address_number": "123", "complement": "Apt 101", "neighborhood": "Sample Neighborhood", "city": "Sample City", "state": "SP", "postal_code": "00000-000", "country": "BR" },
  "currency": "BRL",
  "installment_value": 100,
  "installment_count": 1,
  "due_date": "2025-12-31",
  "description": "Sample transaction",
  "type_charge": "credit_card",
  "card_name": "John Doe",
  "card_number": "4111111111111111",
  "card_expiry_month": "12",
  "card_expiry_year": "2030",
  "card_cvv": "123",
  "threeds_authentication": true,
  "device_info": { /* same as above */ },
  "webhook_url": "https://webhook.example.com/status",
  "redirect_url": "https://merchant.example.com/thank-you"
}

3) External 3DS result (already authenticated upstream)

{
  "wallet_uuid": "00000000-0000-0000-0000-000000000000",
  "merchant_id": "11111111-1111-1111-1111-111111111111",
  "payer_name": "John Doe",
  "payer_email": "[email protected]",
  "payer_cell_phone": "+155599999999",
  "items": [ { "name": "Test Product", "description": "Sample", "quantity": 1, "total_amount": 100.00, "unit_amount": 100.00, "sku": "TEST-SKU-001", "code": "TEST-CODE-001" } ],
  "payer_address": { "street": "Test Avenue", "address_number": "123", "complement": "Suite 456", "neighborhood": "Downtown", "city": "Testville", "state": "CA", "postal_code": "12345-678", "country": "US" },
  "currency": "BRL",
  "installment_value": 100.00,
  "installment_count": 1,
  "due_date": "2025-12-31",
  "description": "External 3DS",
  "type_charge": "credit_card",
  "card_name": "John Doe",
  "card_number": "4111111111111111",
  "card_expiry_month": "12",
  "card_expiry_year": "2030",
  "card_cvv": "123",
  "threeds_external": {
    "eci": "05",
    "request_id": "3ds-ext-req-987654321",
    "xid": "dXNlci10ZXN0LXhpbGwtYWJjMTIz",
    "cavv": "AAABBIIFmAAAAAAAAAAAAAAAAA=",
    "version": "2.2.0"
  },
  "webhook_url": "https://webhook.example.com/payment-status",
  "redirect_url": "https://merchant.example.com/thank-you"
}

📬 Responses

Challenge required

{
  "status": "pending",
  "url_3ds": "https://confirmation.a55.tech/charge/791b390a-f3ce-4c50-90a1-3b813b59b455"
}

No challenge

{ "status": "confirmed" }

Final status will be delivered to your webhook_url.


🧰 Post‑Challenge Redirect (Parent‑Window Pattern)

Listen in the parent window and redirect there (avoid window.top.location from iFrames in cross‑origin contexts):

<script>
  window.addEventListener('message', function (event) {
    if (event.data && event.data.event === '3ds-auth-complete') {
      const chargeUuid = event.data.chargeUuid;
      // custom actions
    }
    // if send redirect_url
		if (event.data && event.data.event === '3ds-redirect-request') {
       window.location.replace(event.data.redirectUrl);
    }
  });
</script>

Render the url_3ds in a modal/iframe or perform a full‑page redirect. Prefer validating event.origin and an allow‑list of hosts prior to navigation.


📲 Device Data Collection (DDC) — A55Pay SDK

Improve issuer risk signals by collecting device data.

Install

<script src="https://cdn.jsdelivr.net/npm/a55pay-sdk"></script>

How it works

sequenceDiagram
  participant C as Client/Checkout
  participant SDK as A55Pay SDK
  participant B as A55 Backend
  participant CS as CyberSource
  C->>SDK: A55Pay.authentication()
  SDK->>B: POST /setup-authentication
  B->>SDK: access_token + collection_url
  SDK->>CS: Device Data Collection
  CS-->>SDK: profile.completed
  SDK-->>C: sessionId
  C->>B: Send charge with device_info.session_id

Usage

A55Pay.authentication({
  transactionReference: "transaction-uuid",
  cardBrand: "Visa",
  cardExpiryMonth: "08",
  cardExpiryYear: "2029",
  cardNumber: "4111111111111111",
  onSuccess: ({ sessionId }) => {
    // Include sessionId in your charge payload
  },
  onError: (err) => console.error('Authentication error:', err)
});

Charge payload snippet

const chargePayload = {
  // ...
  device_info: {
    session_id: sessionId
  }
  // ...
};

✅ Best Practices

  • Implement Device Data Collection (DDC) with the A55Pay SDK and include the returned session_id in device_info (improves issuer risk signals and reduces friction).
  • Prefer modal/iframe for 3DS and handle navigation in the parent via postMessage.
  • Provide complete device_info, address, items, and contact data.
  • Monitor the webhook for final status transitions.


❓ FAQ

Is 3DS always a challenge? No; issuers may run frictionless based on risk.

What is DataOnly? A frictionless data pass‑through (Visa/Mastercard). It improves approval but does not provide liability shift; only one of 3DS or DataOnly can be enabled at a time per account.

Where do I get the final result? From your webhook; the url_3ds page is only for authentication.