nodejs-cryptomus
Version:
A comprehensive Node.js client for the Cryptomus API
136 lines (126 loc) • 3.84 kB
text/typescript
import axios, { AxiosInstance, AxiosRequestConfig, AxiosError } from 'axios';
import { CryptomusOptions, RequestOptions, ApiResponse, ApiErrorResponse, CryptomusError } from './types';
import { generateSignature } from './utils/signature';
/**
* Cryptomus API client
*/
export class CryptomusClient {
private readonly merchantId: string;
private readonly paymentKey: string;
private readonly payoutKey?: string;
private readonly apiUrl: string;
private readonly httpClient: AxiosInstance;
/**
* Create a new Cryptomus API client
*
* @param options - Configuration options
*/
constructor(options: CryptomusOptions) {
this.merchantId = options.merchantId;
this.paymentKey = options.paymentKey;
this.payoutKey = options.payoutKey;
this.apiUrl = options.apiUrl || 'https://api.cryptomus.com/v1';
this.httpClient = axios.create({
baseURL: this.apiUrl,
timeout: 30000,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
});
}
/**
* Make a request to the payment API
*
* @param method - HTTP method
* @param endpoint - API endpoint
* @param data - Request payload
* @param options - Request options
* @returns API response
*/
public async requestPayment<T>(
method: 'GET' | 'POST',
endpoint: string,
data: Record<string, any> = {},
options: RequestOptions = {}
): Promise<ApiResponse<T>> {
return this.request(method, endpoint, data, this.paymentKey, options);
}
/**
* Make a request to the payout API
*
* @param method - HTTP method
* @param endpoint - API endpoint
* @param data - Request payload
* @param options - Request options
* @returns API response
* @throws Error if payout key is not provided
*/
public async requestPayout<T>(
method: 'GET' | 'POST',
endpoint: string,
data: Record<string, any> = {},
options: RequestOptions = {}
): Promise<ApiResponse<T>> {
if (!this.payoutKey) {
throw new Error('Payout key is required for payout operations');
}
return this.request(method, endpoint, data, this.payoutKey, options);
}
/**
* Make a request to the API
*
* @param method - HTTP method
* @param endpoint - API endpoint
* @param data - Request payload
* @param apiKey - API key
* @param options - Request options
* @returns API response
* @throws CryptomusError with API error message
*/
private async request<T>(
method: 'GET' | 'POST',
endpoint: string,
data: Record<string, any> = {},
apiKey: string,
options: RequestOptions = {}
): Promise<ApiResponse<T>> {
const payload = method === 'GET' ? {} : data;
const sign = generateSignature(payload, apiKey);
const config: AxiosRequestConfig = {
method,
url: endpoint,
headers: {
...options.headers,
'merchant': this.merchantId,
'sign': sign
},
timeout: options.timeout
};
if (method === 'GET') {
config.params = data;
} else {
config.data = payload;
}
try {
const response = await this.httpClient.request(config);
return response.data as ApiResponse<T>;
} catch (error: unknown) {
if (axios.isAxiosError(error) && error.response) {
const axiosError = error as AxiosError;
const errorResponse = axiosError.response?.data as ApiErrorResponse;
throw new CryptomusError(
errorResponse.message || 'API request failed',
errorResponse.errors,
axiosError.response?.status
);
}
// Re-throw any other errors
if (error instanceof Error) {
throw new CryptomusError(error.message);
} else {
throw new CryptomusError('Unknown error occurred');
}
}
}
}