Documentation Index Fetch the complete documentation index at: https://docs.peere.network/llms.txt
Use this file to discover all available pages before exploring further.
Device IDs are crucial for enabling seamless customer discovery and identity-based payments in Peere Network. This guide explains how device identification works and how to implement it effectively.
What is a Device ID?
Device Identification A Device ID is a unique identifier that links a customer’s device (phone, tablet, computer) to their Peere Network identity, enabling merchants to find and bill customers without requiring manual input.
How Device IDs Work
Device Registration
When customers visit your website or app, their device gets a unique identifier
Bank Linking
Banks link customer devices to their unique phrases for merchant discovery
Merchant Lookup
Merchants can find customers using device IDs when they’re present at checkout
Seamless Payment
Customers can be billed automatically without entering payment details
Device ID Generation
Client-Side Implementation
JavaScript/Web
React Native/Mobile
Flutter/Dart
// Generate or retrieve device ID
function getDeviceId () {
let deviceId = localStorage . getItem ( 'peere_device_id' );
if ( ! deviceId ) {
// Generate new device ID
deviceId = 'device_' + generateUniqueId ();
localStorage . setItem ( 'peere_device_id' , deviceId );
}
return deviceId ;
}
function generateUniqueId () {
return Date . now (). toString ( 36 ) + Math . random (). toString ( 36 ). substr ( 2 );
}
// Use device ID for customer lookup
async function lookupCustomer () {
const deviceId = getDeviceId ();
try {
const response = await fetch ( '/api/customer/device/lookup' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'Authorization' : `Bearer ${ API_KEY } `
},
body: JSON . stringify ({ deviceId })
});
const data = await response . json ();
if ( data . success ) {
// Customer found - can proceed with Peere payment
return {
found: true ,
customerName: data . data . customerName ,
phrase: data . data . phrase ,
bankName: data . data . bankName
};
}
} catch ( error ) {
console . error ( 'Customer lookup failed:' , error );
}
return { found: false };
}
import AsyncStorage from '@react-native-async-storage/async-storage' ;
import DeviceInfo from 'react-native-device-info' ;
class DeviceManager {
static async getDeviceId () {
try {
let deviceId = await AsyncStorage . getItem ( 'peere_device_id' );
if ( ! deviceId ) {
// Use device-specific identifier
const uniqueId = await DeviceInfo . getUniqueId ();
deviceId = `device_ ${ uniqueId } _ ${ Date . now () } ` ;
await AsyncStorage . setItem ( 'peere_device_id' , deviceId );
}
return deviceId ;
} catch ( error ) {
console . error ( 'Failed to get device ID:' , error );
return null ;
}
}
static async lookupCustomer () {
const deviceId = await this . getDeviceId ();
if ( ! deviceId ) return { found: false };
try {
const response = await fetch ( 'https://api.peere.network/v1/customer/device/lookup' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
'Authorization' : `Bearer ${ API_KEY } `
},
body: JSON . stringify ({ deviceId })
});
const data = await response . json ();
return data . success ? { found: true , ... data . data } : { found: false };
} catch ( error ) {
console . error ( 'Customer lookup failed:' , error );
return { found: false };
}
}
}
import 'package:shared_preferences/shared_preferences.dart' ;
import 'package:device_info_plus/device_info_plus.dart' ;
import 'package:http/http.dart' as http;
import 'dart:convert' ;
class DeviceManager {
static const String \_deviceIdKey = 'peere_device_id' ;
static Future < String ?> getDeviceId () async {
final prefs = await SharedPreferences . getInstance ();
String ? deviceId = prefs. getString (\_deviceIdKey);
if (deviceId == null ) {
final deviceInfo = DeviceInfoPlugin ();
String uniqueId;
if ( Platform .isAndroid) {
final androidInfo = await deviceInfo.androidInfo;
uniqueId = androidInfo.id;
} else if ( Platform .isIOS) {
final iosInfo = await deviceInfo.iosInfo;
uniqueId = iosInfo.identifierForVendor ?? '' ;
} else {
uniqueId = DateTime . now ().millisecondsSinceEpoch. toString ();
}
deviceId = 'device_ ${ uniqueId } _ ${ DateTime . now (). millisecondsSinceEpoch } ' ;
await prefs. setString (_deviceIdKey, deviceId);
}
return deviceId;
}
static Future < Map < String , dynamic >> lookupCustomer () async {
final deviceId = await getDeviceId ();
if (deviceId == null ) return { 'found' : false };
try {
final response = await http. post (
Uri . parse ( 'https://api.peere.network/v1/customer/device/lookup' ),
headers : {
'Content-Type' : 'application/json' ,
'Authorization' : 'Bearer $ API_KEY ' ,
},
body : jsonEncode ({ 'deviceId' : deviceId}),
);
final data = jsonDecode (response.body);
return data[ 'success' ] ? { 'found' : true , ...data[ 'data' ]} : { 'found' : false };
} catch (error) {
print ( 'Customer lookup failed: $ error ' );
return { 'found' : false };
}
}
}
Bank Device Linking
Banks must link customer devices to their phrases to enable merchant discovery:
Linking Process
Link Device
Bulk Device Linking
curl -X POST "https://api.peere.network/v1/bank/customer/device/link" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerId": "customer_123",
"phrase": "customer-unique-phrase",
"deviceId": "device_789"
}'
Device Management
List Devices
Unlink Device
curl -X GET "https://api.peere.network/v1/bank/devices/list?page=1&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY"
Response: {
"statusCode" : 200 ,
"success" : true ,
"data" : {
"devices" : [
{
"deviceId" : "device_789" ,
"customerId" : "customer_123" ,
"phrase" : "customer-phrase" ,
"linkedAt" : "2024-01-01T00:00:00Z"
}
],
"total" : 1 ,
"page" : 1 ,
"limit" : 20
}
}
curl -X POST "https://api.peere.network/v1/bank/customer/device/unlink" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"customerId": "customer_123",
"phrase": "customer-phrase",
"deviceId": "device_789"
}'
Merchant Device Lookup
Merchants can find customers using device IDs:
Customer Discovery Flow
Capture Device ID
Get the device ID when customer visits your website/app
Lookup Customer
Use the device lookup API to find the customer
Display Options
Show Peere payment option if customer is found
Process Payment
Use the returned phrase for billing operations
Implementation Example
Checkout Integration
Backend Implementation
class PeereCheckout {
constructor ( apiKey ) {
this . apiKey = apiKey ;
this . deviceId = this . getDeviceId ();
}
getDeviceId () {
let deviceId = localStorage . getItem ( "peere_device_id" );
if ( ! deviceId ) {
deviceId = "device_" + Date . now () + "_" + Math . random (). toString ( 36 );
localStorage . setItem ( "peere_device_id" , deviceId );
}
return deviceId ;
}
async checkPeereAvailability () {
try {
const response = await fetch ( "/api/customer/device/lookup" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ this . apiKey } ` ,
},
body: JSON . stringify ({ deviceId: this . deviceId }),
});
const data = await response . json ();
if ( data . success ) {
this . showPeereOption ( data . data );
return true ;
}
} catch ( error ) {
console . error ( "Peere availability check failed:" , error );
}
return false ;
}
showPeereOption ( customerData ) {
const checkoutContainer = document . getElementById ( "checkout-options" );
const peereOption = document . createElement ( "div" );
peereOption . className = "payment-option peere-option" ;
peereOption . innerHTML = `
<div class="peere-payment">
<img src="/peere-logo.png" alt="Peere" />
<div class="customer-info">
<p>Pay with Peere</p>
<small>Linked to ${ customerData . bankName } </small>
</div>
<button onclick="this.payWithPeere(' ${ customerData . phrase } ')">
Select
</button>
</div>
` ;
checkoutContainer . prepend ( peereOption );
}
async payWithPeere ( phrase ) {
// Implement Peere payment flow
const amount = this . getCartTotal ();
const description = this . getOrderDescription ();
try {
const response = await fetch ( "/api/customer/bill" , {
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"Authorization" : `Bearer ${ this . apiKey } ` ,
},
body: JSON . stringify ({
agreementPhrases: [ phrase ],
amount: amount ,
currency: "NGN" ,
description: description ,
}),
});
const result = await response . json ();
if ( result . success ) {
this . handlePaymentSuccess ( result );
} else {
this . handlePaymentError ( result );
}
} catch ( error ) {
this . handlePaymentError ( error );
}
}
}
// Initialize on page load
document . addEventListener ( "DOMContentLoaded" , () => {
const checkout = new PeereCheckout ( "your-api-key" );
checkout . checkPeereAvailability ();
});
Device ID Best Practices
Security Considerations
Privacy Protection
Don’t store personally identifiable information with device IDs - Use hashed or encrypted device identifiers when possible - Comply with privacy regulations (GDPR, CCPA)
Data Retention
Set appropriate retention periods for device data - Allow users to request device unlinking - Clean up orphaned device records regularly
Caching Strategy
Batch Processing
class DeviceCache {
constructor () {
this . cache = new Map ();
this . cacheTimeout = 5 * 60 * 1000 ; // 5 minutes
}
async lookupCustomer ( deviceId ) {
const cacheKey = `device_ ${ deviceId } ` ;
const cached = this . cache . get ( cacheKey );
if ( cached && Date . now () - cached . timestamp < this . cacheTimeout ) {
return cached . data ;
}
const result = await this . fetchCustomerData ( deviceId );
if ( result . found ) {
this . cache . set ( cacheKey , {
data: result ,
timestamp: Date . now ()
});
}
return result ;
}
async fetchCustomerData ( deviceId ) {
// Actual API call implementation
}
}
class BatchDeviceProcessor {
constructor () {
this . queue = [];
this . processing = false ;
this . batchSize = 10 ;
this . batchTimeout = 1000 ; // 1 second
}
async lookupDevice ( deviceId ) {
return new Promise (( resolve , reject ) => {
this . queue . push ({ deviceId , resolve , reject });
this . processBatch ();
});
}
async processBatch () {
if ( this . processing || this . queue . length === 0 ) return ;
this . processing = true ;
setTimeout ( async () => {
const batch = this . queue . splice ( 0 , this . batchSize );
try {
const deviceIds = batch . map ( item => item . deviceId );
const results = await this . batchLookup ( deviceIds );
batch . forEach (( item , index ) => {
item . resolve ( results [ index ]);
});
} catch ( error ) {
batch . forEach ( item => item . reject ( error ));
}
this . processing = false ;
if ( this . queue . length > 0 ) {
this . processBatch ();
}
}, this . batchTimeout );
}
}
Troubleshooting
Common Issues
Device ID Problems and Solutions
Symptoms: API returns 404 or customer not found Causes: Device not linked by bank, incorrect device ID format Solutions: Verify device linking, check device ID generation logic
Symptoms: Same customer has multiple device IDs Causes: Device ID regeneration, multiple browsers/apps Solutions: Implement device ID persistence, allow multiple device linking
Lookup Performance Issues
Symptoms: Slow device lookup responses Causes: No caching, too many API calls Solutions: Implement caching, batch requests, optimize API calls
Next Steps
Customer Discovery Learn advanced customer discovery techniques
Billing Integration Implement billing flows with discovered customers
Webhooks Set up real-time notifications
API Reference Explore device-related API endpoints