Skip to main content

API Integration

API integration guide for ZÈYA Mobile App.

API Configuration

Base URLs

The app uses environment-based API endpoints:

Production:

https://zeyaapp.com/api/v1/

Staging:

https://staging.zeyaapp.com/api/v1/

Environment Variables

Configured in eas.json and .env:

EXPO_PUBLIC_API_URL=zeyaapp.com/api/v1
EXPO_PUBLIC_FILE_URL=zeyaapp.com
EXPO_PUBLIC_HTTP_PROTOCOL=https
EXPO_PUBLIC_APP_ENV=production
EXPO_PUBLIC_LOCAL_API_URL=staging.zeyaapp.com/api/v1
EXPO_PUBLIC_LOCAL_FILE_URL=staging.zeyaapp.com
EXPO_PUBLIC_LOCAL_HTTP_PROTOCOL=https

API Provider

ApiProvider Context

The app uses a centralized API provider (src/context/ApiProvider.js):

import { ApiContext } from '../context/ApiProvider';

function MyComponent() {
const { apiCall, authToken, user } = useContext(ApiContext);
// Use API context
}

Features

  • Automatic token management
  • Request/response interceptors
  • Error handling
  • Unauthorized endpoint handling
  • Token refresh

Making API Calls

Basic API Call

import { useContext } from 'react';
import { ApiContext } from '../context/ApiProvider';

function MyComponent() {
const { apiCall } = useContext(ApiContext);

const fetchData = async () => {
try {
const response = await apiCall('products', {
method: 'GET',
});
console.log(response.data);
} catch (error) {
console.error('Error:', error);
}
};
}

POST Request

const createProduct = async (productData) => {
try {
const response = await apiCall('add-product', {
method: 'POST',
data: productData,
});
return response.data;
} catch (error) {
throw error;
}
};

PUT/PATCH Request

const updateProduct = async (productId, updates) => {
try {
const response = await apiCall(`update-product/${productId}`, {
method: 'POST',
data: updates,
});
return response.data;
} catch (error) {
throw error;
}
};

DELETE Request

const deleteProduct = async (productId) => {
try {
const response = await apiCall(`product/${productId}`, {
method: 'DELETE',
});
return response.data;
} catch (error) {
throw error;
}
};

Authentication

Login

const login = async (email, password) => {
try {
const response = await apiCall('login', {
method: 'POST',
data: { email, password },
});
// Token is automatically stored by ApiProvider
return response.data;
} catch (error) {
throw error;
}
};

Register

const register = async (userData) => {
try {
const response = await apiCall('register', {
method: 'POST',
data: userData,
});
return response.data;
} catch (error) {
throw error;
}
};

Logout

const logout = async () => {
try {
await apiCall('logout', {
method: 'GET',
});
// Token is automatically cleared by ApiProvider
} catch (error) {
throw error;
}
};

Unauthorized Endpoints

The following endpoints don't require authentication:

  • login
  • register
  • password-reset-otp-sent
  • validate-otp
  • submit-reset-password
  • alternate-login
  • alternate-login-apple
  • guest-products
  • preview-groups
  • preview-groups-data
  • get-dashboard-data
  • save-guest-device

Error Handling

API Error Structure

{
success: false,
error: "Error message",
code: "ERROR_CODE",
errors: { ... } // For validation errors
}

Handling Errors

try {
const response = await apiCall('endpoint');
} catch (error) {
if (error.response) {
// Server responded with error
const { error: errorMessage, code, errors } = error.response.data;

if (code === 'VALIDATION_ERROR') {
// Handle validation errors
console.log('Validation errors:', errors);
} else {
// Handle other errors
Alert.alert('Error', errorMessage);
}
} else if (error.request) {
// Request made but no response
Alert.alert('Network Error', 'Please check your internet connection');
} else {
// Something else happened
Alert.alert('Error', 'An unexpected error occurred');
}
}

Response Format

Success Response

{
"success": true,
"data": { ... },
"message": "Operation successful"
}

Paginated Response

{
"success": true,
"data": [ ... ],
"pagination": {
"current_page": 1,
"total_pages": 5,
"total_items": 100,
"per_page": 20,
"has_next": true,
"has_prev": false
}
}

Common API Endpoints

Products

// Get products
apiCall('products', { method: 'GET' });

// Create product
apiCall('add-product', {
method: 'POST',
data: productData,
});

// Update product
apiCall(`update-product/${id}`, {
method: 'POST',
data: updates,
});

// Delete product
apiCall(`product/${id}`, { method: 'DELETE' });

User Profile

// Get user profile
apiCall('user-profile', { method: 'GET' });

// Update profile
apiCall('user-update', {
method: 'POST',
data: profileData,
});

Chat

// Get chats
apiCall('user-chat', { method: 'GET' });

// Get messages
apiCall(`user-chat/${transactionId}/message`, {
method: 'GET',
});

// Send message
apiCall(`user-chat/${transactionId}/message`, {
method: 'POST',
data: { text: 'Hello' },
});

Groups

// Get groups
apiCall('groups', { method: 'GET' });

// Create group
apiCall('groups', {
method: 'POST',
data: groupData,
});

// Join group
apiCall('group-join', {
method: 'POST',
data: { group_uid: '...' },
});

File Uploads

Upload Product Images

import * as ImagePicker from 'expo-image-picker';

const uploadProductImages = async (productId, images) => {
const formData = new FormData();

images.forEach((image, index) => {
formData.append(`images[${index}]`, {
uri: image.uri,
type: 'image/jpeg',
name: `image_${index}.jpg`,
});
});

try {
const response = await apiCall(`update-product/${productId}`, {
method: 'POST',
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
},
});
return response.data;
} catch (error) {
throw error;
}
};

API Utilities

Storage Utilities

import Storage from '../share/storage';

// Save token
await Storage().saveToken('auth_token', token);

// Get token
const token = await Storage().getToken('auth_token');

// Remove token
await Storage().removeToken('auth_token');

Constants

import Constants from '../share/constant';

// Use API constants
const AUTH_KEY = Constants().AUTH__TENANT_KEY;

Testing API Integration

Mock API Responses

// For development/testing
const mockResponse = {
success: true,
data: { ... },
};

// Use in tests or development

Network Debugging

  • Use Flipper for network inspection
  • Check Expo CLI logs
  • Use React Native Debugger