SCA
This page explains the SCA (Strong Customer Authentication), how to use its endpoints, and how it is implemented in the API.
📘 Introduction
Strong Customer Authentication (SCA), is a regulatory requirement under the second European Payment Services Directive (PSD2). It strengthens online payment security and protects users from fraud.
Applicability:
Since March 14, 2022, SCA applies to all online transactions in the European Economic Area (EEA) and the United Kingdom.
Purpose:
SCA was introduced to ensure secure payments, reduce fraud, and comply with DSP2 regulatory requirements (ACPR & RTS). It builds on the original PSD (2007) by reinforcing identity verification and secure operations for payment services.
flowchart TD
A([User's SCA Setup]):::entry --> B[📧 Email verification]:::check
B --> C[📱 Phone number verifications]:::check
C --> D[🔑 Secret code setup]:::highlight
D --> E[🔏 Secret code verifications]:::check
E --> F([✅ User's SCA Validated]):::entry
%% --- Styles ---
classDef entry fill:#d9f7be,stroke:#52c41a,stroke-width:2
classDef check fill:#e6f7ff,stroke:#1890ff,stroke-width:1
classDef highlight fill:#f9f0ff,stroke:#722ed1,stroke-width:2
📖 Why SCA is Required
Strong Customer Authentication (SCA) is a legal obligation under PSD2. Its purpose is threefold:
- Regulatory compliance - Ensures alignment with DSP2, ACPR supervision, and Regulatory Technical Standards (RTS).
- Security - Protects users against fraud by reinforcing identity checks.
- User trust - Provides a safer experience while maintaining usability.
⏰ When SCA is Required
SCA is not applied uniformly. It is required in specific contexts:
1. First Login and Periodic Re-authentication
- At the first login, users must authenticate with two independent factors.
- Afterwards, re-authentication is required every 180 days.
During the 180-day period, users may still access:
- Their account balance
- The last 3 months of transaction history
using only their regular password. This exception is designed to preserve usability while remaining compliant.
2. Sensitive Remote Operations
SCA is systematically required when performing operations that could cause financial loss or involve sensitive data changes.
Examples:
- Adding a new beneficiary
- Updating personal information
Each such action must be explicitly authorized by the user through the full SCA process.
3. Payment Operations
Every payment operation requires SCA, regardless of context.
Example:
- Executing an external SEPA transfer (from the user’s payment account to another bank account).
In practice at MPS, this means no transfer or outgoing payment can be initiated without a completed SCA workflow.
flowchart TD
subgraph LOG ["<b><font size='3'>User account connexion</font></b>"]
A([Login + password input]):::entry
B[Setup SCA]:::alert
C{"Date verification of the user's last Two Factor Authentication"}:::action
E[2FA]:::step
end
subgraph USE ["<b><font size='3'>User Connected</font></b>"]
F[Using MPS, can only access non-sensitive data]:::action
G{New operation}:::action
H[2FA]:::step
I([Authorized Pay out / Sensitive data management]):::entry
end
%% --- Liaisons principales ---
A -->|First time| B
A -->|SCA already setup| C
C -->|< 180 days| F
C -->|> 180 days| E
B --> E
%% D --> F
E --> F
F --> G
G -->|Non-sensitive| F
G -->|Sensitive| H
H --> I
%% --- Styles de base ---
classDef hidden fill:none,stroke:none
classDef entry fill:#d9f7be,stroke:#52c41a,stroke-width:2
classDef action fill:#e6f7ff,stroke:#1890ff,stroke-width:1
classDef check fill:#e6f0ff,stroke:#1e40af,stroke-width:2
classDef step fill:#f9f0ff,stroke:#722ed1,stroke-width:2
classDef final fill:#ffe7ba,stroke:#fa8c16,stroke-width:3
classDef alert fill:#ffe6e6,stroke:#d9363e,stroke-width:3
%% --- Flèches colorées pour distinction Yes/No ---
linkStyle 0,3,4,8 stroke:#f5222d,stroke-width:2
linkStyle 2,5,9 stroke:#52c41a,stroke-width:2
linkStyle 1,6,7 stroke:#1890ff,stroke-width:2
🧩 SCA Factors
SCA is based on the principle of combining two out of three independent factor categories. If one factor is compromised, it must not affect the reliability of the others.
| Category | Description | Examples |
|---|---|---|
| Knowledge | Something the user knows | Password, PIN, secret code |
| Possession | Something the user owns | Smartphone, hardware token, email access |
| Inherence | Something the user is | Fingerprint, facial or voice recognition |
Factors Used at MPS
At MPS, three factors are implemented in practice:
- Email — used as a possession/knowledge check.
- Phone number — used as a possession check through SMS validation.
- Secret code — used as a knowledge factor, set up and confirmed by the user.
A user is considered fully authenticated (workflow_completed = true) only once all three factors are validated. This ensures compliance with PSD2 and the highest level of security.
🛠️Key Concepts
Platform (platformUUID)
platformUUID)A Universally Unique IDentifier for each platform.
User (userUUID)
userUUID)A Universally Unique IDentifier for each user across API requests (project owners, investors, managers).
Strong Customer Authentication (SCA)
Sequential multi-factor authentication mechanism: 📧email → 📱phone → 🔑secret code.
Workflow
A sequential set of validations, accessible via GET strong_auth/status.
JWT (JSON Web Token)
A Short-lived token proving SCA is done. Must be reused while valid.
Session vs Operation
- Per session → access valid for a given time.
- Per operation → SCA required for each sensitive operation.
📑Summary of SCA Endpoints
1. 🔵SCA Workflow Check
GET /platforms/{platformUUID}/users/{userUUID}/strong_auth/status
Checks the current state of a user's SCA workflow.
2. 🔵OTP Generation
POST /strong_auth/otp/generate/{process}
Generates an OTP for email, phone, secret code, or auth verification.
3. 🔵OTP Verification
POST /strong_auth/otp/verify/{process}
Verifies the OTP for the corresponding process. To do after the generation of the OTP.
4. 🔵Secret Code Setup
POST /strong_auth/secret_code/setup
Initializes a new secret code for the user. To do after you verified the email and phone number of the user, and before the OTP generations/validations for the secret code.
5. 🔵Secret Code Verify
POST /strong_auth/secret_code/verify
Verifies the secret code and returns a JWT token for authenticated operations. You can only do it when the whole workflow is complete, after setting up the secret code and verified it by email and sms.
The JWT will allow you to generate an OTP for the "auth_by_***" processes. Those processes will allow you to perform actions that need to be secured.
6. 🔵State Reset
POST /strong_auth/reset/{source}
Resets the validation state of a factor (email, phone, or secret code). After a reset, the user must redo the verification only for that factor.
🧭Typical Workflow
After creating a user, the Strong Authentication workflow runs as follows:
1. 📧 Email verification
POST OTP generate /email_by_email→POST OTP verify /email_by_email- For a new user, only
by_emailOTP is required. - If the email source is reset later but phone number is already validated, validation will require both
by_emailandby_sms.
2.📱Phone number verification
-
Always requires the two verifications:
a. Verification by email
b. Verification by SMS
-
Each step uses:
POST OTP generate→POST OTP verify
3.🔑Secret code setup
-
User sets a code with
POST Secret Code Setup. -
Verification then requires the two methods:
a. Verification by email
b. Verification by SMS
-
Once fully validated → Retrieve the JWT token with
POST Secret Code Verify.
At workflow initiation, all fields in
GET statusarefalseorpending. Each successful step updates the workflow status accordingly.
flowchart TD
%% --- Subgraphs: clear separation user / platform ---
subgraph UA ["👤 <b><font size='4'>User Actions</font></b>"]
U1[📧 Enters email address]:::input
U2[📬 Enters code received by email]:::code
U3[📱 Enters phone number]:::input
U4[📬 Enters code received by email]:::code
U5[📲 Enters code received by SMS]:::code
U6[🔐 Chooses secret code<br/>and enters it twice]:::input
U7[📬 Enters code received by email]:::code
U8[📲 Enters code received by SMS]:::code
end
subgraph PA ["⚙️ <b><font size='4'>API Calls</font></b>"]
P1["POST /otp/generate/email_by_email"]:::generate
P2["POST /otp/verify/email_by_email"]:::verify
P3["POST /otp/generate/phone_number_by_email"]:::generate
P4["POST /otp/verify/phone_number_by_email"]:::verify
P5["POST /otp/generate/phone_number_by_sms"]:::generate
P6["POST /otp/verify/phone_number_by_sms"]:::verify
P7["POST /secret_code/setup"]:::SCsetup
P8["POST /otp/generate/secret_code_by_email"]:::generate
P9["POST /otp/verify/secret_code_by_email"]:::verify
P10["POST /otp/generate/secret_code_by_sms"]:::generate
P11["POST /otp/verify/secret_code_by_sms"]:::verify
end
%% --- Final node after full setup ---
F1((workflow_completed = true<br/>✅ SCA setup done)):::final
%% --- Interaction sequence ---
U1 --> P1
P1 --> U2
U2 --> P2
P2 --> U3
U3 --> P3
P3 --> U4
U4 --> P4
P4 -.-> P5
P5 --> U5
U5 --> P6
P6 --> U6
U6 --> P7
P7 -.-> P8
P8 --> U7
U7 --> P9
P9 -.-> P10
P10 --> U8
U8 --> P11
P11 -.-> F1
%% --- Note about OTP validity ---
Note1[/"ℹ️ Each OTP is valid for 5 minutes."/]
Note1 -.-> PA
%% --- Styles ---
classDef input fill:#fff0f6,stroke:#c41d7f,stroke-width:2
classDef code fill:#f9f0ff,stroke:#722ed1,stroke-width:2
classDef generate fill:#e6f7ff,stroke:#1890ff,stroke-width:2
classDef SCsetup fill:#d6e4ff,stroke:#1d39c4,stroke-width:2
classDef verify fill:#e6fffb,stroke:#08979c,stroke-width:2
classDef final fill:#e6ffe6,stroke:#2d7a2d,stroke-width:2
♻️ Resetting a Source
Use the endpoint : POST strong_auth/reset/{source}
Then you must redo the verification for the specific source (email, phone_number, or secret_code).
Other validated factors remain intact.
Example: Resetting
phone_number→ Only the phone number verification from the workflow above needs to be done.Don't forget that you will need the
by_emailandby_smsOTPs if you reset the email source but that you keep your phone_number validated.
📝API Call Example
Request:
GET https://sandbox.mipisepaymentservices.com/api/platforms/{platformUUID}/users/{userUUID}/strong_auth/status
Authorization: Bearer {access_token}
Content-Type: application/jsonResponse (200 OK):
{
"workflow_completed": true,
"email": {
"state": "validated",
"verified_at": "2025-08-06 14:42:43 +0200"
},
"phone_number": {
"state": "validated",
"verified_at": "2025-08-06 14:42:43 +0200"
},
"secret_code": {
"state": "validated",
"verified_at": "2025-08-06 14:42:43 +0200"
}
}Field Descriptions
| Field | Type | Description | Possible Values |
|---|---|---|---|
| workflow_completed | boolean | Whether the SCA workflow is fully validated | true / false |
| email.state | string | Email validation status | pending_email_validation, pending_sms_validation, validated |
| email.verified_at | date-time | Timestamp of email validation | ISO 8601 or null |
| phone_number.state | string | Phone validation status | pending_email_validation, pending_sms_validation, validated |
| phone_number.verified_at | date-time | Timestamp of phone validation | ISO 8601 or null |
| secret_code.state | string | Secret code configuration/validation status | pending_configuration, pending_email_validation, pending_sms_validation, validated |
| secret_code.verified_at | date-time | Timestamp of secret code validation | ISO 8601 or null |
🚨 Error Codes
The following error codes are common to all endpoints.
For more informations, please visit the Error handling page.
| Code | Meaning | Possible Causes |
|---|---|---|
| 400 | Bad Request | Missing or badly formatted parameters |
| 401 | Unauthorized | Invalid or expired JWT token |
| 404 | Resource Not Found | platformUUID or userUUID does not exist |
| 422 | Unprocessable Entity | Inconsistent data or invalid state for the operation |
📌 Key Takeaways
- SCA is a regulatory requirement under PSD2, supervised by ACPR and RTS.
- It protects sensitive operations and all payments through multi-factor checks.
- At MPS, the workflow relies on email, phone, and secret code, all required for full validation.
- Use the
GET Strong Auth Statusendpoint to confirm readiness before initiating any regulated action.
Updated about 10 hours ago