CentralPay Documentation CentralPay Documentation
  • General information
  • Documentation
  • Developers
  • English
    • FrenchSwitch to French
CentralPay Documentation CentralPay Documentation
  • General information
  • Documentation
  • Developers
  • English
    • FrenchSwitch to French
Documentation
  • Folder icon closed Folder open iconQuick start guide >
  • Folder icon closed Folder open iconMerchant, accounts and sales channels
    • Merchant Profilemerchant
    • Customer profilescustomer
    • Retail locationspointOfSale
    • Payment accountswallet
    • EM Accountswallet
    • Outgoing paymentpayout
  • Folder icon closed Folder open iconAutomations, integrations and exports
    • Email/SMS notifications
    • Anti-fraud services
    • File Import
    • Accounting Exports
    • Data Exports
    • Webhooks
  • Folder icon closed Folder open iconPayment Links
    • General information
    • Payment requestspaymentRequest
    • Payment page (SmartForm)
    • Callbacks, statuses and hooks
  • Folder icon closed Folder open iconCard transaction
    • General information
    • CUSTOM payment form
    • 3DS 2.0 Authentication
    • Card Transactiontransaction
    • Recurring Card Transactiontransaction
    • Card transaction via walletApplePay / GooglePay
    • Card Refund Transactionrefund / credit / dispute
    • Confirmation email
    • Bank statement descriptor
    • Currency management
    • Virtual Card Management (VCC)
    • Callbacks, statuses and hooks
  • Folder icon closed Folder open iconBank Transfer Transaction
    • General information
    • Virtual IBANs
    • Bank Transfer TransactionsctTransaction
    • Pay by Bank – Payment Initiation (PIS)
    • Reconciliation of a payment requestbankReconciliation
    • SCT R-transactionrefund
    • International wire transfers
    • Responses, statuses, and webhooks
  • Folder icon closed Folder open iconSEPA direct debit transaction
    • General information
    • SEPA Creditor ID
    • Bank account statement
    • Creating a SEPA direct debit mandate
    • Direct Debit transactionsddTransaction
    • SDD R-Transactionrefund / sddTransactionReversal
    • Responses, statuses, and webhooks
  • Folder icon closed Folder open iconRecurring payments
    • Subscriptionsubscription
    • Installmentinstallment
  • Folder icon closed Folder open icon3DS 2.2 authentication
    • Transaction Initiated by the Holder (CIT – BRW)
    • Merchant-initiated transaction (MIT – 3RI)
    • Optimize the Frictionless Rate
    • FAQ – 3DS 2.2
  • Folder icon closed Folder open iconMerchant management
    • General information
    • Enrollment requestmerchant-enrollment
    • Complete an enrollmentmerchant-enrollment
    • Enrollment validation
    • Limited Electronic Money Accountcustomer / wallets
    • Remove the limit on an Electronic Money Accountmerchant-enrollment
    • Responses, articles of association, and webhooks
  • Folder icon closed Folder open iconPayouts
    • General information
    • Independent transfertransfer / transferReversal
    • Transfer via Transaction or PaymentRequesttransaction / paymentRequest
    • Payout to a Third Party
    • Responses, statuses, and webhooks
  • Folder icon closed Folder open iconCMS Plugin
    • WooCommerce
    • PrestaShop
    • Magento
  • Folder icon closed Folder open iconBest practices
    • VAT Returns by Country
    • Merchant-Initiated Transaction (MIT)
    • Verification of Payee (VoP)
      • FAQ – Verification of Payee

Transaction Initiated by the Holder (CIT – BRW)

Estimated reading: 11 minutes

The BRW (Browser) flow applies to Customer-Initiated Transactions (CIT): the cardholder is present and authorizes the payment personally. This authenticated CIT also serves as the foundation for future MIT transactions.

👉 For a transaction initiated by the merchant without the cardholder (recurring billing, variable amounts, usage-based charges, one-time fees), see the 3RI flow documentation.

❌ Be careful when choosing the payment flow: Using BRW for a merchant-initiated transaction (MIT) results in non-compliance, unnecessary friction, and a significant drop in the conversion rate.

