import { z } from 'zod';
import { FinixContext, ToolFactory } from '../../types.js';
import { FinixClient } from '../../utils/finixClient.js';
const createSellerPrompt = () => `
This tool creates a new Seller Identity in Finix with full underwriting data.
Required arguments:
- email (str): The email address of the seller.
- first_name (str): The first name of the primary contact.
- last_name (str): The last name of the primary contact.
- business_name (str): The legal business name.
- business_type (str): The business type (e.g., INDIVIDUAL_SOLE_PROPRIETORSHIP, CORPORATION, etc.).
- business_description (str): Description of the business for underwriting.
Optional arguments include extensive business and underwriting data fields.
See the schema for complete field descriptions.
`;
const createSellerParameters = () => z.object({
// Required basic info
email: z.string().email().describe('The email address of the seller'),
first_name: z.string().describe('The first name of the primary contact'),
last_name: z.string().describe('The last name of the primary contact'),
business_name: z.string().describe('The legal business name'),
business_type: z.enum([
'INDIVIDUAL_SOLE_PROPRIETORSHIP', 'CORPORATION', 'LIMITED_LIABILITY_COMPANY',
'PARTNERSHIP', 'ASSOCIATION', 'GOVERNMENT_AGENCY', 'OTHER'
]).describe('The business type'),
business_description: z.string().describe('Description of the business for underwriting'),
// Business contact info
phone: z.string().optional().describe('Personal phone number'),
business_phone: z.string().optional().describe('Business phone number'),
business_tax_id: z.string().optional().describe('Business tax ID (EIN)'),
tax_id: z.string().optional().describe('Personal tax ID (SSN)'),
url: z.string().optional().describe('Business website URL'),
// Addresses
personal_address: z.object({
line1: z.string().describe('Address line 1'),
line2: z.string().optional().describe('Address line 2'),
city: z.string().describe('City'),
region: z.string().describe('State/Region (e.g., CA)'),
postal_code: z.string().describe('Postal/ZIP code'),
country: z.string().default('USA').describe('Country code')
}).optional().describe('Personal address of the primary contact'),
business_address: z.object({
line1: z.string().describe('Address line 1'),
line2: z.string().optional().describe('Address line 2'),
city: z.string().describe('City'),
region: z.string().describe('State/Region (e.g., CA)'),
postal_code: z.string().describe('Postal/ZIP code'),
country: z.string().default('USA').describe('Country code')
}).optional().describe('Business address'),
// Business details
doing_business_as: z.string().optional().describe('DBA name'),
default_statement_descriptor: z.string().optional().describe('Statement descriptor for transactions'),
title: z.string().optional().describe('Title of the primary contact (e.g., CEO)'),
principal_percentage_ownership: z.number().min(0).max(100).optional().describe('Ownership percentage'),
mcc: z.string().optional().describe('Merchant Category Code'),
ownership_type: z.enum(['PRIVATE', 'PUBLIC']).optional().describe('Ownership type'),
// Dates
dob: z.object({
year: z.number().int().describe('Birth year'),
month: z.number().int().min(1).max(12).describe('Birth month (1-12)'),
day: z.number().int().min(1).max(31).describe('Birth day (1-31)')
}).optional().describe('Date of birth of primary contact'),
incorporation_date: z.object({
year: z.number().int().describe('Incorporation year'),
month: z.number().int().min(1).max(12).describe('Incorporation month (1-12)'),
day: z.number().int().min(1).max(31).describe('Incorporation day (1-31)')
}).optional().describe('Date of business incorporation'),
// Financial info
annual_card_volume: z.number().optional().describe('Annual card processing volume in cents'),
max_transaction_amount: z.number().optional().describe('Maximum single transaction amount in cents'),
ach_max_transaction_amount: z.number().optional().describe('Maximum ACH transaction amount in cents'),
has_accepted_credit_cards_previously: z.boolean().optional().describe('Has accepted credit cards before'),
// Underwriting data
annual_ach_volume: z.number().optional().describe('Annual ACH volume in cents'),
average_ach_transfer_amount: z.number().optional().describe('Average ACH transfer amount in cents'),
average_card_transfer_amount: z.number().optional().describe('Average card transfer amount in cents'),
card_volume_distribution: z.object({
card_present_percentage: z.number().min(0).max(100).describe('Card present percentage'),
mail_order_telephone_order_percentage: z.number().min(0).max(100).describe('MOTO percentage'),
ecommerce_percentage: z.number().min(0).max(100).describe('Ecommerce percentage')
}).optional().describe('Card volume distribution'),
volume_distribution_by_business_type: z.object({
business_to_business_volume_percentage: z.number().min(0).max(100).describe('B2B percentage'),
business_to_consumer_volume_percentage: z.number().min(0).max(100).describe('B2C percentage'),
consumer_to_consumer_volume_percentage: z.number().min(0).max(100).describe('C2C percentage'),
person_to_person_volume_percentage: z.number().min(0).max(100).describe('P2P percentage'),
other_volume_percentage: z.number().min(0).max(100).describe('Other percentage')
}).optional().describe('Volume distribution by business type'),
refund_policy: z.enum([
'NO_REFUNDS', 'REFUNDS_WITH_RESTOCKING_FEE', 'MERCHANDISE_EXCHANGE_ONLY',
'FULL_REFUNDS', 'OTHER'
]).optional().describe('Refund policy'),
// Agreement and credit check info
merchant_agreement_accepted: z.boolean().optional().describe('Merchant agreement accepted'),
merchant_agreement_timestamp: z.string().optional().describe('When agreement was accepted (ISO 8601)'),
merchant_agreement_ip_address: z.string().optional().describe('IP address when agreement was accepted'),
merchant_agreement_user_agent: z.string().optional().describe('User agent when agreement was accepted'),
credit_check_allowed: z.boolean().optional().describe('Credit check allowed'),
credit_check_timestamp: z.string().optional().describe('When credit check was authorized (ISO 8601)'),
credit_check_ip_address: z.string().optional().describe('IP address for credit check'),
credit_check_user_agent: z.string().optional().describe('User agent for credit check'),
// Tags
tags: z.record(z.string()).optional().describe('Key-value pairs for tagging')
});
const createSellerAnnotations = () => ({
destructiveHint: false,
idempotentHint: false,
openWorldHint: true,
readOnlyHint: false,
title: 'Create Seller Identity'
});
const createSeller = async (client: FinixClient, _context: FinixContext, params: any): Promise<any> => {
try {
if (!client.hasCredentials()) {
throw new Error('Finix username and password are required for this operation. Please configure FINIX_USERNAME and FINIX_PASSWORD in your environment.');
}
const {
email, first_name, last_name, business_name, business_type, business_description,
phone, business_phone, business_tax_id, tax_id, url,
personal_address, business_address,
doing_business_as, default_statement_descriptor, title, principal_percentage_ownership,
mcc, ownership_type, dob, incorporation_date,
annual_card_volume, max_transaction_amount, ach_max_transaction_amount,
has_accepted_credit_cards_previously,
annual_ach_volume, average_ach_transfer_amount, average_card_transfer_amount,
card_volume_distribution, volume_distribution_by_business_type, refund_policy,
merchant_agreement_accepted, merchant_agreement_timestamp, merchant_agreement_ip_address, merchant_agreement_user_agent,
credit_check_allowed, credit_check_timestamp, credit_check_ip_address, credit_check_user_agent,
tags
} = params;
const payload: any = {
type: 'BUSINESS',
identity_roles: ['SELLER'],
entity: {
email,
first_name,
last_name,
business_name,
business_type,
...(phone && { phone }),
...(business_phone && { business_phone }),
...(business_tax_id && { business_tax_id }),
...(tax_id && { tax_id }),
...(url && { url }),
...(personal_address && { personal_address }),
...(business_address && { business_address }),
...(doing_business_as && { doing_business_as }),
...(default_statement_descriptor && { default_statement_descriptor }),
...(title && { title }),
...(principal_percentage_ownership !== undefined && { principal_percentage_ownership }),
...(mcc && { mcc }),
...(ownership_type && { ownership_type }),
...(dob && { dob }),
...(incorporation_date && { incorporation_date }),
...(annual_card_volume !== undefined && { annual_card_volume }),
...(max_transaction_amount !== undefined && { max_transaction_amount }),
...(ach_max_transaction_amount !== undefined && { ach_max_transaction_amount }),
...(has_accepted_credit_cards_previously !== undefined && { has_accepted_credit_cards_previously })
},
...(tags && { tags })
};
// Build additional underwriting data if any fields are provided
const underwritingData: any = {};
if (business_description) underwritingData.business_description = business_description;
if (annual_ach_volume !== undefined) underwritingData.annual_ach_volume = annual_ach_volume;
if (average_ach_transfer_amount !== undefined) underwritingData.average_ach_transfer_amount = average_ach_transfer_amount;
if (average_card_transfer_amount !== undefined) underwritingData.average_card_transfer_amount = average_card_transfer_amount;
if (card_volume_distribution) underwritingData.card_volume_distribution = card_volume_distribution;
if (volume_distribution_by_business_type) underwritingData.volume_distribution_by_business_type = volume_distribution_by_business_type;
if (refund_policy) underwritingData.refund_policy = refund_policy;
if (merchant_agreement_accepted !== undefined) underwritingData.merchant_agreement_accepted = merchant_agreement_accepted;
if (merchant_agreement_timestamp) underwritingData.merchant_agreement_timestamp = merchant_agreement_timestamp;
if (merchant_agreement_ip_address) underwritingData.merchant_agreement_ip_address = merchant_agreement_ip_address;
if (merchant_agreement_user_agent) underwritingData.merchant_agreement_user_agent = merchant_agreement_user_agent;
if (credit_check_allowed !== undefined) underwritingData.credit_check_allowed = credit_check_allowed;
if (credit_check_timestamp) underwritingData.credit_check_timestamp = credit_check_timestamp;
if (credit_check_ip_address) underwritingData.credit_check_ip_address = credit_check_ip_address;
if (credit_check_user_agent) underwritingData.credit_check_user_agent = credit_check_user_agent;
if (Object.keys(underwritingData).length > 0) {
payload.additional_underwriting_data = underwritingData;
}
const response = await client.post('/identities', payload);
if (response.error) {
throw new Error(`Error creating seller identity: ${response.error.message}`);
}
const identity = response.data;
// Return clean data without _links
const { _links, ...cleanIdentity } = identity;
return cleanIdentity;
} catch (error) {
throw error;
}
};
const tool: ToolFactory = () => ({
method: 'create_seller',
name: 'Create Seller Identity',
description: createSellerPrompt(),
parameters: createSellerParameters(),
annotations: createSellerAnnotations(),
actions: {
identities: {
create: true
}
},
execute: createSeller
});
export default tool;