Skip to main content
The userActions.ts module provides utility functions for managing Cryptlex users from payment platform webhook events.

Functions

checkUserExists

Checks if a user exists by email address.
email
string
required
The email address to search for
client
CtlxClientType
required
The Cryptlex API client instance
userId
string | null
Returns the user ID if found, or null if no user exists with that email
Implementation:
async function checkUserExists(email: string, client: CtlxClientType) {
    let userId: string | null = null
    const userResponse = await client.GET('/v3/users', {
        params: {
            query: {
                email: { eq: email },
            },
        },
    })
    if (userResponse.error) {
        throw new Error(`User search failed: ${userResponse.error.message}.`)
    }
    if (userResponse.data[0]) {
        userId = userResponse.data[0].id
    }
    return userId
}
Source: userActions.ts:5

createUser

Creates a new user in Cryptlex with the provided details.
email
string
required
User’s email address
customerName
string
required
User’s first name (from payment platform)
client
CtlxClientType
required
The Cryptlex API client instance
lastName
string
User’s last name
company
string
User’s company name
metadata
Array<{ key: string; value: string; viewPermissions?: [] }>
Additional metadata to attach to the user
userId
string
The ID of the newly created user
Key Details:
  • Generates a random 10-character password using nanoid(10)
  • Sets user role to 'user'
  • Only includes optional fields if they are defined and not null
Usage Example:
const userId = await createUser(
  '[email protected]',
  'John',
  client,
  'Doe',
  'Acme Inc'
);
Source: userActions.ts:23

updateUser

Updates an existing user’s details.
userId
string
required
The ID of the user to update
customerName
string
required
New first name (only updated if not empty)
client
CtlxClientType
required
The Cryptlex API client instance
lastName
string
New last name
company
string
New company name
email
string | null
New email address (only updated if not empty or null)
userId
string
The ID of the updated user
Key Details:
  • Only includes fields in the update request if they are defined and not null/empty
  • Uses PATCH request to /v3/users/{id}
Usage Example:
const userId = await updateUser(
  'usr_abc123',
  'Jane',
  client,
  'Smith',
  'New Company Inc'
);
Source: userActions.ts:63

insertUser

Checks for an existing user with the same email or creates a new one if it doesn’t exist. Returns the user ID.
email
string
required
User’s email address
customerName
string
required
Name to be set for the created user
client
CtlxClientType
required
The Cryptlex API client instance
lastName
string
User’s last name
company
string
User’s company name
userId
string | null
The user ID (existing or newly created)
Key Details:
  • Handles race conditions: if two webhook events try to create the same user simultaneously, it checks again after creation failure
  • Does NOT update existing users (use upsertUser for that)
Usage Example:
// From Stripe invoice.paid handler
const email = invoice.customer_email;
const userName = invoice.customer_name ?? `Stripe Invoice ${invoice.id}`;
const userId = await insertUser(email, userName, client);
Source: userActions.ts:114

upsertUser

Updates an existing user with the same email or creates a new one if it doesn’t exist. Returns the user ID.
email
string
required
User’s email address
customerName
string
required
Name to be set for the user
client
CtlxClientType
required
The Cryptlex API client instance
lastName
string
User’s last name
company
string
User’s company name
userId
string | null
The user ID (existing or newly created)
Key Details:
  • Unlike insertUser, this function WILL update existing users
  • Handles race conditions similar to insertUser
  • Preferred for customer creation events where you want to ensure the latest data
Usage Example:
// From Stripe customer.created handler
const email = event.data.object.email;
const userName = event.data.object.name;
const userId = await upsertUser(email, userName, client);
Source: userActions.ts:145

When to Use Each Function

FunctionUse Case
checkUserExistsInternal helper - not typically called directly
createUserWhen you’re certain a new user needs to be created
updateUserWhen you have a user ID and need to update details
insertUserFor license creation events where you need a user ID but shouldn’t modify existing users
upsertUserFor customer creation/update events where you want to keep user data in sync

Error Handling

All functions throw descriptive errors:
// User search failed
throw new Error(`User search failed: ${userResponse.error.message}.`)

// User creation failed
throw new Error(`User creation failed: ${user.error.message}`);

// User update failed
throw new Error(`User updation failed: ${user.error.message}`);

Build docs developers (and LLMs) love