1. The main steps in the BRW workflow

The BRW flow consists of five steps on the API side, two of which are conditional: versioning (is the card authenticatable?) → 3DS Method (if necessary) → authentication → challenge (if required by the bank) → result, before completing the transaction.

3DS 2.2 BRW flow diagram
ℹ️ The entire process must take place on a single web page, without being redirected to a bank page, using an iframe solution. This is a requirement of the banking process. 

To speed up your integration of the BRW flow, you can start with a complete sample application (PHP/Twig) that replicates the entire sequence described on this page: CUSTOM payment form, versioning, 3DS Method in an iframe, authentication, challenge handling, results, and then the transaction, all on a single page, in accordance with banking requirements.

👉 Download the sample code · View the online demo

Before running the sample code, enter your credentials in the file .env  (API_USER,  API_PASSWORD,  POS_UUID) and point it HOST_CENTRALPAY_API_CORE to the test environment https://test-api.centralpay.net/v2/rest/.

2. Versioning

The versioning is the first step: it queries the card network to determine whether the card can be authenticated using 3DS 2.2, and retrieves the technical information needed for the rest of the process. Specifically, you send the card’s PAN (Primary Account Number, the 16-digit number) to the CentralPay API.

Sample (curl) :

curl --location --request POST 'https://test-api.centralpay.net/v2/rest/3ds2/versioning' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic ZG9jdGVzdDo0STlISlJUZA==' \
--data-urlencode 'acctNumber=4000001000000067'

Understanding the response. A card is said to be “enrolled” when the bank that issued it participates in the 3DS 2.2 protocol for that card. This is determined by the issuing bank: neither you nor CentralPay can enroll a card. Versioning is used precisely to determine whether this is the case.

  • Card not enrolled → versioning return a 404 error: the 3DS 2.2 authentification is impossible for this card. Plan for a fallback (switch to 3DS1 if supported, or decline the payment according to your risk policy).
  • Card enrolled → you receive a transaction ID, the threeDSServerTransID (generated by CentralPay and retained until the final result is available), as well as, if applicable, the data required for the “3DS Method” (a URL and data encoded in Base64).

For a rolled-up card, there are two possible answers:

Version 1 (the most common) — a 3DS Method is expected:

{
    "threeDSServerTransID": "7d031b8e-7fb7-4215-b866-eaacb395002f",
    "threeDSMethodURL": "https://test-3dss-demo.centralpay.net/acs/3ds-method",
    "threeDSMethodDataForm": {
        "threeDSMethodData": "eyJ0aHJlZURTTWV0aG9kTm90aWZpY2F0aW9uVVJMIjoiaHR0cHM6Ly90ZXN0LTNkc3MuY2VudHJhbHBheS5uZXQvM2RzLzNkcy1tZXRob2Qtbm90aWZpY2F0aW9uLyIsInRocmVlRFNTZXJ2ZXJUcmFuc0lEIjoiOWNjNmIzM2MtZGQzNS00ZmJkLTgxY2QtZmQ5Y2YwYWVlZDljIn0="
    },
    "errorDetails": null
}

The threeDSMethodURL and threeDSMethodData field have been filled in: proceed to step 3. 3DS Method.

Version 2 — no 3DS Method:

{
    "threeDSServerTransID": "7d031b8e-7fb7-4215-b866-eaacb395002f",
    "threeDSMethodURL": null,
    "threeDSMethodDataForm": null,
    "errorDetails": null
}

Only threeDSServerTransID is filled in (the 3DS Method fields are empty): proceed directly to Step 4. Authentication.

3. 3DS Method

What is it used for? The 3DS Method allows the cardholder’s bank — via its ACS (Access Control Server, the issuing bank’s server that authenticates the cardholder) — to discreetly collect technical information about the customer’s browser, before authentication. This information enhances the bank’s risk analysis and increases the likelihood of frictionless authentication (without requiring the cardholder to complete a challenge).

When should this be executed? Only if versioning returned a value for threeDSMethodURL and threeDSMethodData (the “Version 1” case above). Otherwise, proceed directly to authentication.

