Account Already Exists Error
https://bessapay.net/errors/account-already-existsOverview
An Account Already Exists error occurs when you attempt to create a new account with an identifier (email, username, etc.) that is already registered in the system. This error is returned with HTTP status code 409 (Conflict).
Details
- Error Code: ACCOUNT_ALREADY_EXISTS
- HTTP Status: 409
- Error Type: Client Error
Common scenarios
- • User registration with existing email
- • Creating a business account with existing tax ID
- • Registering with a username that's already taken
- • API key creation with existing name
- • Creating a duplicate merchant account
Example
1{
2 "type": "https://bessapay.net/errors/account-already-exists",
3 "title": "Account Already Exists",
4 "status": 409,
5 "detail": "An account with email 'user@example.com' already exists",
6 "instance": "/api/v1/accounts",
7 "errorCode": "ACCOUNT_ALREADY_EXISTS",
8 "timestamp": "2023-06-15T19:12:45Z",
9 "conflictingField": "email"
10}How to Handle
Check for existing accounts first
Before attempting to create a new account, check if the account already exists using a lookup endpoint. This can help provide a better user experience.
1// Check if account exists before creating
2async function checkAndCreateAccount(accountData) {
3 try {
4 // First check if the email exists
5 const checkResponse = await fetch(`https://api.semuni.com/v1/accounts/exists?email=${encodeURIComponent(accountData.email)}`, {
6 headers: {
7 'Authorization': `Bearer ${apiKey}`,
8 'Content-Type': 'application/json'
9 }
10 });
11
12 const checkResult = await checkResponse.json();
13
14 if (checkResult.exists) {
15 // Account already exists, handle gracefully
16 return {
17 success: false,
18 error: 'An account with this email already exists',
19 suggestLogin: true
20 };
21 }
22
23 // Account doesn't exist, proceed with creation
24 const createResponse = await fetch('https://api.semuni.com/v1/accounts', {
25 method: 'POST',
26 headers: {
27 'Authorization': `Bearer ${apiKey}`,
28 'Content-Type': 'application/json'
29 },
30 body: JSON.stringify(accountData)
31 });
32
33 if (!createResponse.ok) {
34 const errorData = await createResponse.json();
35
36 // Double-check for race condition
37 if (errorData.type === 'https://bessapay.net/errors/account-already-exists') {
38 return {
39 success: false,
40 error: errorData.detail,
41 suggestLogin: true
42 };
43 }
44
45 throw new Error(errorData.detail || 'Failed to create account');
46 }
47
48 const newAccount = await createResponse.json();
49 return {
50 success: true,
51 account: newAccount
52 };
53 } catch (error) {
54 console.error('Error in account creation:', error);
55 throw error;
56 }
57}Offer alternate identifiers
If a username or email is already taken, suggest alternatives to the user. For example, if "johnsmith" is taken, suggest "johnsmith1" or "john.smith".
Provide account recovery options
When an account already exists, provide options for password recovery or account access instead of just showing an error message.
Use unique constraints properly
If you're building your own application that interfaces with BessaPay, ensure you're using unique constraints appropriately in your database to prevent duplicate account creation before making API calls.
Code Example: Enhanced User Registration
1// Complete example of handling account conflicts during registration
2async function registerUser(userData) {
3 try {
4 const response = await fetch('https://api.semuni.com/v1/accounts', {
5 method: 'POST',
6 headers: {
7 'Authorization': `Bearer ${apiKey}`,
8 'Content-Type': 'application/json'
9 },
10 body: JSON.stringify(userData)
11 });
12
13 if (response.status === 409) {
14 const errorData = await response.json();
15
16 // Check if it's an account already exists error
17 if (errorData.type === 'https://bessapay.net/errors/account-already-exists') {
18 console.warn('Account exists error:', errorData);
19
20 // Get the conflicting field
21 const conflictField = errorData.conflictingField || 'email';
22
23 // Show appropriate message based on conflicting field
24 switch(conflictField) {
25 case 'email':
26 return {
27 success: false,
28 errorType: 'accountExists',
29 message: 'An account with this email already exists',
30 actions: [
31 { type: 'login', label: 'Sign in instead' },
32 { type: 'recover', label: 'Forgot password?' }
33 ]
34 };
35
36 case 'username':
37 // Generate alternative usernames
38 const alternatives = generateAlternativeUsernames(userData.username);
39
40 return {
41 success: false,
42 errorType: 'usernameTaken',
43 message: 'This username is already taken',
44 suggestions: alternatives,
45 actions: [
46 { type: 'choose', label: 'Choose from suggestions' },
47 { type: 'enter', label: 'Enter different username' }
48 ]
49 };
50
51 default:
52 return {
53 success: false,
54 errorType: 'conflict',
55 message: errorData.detail,
56 actions: [
57 { type: 'modify', label: 'Modify details' },
58 { type: 'contact', label: 'Contact support' }
59 ]
60 };
61 }
62 }
63 }
64
65 if (!response.ok) {
66 const errorData = await response.json();
67 throw new Error(errorData.detail || 'Registration failed');
68 }
69
70 const account = await response.json();
71
72 return {
73 success: true,
74 account
75 };
76 } catch (error) {
77 console.error('Registration error:', error);
78 return {
79 success: false,
80 errorType: 'system',
81 message: 'An error occurred during registration. Please try again later.'
82 };
83 }
84}
85
86// Helper function to generate alternative usernames
87function generateAlternativeUsernames(username) {
88 const alternatives = [];
89
90 // Add a number
91 for (let i = 1; i <= 3; i++) {
92 alternatives.push(`${username}${i}`);
93 }
94
95 // Add a dot
96 if (!username.includes('.')) {
97 // Split into first and last parts if possible
98 const parts = username.match(/([a-z]+)([a-z]+)/i);
99 if (parts && parts.length >= 3) {
100 alternatives.push(`${parts[1]}.${parts[2]}`);
101 }
102 }
103
104 // Add an underscore
105 if (!username.includes('_')) {
106 alternatives.push(`${username}_account`);
107 }
108
109 return alternatives;
110}