Skip to content

Commit

Permalink
Add Number Verification sample code
Browse files Browse the repository at this point in the history
  • Loading branch information
diegotid committed Sep 5, 2024
1 parent c15a78a commit 16b57b6
Show file tree
Hide file tree
Showing 2 changed files with 283 additions and 12 deletions.
271 changes: 271 additions & 0 deletions catalog/numberverification/samplecode_numberverification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
---
title: Sample code for Number Verification
excerpt: The following samples show how to use the [Open Gateway Number Verification API](https://opengateway.telefonica.com/en/apis/number-verification), for fraud prevention purposes, in order to check if a given phone number matches the one on the SIM card installed in the end-user's device.
category: 66aa4f941e51e7000fa353ce
---

Although the API consumption flow for this API must be always triggered from such end-user's device - therefore from the application's frontend - according to its intrinsic feature, the flow will always complete on the backend. The following code shows, for didactic purposes, a hypothetical or sample SDK used on the backend, in several programming languages, from a generic Open Gateway's channel partner, also known as aggregator.

The final implementation will depend on the channel partner's development tools offering. Some of them might even provide you with both backend SDKs and frontend SDKs, the latter handling details such as network interface switching for proper mobile line identification. Apart from this extra frontend features (available upon channel partner discretion), note that channel partners' Open Gateway SDKs are just code modules wrapping authentication and API calls providing an interface in your app's programming for convenience.

Sample code on how to consume the API without an SDK, directly with HTTP requests, is also provided, and it is common and valid no matter what your partner is, thanks to the CAMARA standardization. If you do not use an SDK you need to code the HTTP calls and additional stuff like encoding your credentials, calling authorization endpoints, handling tokens, etc. You can check our sample [Postman collection](https://bxbucket.blob.core.windows.net/bxbucket/opengateway-web/uploads/OpenGateway.postman_collection.json) as a reference.

### Table of contents
- [Frontend](#frontend)
- [Requesting the authorization code from the frontend](#requesting-the-authorization-code-from-the-frontend)
- [Backend](#backend)
- [Getting the access token from the callback endpoint at the backend](#getting-the-access-token-from-the-callback-endpoint-at-the-backend)
- [Using the service API](#using-the-service-api)

## Code samples

### Frontend

This API consumption flow must always start on the end-user's device, since its feature is precisely verifying that a given phone number is the one effectively used in such device, which can be verified by the operator by receiving the online request from it:
* Application's frontend performs an HTTP request to get a `code`, and provides a `redirect_uri` it wants such `code` to be redirected to.
* Application's frontend will receive an HTTP redirect (status 302) and needs to be able to handle it. If it is a web application running on a web browser, the browser will natively follow the redirection. If it is not, in depends on the coding language and/or HTTP module or library used, or on its settings, how the flow will follow all the way to your application's backend through the mobile network operator authentication server.
* Application's backend receives the `code` from this HTTP redirection, by publishing an endpoint in the given `redirect_uri`, and then exchanges it for an access token. The latter is achieved as shown in the [Backend](#backend) flow.

The authentication protocol used in Open Gateway for frontend flows is the OIDC standard Authorization Code Flow. You can check the CAMARA documentation on this flow [here](https://github.com/camaraproject/IdentityAndConsentManagement/blob/release-0.1.0/documentation/CAMARA-API-access-and-user-consent.md#authorization-code-flow-frontend-flow).

#### Requesting the authorization code from the frontend

The following samples show how your application can trigger the authentication flow from the frontend either from code or by submitting a simple HTML form. The same can be achieved from code in any other programming language with the ability to perform HTTP requests:
```javascript HTTP using JavaScript (ES6)
let userPhoneNumber = "+34555555555";

let clientId = "my-app-id";
let clientSecret = "my-app-secret";
let apiPurpose = "dpv:FraudPreventionAndDetection#number-verification-verify-read";
let myCallbackEndpoint = "https://my_app_server/numberverification-callback";

const params = {
client_id: clientId,
response_type: "code",
purpose: apiPurpose,
redirect_uri: myCallbackEndpoint,
state: userPhoneNumber // Using `state` as the parameter that is always forwarded to the redirect_uri
};

// Create the query string
const queryString = new URLSearchParams(params).toString();

// URL with query string
const url = `https://opengateway.aggregator.com/authorize?${queryString}`;

const requestOptions = {
method: "GET",
redirect: "follow"
};

fetch(url, requestOptions);
```
```html HTML form
<!--
In this example you need your callback URL to continue the flow calling the service API
and providing an HTML response to be shown in the web browser displaying the result.
The following form is published from the same web server hosting the callback URL.
-->

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>API Request Form</title>
</head>
<body>
<h1>Number verification</h1>
<form id="apiRequestForm" action="https://opengateway.aggregator.com/authorize" method="GET">
<input type="hidden" name="client_id" value="my-app-id">
<input type="hidden" name="response_type" value="code">
<input type="hidden" name="purpose" value="dpv:FraudPreventionAndDetection#number-verification-verify-read">
<input type="hidden" name="redirect_uri" value="/numberverification-callback">

<label for="state">Your phone number:</label>
<input type="text" id="state" name="state" value="+34555555555" required>

<button type="submit">Verify</button>
</form>
</body>
</html>
```

### Backend

As the opposite to the flow triggering, this API consumption flow will always complete on the application's backend, since the authorization code is to be received via HTTP redirect on your redirect_uri, aka callback URL, which must be published on a web server.

#### Getting the access token from the callback endpoint at the backend

Samples represent how to publish the callback URL in Python or Node.js, so the code from the Auth Code Flow can be received. The same can be achieved in any other language with capabilities to run an HTTP server and listen for the redirect from the authentication flow:

```python Sample SDK for Python
from flask import Flask, request, jsonify
from aggregator_opengateway_sdk import ClientCredentials, NumberVerification

credentials = ClientCredentials(
clientid='my-app-id',
clientsecret='my-app-secret'
)

app = Flask(__name__)

@app.route('/numberverification-callback', methods=['GET'])
def callback():
code = request.args.get('code', '')
phone_number = request.args.get('state', '')
api_client = NumberVerification(credentials, code)

if __name__ == '__main__':
app.run()
```
```node Sample SDK for Node.js
import { ClientCredentials, NumberVerification } from "aggregator/opengateway-sdk"
import express from "express"

const credentials: ClientCredentials(
clientId: 'my-app-id',
clientSecret: 'my-app-secret'
)

const app = express()
const port = 3000

app.get('/numberverification-callback', (req, res) => {
const code = req.query.code
const phoneNumber = req.query.state
const apiClient = new NumberVerification(credentials, code)
})

app.listen(port, () => {
console.log(`Number verification callback URL is running`);
})
```
```python HTTP using Python
from flask import Flask, request, jsonify

client_id = "my-app-id"
client_secret = "my-app-secret"
app_credentials = f"{client_id}:{client_secret}"
credentials = base64.b64encode(app_credentials.encode('utf-8')).decode('utf-8')
api_purpose = "dpv:FraudPreventionAndDetection#number-verification-verify-read"

app = Flask(__name__)

@app.route('/numberverification-callback', methods=['GET'])
def callback():
code = request.args.get('code', '')
phone_number = request.args.get('state', '')
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": f"Basic {credentials}"
}
data = {
"grant_type": "authorization_code",
"code": code
}
response = requests.post(
"https://opengateway.aggregator.com/token",
headers=headers,
data=data
)
access_token = response.json().get("access_token")

if __name__ == '__main__':
app.run()
```
```node HTTP using Node.js
import express from "express"

let clientId = "my-app-id"
let clientSecret = "my-app-secret"
let appCredentials = btoa(`${clientId}:${clientSecret}`)
let apiPurpose = "dpv:FraudPreventionAndDetection#number-verification-verify-read"

const app = express()
const port = 3000

app.get('/numberverification-callback', (req, res) => {
const code = req.query.code
const phoneNumber = req.query.state

let accessToken

const myHeaders = new Headers()
myHeaders.append("Content-Type", "application/x-www-form-urlencode")
myHeaders.append("Authorization", `Basic ${appCredentials}`)
const requestBody = JSON.stringify({
"grant_type": "authorization_code",
"code": code
})
const requestOptions = {
method: "POST",
headers: myHeaders,
body: requestBody
}
fetch("https://opengateway.aggregator.com/token", requestOptions)
.then(response => response.json())
.then(result => {
accessToken = result.access_token
})
})

app.listen(port, () => {
console.log(`Number verification callback URL is running`);
})

```

#### Using the service API

Once your app is authenticated it only takes a single line of code to use the service API and effectively get a result.

```python Sample SDK for Python
result = await api_client.verify(phone_number)

print(f"Phone number {'verified' if result else 'does not match mobile line'}")
```
```node Sample SDK for Node.js
let result = await apiClient.verify(phoneNumber)

console.log(`Phone number ${result ? "verified" : "does not match mobile line"}`)
```
```python HTTP using Python
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {access_token}"
}
data = {
"phoneNumber": phone_number
}
response = requests.post(
"https://opengateway.aggregator.com/number-verification/v0/verify",
headers=headers,
json=data
)
result = response.json().get("devicePhoneNumberVerified")

print(f"Phone number {'verified' if result else 'does not match mobile line'}")
```
```node HTTP using Node.js
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", `Bearer ${accessToken}`);

const requestBody = JSON.stringify({
"phoneNumber": phoneNumber
})
const requestOptions = {
method: "POST",
headers: myHeaders,
body: requestBody
}

fetch("https://opengateway.aggregator.com/number-verification/v0/verify", requestOptions)
.then(response => response.json())
.then(result => {
const verified = result.devicePhoneNumberVerified

console.log(`Phone number ${verified ? "verified" : "does not match mobile line"}`)
})
```
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
title: Sample code
title: Sample code for SIM Swap
excerpt: The following samples show how to use the [Open Gateway SIM Swap API](https://opengateway.telefonica.com/en/apis/sim-swap), for fraud prevention purposes, in order to check if a given mobile line, identified by its phone number, has gotten a SIM card swap lately.
category: 66aa4f941e51e7000fa353ce
---

The following code shows, for didactic purposes, a hypothetical SDK, in several programming languages, from a generic Open Gateway's channel partner, also known as aggregator. The final implementation will depend on the channel partner's development tools offering. Note that channel partners' Open Gateway SDKs are just code modules wrapping authentication and API calls providing an interface in your app's programming for convenience.
The following code shows, for didactic purposes, a hypothetical or sample SDK, in several programming languages, from a generic Open Gateway's channel partner, also known as aggregator. The final implementation will depend on the channel partner's development tools offering. Note that channel partners' Open Gateway SDKs are just code modules wrapping authentication and API calls providing an interface in your app's programming for convenience.

Sample code on how to consume the API without an SDK, directly with HTTP requests, is also provided, and it is common and valid no matter what your partner is, thanks to the CAMARA standardization. If you do not use an SDK you need to code the HTTP calls and additional stuff like encoding your credentials, calling authorization endpoints, handling tokens, etc. You can check our sample [Postman collection](https://bxbucket.blob.core.windows.net/bxbucket/opengateway-web/uploads/OpenGateway.postman_collection.json) as a reference.

Expand All @@ -30,7 +30,7 @@ First step is to instantiate the SIM Swap service class included in the correspo

Since Open Gateway authentication is 3-legged, meaning it identifies the application, the operator and the operator's subscriber, who is also the end-user holder of the mobile line, each check for a different phone number needs its own SDK class instantiation, or access token if not using an SDK.

```node Generic SDK for Node.js
```node Sample SDK for Node.js
import { ClientCredentials, SIMSwap } from "aggregator/opengateway-sdk"

const credentials: ClientCredentials(
Expand All @@ -42,7 +42,7 @@ const CUSTOMER_PHONE_NUMBER = '+34555555555'

const simswapClient = new SIMSwap(credentials, null, CUSTOMER_PHONE_NUMBER)
```
```java Generic SDK for Java
```java Sample SDK for Java
import aggregator.opengatewaysdk.ClientCredentials;
import aggregator.opengatewaysdk.SIMSwap;

Expand All @@ -55,7 +55,7 @@ final String customerPhoneNumber = "+34555555555";

SIMSwap simswapClient = new SIMSwap(credentials, null, customerPhoneNumber);
```
```python Generic SDK for Python
```python Sample SDK for Python
from aggregator_opengateway_sdk import ClientCredentials, SIMSwap

credentials = ClientCredentials(
Expand Down Expand Up @@ -248,19 +248,19 @@ access_token = response.json().get("access_token")

Once your app is authenticated it only takes a single line of code to use the service API and effectively get a result.

```node Generic SDK for Node.js
```node Sample SDK for Node.js
let result = await simswapClient.retrieveDate()

console.log(`SIM was swapped: ${result.toLocaleString('en-GB', { timeZone: 'UTC' })}`)
```
```java Generic SDK for Java
```java Sample SDK for Java
CompletableFuture<Boolean> resultFuture = simswapClient.retrieveDate();

resultFuture.thenAccept(result -> {
System.out.println("SIM was swapped: " + DateTimeFormatter.ISO_LOCAL_DATE.format(result));
})
```
```python Generic SDK for Python
```python Sample SDK for Python
result = await simswap_client.retrieve_date()

print(f"SIM was swapped: {result.strftime('%B %d, %Y, %I:%M:%S %p')}")
Expand Down Expand Up @@ -410,7 +410,7 @@ fetch(url, requestOptions);

Samples represent how to publish the callback URL in Python or Node.js, so the code from the Auth Code Flow can be received. The same can be achieved in any other language with capabilities to run an HTTP server and listen for the redirect from the authentication flow:

```python Generic SDK for Python
```python Sample SDK for Python
from flask import Flask, request, jsonify
from aggregator_opengateway_sdk import ClientCredentials, SIMSwap

Expand All @@ -430,7 +430,7 @@ def callback():
if __name__ == '__main__':
app.run()
```
```node Generic SDK for Node.js
```node Sample SDK for Node.js
import { ClientCredentials, SIMSwap } from "aggregator/opengateway-sdk"
import express from "express"

Expand All @@ -457,12 +457,12 @@ app.listen(port, () => {

Once your app is authenticated it only takes a single line of code to use the service API and effectively get a result.

```python Generic SDK for Python
```python Sample SDK for Python
result = await simswap_client.retrieve_date(phone_number)

print(f"SIM was swapped: {result.strftime('%B %d, %Y, %I:%M:%S %p')}")
```
```node Generic SDK for Node.js
```node Sample SDK for Node.js
let result = await simswapClient.retrieveDate(phoneNumber)

console.log(`SIM was swapped: ${result.toLocaleString('en-GB', { timeZone: 'UTC' })}`)
Expand Down

0 comments on commit 16b57b6

Please sign in to comment.