How? Load the threeDSMethodURL into an invisible iframe (hidden from view: this exchange is purely technical and should not display anything to the user) and post the threeDSMethodData field there. The user’s browser makes this call to the bank in the background.

4. (BRW) Authentification

The request is sent to the CentralPay API URL 3ds2/authentication. This request transmits contextual data related to the cardholder and their browser, which allows the bank to determine whether active authentication (challenge) is required.

Sample (curl) :

curl --location --request POST 'https://test-api.centralpay.net/v2/rest/3ds2/authentication' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic ZG9jdGVzdDo0STlISlJUZA==' \
--data-urlencode 'threeDSServerTransID=7d031b8e-7fb7-4215-b866-eaacb395002f' \
--data-urlencode 'cardTokenId=5b9nb5cf-4470-4e58-b690-dd8965860eb8' \
--data-urlencode 'deviceChannel=02' \
--data-urlencode 'messageCategory=01' \
--data-urlencode 'purchaseAmount=1000' \
--data-urlencode 'purchaseCurrency=EUR' \
--data-urlencode 'threeDSRequestorAuthenticationInd=01' \
--data-urlencode 'browserJavaEnabled=true' \
--data-urlencode 'browserLanguage=fr-FR' \
--data-urlencode 'browserColorDepth=24' \
--data-urlencode 'browserScreenHeight=1052' \
--data-urlencode 'browserScreenWidth=1853' \
--data-urlencode 'browserTZ=120' \
--data-urlencode 'browserIP=127.0.0.1' \
--data-urlencode 'browserUserAgent=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0' \
--data-urlencode 'browserAcceptHeader=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
--data-urlencode 'notificationURL=http://dev4.dev.centralpay.net:1101/requestor/challenge-notification' \
--data-urlencode 'threeDSRequestorURL=https://www.centralpay.eu'
💡 deviceChannel=02 indicates the browser channel, specific to the BRW feed. The browser* (the cardholder's browser characteristics) are therefore required here.
To increase the frictionless authentication rate, enrich this request with contextual data about the cardholder → see Optimizing the Frictionless Rate

Fields to be specified based on the purpose of the CIT. Field threeDSRequestorAuthenticationInd is required: it specifies the type of authentication. A CIT BRW can be used to authenticate a payment (messageCategory=01, PA), or to authenticate a card or its holder without a charge (messageCategory=02, NPA) — for example, to register a card, update it, or verify the cardholder. Both fields must be filled out consistently:

threeDSRequestorAuthenticationIndPurpose of the CITmessageCategoryAdditional required fields
01 — PaymentPer-unit payment (one-time)01 (PA)—
02 — RecurringRecurring payment (subscription)01 (PA)recurringExpiry, recurringFrequency
03 — InstalmentInstallment payments (in several payments)01 (PA)recurringExpiry, recurringFrequency, purchaseInstalData
04 — Add cardRegistering/encoding a card for future use, with no charge02 (NPA)—
05 — Maintain cardUpdating the information for an already registered card (e.g., renewal)02 (NPA)—
06 — Cardholder verificationCardholder verification as part of the ID&V process for an EMV token02 (NPA)—
  • recurringExpiry → the date after which no further authorizations will be issued (format YYYYMMDD).
  • recurringFrequency → minimum number of days between two authorizations (1 to 999).
  • purchaseInstalData → maximum number of authorizations (due dates) specified for installment payments (1 to 999).
ℹ️ Cases 04, 05, and 06 are non-payment authentications: no amount or recurrence field is required. They do not necessarily lead to an MIT transaction — they are often an end in themselves (to register, verify, or maintain a card). The card authenticated in this way can then be used for both CIT (cardholder present) and MIT (3RI) transactions.  

The response contains an authentication status (transStatus) that determines the next steps:

❌ No authorization — do not complete the transaction

Status (transStatus)Meaning
NNon authenticated/unverified account. Transaction declined.
UAuthentication/verification failed (technical issue or other problem).
RAuthentication/verification declined. The sender requests that you do not attempt to obtain authorization.
IFor informational purposes only. Acknowledgment of the applicant’s preference for the 3DS Challenge.

✅ Authorization without challenge

Status (transStatus)Meaning
YAuthentication successful.
AAttempt made. Not authenticated/verified, but a proof of the attempt is provided.

🔐 Authorization after challenge

Status (transStatus)Meaning
CChallenge required: the owner must actively authenticate (see step 5) using CReq/CRes (Challenge Request/Response) messages.
DChallenge required. Decoupled authentication confirmed.

Sample of responses:

C — Challenge required:

{
    "threeDSServerTransID": "7d031b8e-7fb7-4215-b866-eaacb395002f",
    "transStatus": "C",
    "acsTransID": "375d90ad-3873-498b-9133-380cbbc8d99d",
    "acsURL": "https://test-3dss-demo.centralpay.net/acs/challenge",
    "acsChallengeMandated": "Y",
    "base64EncodedChallengeRequest": "eyJtZXNzYWdlVHlwZSI6IkNSZXEiLCJ0aHJlZURTU2VydmVyVHJhbnNJRCI6ImU2MDFlYjQ0LTU2N2MtNDM4Ny05MmZjLWU2ZjIzMjJiODIyYiIsImFjc1RyYW5zSUQiOiI3ZTQzZDI4ZC00M2RkLTRmM2MtYTcwOS00YjZkZDVlZjc5Y2QiLCJtZXNzYWdlVmVyc2lvbiI6IjIuMS4wIn0=",
    "contractId": "71602dd0-2790-4743-877b-e72530d7576d"
}

Y — Authentication successful (no challenge required):

{
    "threeDSServerTransID": "7d994177-32d8-43f7-87a4-3a3cd734cbfe",
    "transStatus": "Y",
    "acsTransID": "375d90ad-3873-498b-9133-380cbbc8d99d",
    "authenticationValue": "MTIzNDU2Nzg5MDA5ODc2NTQzMjEa",
    "eci": "02",
    "contractId": "71602dd0-2790-4743-877b-e72530d7576d"
}

The required fields for the transaction are present: threeDSServerTransID, transStatus, authenticationValue (the CAVV — Cardholder Authentication Verification Value, the security code that verifies authentication) and eci (Electronic Commerce Indicator, which indicates the level of authentication achieved and determines the transfer of liability in the event of fraud). The xid is not provided: it is an optional reference intended for merchants.

N — Transaction declined:

{
    "threeDSServerTransID": "6396b832-3e5b-4143-bde6-f5r1c1e47da0",
    "transStatus": "N",
    "eci": "00",
    "contractId": "258128f3-5db9-4235-918a-f1d786f67c29"
}

5. Challenge

The challenge is the step in which the cardholder actively authenticates themselves with their bank (one-time code received via text message, validation in the banking app, biometrics, etc.). It occurs only if the authentication returned transStatus = C.

  • An iframe must submit a form to the acsURL page returned in step 4.
  • The only parameter sent is creq, whose value is the base64EncodedChallengeRequest obtained from authentication.
  • At the end of the challenge, the URL you provided (notificationURL) is called by the bank.

In a test environment, the challenge appears as an OTP (One-Time Password); in production, the bank’s ACS window appears:

OTP challenge window in a test environment

Test OTP:

  • 1234 → Y (simulates a successful challenge – Authentication successful)
  • 4444 → A (simulates a successful challenge – Not authenticated/verified, but a proof of the attempt is provided.)
  • 1111 → N (simulates a failed challenge – No authenticated/unverified account)
  • 2222 → R (simulates a failed challenge – Authentication/verification declined)
  • 3333 → U (simulates a failed challenge – Authentication/verification failed (technical issue or other problem)

6. Challenge response

Once the challenge is complete, the result is returned in the cres parameter, encoded in Base64. Decode it to read the status. Example in PHP:

$retour = json_decode(base64_decode($_POST['cres']), true);
  • If the status is Y or A, the challenge is validated and the payment is authorized: call GET /results (step 7) to retrieve the 3DS data required for the transaction.
  • Any other value means the challenge failed: the payment was declined.

7. Result

This step retrieves the final 3DS data to be included in the transaction. Send the threeDSServerTransID authentication request.

ℹ️ If the authentication returned transStatus = Y directly (without a challenge), the 3DS data is already included: this step is not necessary.

Call:

curl --location -g --request GET 'https://test-api.centralpay.net/v2/rest/3ds2/results/{{threeDSServerTransID}}' \
--header 'Authorization: Basic ZG9jdGVzdDo0STlISlJUZA=='

Response:

{
    "threeDSServerTransID": "7d031b8e-7fb7-4215-b866-eaacb395002f",
    "transStatus": "Y",
    "acsTransID": "375d90ad-3873-498b-9133-380cbbc8d99d",
    "authenticationValue": "JAmi21makAifmwqo2120cjq1AAA=",
    "eci": "01"
}
🔁 Prepare for future MITs (3RI). If this CIT is to serve as a reference for subsequent payments initiated by the merchant, retain the acsTransID from the authentication sequence: it will be required as threeDSReqPriorRef on the 3RI side.

8. Transaction

Information required to validate a transaction authenticated using 3DS 2.2:

  • 3ds[threeDSServerTransID] = threeDSServerTransID
  • 3ds[status] = transStatus
  • 3ds[cavv] = authenticationValue
  • 3ds[eci] = eci (required if available)
  • 3ds[xid] = custom parameter, free-form reference for merchants

Sample (curl) :

curl --location --request POST 'https://test-api.centralpay.net/v2/rest/transaction' \
--header 'Origin: https://example.centralpay.net' \
--header 'Authorization: Basic ZG9jdGVzdDo0STlISlJUZA==' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'currency=EUR' \
--data-urlencode 'amount=1500' \
--data-urlencode 'endUserIp=9.64.32.8' \
--data-urlencode 'endUserLanguage=ita' \
--data-urlencode 'merchantTransactionId=cpcg_12654de89ce44' \
--data-urlencode 'pointOfSaleId=1beb8574-cf4c-4b12-b065-d12b3f0eaa90' \
--data-urlencode 'browserUserAgent=Mozilla/5.0 (iPhone; CPU iPhone OS 16_1_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.1 Mobile/15E148 Safari/604.1' \
--data-urlencode 'browserAcceptLanguage=it_IT' \
--data-urlencode 'paymentRequestBreakdownId=5485d7e6-60c3-753c-94d3-682eaaf9ae6e' \
--data-urlencode 'email=support@centralpay.eu' \
--data-urlencode 'receiptEmail=support@centralpay.eu' \
--data-urlencode 'capture=true' \
--data-urlencode 'cardTokenId=5b9nb5cf-4470-4e58-b690-dd8965860eb8' \
--data-urlencode 'order[cardholderEmail]=support@centralpay.eu' \
--data-urlencode 'order[firstName]=John' \
--data-urlencode 'order[lastName]=Doe' \
--data-urlencode 'source=EC' \
--data-urlencode '3ds[xid]=35876533346561303461' \
--data-urlencode '3ds[cavv]=JAmi21makAifmwqo2120cjq1AAA=' \
--data-urlencode '3ds[eci]=01' \
--data-urlencode '3ds[status]=Y' \
--data-urlencode '3ds[threeDSServerTransID]=7d031b8e-7fb7-4215-b866-eaacb395002f'

Next step: For subsequent merchant-initiated transactions (MIT), see 3DS 2.2 – 3RI.

Transaction Initiated by the Holder (CIT – BRW) - Previous3DS 2.2 authenticationNext - Transaction Initiated by the Holder (CIT – BRW)Merchant-initiated transaction (MIT – 3RI)

Recently visited pages

  • Déclaration TVA par pays
  • WooCommerce
  • 3DS 2.0 Authentication
  • Payment requests
  • See more
CONTENTS

Doc Contents

Doc Footnotes

Doc Elements

  • Legal notices
  • Privacy policy

© 2026 CentralPay

You must log in to continue.

Login to CentralPay Documentation

Forgotten account?

Reset your password

Enter your username or email address and we will send you a link to reset your password.

Back to login
  • French