# Dynamic Linking

You can leverage the Keyless authentication mechanism to sign unrelated transactions, including Strong customer authentication (SCA) transactions.

Payment service providers compliant with [SCA PSD2 dynamic linking](https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=uriserv%3AOJ.L_.2018.069.01.0023.01.ENG\&toc=OJ%3AL%3A2018%3A069%3ATOC) are required to:

* Generate an **authentication code** specific to the amount of the payment transaction and the payee agreed to by the payer when initiating the transaction
* Make the payer **aware** of the amount of the payment transaction, and of the payee

Keyless helps you by:

* protecting the **authentication code** that you use for dynamic linking.
* displaying and signing the information to make the payer **aware** of details of the transaction.

{% hint style="warning" %}
Keyless is not a payment service provider.\
Keyless won't issue an authentication code tied to the transaction information.
{% endhint %}

{% @mermaid/diagram content="sequenceDiagram
participant Customer backend
participant Customer app
participant Keyless SDK
participant Keyless API
Customer app->>Keyless SDK:Keyless.Authenticate(transaction details)
Keyless SDK->>Keyless SDK:User reviews transaction details <br />and Approves transaction
note over Keyless SDK,Keyless API:Keyless Authentication happens<br />Keyless signs transaction details
Keyless SDK->>Customer app:KeylessResult that includes <br />a signed JWT with transaction details
Customer app->>Customer backend:Customer app can send <br/>signed JWT to backend
Customer backend->>Customer backend:Customer backend can validate the signature" fullWidth="true" %}

## Strong customer authentication (SCA)

By adding Keyless to your checkout flow you also benefit from [Keyless Passwordless Multi Factor Authentication (MFA)](https://keyless.io/solutions/passwordless-mfa).

SCA requires authentication to use at least two of the following three elements.

* Something that only the customer knows. For example, a password or PIN.
* Something that only the customer has. For example, a mobile phone or hardware token.
* Something that the customer is. For example, a biometric such as a fingerprint or face.

With Keyless Passwordless MFA you can satisfy the last two points from the list above.

## SCA Compliant Dynamic Linking

The following sections contain some examples on implementing SCA with Keyless.

### Display transaction information

Keyless displays a screen containing a list of labels and associated information on your behalf.\
For this reason, the format of the `dynamicLinkingInfo` must be a jsonArray containing jsonObjects (key/value pairs). We expect a valid JSON as follows:

```
[
    {key1 : value1},
    {key2 : value2},
    ...
    {keyN: valueN}
]
```

This information is added to the Authentication request that the user needs to approve.

### SCA tied to the authentication code

Once the user approves the transaction data, Keyless starts the authentication to:

1. Authenticate the payer with the device factor and the biometric factor using Keyless MFA.
2. Tie the transaction data to the Keyless MFA

To tie the transaction data to the Keyless MFA, populate the parameter `dynamicLinkingInfo` of the authentication configuration `AuthConfig`. Add the authentication code or any other information you want to display to the user and sign with Keyless MFA. For example, add the "authentication code".

{% hint style="info" %}
The `transactionData` contained in `dynamicLinkingInfo` must respect the format to [display transaction information](#display-transaction-information).
{% endhint %}

Keyless can produce a signed JWT containing a claim titled `td` (transaction data) that contains the payload you passed as `dynamicLinnkingInfo`.

{% hint style="warning" %}
Keyless is not storing history of records about the transaction amount, the payee, the payer and the authentication code.
{% endhint %}

{% tabs %}
{% tab title="Android" %}

```kotlin
//Keyless adds a td claim to the JWTs containing the data you specify
val dynamicLinkingInfo = DynamicLinkingInfo(transactionData = "<your transaction data to display and sign>")

// authenticate with biometric
val biomAuthConfig = BiomAuthConfig(dynamicLinkingInfo = dynamicLinkingInfo)

// perform the authentication
Keyless.authenticate(
    configuration = biomAuthConfig,
    onCompletion = { /*TODO: process result*/ }
)
```

{% endtab %}

{% tab title="iOS" %}

```swift
//Keyless adds a td claim to the JWTs containing the data you specify
let dynamicLinkingInfo = DynamicLinkingInfo(transactionData = "<your transaction data to display and sign>")

// authenticate with biometric
let biomAuthConfig = BiomAuthConfig(dynamicLinkingInfo: dynamicLinkingInfo)

// perform the authentication
Keyless.authenticate(
    configuration: biomAuthConfig,
    onCompletion: { /*TODO: process result*/ }
)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';
import 'package:keyless_flutter_sdk/models/dynamic_linking_info.dart';

final dynamicLinkingInfo = DynamicLinkingInfo(transactionData: "<your transaction data to display and sign>");

// authenticate with biometric
final biomAuthConfig = BiomAuthConfig(dynamicLinkingInfo: dynamicLinkingInfo);

try {
    // perform the authentication
    final result = await Keyless.instance.authenticate(biomAuthConfig);
    // process the signed JWT from result.signedJwt
    print("Authentication successful. Signed JWT: ${result.signedJwt}");
} catch (error) {
    print("Authentication failed: $error");
}
```

{% endtab %}
{% endtabs %}

### Verify the transaction

If the authentication is successful, the `AuthenticationSuccess` contains the following fields:

* `signedJwt`: the signed JWT (specs below).

```json
// JWT header
{
  "alg": "ES256",
  "typ": "JWT",
  "kid": "PIN/FACE"
}
// JWT payload
{
  "iat": 1720519812,
  "td": "your transaction data to display and sign",
  "version": "1.1.0",
  "sub": "keyless_id",
  "external_user_id": "external user id only if present"
}
```

{% hint style="info" %}
The `external_user_id` claim is included only if the user requesting the JWT has an [external user id](https://github.com/KeylessTech/docs.keyless.io/blob/master/spaces/sdk-docs/server-api/external-users/README.md) associated
{% endhint %}

Verify the JWT using the public key from [Keyless backend](https://docs.keyless.io/consumer/server-api/operations#jwt).

Congrats, you just performed a Strong Customer Authentication displaying and signing the transaction information.
