React Native SDK for Meon E-Sign integration
npm install react-native-meon-esign

A React Native SDK for seamless integration of Meon E-Sign services in your mobile applications. Enable Aadhaar-based digital signatures with just a few lines of code.
- 🔐 Secure Authentication - Built-in credential management
- ✍️ Digital Signature - Aadhaar-based e-Sign integration
- 📄 PDF Signing - Support for multi-page documents
- 🎯 Multiple Signatures - Define multiple signature coordinates
- 📱 WebView Integration - Smooth in-app signing experience
- ✅ Auto PDF Fetch - Automatic signed document retrieval
- 🎨 Customizable UI - Flexible styling options
- ⚡ Easy Integration - Minimal configuration required
``bash`
npm install react-native-meon-esign react-native-webview
or with Yarn:
`bash`
yarn add react-native-meon-esign
For iOS, install pods:
`bash`
cd ios && pod install && cd ..
`javascript
import React from 'react';
import { View } from 'react-native';
import MeonEsign from 'react-native-meon-esign';
const App = () => {
return (
username="USERNAME"
password="PASSWORD"
// User Details
name="Mukul Pratap Singh"
email="user@example.com"
mobile="9999999999"
// Document
documentName="agreement.pdf"
documentData="JVBERi0xLjQKJeL..." // Base64 PDF
// Signature Positions
coordinates={[
{
page_number: "1",
x_coordinate: "130",
y_coordinate: "100",
height: "50",
width: "103"
}
]}
// Callbacks
onSuccess={(data) => {
console.log('Signed PDF:', data.pdfUrl);
}}
onError={(error) => {
console.error('Error:', error);
}}
onClose={() => {
console.log('User closed');
}}
/>
);
};
export default App;
`
`javascript
import React, { useState } from 'react';
import { View, TouchableOpacity, Text } from 'react-native';
import MeonEsign from 'react-native-meon-esign';
const EsignScreen = () => {
const [showEsign, setShowEsign] = useState(false);
if (showEsign) {
return (
username="USERNAME"
password="PASSWORD"
// User Information
name="Mukul Pratap Singh"
email="nitin.kumar@meon.co.in"
mobile="9998889997"
// Document Details
documentName="test.pdf"
documentData="base64_encoded_pdf_here"
// Signature Coordinates (where to place signatures)
coordinates={[
{
page_number: "1",
x_coordinate: "130",
y_coordinate: "100",
height: "50",
width: "103"
},
{
page_number: "2",
x_coordinate: "130",
y_coordinate: "100",
height: "50",
width: "103"
}
]}
// Optional Configuration
reason="Account Opening"
daysToExpire="1"
esignType="EKYC"
needNameMatch={true}
percentageNameMatch={80}
needAadhaarMatch={true}
aadhaarNumber="3744" // Last 4 digits
needGenderMatch={true}
gender="M" // M or F
// Callbacks
onSuccess={(data) => {
console.log('✅ E-Sign Success!');
console.log('Signed PDF URL:', data.pdfUrl);
console.log('Token:', data.token);
// Handle validation errors if any
if (data.nameMismatchError) {
console.warn('Name Mismatch:', data.nameMismatchError);
}
setShowEsign(false);
// Download or save the signed PDF using data.pdfUrl
}}
onError={(error) => {
console.error('❌ E-Sign Error:', error);
alert(E-Sign failed: ${error});
setShowEsign(false);
}}
onClose={() => {
console.log('User closed e-sign');
setShowEsign(false);
}}
// UI Customization
showHeader={true}
headerTitle="Complete E-Signature"
customStyles={{
container: { backgroundColor: '#f5f5f5' },
header: { backgroundColor: '#0047AB' },
headerTitle: { color: '#fff' }
}}
/>
);
}
return (
backgroundColor: '#0047AB',
padding: 15,
borderRadius: 8,
}}
onPress={() => setShowEsign(true)}
>
Start E-Sign
);
};
export default EsignScreen;
`
#### Required Props
| Prop | Type | Description |
|------|------|-------------|
| username | string | Meon authentication username |password
| | string | Meon authentication password |name
| | string | Signer's full name |email
| | string | Signer's email address |mobile
| | string | Signer's mobile number |documentName
| | string | Name of the document (e.g., "contract.pdf") |documentData
| | string | Base64 encoded PDF document |coordinates
| | array | Array of signature coordinate objects |
#### Coordinate Object Structure
`javascript`
{
page_number: "1", // Page number (string)
x_coordinate: "130", // X position from left (string)
y_coordinate: "100", // Y position from top (string)
height: "50", // Signature box height (string)
width: "103" // Signature box width (string)
}
#### Optional Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| reason | string | "Account Opening" | Reason for signing |daysToExpire
| | string | "1" | Days until link expires |webhook
| | string | - | Webhook URL for notifications |redirectUrl
| | string | - | Redirect URL after completion |esignType
| | string | "EKYC" | Type of e-sign |removePreviewPdf
| | boolean | false | Remove PDF preview |needNameMatch
| | boolean | true | Verify name with Aadhaar |debit
| | boolean | false | Debit flag |percentageNameMatch
| | number | 80 | Name match threshold percentage |needAadhaarMatch
| | boolean | true | Verify Aadhaar number |aadhaarNumber
| | string | "3744" | Last 4 digits of Aadhaar |needGenderMatch
| | boolean | true | Verify gender |gender
| | string | "M" | Gender ("M" or "F") |showHeader
| | boolean | true | Show header with controls |headerTitle
| | string | "E-Sign Process" | Header title text |baseURL
| | string | UAT URL | Base API URL |customStyles
| | object | {} | Custom style object |
#### onSuccess
Called when e-sign process completes successfully.
Parameters:
`javascript`
{
success: true,
pdfUrl: "https://...", // Signed PDF download URL
token: "uuid", // Transaction token
nameMismatchError: null, // Name mismatch details (if any)
aadhaarMismatchError: null, // Aadhaar mismatch details (if any)
genderMismatchError: null // Gender mismatch details (if any)
}
#### onError
Called when an error occurs during the e-sign process.
Parameters:
- error (string): Error message
#### onClose
Called when user closes the e-sign interface.
`javascript`
customStyles={{
container: {
backgroundColor: '#f0f0f0'
},
header: {
backgroundColor: '#0047AB',
elevation: 4,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
},
headerTitle: {
color: '#ffffff',
fontSize: 20,
fontWeight: '600'
}
}}
1. Authentication: SDK authenticates with provided credentials
2. Document Preparation: Uploads PDF and signature coordinates
3. WebView Display: Opens Meon e-sign interface in WebView
4. User Signs: User completes Aadhaar-based verification and signing
5. Auto Fetch: SDK automatically fetches signed PDF
6. Callback: Returns signed PDF URL via onSuccess callback
`bash`
npm install react-native-fs
`javascript
import RNFS from 'react-native-fs';
const convertPdfToBase64 = async (pdfPath) => {
try {
const base64 = await RNFS.readFile(pdfPath, 'base64');
return base64;
} catch (error) {
console.error('Error reading PDF:', error);
return null;
}
};
`
`bash`
npm install react-native-document-picker
`javascript
import DocumentPicker from 'react-native-document-picker';
import RNFS from 'react-native-fs';
const pickAndConvertPDF = async () => {
try {
const result = await DocumentPicker.pick({
type: [DocumentPicker.types.pdf],
});
const base64 = await RNFS.readFile(result[0].uri, 'base64');
return base64;
} catch (error) {
if (DocumentPicker.isCancel(error)) {
console.log('User cancelled');
} else {
console.error('Error:', error);
}
return null;
}
};
`
Coordinates define where signature boxes appear on the PDF:
`javascript`
coordinates={[
{
page_number: "1", // First page
x_coordinate: "100", // 100px from left
y_coordinate: "700", // 700px from top
height: "60", // 60px tall
width: "150" // 150px wide
},
{
page_number: "3", // Third page
x_coordinate: "400", // 400px from left
y_coordinate: "200", // 200px from top
height: "60",
width: "150"
}
]}
Tips:
- Coordinates are in pixels
- Origin (0,0) is top-left corner
- Test coordinates with preview before production
- Keep signature boxes large enough (min 50x100px)
1. Never hardcode credentials in production apps
2. Store credentials securely using:
- react-native-keychain
- react-native-encrypted-storage
- Secure backend API
3. Use HTTPS for all API communications
4. Validate user input before passing to SDK
5. Handle errors gracefully to avoid exposing sensitive data
Example:
`javascript
import * as Keychain from 'react-native-keychain';
// Store credentials
await Keychain.setGenericPassword('username', 'password');
// Retrieve credentials
const credentials = await Keychain.getGenericPassword();
`
UAT (Testing):
``
https://esignuat.meon.co.in/EsignServices
Production:
``
https://esign.meon.co.in/EsignServices
Change baseURL prop based on environment:`javascript
const isProduction = true;
const baseURL = isProduction
? 'https://esign.meon.co.in/EsignServices'
: 'https://esignuat.meon.co.in/EsignServices';
`
Solution: Ensure react-native-webview is properly installed and linked.
`bash`
npm install react-native-webview
cd ios && pod install
Solution: Verify credentials are correct and account is active.
Solution: Ensure PDF is properly base64 encoded without data URI prefix.
`javascript
// ❌ Wrong
documentData="data:application/pdf;base64,JVBERi0..."
// ✅ Correct
documentData="JVBERi0..."
``
Solution: Check coordinate values are within PDF page dimensions.
| Platform | Supported | Minimum Version |
|----------|-----------|-----------------|
| Android | ✅ Yes | Android 5.0+ |
| iOS | ✅ Yes | iOS 11.0+ |
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
For issues, questions, or feature requests:
- 🐛 GitHub Issues
- 📧 Email: support@meon.co.in
- 📖 Documentation
- Meon Technologies for E-Sign API
- React Native Community
- All contributors
---
Made with ❤️ for seamless digital signatures in React Native
Happy Signing! ✍️