Skip to main content

How 3DS Appears in Transactions & Orders

Every standalone 3DS journey now creates an Order and a Transaction the moment you call the Initialisation API. This makes the whole 3DS journey visible in the Merchant Portal and over webhooks — including journeys that fail or are abandoned before any payment is attempted.

This page explains what these records are, how their status changes during the 3DS flow, and how to interpret them.

info

This applies to the standalone 3DS APIs (/3ds/v2/initialization and related calls). Hosted Payment Page (HPP) transactions create their own order and transaction through the HPP flow and are not affected.

Why you see an Authorization you didn't make

When the Initialisation API is called, NetValve does not yet know whether the journey will end in a Sale, an Authorization, or nothing at all — the payment call comes later, if it comes at all. So the record is created as:

FieldValue at 3DS initialisation
Transaction typeAuthorization (provisional — see below)
Transaction statusPending
Order statusPending
Amount / currencyFrom the initialisation request
Card detailsMasked card number and card type

The type is Authorization because nothing has been charged at 3DS time. It is a provisional type:

  • If you follow up with a Sale or Authorization call carrying the 3DS values, the same transaction record is reused and updated — the type is overwritten with the real one, and the record continues its life as a normal payment transaction under the same transaction ID and order ID.
  • If the journey fails at a 3DS step, the record is declined with a 3DS_ response code, so the failure is visible even though no payment was ever attempted.
  • If the journey is abandoned, the record simply stays Pending.

Status lifecycle

3DS Initialisation called
→ Order: Pending, Transaction: Pending (type Authorization)

Challenge required / device data collection / authentication in progress
→ stays Pending

3DS authentication successful
→ stays Pending (nothing is charged until you call /sale or /authorize)

3DS step fails (initialisation, authentication, challenge, or result)
→ Transaction: Declined, Order: Declined
→ Response code: 3DS_2xxx, response message: the actual failure reason
→ Webhook: AUTHORISATION_FAILED

Sale/Authorization called with the 3DS values
→ same transaction is reused and processed as a normal payment
→ type, status and response codes now reflect the actual payment

Customer abandons / journey never completes
→ stays Pending (never charged, never declined)

Only terminal 3DS failures decline the record. All intermediate and successful 3DS states keep it Pending, because a successful authentication still needs your Sale or Authorization call before any money moves.

New response fields on the 3DS APIs

The 3DS API responses now return the linked payment record so you can correlate the 3DS journey with the transaction and order:

Initialisation response (excerpt)
{
"responseCode": "3DS_1000",
"responseMessage": "Three DS Transaction Successful.",
"transactionID": 1048291,
"orderId": 993412,
"orderState": "PENDING",
"threeDSProviderResponse": {
"transID": "c19d5b5b-0dd6-47f4-98ad-096f319cd8c6",
"...": "..."
}
}
ParameterTypeDescription
transactionIDLongThe payment transaction created for this 3DS journey. When you later call Sale/Authorization with the 3DS values, the payment is recorded under this same transaction ID.
orderIdLongThe order created for this 3DS journey. The follow-up sale is recorded under this same order.
orderStateStringPENDING (journey in progress / awaiting payment), DECLINED (3DS failed or payment declined), PAID (payment completed).
note

Do not confuse transactionID (the payment transaction) with threeDSProviderResponse.transID (the 3DS transaction used in the 3DS API calls). They are different identifiers.

Interpreting these records

What you seeWhat it means
Type Authorization, status Pending, no response code3DS journey in progress, or the customer abandoned it, or 3DS succeeded but no Sale/Authorization call followed. No payment was attempted.
Type Authorization, status Declined, response code 3DS_2xxxThe journey ended at a 3DS step. The response code tells you which step and why (see below). This is not a bank decline — the card was never sent to the bank.
Type Sale or Authorization, bank/processor response codes3DS completed and a real payment was attempted. Interpret as any normal transaction.

Key takeaway for reconciliation: a Pending or 3DS-declined record means the cardholder was never charged. The 3DS_2xxx codes describe authentication outcomes, not payment outcomes.

Impact on approval rates and reporting

Since this feature was released, your transaction data contains records that did not exist before: journeys that failed or stopped at 3DS. Your real approval rate at the bank has not changed — declines that were previously invisible are now recorded. If your reports suddenly show more transactions and more declines, this is why.

What this means in practice:

  • NetValve portal approval-rate charts are not affected. They only count transactions that received a bank response, and they count per order. Transactions declined at 3DS never reached a bank, carry no bank response code, and are excluded automatically.
  • Transaction listings, exports, and webhooks now include 3DS-only declines. If you calculate approval rates yourself from these feeds, your denominator has grown, and your computed rate will appear to drop — without any change in bank behaviour.

