List Stores
Endpoint
POST https://merchant.dv.vai247.pro/api/v1/payment-gateway/stores/list
Authentication
This endpoint uses standard authentication and requires only the X-Api-Key header.
Required Header:
X-Api-Key: Your API key
See Authentication for more details.
Description
The List Stores endpoint retrieves all stores associated with your merchant account. The storeId returned by this endpoint is required for:
- Creating payment orders - The
storeIdmust be provided when calling the Create Order endpoint - Generating KHQR codes - The
storeIdis required when calling the Generate QR endpoint
This endpoint should typically be called before initiating any payment operations to ensure you have the correct store identifiers.
Request Parameters
This endpoint does not require any request body parameters. Authentication is handled via the X-Api-Key header.
Code Examples
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
type Store struct {
StoreID int64 `json:"storeId"`
StoreName string `json:"storeName"`
Address string `json:"address"`
}
type StoresResponse struct {
StatusCode int `json:"statusCode"`
Message string `json:"message"`
Data []Store `json:"data"`
TraceID string `json:"traceId"`
}
func listStores(apiKey string) (*StoresResponse, error) {
url := "https://merchant.dv.vai247.pro/api/v1/payment-gateway/stores/list"
req, err := http.NewRequest("POST", url, nil)
if err != nil {
return nil, err
}
// Add authentication header
req.Header.Set("X-Api-Key", apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var result StoresResponse
if err := json.Unmarshal(body, &result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
stores, err := listStores("your-api-key")
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Found %d store(s):\n", len(stores.Data))
for _, store := range stores.Data {
fmt.Printf("\nStore ID: %d\n", store.StoreID)
fmt.Printf("Name: %s\n", store.StoreName)
fmt.Printf("Address: %s\n", store.Address)
}
}
const axios = require('axios');
async function listStores(apiKey) {
const url = 'https://merchant.dv.vai247.pro/api/v1/payment-gateway/stores/list';
const headers = {
'X-Api-Key': apiKey,
'Content-Type': 'application/json'
};
try {
const response = await axios.post(url, {}, { headers });
return response.data;
} catch (error) {
console.error('Error fetching stores:', error.response?.data || error.message);
throw error;
}
}
// Usage
(async () => {
try {
const stores = await listStores('your-api-key');
console.log(`Found ${stores.data.length} store(s):`);
stores.data.forEach(store => {
console.log('\nStore ID:', store.storeId);
console.log('Name:', store.storeName);
console.log('Address:', store.address);
});
} catch (error) {
console.error('Failed to fetch stores');
}
})();
Response
Success Response (200)
{
"statusCode": 200,
"message": "Success",
"data": [
{
"storeId": 1234567890,
"storeName": "Main Store - Downtown",
"address": "123 Main Street, Phnom Penh, Cambodia"
},
{
"storeId": 1234567891,
"storeName": "Branch Store - Airport",
"address": "456 Airport Road, Phnom Penh, Cambodia"
}
],
"traceId": "trace_abc123"
}
Response Fields
| Field | Type | Description |
|---|---|---|
statusCode | number | HTTP status code (200 for success) |
message | string | Response message |
data | array | Array of store objects |
data[].storeId | number | Unique store identifier (use this for Create Order and Generate QR) |
data[].storeName | string | Display name of the store |
data[].address | string | Physical address of the store |
traceId | string | Request trace identifier for debugging |
Error Responses
400 Bad Request
Missing required headers or invalid request format.
{
"statusCode": 400,
"message": "Bad Request - missing required headers or invalid request body",
"error": "Bad Request"
}
401 Unauthorized
Invalid API credentials provided.
{
"statusCode": 401,
"message": "Unauthorized - invalid API credentials",
"error": "Unauthorized"
}
404 Not Found
No stores found for the merchant account.
{
"statusCode": 404,
"message": "Not Found - store not found",
"error": "Not Found"
}
500 Internal Server Error
Server-side error occurred while processing the request.
{
"statusCode": 500,
"message": "Internal Server Error",
"error": "Internal Server Error"
}
Use Cases
1. Before Creating Orders
Retrieve store information before creating payment orders:
// Step 1: Get available stores
const stores = await listStores('your-api-key');
const storeId = stores.data[0].storeId;
// Step 2: Use storeId to create an order
const order = await createOrder(storeId, 100.00, 'USD');
2. Before Generating KHQR Codes
Obtain the storeId required for KHQR generation:
// Step 1: Get store information
const stores = await listStores('your-api-key');
const storeId = stores.data[0].storeId;
// Step 2: Generate KHQR code with storeId
const qr = await generateQRCode(storeId, 50.00, 'USD');
3. Multi-Store Management
For merchants with multiple stores, implement store selection:
const stores = await listStores('your-api-key');
// Let user select their store
stores.data.forEach((store, index) => {
console.log(`${index + 1}. ${store.storeName} - ${store.address}`);
});
// Use selected storeId for payment operations
const selectedStoreId = stores.data[selectedIndex].storeId;
4. Store Display in POS Systems
Display store information in your point-of-sale system:
const stores = await listStores('your-api-key');
// Show current store information
const currentStore = stores.data.find(s => s.storeId === currentStoreId);
console.log(`Active Store: ${currentStore.storeName}`);
console.log(`Location: ${currentStore.address}`);
Integration Workflow
Here's a typical integration workflow using the List Stores endpoint:
sequenceDiagram
participant App as Your Application
participant API as DVPay API
participant Cache as Local Cache
App->>API: POST /stores/list
API-->>App: Return stores array
App->>Cache: Store storeId locally
Note over App,Cache: Store selection
App->>Cache: Get cached storeId
Note over App,API: Payment operations
App->>API: POST /order/create (with storeId)
API-->>App: Return order with QR code
App->>API: POST /payment/generate-qr (with storeId)
API-->>App: Return KHQR code
Best Practices
1. Cache Store Information
Cache the store list to minimize API calls and improve performance:
let storeCache = null;
let cacheTimestamp = null;
const CACHE_DURATION = 3600000; // 1 hour in milliseconds
async function getStores(apiKey, forceRefresh = false) {
const now = Date.now();
if (!forceRefresh && storeCache && (now - cacheTimestamp < CACHE_DURATION)) {
return storeCache;
}
const stores = await listStores(apiKey);
storeCache = stores;
cacheTimestamp = now;
return stores;
}
2. Handle Empty Store Lists
Always check if stores exist before proceeding:
const stores = await listStores('your-api-key');
if (!stores.data || stores.data.length === 0) {
throw new Error('No stores available. Please configure stores in DVPay mobile app.');
}
3. Store Selection for Multi-Store Merchants
Implement proper store selection logic:
async function selectStore(apiKey, criteria) {
const stores = await listStores(apiKey);
// Select by name
if (criteria.name) {
return stores.data.find(s =>
s.storeName.toLowerCase().includes(criteria.name.toLowerCase())
);
}
// Select by ID
if (criteria.id) {
return stores.data.find(s => s.storeId === criteria.id);
}
// Default to first store
return stores.data[0];
}
4. Validate StoreId Before Payment Operations
Ensure the storeId exists before using it:
async function validateStoreId(apiKey, storeId) {
const stores = await listStores(apiKey);
const storeExists = stores.data.some(s => s.storeId === storeId);
if (!storeExists) {
throw new Error(`Invalid storeId: ${storeId}`);
}
return true;
}
5. Refresh Cache When Stores Change
Implement cache invalidation when stores are modified:
// After adding a new store via DVPay mobile app
async function refreshStores(apiKey) {
return await getStores(apiKey, true); // Force refresh
}
Related Endpoints
- Create Order - Requires
storeIdfrom this endpoint - Generate QR - Requires
storeIdfor KHQR generation - Transaction Detail - Returns store information for completed transactions
storeId must be valid and belong to your merchant account. Using an invalid or unauthorized storeId will result in a 404 error when creating orders or generating QR codes.Troubleshooting
No Stores Returned (404)
If you receive a 404 error or empty store list:
- Verify that you have created at least one store in the DVPay mobile application
- Navigate to: DVPay Mobile App → Settings → Stores → Add Store
- Wait a few minutes for the store to be activated
- Retry the API call
Unauthorized Error (401)
- Verify your API key is correct and active
- Check that you're using the correct API key header:
X-Api-Key - Ensure your API key has not expired or been revoked
Store Information Outdated
If cached store information becomes stale:
- Implement a cache refresh mechanism
- Force a refresh after store modifications in the mobile app
- Consider adding a manual refresh option in your application
Security Notes
- Store IDs are not sensitive but should be validated before use
- Never expose API keys in client-side code when fetching store lists
- Implement rate limiting if polling this endpoint frequently
- Use secure storage for cached store information