the current "Gold Standard" for secure and convenient payments
in the physical world.
This document describes FIDO® Web Pay (FWP), which is a Web-adapted version of EMV,
combining the technology underpinning FIDO2
with the W3C
PaymentRequest API and
a browser-resident (built-in) payment application.
Through an extension to EMV, FWP can be used with virtually to any account-based payment system,
including the eurozone's
the primary technical enhancement to EMV, is that the FWP client
encrypts user-authorizations, enabling the following subgoals:
Obviate the need for tokenization services.
Limit the amount of personally identifiable information (PII) shared
with third parties, to the name of the user's bank and payment method.
This is presumably compliant with
requirements as well as with GDPR.
Separate account numbers from issuer (bank branch) identifiers.
The latter should preferably be expressed as service URLs,
externally managed databases holding issuer payment processor end-points.
Note that FWP is not a payment system, it is a payment authorization scheme,
exclusively dealing with the user's part of the payment process.
That is, the backend infrastructure and associated APIs are out of scope for this specification.
However, to guide implementers, this document outlines
a sample infrastructure at a "conceptual" level.
Note though that regardless of the backend design, FWP assertions
must (due to the EMV end-to-end security model),
always be routed back to the designated issuer "verbatim"
(together with other required data) in order to initiate a payment transaction.
It is assumed that at this stage in time,
backend infrastructures will be independently defined by each payment network
rather than becoming a unified standard. See also Integration.
Throughout the rest of this document, actor names are
written as Name.
The Browser actor is in this specification
considered to be equivalent to "User Agent".
A PSP (Payment System Provider) is in this specification
denoting any service or network acting as a trusted intermediary between
a Merchant and an Issuer.
In FWP objects, Merchant is referred to as "payee".
The steps outlined in Detailed Operation
depend on that the User already have received
one or more FWP credentials
("Virtual Cards") in an Enrollment process.
FWP credentials are stored in a local database in the client device, where each entry is
supposed to contain the following attributes:
Issuer specific (shared) public encryption key.
Unless an encryptionKeyId has been specified, the encryptionKey
MUST be inserted in FWP encryption objects.
Optional. If specified, FWP encryption objects
MUST contain this identifier.
COSE compliant content encryption algorithm for
COSE compliant key encryption algorithm for
Account identifier associated with the credential.
Text string that (with respect to the Issuer),
uniquely identifies the payment credential.
URL holding the FWP method for a particular payment network.
Bank Identification Number (BIN) or URL associated with
The exact definition is specific for each paymentMethod.
See also Service Discovery.
SVG image identifying the payment credential for
The content of such images are entirely Issuer specific,
but images MUST adhere to certain (TDB), dimensions in order
to render properly by the wallet.
Note: how attributes are represented in the credential database is implementation specific,
whereas FWP assertions are normative.
The exact enrollment process is yet to be defined; the assumption is that it
could be accomplished by extending the existing W3C
Web Authentication enrollment system.
The extension would enable the Browser
to securely distinguish between "ordinary" FIDO keys,
and those targeted for payments which is required for maintaining
a database in the Browser holding FWP credentials.
It would be great if the enrollment system could handle
multiple credentials in a single operation, because an Issuer may want to
support international card networks as well as national or regional payment networks
It MAY be technically feasible using a FIDO key associated with an FWP credential
for Web Authentication as well, but this would be a deployment decision
by the Issuer.
FWP effectively forms a browser "Wallet",
holding an arbitrary number of payment credentials, each representing a
This section describes the different steps needed to authorize a payment operation using FWP.
To improve readability, JSON data is "pretty-printed",
while CBOR data is provided in "diagnostic notation".
The foundation for the description is the following sequence diagram sample
where each step is linked to a clickable number in a box:
Note that the normative part of this specification only covers the
steps within the dotted rectangle. That is, how FWP implements
At this point the User is assumed to have clicked on
a "Buy" button (after first having selected an FWP compliant payment method),
causing a Merchant Web page to invoke
a custom doPaymentRequest() method, like in the following sample:
When the PaymentRequest.show() method is invoked, the Browser
(FWP implementation) MUST perform the following checks:
There is an accompanying data attribute holding a
The data object contains a payeeName
The data object contains a networks
The networks array holds a non-empty list of
That each object in the networks array contains a name
That none of the objects in the networks array contain other
attributes, with the exception of an optionalnetworkData
is limited to integers in the range of -2^53 to +2^53.
There is only onePaymentItem and it has a
label attribute with the argument null.
There is a non-emptyid argument included in the
details parameter to the PaymentRequest constructor.
Any deviations MUST throw an exception.
Note that the name properties in the networks
array denote the actual payment methods, corresponding to the paymentMethod
attribute in FWP credentials.
Note that the PaymentRequest.canMakePayment() method MUST return true
if the User have one or more FWP credentials,
regardless if they match the associated PaymentRequest list or not;
else it MUST return false.
Show Payment Authorization UI
After successful invocation of the PaymentRequest.show()
method, the Browser responds with
a payment authorization UI like the following:
Non-normative UI in "dark mode".
If the User has no matching payment credentials,
the Browser MUST indicate that and give the User
an option to return to the Merchant "Checkout" page.
If the User has multiple matching payment credentials,
the Browser MUST provide a way to select a specific credential.
In the sample UI shown above, the User
can swipe credentials to the left and right, while arrow symbols are used to show if there
are more credentials available. That is, if there is no left arrow, the credential selector is
at the left end point.
If a selected credential is associated with an external token which is currently not
available, the User should be asked to insert it.
Perform User Authorization
At this point the Userauthorizes the request with a fingerprint, PIN, or similar.
A successful user authorization causes the next step to be performed.
Create FWP Assertion
At this point the Browser
creates an FWP assertion which requires the following steps to be performed:
4.1 Extract PaymentRequest Core Data (PRCD)
Create a CBOR representation of the core payment request data supplied
by the Merchant. For the sample code this should
result in the following object:
Payment method associated with the selected FWP credential.
Included for "completeness".
Optional. This attribute MUST be included if
specified in the PaymentRequest constructor
for the particular paymentMethod, otherwise it MUST NOT be defined.
Note that possible networkData data is specified by the calling
be converted to CBOR when included in this object. Due to a
Number is converted to unsigned or
negativeinteger depending on the value.
String is converted to
Object is converted to map.
Array is converted to array.
null, true, and false
are converted to their respective CBOR counterpart.
Up-to-date information about the core software components.
Included for security and logging purposes.
The outer CBOR map contains two entries, 1 for the operating system,
and 2 for the "user-agent" (browser),
while the sub-maps hold name (3) and version (4) respectively.
Note that hardware (device) data is assumed to be established during credential
time stamp generated by the FWP implementation.
If the local time zone is known, it SHOULD be included,
else the UTC notation ("Z") MUST be used.
Since the authorization signature is intended to also cover the the FIDO
publicKey and signatureAlgorithm
associated with the selected FWP credential,
these elements MUST also be included in the data to be signed.
This object is subsequently referred to as Authorization Data (AD).
AD is (after SHA256-digesting), used as the sole FIDO "challenge" source.
4.3 Create Signed Authorization Data (SAD)
Now apply the FIDO signature key (identified by credentialId),
associated with the selected FWP credential to sign AD using the
scheme described in
FIDO Web Pay - Crypto.
For the sample code this should result in the following object:
Encrypted Signed Authorization Data (ESAD) supplied in a Base64Url string
(in subsequent examples shown as a placeholder only).
The FWP Assertion is made available
to the PaymentRequest invocation code via the
Return FWP Assertion
At this point the checkout Web code would normally
return the completed FWP Assertion to the
Merchant server through a FORM POST
or fetch() operation.
Process FWP Assertion and Create PSPRequest Object
After receiving the FWP Assertion,
the Merchant would usually call a
PSP with a specifically crafted object.
The exact definition is likely to be specific for each PSP network
and is therefore out of scope for this specification.
The following sample outlines such an object:
Request IP address (in V4 or V6 format) of the User device.
Included for security and logging purposes.
ISO time stamp generated by the Merchant.
Send PSPRequest Object
At this point the Merchant sends the completed PSPRequest
object to the appropriate PSP.
Note that authentication of the Merchant is out of scope
for this specification.
Process PSPRequest and Create IssuerRequest Object
After successfully having authenticated the Merchant request,
the PSP MUST perform a number of checks on the
received object including:
That paymentRequest is properly formatted and that
the payeeName attribute
matches the Merchant common name registered with the PSP.
That the fwpAssertion.paymentMethod is supported.
That the format of the fwpAssertion.issuerId matches
That the receiveAccount matches a Merchant account
registered with the PSP.
That the timeStamp is within "reasonable limits".
That the rest of the expected parameters are available as well that there are no unknown attributes.
Any deviations MUST cause the request to be rejected.
Fault handling is out of scope for this specification.
The next step is creating a suitable IssuerRequest object.
The exact definition is likely to be specific for each payment network and
is therefore out of scope for this specification.
The following sample outlines such an object:
Copy of the PSPRequest object
received from the Merchant.
The Merchant host name registered by the PSP.
ISO time stamp generated by the PSP.
Send IssuerRequest Object
At this point the PSP sends the completed IssuerRequest
object to the designated Issuer.
Note that the method used for locating the proper Issuer depends on
the paymentMethod and issuerId attributes.
In the sample the IssuerRequest object
would presumably be sent to https://mybank.fr/payment.
Before initiating a payment transaction the Issuer
MUST decode and perform a number of steps to verify the
correctness of the received IssuerRequest object.
Any deviation MUST terminate the operation in progress and return an
error message to the PSP in a not here specified manner.
10.1 Core Validation.
Verify that IssuerRequest schema-wise is properly formatted.
Verify that the timeStamp is within "reasonable limits".
Verify that the pspRequest.fwpAssertion.paymentMethod is supported.
Verify that the pspRequest.receiveAccount
is compatible with the pspRequest.fwpAssertion.paymentMethod.
Verify that the pspRequest.fwpAssertion.issuerId
is compatible with the pspRequest.fwpAssertion.paymentMethod
as well as matching the Issuer.
Verify that pspRequest.paymentRequest
represents a valid PRCD object.
10.2 Extract Signed Authorization Data (SAD)
Decode the Base64Url string supplied in pspRequest.fwpAssertion.encryptedAuthorization.
Parse the result of the previous operation as CBOR and set result as ESAD.
Verify that the resulting object is compatible with the CEF profile specified by FWP.
Verify that the public key or key Id declared in the CEF object matches an
existing decryption (private) key of the Issuer.
Decrypt the ESAD object using the private key retrieved in the previous operation.
Parse the result of the previous operation as CBOR and set result as SAD.
Verify that the SAD object schema-wise has the proper format.
10.3 Validate Request Data
Verify that SAD.version is supported.
Verify that pspRequest.paymentRequest is equivalent to SAD.paymentRequest.
That is, verifying that the Merchant payment claim corresponds to what the
User have actually seen and authorized.
Verify that pspRequest.payeeHost is equivalent to SAD.payeeHost.
That is, verifying that the User was not subject to phishing.
Note that phishing attacks against FWP are not useful for stealing money,
but for redirecting purchased goods to another address.
Verify that the SAD.timeStamp is within "reasonable limits".
Tentative: CurrentTime - 600s < SAD.timeStamp < CurrentTime + 60s.
Verify that the optionalSAD.networkData attribute complies
with the Issuer specific requirements.
10.4 Validate Authorization Signature
Verify the signature of the recovered SAD object.
Since the public key is included in the signature container, signature validation
does not require database lookups.
Verify that the aforementioned public key is linked to a User
account matching the SAD.accountId and SAD.serialNumber attributes
(where the latter would typically serve as the primary key in a credential database table).
Note that this check requires that the public key is in a canonical form.
Fortunately, this is a "built-in" feature if public keys are stored in the COSE format.
Using SHA256 hashes of public keys is a common method for limiting the
the need storing and comparing large keys (like required by the RSA algorithm).
10.5 Replay Handling
To cope with possible replays, verify that the received User authorization
has not already been used. This can be accomplished by maintaining a lookup cache
holding SHA256 hashes of ESAD objects associated
with successfully processed requests.
Cached items would be removed based on their SAD.timeStamp value.
SHOULD support idempotent operation to facilitate transaction retries
that may happen due to network glitches or similar.
Other Validation Steps
Obviously there are other things to verify but these are not directly related to FWP,
like checking that the User has funds available matching the
It is pretty clear that the integration of systems like FWP in payment networks
is crucial for acceptance by the market.
For card based payments FWP implementations can build on the existing
EMV foundation since essentially only the formats differ.
Although the lack of a PAN (card number) in FWP may appear as a major obstacle,
the issuerId would in this case hold a "neutered" PAN where
the BIN (Bank Identification Number) is set, while the rest are set to zeroes + Luhn check digit.
E.g. VISA: 4972039000000004. However, using Issuer URLs
is also a viable alternative for card payments because payment processors
associated with "regular" EMV and FWP payments would probably not
share end points.
For account-to-account payments there are currently no generally agreed upon standards
for consumer payments, but remapping existing card based systems and infrastructures
seems though like a possible path.
Note that FWP makes the use of delegated authorization transparent
for both the User and the Merchant.
Delegated authorization differs from
by keeping the authorization process and associated User
account information, inside of the core payment network.
This enables validation of potentially untrustedMerchant
data as well as eliminating dependencies on certified Merchant
3D Secure SDKs.
Delegated authorization builds on the assumption that the PSP is trusted
for carrying out payment initiations on behalf of a User
(based on a preceding User authorization step),
which is an established concept in most payment networks.
(In the FWP standard mode the PSP only acts as a proxy
for the Merchant).
The delegated authorization mode is illustrated by the following sequence diagram:
Note that step 1-7 are identical to the FWP "standard" mode.
"Payment Rails" refer to existing payment systems.
In an Open Banking context the PSP would be equivalent to a PISP while
the Authorizer would be a specialized AS.
Process PSPRequest and Create AuthorizeRequest Object
This step should involve the same verifications as in step 8
in the standard mode.
A suitable AuthorizeRequest object would typically follow the
IssuerRequest sample in step 8.
Send AuthorizeRequest Object
At this point the PSP sends the completed AuthorizeRequest
object to the designated Authorizer.
Note that the method used for locating the proper Authorizer depends on
the paymentMethod and issuerId attributes.
This step should involve the same verifications as in step 10
in the standard mode.
Return Authorized Data
If the preceding step is successful, AuthorizeRequest
would typically return the (now decrypted) User account number.
In an Open Banking implementation based on OAuth2 concepts,
the return data would contain access tokens and consent information.
Create Payment Instruction
After receiving the User account number a
payment instruction object is created.
The format and contents of such objects are payment network specific and
are therefore not described here.
Invoke "Payment Rails"
Perform a payment instruction request in a payment network specific way.
Process Payment Instruction
Process the payment instruction
request in a payment network specific way.
The FWP client is loosely derived from a proof-of-concept system called
By continuing along this path, features like the following could potentially be added:
Support for non-direct payments,
including secure (tokenized) versions of Card-on-File.
Support for real-time account balances.
Support for Userrefunding.
Support for universal digital receipts.
Support for private messaging and additional authentication information between the
Issuer and User.
Note that some of the features above could impact the PaymentRequest API.
An alternative to building FWP support into browsers, is moving the FWP implementation
(including the credential database), down into the client platform layer.
This would open FWP to other scenarios like:
Point-of-sale (PoS) payments.
This would (at least initially) depend on QR-code for invocation.
Person-to-person (P2P) payments.
Such an arrangement would also introduce additional features including:
Making it easier for alternative browser vendors adopting the FWP system
since they would not have to build a copy of FWP themselves;
a thin wrapper should suffice.
Relieving users from having to enroll payment credentials
for each browser they want to use.
Limiting the number of systems to certify in the case certification
becomes a requirement.
Usage of CBOR
That the internals of FWP assertions are based on CBOR rather than JSON may
seem odd since CBOR currently is not particularly common on the Web.
However, there is a pretty strong rationale for using CBOR for this
The deterministic mode of RFC8949
offers the following advantages:
Simplified cryptographic operations, not needing specific canonicalization support or
awkward Base64Url encoding of data to be signed.
Elements always appear at the same position, making documentation
matching actual data.
FWP assertions are (due to the end-to-and security model), only processable by
the Issuer and possible delegated parties.
FIDO attestations require CBOR support.
The FWP core was heavily influenced by an earlier Microsoft research project
called Windows CardSpace.