Overview
The Devdraft C# SDK provides a complete client library for integrating payment processing, customer management, and webhook functionality into your .NET applications.
Async/Await Full async/await support for modern .NET applications
Dependency Injection Built-in support for Microsoft.Extensions.DependencyInjection
Type-Safe Strong typing with generics and nullable reference types
Resilience Polly integration for retry policies and circuit breakers
Installation
Using NuGet Package Manager
dotnet add package Devdraft
Or via Package Manager Console:
Or add to your .csproj file:
< ItemGroup >
< PackageReference Include = "Devdraft" Version = "1.0.0" />
</ ItemGroup >
Requirements
.NET Standard 2.0 or higher
.NET Core 3.1+ / .NET 5+ / .NET 6+ recommended
Quick Start
using Microsoft . Extensions . Hosting ;
using Microsoft . Extensions . DependencyInjection ;
using Devdraft . Api ;
using Devdraft . Client ;
using Devdraft . Model ;
namespace YourApp
{
class Program
{
static async Task Main ( string [] args )
{
var host = CreateHostBuilder ( args ). Build ();
// Get API instance from DI container
var transfersApi = host . Services . GetRequiredService < ITransfersApi >();
// Create a transfer
var transferDto = new CreateDirectWalletTransferDto (
walletId : "your-wallet-id" ,
network : "solana" ,
stableCoinCurrency : "usdc" ,
amount : 100.00m
);
var response = await transfersApi . TransferControllerCreateDirectWalletTransferAsync ( transferDto );
var transfer = response . Ok ();
Console . WriteLine ( $"Transfer created: { transfer . Id }" );
}
static IHostBuilder CreateHostBuilder ( string [] args ) =>
Host . CreateDefaultBuilder ( args )
. ConfigureApi (( context , services , options ) =>
{
// Configure API keys
var clientKey = new ApiKeyToken ( "x-client-key" ,
Environment . GetEnvironmentVariable ( "DEVDRAFT_CLIENT_KEY" ));
var clientSecret = new ApiKeyToken ( "x-client-secret" ,
Environment . GetEnvironmentVariable ( "DEVDRAFT_CLIENT_SECRET" ));
options . AddTokens ( clientKey , clientSecret );
// Configure HTTP client with resilience policies
options . AddApiHttpClients ( builder =>
{
builder
. AddRetryPolicy ( 3 )
. AddTimeoutPolicy ( TimeSpan . FromSeconds ( 30 ))
. AddCircuitBreakerPolicy ( 10 , TimeSpan . FromSeconds ( 30 ));
});
});
}
}
API Interfaces
The SDK is organized into API interfaces, each handling a specific domain:
API Interface Description IAPIHealthApi Service health checks and status monitoring IAppBalancesApi Query application balances across stablecoins ICustomersApi Customer management and KYC operations IExchangeRatesApi Real-time currency exchange rates IInvoicesApi Invoice creation and management ILiquidationAddressesApi Cryptocurrency liquidation addresses IPaymentIntentsApi Payment intent creation for bank and stablecoin IPaymentLinksApi Generate and manage payment links IProductsApi Product catalog management ITaxesApi Tax configuration and management ITestPaymentsApi Test payment processing in sandbox ITransfersApi Initiate and manage fund transfers IWalletsApi Wallet management and balances IWebhooksApi Webhook configuration and management
API Health
Monitor service health and availability.
Methods
HealthControllerCheckV0Async()
Authenticated health check endpoint requiring API credentials.
using Devdraft . Api ;
using Microsoft . Extensions . DependencyInjection ;
// Inject the API
var healthApi = host . Services . GetRequiredService < IAPIHealthApi >();
try
{
var response = await healthApi . HealthControllerCheckV0Async ();
Console . WriteLine ( "Service is healthy and authenticated" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Health check failed: { ex . Message }" );
}
Returns: Task<IHealthControllerCheckV0ApiResponse>
HealthControllerPublicHealthCheckV0Async()
Public health check endpoint (no authentication required).
var response = await healthApi . HealthControllerPublicHealthCheckV0Async ();
var status = response . Ok ();
Console . WriteLine ( $"Service status: { status . Status }" );
Returns: Task<IHealthControllerPublicHealthCheckV0ApiResponse>
App Balances
Query your application’s stablecoin balances.
Methods
BalanceControllerGetAllBalancesAsync()
Get all stablecoin balances for your application.
using Devdraft . Api ;
using Microsoft . Extensions . DependencyInjection ;
var balancesApi = host . Services . GetRequiredService < IAppBalancesApi >();
try
{
var response = await balancesApi . BalanceControllerGetAllBalancesAsync ();
var balances = response . Ok ();
Console . WriteLine ( $"USDC Balance: { balances . Usdc }" );
Console . WriteLine ( $"EURC Balance: { balances . Eurc }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Returns: Task<IBalanceControllerGetAllBalancesApiResponse>
BalanceControllerGetUSDCBalanceAsync()
Get USDC balance only.
var response = await balancesApi . BalanceControllerGetUSDCBalanceAsync ();
var usdcBalance = response . Ok ();
Console . WriteLine ( $"USDC: { usdcBalance . Amount }" );
Returns: Task<IBalanceControllerGetUSDCBalanceApiResponse>
BalanceControllerGetEURCBalanceAsync()
Get EURC balance only.
var response = await balancesApi . BalanceControllerGetEURCBalanceAsync ();
var eurcBalance = response . Ok ();
Console . WriteLine ( $"EURC: { eurcBalance . Amount }" );
Returns: Task<IBalanceControllerGetEURCBalanceApiResponse>
Customers
Manage customer records and KYC information.
Methods
CustomerControllerCreateAsync(createCustomerDto)
Create a new customer.
using Devdraft . Api ;
using Devdraft . Model ;
using Microsoft . Extensions . DependencyInjection ;
var customersApi = host . Services . GetRequiredService < ICustomersApi >();
try
{
var customerDto = new CreateCustomerDto (
firstName : "John" ,
lastName : "Doe" ,
email : "john.doe@example.com" ,
type : CustomerType . INDIVIDUAL ,
country : "US"
);
var response = await customersApi . CustomerControllerCreateAsync ( customerDto );
var customer = response . Ok ();
Console . WriteLine ( $"Customer created: { customer . Id }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Parameters:
createCustomerDto: CreateCustomerDto - Customer details
Returns: Task<ICustomerControllerCreateApiResponse>
CustomerControllerFindAllAsync(page, limit, status)
Get all customers with optional filters.
var response = await customersApi . CustomerControllerFindAllAsync (
page : 1 ,
limit : 20 ,
status : "ACTIVE"
);
var customers = response . Ok ();
foreach ( var customer in customers )
{
Console . WriteLine ( $"{ customer . FirstName } { customer . LastName } - { customer . Email }" );
}
Parameters:
page: int? - Page number (optional, default: 1)
limit: int? - Items per page (optional, default: 20)
status: string? - Filter by status (optional)
Returns: Task<ICustomerControllerFindAllApiResponse>
CustomerControllerFindOneAsync(id)
Get a customer by ID.
var response = await customersApi . CustomerControllerFindOneAsync ( "customer-id-here" );
var customer = response . Ok ();
Console . WriteLine ( $"Customer: { customer . FirstName } { customer . LastName }" );
Parameters:
Returns: Task<ICustomerControllerFindOneApiResponse>
CustomerControllerUpdateAsync(id, updateCustomerDto)
Update a customer’s information.
var updateDto = new UpdateCustomerDto
{
Phone = "+1234567890" ,
Address = "123 Main St"
};
var response = await customersApi . CustomerControllerUpdateAsync ( "customer-id-here" , updateDto );
var updated = response . Ok ();
Console . WriteLine ( $"Customer updated: { updated . Id }" );
Parameters:
id: string - Customer ID
updateCustomerDto: UpdateCustomerDto - Fields to update
Returns: Task<ICustomerControllerUpdateApiResponse>
Exchange Rates
Get real-time currency exchange rates.
Methods
ExchangeRateControllerGetExchangeRateAsync(from, to)
Get exchange rate between any two supported currencies.
using Devdraft . Api ;
using Microsoft . Extensions . DependencyInjection ;
var ratesApi = host . Services . GetRequiredService < IExchangeRatesApi >();
try
{
var response = await ratesApi . ExchangeRateControllerGetExchangeRateAsync (
varFrom : "USD" ,
to : "EUR"
);
var rate = response . Ok ();
Console . WriteLine ( $"1 USD = { rate . Rate } EUR" );
Console . WriteLine ( $"Rate expires at: { rate . ExpiresAt }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Parameters:
varFrom: string? - Source currency code
to: string? - Target currency code
Returns: Task<IExchangeRateControllerGetExchangeRateApiResponse>
ExchangeRateControllerGetUSDToEURRateAsync()
Get USD to EUR exchange rate.
var response = await ratesApi . ExchangeRateControllerGetUSDToEURRateAsync ();
var usdToEur = response . Ok ();
Console . WriteLine ( $"USD to EUR: { usdToEur . Rate }" );
Returns: Task<IExchangeRateControllerGetUSDToEURRateApiResponse>
ExchangeRateControllerGetEURToUSDRateAsync()
Get EUR to USD exchange rate.
var response = await ratesApi . ExchangeRateControllerGetEURToUSDRateAsync ();
var eurToUsd = response . Ok ();
Console . WriteLine ( $"EUR to USD: { eurToUsd . Rate }" );
Returns: Task<IExchangeRateControllerGetEURToUSDRateApiResponse>
Invoices
Create and manage invoices for your customers.
Methods
InvoiceControllerCreateAsync(createInvoiceDto)
Create a new invoice.
using Devdraft . Api ;
using Devdraft . Model ;
using Microsoft . Extensions . DependencyInjection ;
var invoicesApi = host . Services . GetRequiredService < IInvoicesApi >();
try
{
var invoiceDto = new CreateInvoiceDto (
customerId : "customer-id" ,
items : new List < InvoiceProductDto >
{
new InvoiceProductDto (
description : "Premium Subscription" ,
quantity : 1 ,
price : 99.99m ,
currency : "USD"
)
},
dueDate : DateTime . Parse ( "2024-12-31" )
);
var response = await invoicesApi . InvoiceControllerCreateAsync ( invoiceDto );
var invoice = response . Ok ();
Console . WriteLine ( $"Invoice created: { invoice . Id }" );
Console . WriteLine ( $"Total: { invoice . Total }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Parameters:
createInvoiceDto: CreateInvoiceDto - Invoice details
Returns: Task<IInvoiceControllerCreateApiResponse>
InvoiceControllerFindAllAsync(page, limit, status)
Get all invoices.
var response = await invoicesApi . InvoiceControllerFindAllAsync (
page : 1 ,
limit : 50 ,
status : "UNPAID"
);
var invoices = response . Ok ();
foreach ( var invoice in invoices )
{
Console . WriteLine ( $"Invoice { invoice . Id }: { invoice . Total }" );
}
Parameters:
page: int? - Page number (optional)
limit: int? - Items per page (optional)
status: string? - Filter by status (optional)
Returns: Task<IInvoiceControllerFindAllApiResponse>
InvoiceControllerFindOneAsync(id)
Get an invoice by ID.
var response = await invoicesApi . InvoiceControllerFindOneAsync ( "invoice-id" );
var invoice = response . Ok ();
Console . WriteLine ( $"Invoice total: { invoice . Total }" );
Parameters:
Returns: Task<IInvoiceControllerFindOneApiResponse>
InvoiceControllerUpdateAsync(id, updateInvoiceDto)
Update an invoice.
var updateDto = new UpdateInvoiceDto
{
Status = "PAID" ,
PaidAt = DateTime . UtcNow
};
var response = await invoicesApi . InvoiceControllerUpdateAsync ( "invoice-id" , updateDto );
var updated = response . Ok ();
Console . WriteLine ( $"Invoice updated: { updated . Id }" );
Parameters:
id: string - Invoice ID
updateInvoiceDto: UpdateInvoiceDto - Fields to update
Returns: Task<IInvoiceControllerUpdateApiResponse>
Liquidation Addresses
Manage cryptocurrency liquidation addresses for customers.
Methods
LiquidationAddressControllerCreateLiquidationAddressAsync(customerId, createLiquidationAddressDto)
Create a new liquidation address for a customer.
using Devdraft . Api ;
using Devdraft . Model ;
using Microsoft . Extensions . DependencyInjection ;
var liquidationApi = host . Services . GetRequiredService < ILiquidationAddressesApi >();
try
{
var addressDto = new CreateLiquidationAddressDto (
network : "solana" ,
currency : "usdc"
);
var response = await liquidationApi . LiquidationAddressControllerCreateLiquidationAddressAsync (
customerId : "customer-id" ,
createLiquidationAddressDto : addressDto
);
var address = response . Ok ();
Console . WriteLine ( $"Liquidation address: { address . Address }" );
Console . WriteLine ( $"Network: { address . Network }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Parameters:
customerId: string - Customer ID
createLiquidationAddressDto: CreateLiquidationAddressDto - Address details
Returns: Task<ILiquidationAddressControllerCreateLiquidationAddressApiResponse>
LiquidationAddressControllerGetLiquidationAddressesAsync(customerId)
Get all liquidation addresses for a customer.
var response = await liquidationApi . LiquidationAddressControllerGetLiquidationAddressesAsync ( "customer-id" );
var addresses = response . Ok ();
foreach ( var addr in addresses )
{
Console . WriteLine ( $"{ addr . Network }: { addr . Address }" );
}
Parameters:
customerId: string - Customer ID
Returns: Task<ILiquidationAddressControllerGetLiquidationAddressesApiResponse>
LiquidationAddressControllerGetLiquidationAddressAsync(customerId, liquidationAddressId)
Get a specific liquidation address.
var response = await liquidationApi . LiquidationAddressControllerGetLiquidationAddressAsync (
customerId : "customer-id" ,
liquidationAddressId : "address-id"
);
var address = response . Ok ();
Console . WriteLine ( $"Address: { address . Address }" );
Parameters:
customerId: string - Customer ID
liquidationAddressId: string - Address ID
Returns: Task<ILiquidationAddressControllerGetLiquidationAddressApiResponse>
Payment Intents
Create payment intents for bank and stablecoin payments.
Methods
PaymentIntentControllerCreateBankPaymentIntentAsync(createBankPaymentIntentDto)
Create a bank payment intent.
using Devdraft . Api ;
using Devdraft . Model ;
using Microsoft . Extensions . DependencyInjection ;
var intentApi = host . Services . GetRequiredService < IPaymentIntentsApi >();
try
{
var intentDto = new CreateBankPaymentIntentDto (
customerId : "customer-id" ,
amount : 1000.00m ,
currency : "USD" ,
paymentRail : "wire"
);
var response = await intentApi . PaymentIntentControllerCreateBankPaymentIntentAsync ( intentDto );
var intent = response . Ok ();
Console . WriteLine ( $"Payment intent: { intent . Id }" );
Console . WriteLine ( $"Status: { intent . Status }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Parameters:
createBankPaymentIntentDto: CreateBankPaymentIntentDto - Intent details
Returns: Task<IPaymentIntentControllerCreateBankPaymentIntentApiResponse>
PaymentIntentControllerCreateStablePaymentIntentAsync(createStablePaymentIntentDto)
Create a stablecoin payment intent.
var stableIntentDto = new CreateStablePaymentIntentDto (
customerId : "customer-id" ,
amount : 500.00m ,
currency : "usdc" ,
network : "solana"
);
var response = await intentApi . PaymentIntentControllerCreateStablePaymentIntentAsync ( stableIntentDto );
var stableIntent = response . Ok ();
Console . WriteLine ( $"Stable intent: { stableIntent . Id }" );
Parameters:
createStablePaymentIntentDto: CreateStablePaymentIntentDto - Intent details
Returns: Task<IPaymentIntentControllerCreateStablePaymentIntentApiResponse>
Payment Links
Generate and manage payment links for easy customer payments.
Methods
PaymentLinksControllerCreateAsync(createPaymentLinkDto)
Create a new payment link.
using Devdraft . Api ;
using Devdraft . Model ;
using Microsoft . Extensions . DependencyInjection ;
var linksApi = host . Services . GetRequiredService < IPaymentLinksApi >();
try
{
var linkDto = new CreatePaymentLinkDto (
name : "Product Purchase" ,
amount : 99.99m ,
currency : "USD" ,
products : new List < PaymentLinkProductDto >
{
new PaymentLinkProductDto (
name : "Premium Plan" ,
quantity : 1 ,
price : 99.99m
)
}
);
var response = await linksApi . PaymentLinksControllerCreateAsync ( linkDto );
var link = response . Ok ();
Console . WriteLine ( $"Payment link: { link . Url }" );
Console . WriteLine ( $"Share this link with customers: { link . ShortUrl }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Parameters:
createPaymentLinkDto: CreatePaymentLinkDto - Link details
Returns: Task<IPaymentLinksControllerCreateApiResponse>
PaymentLinksControllerFindAllAsync(page, limit, active)
Get all payment links.
var response = await linksApi . PaymentLinksControllerFindAllAsync (
page : 1 ,
limit : 20 ,
active : true
);
var links = response . Ok ();
foreach ( var link in links )
{
Console . WriteLine ( $"{ link . Name }: { link . Url }" );
}
Parameters:
page: int? - Page number (optional)
limit: int? - Items per page (optional)
active: bool? - Filter by active status (optional)
Returns: Task<IPaymentLinksControllerFindAllApiResponse>
PaymentLinksControllerFindOneAsync(id)
Get a payment link by ID.
var response = await linksApi . PaymentLinksControllerFindOneAsync ( "link-id" );
var link = response . Ok ();
Console . WriteLine ( $"Link: { link . Url }" );
Parameters:
id: string - Payment link ID
Returns: Task<IPaymentLinksControllerFindOneApiResponse>
PaymentLinksControllerUpdateAsync(id, updatePaymentLinkDto)
Update a payment link.
var updateDto = new UpdatePaymentLinkDto
{
Active = false ,
ExpiresAt = DateTime . Parse ( "2024-12-31T23:59:59Z" )
};
var response = await linksApi . PaymentLinksControllerUpdateAsync ( "link-id" , updateDto );
var updated = response . Ok ();
Console . WriteLine ( $"Link updated: { updated . Id }" );
Parameters:
id: string - Payment link ID
updatePaymentLinkDto: UpdatePaymentLinkDto - Fields to update
Returns: Task<IPaymentLinksControllerUpdateApiResponse>
Transfers
Initiate and manage fund transfers between different payment rails.
Methods
TransferControllerCreateDirectBankTransferAsync(createDirectBankTransferDto)
Create a direct bank transfer.
using Devdraft . Api ;
using Devdraft . Model ;
using Microsoft . Extensions . DependencyInjection ;
var transfersApi = host . Services . GetRequiredService < ITransfersApi >();
try
{
var transferDto = new CreateDirectBankTransferDto (
walletId : "wallet-id" ,
paymentRail : "wire" ,
sourceCurrency : "usd" ,
destinationCurrency : "usdc" ,
amount : 1000.00m
);
var response = await transfersApi . TransferControllerCreateDirectBankTransferAsync ( transferDto );
var transfer = response . Ok ();
Console . WriteLine ( $"Transfer created: { transfer . Id }" );
Console . WriteLine ( $"Bank instructions: { transfer . SourceDepositInstructions }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Parameters:
createDirectBankTransferDto: CreateDirectBankTransferDto - Transfer details
Returns: Task<ITransferControllerCreateDirectBankTransferApiResponse>
See also: Direct Bank Transfer Guide
TransferControllerCreateDirectWalletTransferAsync(createDirectWalletTransferDto)
Create a direct wallet transfer.
var transferDto = new CreateDirectWalletTransferDto (
walletId : "wallet-id" ,
network : "solana" ,
stableCoinCurrency : "usdc" ,
amount : 500.00m
);
var response = await transfersApi . TransferControllerCreateDirectWalletTransferAsync ( transferDto );
var transfer = response . Ok ();
Console . WriteLine ( $"Transfer created: { transfer . Id }" );
Console . WriteLine ( $"Deposit address: { transfer . SourceDepositInstructions . ToAddress }" );
Parameters:
createDirectWalletTransferDto: CreateDirectWalletTransferDto - Transfer details
Returns: Task<ITransferControllerCreateDirectWalletTransferApiResponse>
See also: Direct Wallet Transfer Guide
TransferControllerCreateExternalBankTransferAsync(createExternalBankTransferDto)
Create an external bank transfer (from your wallet to external bank).
var transferDto = new CreateExternalBankTransferDto (
sourceWalletId : "wallet-id" ,
destinationBankAccountId : "bank-account-id" ,
amount : 1000.00m ,
currency : "USD"
);
var response = await transfersApi . TransferControllerCreateExternalBankTransferAsync ( transferDto );
var transfer = response . Ok ();
Console . WriteLine ( $"External bank transfer: { transfer . Id }" );
Parameters:
createExternalBankTransferDto: CreateExternalBankTransferDto - Transfer details
Returns: Task<ITransferControllerCreateExternalBankTransferApiResponse>
TransferControllerCreateExternalStablecoinTransferAsync(createExternalStablecoinTransferDto)
Create an external stablecoin transfer (from your wallet to external wallet).
var transferDto = new CreateExternalStablecoinTransferDto (
sourceWalletId : "wallet-id" ,
destinationAddress : "0x742d35Cc6Ff82a8C2D8D1Da9da17c7eDfD5bE0a3" ,
network : "ethereum" ,
currency : "usdc" ,
amount : 250.00m
);
var response = await transfersApi . TransferControllerCreateExternalStablecoinTransferAsync ( transferDto );
var transfer = response . Ok ();
Console . WriteLine ( $"External stablecoin transfer: { transfer . Id }" );
Parameters:
createExternalStablecoinTransferDto: CreateExternalStablecoinTransferDto - Transfer details
Returns: Task<ITransferControllerCreateExternalStablecoinTransferApiResponse>
TransferControllerCreateStablecoinConversionAsync(createStablecoinConversionDto)
Convert between different stablecoins or networks.
var conversionDto = new CreateStablecoinConversionDto (
sourceWalletId : "wallet-id" ,
destinationWalletId : "wallet-id" ,
sourceNetwork : "ethereum" ,
destinationNetwork : "solana" ,
sourceCurrency : "usdc" ,
destinationCurrency : "usdc" ,
amount : 1000.00m
);
var response = await transfersApi . TransferControllerCreateStablecoinConversionAsync ( conversionDto );
var conversion = response . Ok ();
Console . WriteLine ( $"Conversion ID: { conversion . Id }" );
Console . WriteLine ( $"Exchange rate: { conversion . ExchangeRate . Rate }" );
Console . WriteLine ( $"Estimated completion: { conversion . EstimatedCompletion }" );
Parameters:
createStablecoinConversionDto: CreateStablecoinConversionDto - Conversion details
Returns: Task<ITransferControllerCreateStablecoinConversionApiResponse>
See also: Stablecoin Conversion Guide
Wallets
Manage wallets and query balances.
Methods
WalletControllerGetWalletsAsync()
Get all wallets for your application.
using Devdraft . Api ;
using Microsoft . Extensions . DependencyInjection ;
var walletsApi = host . Services . GetRequiredService < IWalletsApi >();
try
{
var response = await walletsApi . WalletControllerGetWalletsAsync ();
Console . WriteLine ( "Wallets retrieved successfully" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Returns: Task<IWalletControllerGetWalletsApiResponse>
The response contains wallet IDs that you can use for transfers and other operations. In a future SDK version, this will return typed wallet objects.
Webhooks
Configure webhooks to receive real-time event notifications.
Methods
WebhookControllerCreateAsync(createWebhookDto)
Create a new webhook.
using Devdraft . Api ;
using Devdraft . Model ;
using Microsoft . Extensions . DependencyInjection ;
var webhooksApi = host . Services . GetRequiredService < IWebhooksApi >();
try
{
var webhookDto = new CreateWebhookDto (
url : "https://your-app.com/webhooks/devdraft" ,
name : "Production Webhook" ,
isActive : true ,
encrypted : false
);
var response = await webhooksApi . WebhookControllerCreateAsync ( webhookDto );
var webhook = response . Ok ();
Console . WriteLine ( $"Webhook ID: { webhook . Id }" );
Console . WriteLine ( $"Signing secret: { webhook . SigningSecret }" );
}
catch ( ApiException ex )
{
Console . WriteLine ( $"Error: { ex . Message }" );
}
Parameters:
createWebhookDto: CreateWebhookDto - Webhook configuration
Returns: Task<IWebhookControllerCreateApiResponse>
See also: Webhooks Overview
WebhookControllerFindAllAsync(page, limit, active)
Get all webhooks.
var response = await webhooksApi . WebhookControllerFindAllAsync (
page : 1 ,
limit : 20 ,
active : true
);
var webhooks = response . Ok ();
foreach ( var webhook in webhooks )
{
Console . WriteLine ( $"{ webhook . Name }: { webhook . Url }" );
Console . WriteLine ( $"Active: { webhook . IsActive }" );
}
Parameters:
page: int? - Page number (optional)
limit: int? - Items per page (optional)
active: bool? - Filter by active status (optional)
Returns: Task<IWebhookControllerFindAllApiResponse>
WebhookControllerFindOneAsync(id)
Get a webhook by ID.
var response = await webhooksApi . WebhookControllerFindOneAsync ( "webhook-id" );
var webhook = response . Ok ();
Console . WriteLine ( $"Webhook: { webhook . Name }" );
Console . WriteLine ( $"URL: { webhook . Url }" );
Console . WriteLine ( $"Delivery stats: { webhook . DeliveryStats }" );
Parameters:
Returns: Task<IWebhookControllerFindOneApiResponse>
WebhookControllerUpdateAsync(id, updateWebhookDto)
Update a webhook.
var updateDto = new UpdateWebhookDto
{
Url = "https://your-app.com/webhooks/new-endpoint" ,
IsActive = true
};
var response = await webhooksApi . WebhookControllerUpdateAsync ( "webhook-id" , updateDto );
var updated = response . Ok ();
Console . WriteLine ( $"Webhook updated: { updated . Id }" );
Parameters:
id: string - Webhook ID
updateWebhookDto: UpdateWebhookDto - Fields to update
Returns: Task<IWebhookControllerUpdateApiResponse>
WebhookControllerRemoveAsync(id)
Delete a webhook.
var response = await webhooksApi . WebhookControllerRemoveAsync ( "webhook-id" );
Console . WriteLine ( "Webhook deleted" );
Parameters:
Returns: Task<IWebhookControllerRemoveApiResponse>
Error Handling
All SDK methods return API response objects. Handle errors appropriately:
using Devdraft . Client ;
try
{
var response = await transfersApi . TransferControllerCreateDirectWalletTransferAsync ( transferDto );
// Check if response is successful
if ( response . IsOk )
{
var transfer = response . Ok ();
Console . WriteLine ( $"Transfer created: { transfer . Id }" );
}
else
{
// Handle specific status codes
switch ( response . StatusCode )
{
case 400 :
Console . WriteLine ( $"Invalid request: { response . ReasonPhrase }" );
break ;
case 401 :
Console . WriteLine ( "Authentication failed - check your API credentials" );
break ;
case 404 :
Console . WriteLine ( $"Resource not found: { response . ReasonPhrase }" );
break ;
case 422 :
Console . WriteLine ( $"Validation error: { response . ReasonPhrase }" );
break ;
case 429 :
Console . WriteLine ( "Rate limited - please retry later" );
break ;
default :
Console . WriteLine ( $"API error ({ response . StatusCode }): { response . ReasonPhrase }" );
break ;
}
}
}
catch ( ApiException ex )
{
Console . WriteLine ( $"API Exception: { ex . Message }" );
Console . WriteLine ( $"Status Code: { ex . StatusCode }" );
Console . WriteLine ( $"Response: { ex . ResponseBody }" );
}
catch ( Exception ex )
{
Console . WriteLine ( $"Unexpected error: { ex . Message }" );
}
Best Practices
Use Dependency Injection
Leverage .NET’s built-in DI container for better testability and maintainability. // In Startup.cs or Program.cs
public void ConfigureServices ( IServiceCollection services )
{
services . ConfigureApi (( context , options ) =>
{
var clientKey = new ApiKeyToken ( "x-client-key" ,
Configuration [ "Devdraft:ClientKey" ]);
var clientSecret = new ApiKeyToken ( "x-client-secret" ,
Configuration [ "Devdraft:ClientSecret" ]);
options . AddTokens ( clientKey , clientSecret );
});
}
// In your controller or service
public class PaymentService
{
private readonly ITransfersApi _transfersApi ;
public PaymentService ( ITransfersApi transfersApi )
{
_transfersApi = transfersApi ;
}
public async Task < string > CreateTransferAsync ( decimal amount )
{
var dto = new CreateDirectWalletTransferDto (
walletId : "wallet-id" ,
network : "solana" ,
stableCoinCurrency : "usdc" ,
amount : amount
);
var response = await _transfersApi . TransferControllerCreateDirectWalletTransferAsync ( dto );
var transfer = response . Ok ();
return transfer . Id ;
}
}
Configure Resilience Policies
Use Polly policies for retry, timeout, and circuit breaker patterns. Host . CreateDefaultBuilder ( args )
. ConfigureApi (( context , services , options ) =>
{
options . AddApiHttpClients ( builder =>
{
builder
. AddRetryPolicy ( 3 ) // Retry 3 times
. AddTimeoutPolicy ( TimeSpan . FromSeconds ( 30 )) // 30 second timeout
. AddCircuitBreakerPolicy ( 10 , TimeSpan . FromSeconds ( 30 )); // Break after 10 failures
});
});
Use Async/Await Properly
Always await async methods and don’t block on async code. // Bad: Blocking on async code
var result = api . SomeMethodAsync (). Result ; // DON'T DO THIS
// Good: Proper async/await
var response = await api . SomeMethodAsync ();
var result = response . Ok ();
Handle Nullable Types
Use nullable reference types and check for null values. #nullable enable
public async Task ProcessCustomerAsync ( string ? customerId )
{
if ( string . IsNullOrEmpty ( customerId ))
{
throw new ArgumentException ( "Customer ID is required" , nameof ( customerId ));
}
var response = await customersApi . CustomerControllerFindOneAsync ( customerId );
var customer = response . Ok ();
// Check for null before accessing properties
if ( customer ? . Email != null )
{
Console . WriteLine ( $"Email: { customer . Email }" );
}
}
Use Configuration for Credentials
Store credentials in appsettings.json or environment variables. // appsettings.json
{
"Devdraft" : {
"ClientKey" : "your-client-key" ,
"ClientSecret" : "your-client-secret" ,
"ApiUrl" : "https://api.devdraft.ai"
}
}
// Configuration
services . ConfigureApi (( context , options ) =>
{
var config = context . Configuration ;
var clientKey = new ApiKeyToken ( "x-client-key" ,
config [ "Devdraft:ClientKey" ]);
var clientSecret = new ApiKeyToken ( "x-client-secret" ,
config [ "Devdraft:ClientSecret" ]);
options . AddTokens ( clientKey , clientSecret );
});
Implement Structured Logging
Use ILogger for structured logging. public class PaymentService
{
private readonly ITransfersApi _transfersApi ;
private readonly ILogger < PaymentService > _logger ;
public PaymentService ( ITransfersApi transfersApi , ILogger < PaymentService > logger )
{
_transfersApi = transfersApi ;
_logger = logger ;
}
public async Task < string > CreateTransferAsync ( decimal amount )
{
_logger . LogInformation ( "Creating transfer for amount {Amount}" , amount );
try
{
var dto = new CreateDirectWalletTransferDto (
walletId : "wallet-id" ,
network : "solana" ,
stableCoinCurrency : "usdc" ,
amount : amount
);
var response = await _transfersApi . TransferControllerCreateDirectWalletTransferAsync ( dto );
var transfer = response . Ok ();
_logger . LogInformation ( "Transfer created successfully with ID {TransferId}" , transfer . Id );
return transfer . Id ;
}
catch ( ApiException ex )
{
_logger . LogError ( ex , "Failed to create transfer. Status: {StatusCode}" , ex . StatusCode );
throw ;
}
}
}
Testing with xUnit
Example xUnit test for SDK integration:
using Xunit ;
using Moq ;
using Devdraft . Api ;
using Devdraft . Model ;
using Devdraft . Client ;
public class WebhookServiceTests
{
private readonly Mock < IWebhooksApi > _mockWebhooksApi ;
private readonly WebhookService _service ;
public WebhookServiceTests ()
{
_mockWebhooksApi = new Mock < IWebhooksApi >();
_service = new WebhookService ( _mockWebhooksApi . Object );
}
[ Fact ]
public async Task CreateWebhook_ReturnsWebhookId ()
{
// Arrange
var webhookDto = new CreateWebhookDto (
url : "https://test.example.com/webhook" ,
name : "Test Webhook" ,
isActive : true ,
encrypted : false
);
var expectedWebhook = new WebhookResponseDto
{
Id = "webhook-123" ,
Name = "Test Webhook" ,
IsActive = true
};
var mockResponse = new Mock < IWebhookControllerCreateApiResponse >();
mockResponse . Setup ( r => r . Ok ()). Returns ( expectedWebhook );
mockResponse . Setup ( r => r . IsOk ). Returns ( true );
_mockWebhooksApi
. Setup ( api => api . WebhookControllerCreateAsync ( It . IsAny < CreateWebhookDto >(), default ))
. ReturnsAsync ( mockResponse . Object );
// Act
var result = await _service . CreateWebhookAsync ( webhookDto );
// Assert
Assert . Equal ( "webhook-123" , result );
_mockWebhooksApi . Verify ( api =>
api . WebhookControllerCreateAsync ( It . IsAny < CreateWebhookDto >(), default ),
Times . Once );
}
[ Fact ]
public async Task CreateWebhook_ThrowsException_OnApiError ()
{
// Arrange
var webhookDto = new CreateWebhookDto (
url : "invalid-url" ,
name : "Invalid Webhook" ,
isActive : true ,
encrypted : false
);
_mockWebhooksApi
. Setup ( api => api . WebhookControllerCreateAsync ( It . IsAny < CreateWebhookDto >(), default ))
. ThrowsAsync ( new ApiException ( 400 , "Invalid URL" ));
// Act & Assert
await Assert . ThrowsAsync < ApiException >(() =>
_service . CreateWebhookAsync ( webhookDto ));
}
}
ASP.NET Core Integration
Example ASP.NET Core controller using the SDK:
using Microsoft . AspNetCore . Mvc ;
using Devdraft . Api ;
using Devdraft . Model ;
using Devdraft . Client ;
namespace YourApp . Controllers
{
[ ApiController ]
[ Route ( "api/[controller]" )]
public class TransfersController : ControllerBase
{
private readonly ITransfersApi _transfersApi ;
private readonly ILogger < TransfersController > _logger ;
public TransfersController (
ITransfersApi transfersApi ,
ILogger < TransfersController > logger )
{
_transfersApi = transfersApi ;
_logger = logger ;
}
[ HttpPost ]
public async Task < IActionResult > CreateTransfer ([ FromBody ] CreateTransferRequest request )
{
try
{
var transferDto = new CreateDirectWalletTransferDto (
walletId : request . WalletId ,
network : request . Network ,
stableCoinCurrency : request . Currency ,
amount : request . Amount
);
var response = await _transfersApi . TransferControllerCreateDirectWalletTransferAsync (
transferDto ,
HttpContext . RequestAborted
);
if ( ! response . IsOk )
{
return StatusCode (
( int ) response . StatusCode ,
new { error = response . ReasonPhrase }
);
}
var transfer = response . Ok ();
return Ok ( new
{
transferId = transfer . Id ,
depositAddress = transfer . SourceDepositInstructions ? . ToAddress
});
}
catch ( ApiException ex )
{
_logger . LogError ( ex , "API error creating transfer" );
return StatusCode (( int ) ex . StatusCode , new { error = ex . Message });
}
catch ( Exception ex )
{
_logger . LogError ( ex , "Unexpected error creating transfer" );
return StatusCode ( 500 , new { error = "Internal server error" });
}
}
}
public class CreateTransferRequest
{
public string WalletId { get ; set ; } = string . Empty ;
public string Network { get ; set ; } = "solana" ;
public string Currency { get ; set ; } = "usdc" ;
public decimal Amount { get ; set ; }
}
}
Next Steps
SDK Quickstart Complete integration guide with examples
Transfers Learn about initiating transfers
Webhooks Set up webhook notifications
API Reference Complete REST API documentation