To keep your own reporting consistent:

Metric you wantHow to compute it
Bank approval rate (comparable to before this feature)Exclude transactions whose response code starts with 3DS_ (equivalently: transactions with no bank response code). These never reached the bank.
Full checkout conversion (new — previously not measurable)Include everything. 3DS_2xxx declines show where customers fail authentication; Pending records show abandonment.
3DS pass rate3DS-completed journeys ÷ started journeys, using the 3DS_ records alone.

The new records are additional signal, not extra failures: a spike in 3DS_2017 (authentication failed) or a high abandonment count points at checkout friction that used to be invisible.

3DS decline codes

When a journey fails at a 3DS step, the transaction's response code is the 3DS_ code below and the response message carries the actual failure reason from the 3DS provider.

CodeMeaning
3DS_2000Authentication declined without a specific reason code. Despite the generic name, this is almost always a real decline by the cardholder's issuer or their Access Control Server (the card was not authenticated, or the authentication was rejected) where the 3DS provider did not supply a more specific reason. It is not, in the vast majority of cases, a NetValve technical error. Rarely, this code is also used as a fallback for provider connection failures.
3DS_20083DS processing error from the gateway.
3DS_2010Device data was not collected by the browser — the authentication call was made before/without device data collection.
3DS_2011The ACS challenge was not completed by the cardholder — the result call was made before/without challenge completion.
3DS_2012Authentication rejected by the provider.
3DS_2013Authentication unavailable — the payer could not be authenticated due to a technical or other issue.
3DS_2014Authentication required but was not provided.
3DS_2015No authentication information associated with this transaction.
3DS_2016The requested authentication method is not supported for this payment method.
3DS_2017Authentication failed — the payer was not authenticated. Do not proceed with the payment.
3DS_2018Invalid 3DS transaction ID.
3DS_2019Required 3DS field missing — dsTransactionId, eci and cavv must be provided.
3DS_2020Invalid 3DS field — xid and cavv must be Base64 encoded when provided.

Request-validation codes (3DS_20013DS_2009) are returned on the API response only; see API Status Codes.

3DS_21xx — provider reason codes

When the 3DS provider returns a specific reason for the failure, the transaction carries a 3DS_21xx code instead of the generic 3DS_2000, and the response message states the exact reason. Most of these map directly to the EMV 3DS transStatusReason values, e.g.:

CodeMeaning
3DS_2101Card authentication failed.
3DS_2105Expired card.
3DS_2106Invalid card number.
3DS_2108No card record.
3DS_2111Suspected fraud.
3DS_2112Transaction not permitted for cardholder.
3DS_2114Transaction timed out at the ACS.
3DS_2119Exceeds ACS maximum challenges.
3DS_2126Authentication attempted but not performed by the cardholder.
3DS_2187Transaction excluded from attempts processing (e.g. non-reloadable prepaid cards, non-payment authentications).
3DS_2189Card not enrolled in EMV 3DS, or issuer rejecting authentication.

All 3DS_21xx codes are declines originating from the card scheme, issuer, or the issuer's Access Control Server — not NetValve errors. The response message on the transaction always carries the precise reason text.

Webhooks

When a 3DS step fails and the record is declined, an AUTHORISATION_FAILED webhook is sent with the transaction ID, order ID, the 3DS_2xxx response code and the failure reason. Previously, a payment that died at 3DS produced no notification at all — now you can react to it (e.g. prompt the customer to retry) without polling.

Once a real Sale/Authorization is processed on the record, webhooks behave as for any normal payment.

FAQ

Was my customer charged? Not unless the record shows a completed Sale/Authorization with bank response codes. Records that are Pending, or Declined with a 3DS_2xxx code, never reached the bank.

Why did my approval rate drop after this release? It didn't — see Impact on approval rates and reporting. Declines that used to be invisible (customer failed or abandoned 3DS) are now recorded. Exclude 3DS_-coded transactions to reproduce your previous bank approval rate.

Why do Pending records accumulate? Every started 3DS journey creates one. Journeys the customer abandons stay Pending — this is expected and reflects real drop-off in your checkout. Use the portal filters to include or exclude pending records.

Do I need to change my integration? No. This is a visibility feature. Optionally, you can start using transactionID / orderId from the 3DS responses to correlate records, and consume the AUTHORISATION_FAILED webhook to detect failed authentications in real time.

Why does my sale show up under a transaction/order that existed before the sale? Because the sale reuses the record created at 3DS initialisation, so the whole journey — authentication and payment — lives under one transaction and one order instead of disconnected records.