@houlak/drynex-sdk v1.1.0
Drynex SDK
A modern TypeScript SDK for integrating with the Drynex Payment Gateway. This SDK provides a type-safe and developer-friendly way to interact with Drynex's payment processing services.
ā ļø This SDK is in ALPHA stage and is not intended for public use.
Access and usage are strictly limited to teams authorized by Houlak.
š Table of Contents
⨠Features
- š Full TypeScript support with comprehensive type definitions
- š SDK functionalities:
- Authentication (Login and Refresh Tokens)
- Merchant Management
- Points of Sale Management
- Terminal Management
- Payment Instruments
- Payment Flows (Authorization, Capture, Cancellation, Refund)
- ā” Modern async/await API
- š”ļø Built-in error handling
- š Comprehensive documentation
š¦ Installation
# Using npm
npm install drynex-sdk
# Using yarn
yarn add drynex-sdk
# Using pnpm
pnpm add drynex-sdkš Quick Start
import { DrynexClient, DrynexAuth, DrynexTypes } from 'drynex-sdk';
const environment = DrynexTypes.Enums.Environment.SANDBOX; // or DrynexTypes.Enums.Environment.PRODUCTION
// First, get an authentication token
const tokenResponse = await DrynexAuth.getToken(environment, {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
});
if (!tokenResponse.success || !tokenResponse.data) {
throw new Error('Authentication failed');
}
const accessToken = tokenResponse.data.accessToken;
// Then create the DrynexClient instance with the token
const drynexClientConfig: DrynexTypes.ClientConfig = {
token: accessToken,
environment,
};
const drynexClient = new DrynexClient(drynexClientConfig);
// Now you can use the DrynexClient instance
const createOrganizationRequest: DrynexTypes.RequestTypes.CreateOrganizationRequest = {
name: 'My Organization',
};
const createOrganizationResponse: DrynexTypes.ApiResponse<DrynexTypes.ResponseTypes.OrganizationDTO> =
await drynexClient.organizations.create(createOrganizationRequest);
if (!createOrganizationResponse.success || !createOrganizationResponse.data) {
throw new Error('Create organization failed');
}
const organization: DrynexTypes.ResponseTypes.OrganizationDTO = createOrganizationResponse.data;
const createMerchantRequest: DrynexTypes.RequestTypes.CreateMerchantRequest = {
name: 'My Store',
organization_id: organization.id,
country: 'US',
city: 'New York',
state: 'NY',
billing_address: {
street: '123 Main St',
city: 'New York',
state: 'NY',
country: 'US',
postal_code: '10001',
},
location_address: {
street: '123 Main St',
city: 'New York',
state: 'NY',
country: 'US',
postal_code: '10001',
},
classification_mode: 'retail',
default_currency: 'USD',
supported_currencies: ['USD', 'EUR'],
activity: 'retail',
alias: 'my-store-ny',
email: 'store@example.com',
external_id: 'ext_123',
phone: '+1234567890',
tax_id: '123456789',
rails: {
VISA: {
category_code: '5411',
payfac_id: 'payfac_123',
},
MASTERCARD: {
category_code: '5411',
payfac_id: 'payfac_123',
},
},
};
const createMerchantResponse: DrynexTypes.ApiResponse<DrynexTypes.ResponseTypes.MerchantDTO> =
await drynexClient.merchants.create(createMerchantRequest);
if (!createMerchantResponse.success || !createMerchantResponse.data) {
throw new Error('Create merchant failed');
}
const merchant: DrynexTypes.ResponseTypes.MerchantDTO = createMerchantResponse.data;
const createInstrumentRequest: DrynexTypes.RequestTypes.CreateInstrumentRequest = {
type: 'CARD',
card: {
number: '4242424242424242',
expiration_month: '12',
expiration_year: '2030',
first_name: 'John',
last_name: 'Doe',
cvv: '123',
},
user_data: {
billing_address: {
street: '123 Main St',
number: 'Apt 4B',
city: 'New York',
state: 'NY',
zip_code: '10001',
country: 'US',
},
},
};
const createInstrumentResponse: DrynexTypes.ApiResponse<DrynexTypes.ResponseTypes.InstrumentDTO> =
await drynexClient.instruments.create(createInstrumentRequest);
if (!createInstrumentResponse.success || !createInstrumentResponse.data) {
throw new Error('Create instrument failed');
}
const instrument: DrynexTypes.ResponseTypes.InstrumentDTO = createInstrumentResponse.data;š API Reference
Authentication
The SDK uses a token-based authentication system. Before using any other functionality, you must first obtain an authentication token using the DrynexAuth.getToken function.
DrynexAuth.getToken(environment: Environment, getTokenRequest: GetTokenRequest): Promise<ApiResponse<AuthDTO>>
Retrieves an authentication token using client credentials. This token is required for all subsequent API calls. The token is valid for a limited time and should be refreshed when expired.
import { DrynexAuth, DrynexTypes } from 'drynex-sdk';
const environment = DrynexTypes.Enums.Environment.SANDBOX; // or DrynexTypes.Enums.Environment.PRODUCTION
const tokenResponse = await DrynexAuth.getToken(environment, {
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
});
if (!tokenResponse.success || !tokenResponse.data) {
throw new Error('Authentication failed');
}
const accessToken = tokenResponse.data.accessToken;Creating an DrynexClient instance
The DrynexClient is the main entry point for interacting with the Drynex API. It requires a token obtained from DrynexAuth.getToken and an environment configuration.
import { DrynexClient, DrynexTypes } from 'drynex-sdk';
const clientConfig: DrynexTypes.ClientConfig = {
token: accessToken, // Token obtained from DrynexAuth.getToken
environment: DrynexTypes.Enums.Environment.SANDBOX, // or PRODUCTION
};
const drynexClient = new DrynexClient(clientConfig);Organizations
organizations.create(data: CreateOrganizationRequest): Promise<ApiResponse<OrganizationDTO>>
Creates a new organization in the Drynex system. Organizations can have multiple merchants and are used to group related business entities.
const organization = await drynexClient.organizations.create({
name: 'Acme Corp',
});Merchants
merchants.create(data: CreateMerchantRequest): Promise<ApiResponse<MerchantDTO>>
Creates a new merchant in the Drynex system. This is the first step in setting up a new merchant account. The merchant will be associated with the specified organization and will be configured with the provided payment rails and settings.
const merchant = await drynexClient.merchants.create({
name: 'My Store',
organization_id: 'org_123',
country: 'US',
city: 'New York',
state: 'NY',
billing_address: {
street: '123 Main St',
city: 'New York',
state: 'NY',
country: 'US',
postal_code: '10001',
},
location_address: {
street: '123 Main St',
city: 'New York',
state: 'NY',
country: 'US',
postal_code: '10001',
},
classification_mode: 'retail',
default_currency: 'USD',
supported_currencies: ['USD', 'EUR'],
activity: 'retail',
alias: 'my-store-ny',
email: 'store@example.com',
external_id: 'ext_123',
phone: '+1234567890',
tax_id: '123456789',
rails: {
VISA: {
category_code: '5411',
payfac_id: 'payfac_123',
},
MASTERCARD: {
category_code: '5411',
payfac_id: 'payfac_123',
},
},
});Payment Instruments
instruments.create(data: CreateInstrumentRequest): Promise<ApiResponse<InstrumentDTO>>
Creates a new payment instrument. The instrument is tokenized and stored securely in the Drynex system.
const card = await drynexClient.instruments.create({
type: 'CARD',
card: {
number: '4242424242424242',
expiration_month: '12',
expiration_year: '2025',
first_name: 'John',
last_name: 'Doe',
cvv: '123',
},
user_data: {
billing_address: {
street: '123 Main St',
number: 'Apt 4B',
city: 'New York',
state: 'NY',
zip_code: '10001',
country: 'US',
},
},
});instruments.get(): Promise<ApiResponse<InstrumentDTO[]>>
Retrieves all payment instruments associated with the merchant. This includes both active and inactive instruments, with their current status and details.
const instruments = await drynexClient.instruments.get();instruments.getById(id: string): Promise<ApiResponse<InstrumentDTO>>
Retrieves detailed information about a specific payment instrument, including its type and status.
const instrument = await drynexClient.instruments.getById('instr_123');instruments.update(id: string, data: UpdateInstrumentRequest): Promise<ApiResponse<InstrumentDTO>>
Updates an existing payment instrument's information. This can be used to update expiration dates, cardholder information, or other instrument details.
const updatedInstrument = await drynexClient.instruments.update('instr_123', {
card: {
expiration_month: '12',
expiration_year: '2026',
first_name: 'John',
last_name: 'Smith',
},
});instruments.delete(id: string): Promise<ApiResponse<void>>
Permanently deletes a payment instrument from the system. This operation cannot be undone and will invalidate the instrument for future use.
await drynexClient.instruments.delete('instr_123');Payments
Webhooks
š TypeScript Types
The SDK provides comprehensive TypeScript types that can be imported from the DrynexTypes namespace. This allows you to have full type safety and autocompletion when working with the SDK.
Available Types
import { DrynexTypes } from 'drynex-sdk';
// Enums
const environment = DrynexTypes.Enums.Environment.SANDBOX;
const country = DrynexTypes.Enums.Country.USA;
const rail = DrynexTypes.Enums.Rail.VISA;
// Request Types
const createMerchantRequest: DrynexTypes.RequestTypes.CreateMerchantRequest = {
name: 'My Store',
organization_id: 'org_123',
// ... other merchant fields
};
const createInstrumentRequest: DrynexTypes.RequestTypes.CreateInstrumentRequest = {
type: 'CARD',
card: {
number: '4242424242424242',
expiration_month: '12',
expiration_year: '2025',
first_name: 'John',
last_name: 'Doe',
cvv: '123',
},
};
// Response Types
const merchantResponse: DrynexTypes.ResponseTypes.MerchantDTO = {
id: 'merch_123',
name: 'My Store',
// ... other merchant fields
};
const instrumentResponse: DrynexTypes.ResponseTypes.InstrumentDTO = {
id: 'instr_123',
type: 'CARD',
// ... other instrument fields
};Type Categories
The SDK's types are organized into several categories:
Enums: Constants and enumerations used throughout the SDK
Request Types: Types for API request payloads
Response Types: Types for API response data
API Response: Generic wrapper type for all API responses
interface ApiResponse<T> { data: T | null; success: boolean; error?: { code: string; message: string; details?: Record<string, unknown>; }; }
Type Safety Example
Here's an example of how the types help catch errors at compile time:
import { DrynexClient, DrynexTypes } from 'drynex-sdk';
const client = new DrynexClient({
token: 'your-token',
environment: DrynexTypes.Enums.Environment.SANDBOX,
});
// TypeScript will show an error if required fields are missing
const merchant = await client.merchants.create({
name: 'My Store',
// Error: missing required field 'organization_id'
});
// TypeScript will show an error if field types don't match
const instrument = await client.instruments.create({
type: 'CARD',
card: {
number: 4242424242424242, // Error: number should be a string
expiration_month: 12, // Error: should be a string
expiration_year: 2025, // Error: should be a string
first_name: 'John',
last_name: 'Doe',
},
});
// TypeScript will provide autocompletion for response fields
const response = await client.instruments.getById('ins_123');
if (response.success && response.data) {
console.log(response.data.status); // Autocomplete available
console.log(response.data.type); // Autocomplete available
console.log(response.data.invalid_field); // Error: field doesn't exist
}š”ļø Error Handling
The SDK provides built-in error handling with detailed error messages. All API responses are wrapped in an ApiResponse type:
interface ApiResponse<T> {
data: T | null;
success: boolean;
error?: {
code: string;
message: string;
details?: Record<string, unknown>;
};
}Example error handling:
try {
const result = await DrynexClient.organizations.create({
name: 'Acme Corp',
});
} catch (exception) {
if (exception.error) {
console.error(`Error ${exception.error.code}: ${exception.error.message}`);
if (exception.error.details) {
console.error('Details:', exception.error.details);
}
}
}š License
This project is licensed under the MIT License - see the LICENSE file for details.