Verify Transactions for PSD2
Twilio Verify already allows you to quickly verify phone number ownership with one-time passwords (OTP) over SMS. In a few steps, you can extend these capabilities to help comply with PSD2 by verifying transactions using dynamic linking and Strong Customer Authentication (SCA).
Next, create a new Service with PSD2 mode enabled, as shown in the code sample below.
Once enabled, requests to start and/or complete verifications require the Payee
and Amount
parameters.
_19// Download the helper library from https://www.twilio.com/docs/node/install
_19const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";
_19// Find your Account SID and Auth Token at twilio.com/console
_19// and set the environment variables. See http://twil.io/secure
_19const accountSid = process.env.TWILIO_ACCOUNT_SID;
_19const authToken = process.env.TWILIO_AUTH_TOKEN;
_19const client = twilio(accountSid, authToken);
_19async function createService() {
_19 const service = await client.verify.v2.services.create({
_19 friendlyName: "My PSD2 Service",
_19 console.log(service.psd2Enabled);
_43 "sid": "VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_43 "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_43 "friendly_name": "My PSD2 Service",
_43 "lookup_enabled": false,
_43 "psd2_enabled": true,
_43 "skip_sms_to_landlines": false,
_43 "dtmf_input_required": false,
_43 "mailer_sid": "MDaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_43 "do_not_share_warning_enabled": false,
_43 "custom_code_enabled": true,
_43 "include_date": false,
_43 "apn_credential_sid": "CRaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_43 "fcm_credential_sid": null
_43 "issuer": "test-issuer",
_43 "msg_service_sid": "MGaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_43 "from": "whatsapp:+1234567890"
_43 "default_template_sid": "HJaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_43 "verify_event_subscription_enabled": false,
_43 "date_created": "2015-07-30T20:00:00Z",
_43 "date_updated": "2015-07-30T20:00:00Z",
_43 "url": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_43 "verification_checks": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/VerificationCheck",
_43 "verifications": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Verifications",
_43 "rate_limits": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/RateLimits",
_43 "messaging_configurations": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/MessagingConfigurations",
_43 "entities": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Entities",
_43 "webhooks": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Webhooks",
_43 "access_tokens": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/AccessTokens"
To start a transaction verification, send an HTTP POST
request to your PSD2-enabled Service's Verifications resource. This request must contain the Amount
, Payee
, To
, and Channel
parameters.
This HTTP request causes Twilio to send a verification code to the user. Each verification code is dynamically-linked to the Amount
and Payee
of each transaction. The code is unique to the To
(e.g., the recipient's phone number), Amount
, and Payee
combination. This ensures that verification fails in the event of code interception or transaction mutations.
Each verification code is valid for 10 minutes. Within that ten-minute time frame, any subsequent HTTP POST
requests to the Verifications resource for the transaction cause Twilio send the same verification code.
_23// Download the helper library from https://www.twilio.com/docs/node/install
_23const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";
_23// Find your Account SID and Auth Token at twilio.com/console
_23// and set the environment variables. See http://twil.io/secure
_23const accountSid = process.env.TWILIO_ACCOUNT_SID;
_23const authToken = process.env.TWILIO_AUTH_TOKEN;
_23const client = twilio(accountSid, authToken);
_23async function createVerification() {
_23 const verification = await client.verify.v2
_23 .services("VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
_23 .verifications.create({
_23 console.log(verification.sid);
_23 "sid": "VEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_23 "service_sid": "VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_23 "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_23 "to": "+15017122661",
_23 "date_created": "2015-07-30T20:00:00Z",
_23 "date_updated": "2015-07-30T20:00:00Z",
_23 "payee": "Acme Inc.",
_23 "send_code_attempts": [
_23 "time": "2015-07-30T20:00:00Z",
_23 "attempt_sid": "VLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
_23 "url": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Verifications/VEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
To check if a verification code is correct, send an HTTP POST
request to your PSD2-enabled Service's Verification Check resource. This request must contain the Code
, To
(e.g., the user's phone number), Amount
, and Payee
parameters. A sample request is shown in the example below.
_23// Download the helper library from https://www.twilio.com/docs/node/install
_23const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";
_23// Find your Account SID and Auth Token at twilio.com/console
_23// and set the environment variables. See http://twil.io/secure
_23const accountSid = process.env.TWILIO_ACCOUNT_SID;
_23const authToken = process.env.TWILIO_AUTH_TOKEN;
_23const client = twilio(accountSid, authToken);
_23async function createVerificationCheck() {
_23 const verificationCheck = await client.verify.v2
_23 .services("VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
_23 .verificationChecks.create({
_23 console.log(verificationCheck.status);
_23createVerificationCheck();
_14 "sid": "VEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_14 "service_sid": "VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_14 "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_14 "to": "+15017122661",
_14 "status": "approved",
_14 "payee": "Acme Inc.",
_14 "sna_attempts_error_codes": [],
_14 "date_created": "2015-07-30T20:00:00Z",
_14 "date_updated": "2015-07-30T20:00:00Z"
In some instances, the details of a transaction may change before it can be completed. When that occurs, you can cancel an in-progress transaction verification by updating the Status
of the Verification resource. An example of this request is shown below.
This prevents a user from verifying an out-of-date transaction.
That transactions that have been successfully verified cannot be canceled.
_19// Download the helper library from https://www.twilio.com/docs/node/install
_19const twilio = require("twilio"); // Or, for ESM: import twilio from "twilio";
_19// Find your Account SID and Auth Token at twilio.com/console
_19// and set the environment variables. See http://twil.io/secure
_19const accountSid = process.env.TWILIO_ACCOUNT_SID;
_19const authToken = process.env.TWILIO_AUTH_TOKEN;
_19const client = twilio(accountSid, authToken);
_19async function updateVerification() {
_19 const verification = await client.verify.v2
_19 .services("VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
_19 .verifications("VEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
_19 .update({ status: "canceled" });
_19 console.log(verification.sid);
_23 "sid": "VEXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
_23 "service_sid": "VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_23 "account_sid": "ACaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
_23 "to": "+15017122661",
_23 "status": "canceled",
_23 "date_created": "2015-07-30T20:00:00Z",
_23 "date_updated": "2015-07-30T20:00:00Z",
_23 "send_code_attempts": [
_23 "time": "2015-07-30T20:00:00Z",
_23 "attempt_sid": "VLaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
_23 "url": "https://verify.twilio.com/v2/Services/VAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Verifications/VEaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"