SRS Integration SDK - .NET Library#
📦 Overview#
The SRS Integration SDK is a strongly-typed .NET library that simplifies integration with SRS Integration Partner Services (SIPS). Instead of making direct REST API calls, the SDK provides intuitive client libraries that handle authentication, serialization, error handling, and HTTP communication for you.🔐 Authentication Module - Secure credential exchange and token management
📦 Orders Module - Complete order lifecycle operations (submit, query, track)
✅ Strongly-Typed Models - IntelliSense support and compile-time validation
🔄 Dependency Injection Support - Native integration with .NET DI containers
📝 Comprehensive Error Handling - Structured exceptions and detailed error messages
Target Framework: .NET 6.0+
🎯 Why Use the SDK?#
Benefits Over Direct API Calls#
| Benefit | Description |
|---|
| 🎨 Strongly-Typed | IntelliSense support, compile-time checks, auto-completion |
| ⚡ Faster Development | Pre-built methods eliminate boilerplate HTTP code |
| 🔒 Built-in Token Management | Automatic bearer token handling |
| ✅ Type Safety | Catch errors at compile-time instead of runtime |
| 📚 Better Documentation | XML documentation built into the SDK |
| 🔄 Dependency Injection Ready | Native support for ASP.NET Core and modern .NET apps |
| 🎯 Less Error-Prone | Reduces manual JSON serialization mistakes |
| 🛠️ Easier Maintenance | SDK updates automatically include API changes |
Time Savings: Reduce integration time from weeks to days by eliminating HTTP plumbing code.
⚡ Quick Start#
Prerequisites#
✅ SRS API Credentials (client_id and client_secret)
✅ Access to SRS API endpoints (Staging or Production)
✅ Visual Studio 2022+ or VS Code with C# extension
✅ Azure Key Vault or secrets manager for credential storage
Installation#
📥 Download SDK Binary - Click to expand
SDK Package: Sdk.Lib.Crm.Srs.dll (Private Distribution)Download Location:
The SDK is distributed as a private binary. Contact SRS API Support to receive download credentials.SDK download requires your SRS API client_id and client_secret
Only registered partners can access the SDK
2.
Subject: "SDK Download Access Request"
3.
Include: Company name, client_id, environment (Staging/Production)
4.
Response time: 1-2 business days
1.
Download Sdk.Lib.Crm.Srs.dll using provided credentials
2.
Add DLL reference to your .NET project
3.
Restore dependencies (SDK references standard .NET packages)
Basic Setup#
🔧 Dependency Injection Setup (Recommended) - Click to expand
In your Program.cs or Startup.cs:Register SDK clients with your dependency injection container:Then inject clients into your services:🔧 Manual Setup (Alternative) - Click to expand
Create clients directly without DI:Best Practice: Use dependency injection for better testability and lifecycle management.
🏗️ SDK Architecture#
The SDK is organized into focused modules that align with SRS API functionality:Modules Overview#
🔐 Authentication Module - Click to expand
Purpose: Handles OAuth 2.0 client credentials flow and token managementAuthenticationClient - Main client for authentication operations
ExchangeTokenRequest - Request model for token exchange
ExchangeTokenResponse - Contains access token and expiration
ExchangeClientCredentialsAsync() - Get bearer token using client credentials
Automatic token serialization and error handling
Beginning of every API session
When access token expires (24-hour lifetime)
For service-to-service authentication
📦 Orders Module - Click to expand
Purpose: Complete order lifecycle managementOrdersClient - Main client for order operations
SubmitOrderRequest / SubmitOrderRequestV2 - Order submission models
SubmitOrderResponse - Order confirmation and ID
SubmitOrderAsync() - Submit order (V1 endpoint)
SubmitOrderV2Async() - Submit order (V2 endpoint - recommended)
GetCustomerBranchLocationsAsync() - Get branch locations for customer
GetActiveBranchProductsAsync() - Get products available at branch
GetPricingAsync() - Get real-time pricing for products
ValidateCustomerAsync() - Validate customer access
Product catalog integration
Branch and pricing queries
Order submission and tracking
🚀 Getting Started Guide#
Follow these steps to implement your first integration using the SDK. This workflow mirrors the 8-Step Integration Guide but uses SDK methods instead of direct REST calls.
Step 1: Setup & Configuration#
⚙️ Initialize SDK - Click to expand
| Environment | Base URL |
|---|
| Staging | https://services-qa.roofhub.pro |
| Production | https://services.roofhub.pro |
Register Services:
Use dependency injection to register SDK clients with environment-specific configuration:Best Practice: Store base URL in configuration files, not hardcoded.
Step 2: Authentication#
🔑 Get Access Token - Click to expand
Purpose: Obtain a bearer token to authenticate subsequent API calls.SDK Method: ExchangeClientCredentialsAsync()1.
Retrieve client_id and client_secret from secure storage (Azure Key Vault, etc.)
2.
Create ExchangeTokenRequest with credentials
3.
Call SDK authentication method
4.
Store returned bearer token for use in other API calls
✅ Always retrieve credentials from secrets manager (never hardcode)
✅ Token expires after 24 hours - implement refresh logic
✅ Reuse token for multiple requests (don't get new token per request)
❌ Never log or expose the client_secret
Secrets management system
Step 3: Customer Validation#
✅ Validate Customer - Click to expand
Purpose: Verify customer has API access and retrieve account details.SDK Method: ValidateCustomerAsync(customerCode, bearerToken)Confirms customer is registered with SRS
Returns validIndicator (true/false) for API access
Provides customer account information
Required before order submission
validIndicator - Boolean indicating API access
accountNumber - Customer account code
accountName - Customer business name
creditStatus - Credit standing information
What Happens:
✅ If validIndicator = true → Customer can place orders
❌ If validIndicator = false → Customer not eligible for API ordersBest Practice: Always validate customer before proceeding with order flow.
Step 4: Browse Branch Locations#
📍 Get Branch Locations - Click to expand
Purpose: Retrieve branches available to the customer and get jobAccountNumber.SDK Method: GetCustomerBranchLocationsAsync(customerCode, bearerToken)Critical Field: jobAccountNumber
→ Required for order submission - save this value!List of customer-specific branch locations
jobAccountNumber for each branch
shipToSequenceNumber for delivery addresses
Branch contact information
1.
Call method to get available branches
2.
Display branch list to user
3.
User selects preferred branch
4.
Save jobAccountNumber from selected branch
5.
Use branchCode for product/pricing queries
Why Multiple Branches?
Customers may have different shipping locations serviced by different SRS branches. Each branch may have different product availability and pricing.
Step 5: Get Products & Pricing#
💰 Retrieve Pricing - Click to expand
Purpose: Get available products and real-time pricing for selected branch.GetActiveBranchProductsAsync(branchCode, bearerToken) - Get product catalog
GetPricingAsync(pricingRequest, bearerToken) - Get current prices
Product Catalog (GetActiveBranchProductsAsync):Returns products available at specific branch
Includes product IDs, descriptions, and UOM (unit of measure)
Product availability varies by branch
Pricing Information (GetPricingAsync):Customer-specific pricing
Real-time stock availability
Recommended substitutes if out of stock
customerCode - Customer identifier
branchCode - Selected branch code
productList - Array of products with quantity and UOM
Why Real-Time Pricing?
Prices and availability change frequently. Always get pricing immediately before order submission to ensure accuracy.Best Practice: Cache product catalog but always fetch fresh pricing before checkout.
Step 6: Submit Order#
✅ Submit Order - Click to expand
Purpose: Submit the order to SRS for processing.SDK Method: SubmitOrderV2Async(submitRequest, bearerToken) (Recommended)Required Data (from previous steps):✅ Validated customerCode (Step 3)
✅ jobAccountNumber (Step 4)
✅ Product IDs and pricing (Step 5)
| Method | Environment | Processing |
|---|
| Synchronous | Staging only | Immediate response with order ID |
| Asynchronous | Production (recommended) | Queue-based processing |
Successful Response Contains:message: "Order Submitted"
orderID - SRS order number
transactionID - Your reference number
Next Steps After Submission:Save order ID in your system
Set up webhooks for order status updates Monitor order progress via webhook notifications
❌ Missing jobAccountNumber → Review Step 4
❌ Invalid product IDs → Verify products from Step 5
❌ Pricing mismatch → Re-fetch pricing before submission
🔄 Complete Workflow Example#
📝 End-to-End Integration Example - Click to expand
This example demonstrates the complete 6-step flow from authentication to order submission:1.
Authenticate: Get bearer token using client_id and client_secret
2.
Validate: Confirm customer has API access
3.
Browse: Get customer branch locations and save jobAccountNumber
4.
Products: Retrieve available products at selected branch
5.
Pricing: Get real-time pricing for selected products
6.
Submit: Create and submit order with all required data
Authentication → bearerToken
Validation → customerCode (validated)
Branch Locations → jobAccountNumber, branchCode
Products → productIds
Pricing → current prices
Order Submission → orderID (success)
Execution Time: Typically 2-5 seconds for complete workflow✅ Reuse bearer token for all requests (don't re-authenticate per call)
✅ Cache product catalog, but always fetch fresh pricing
✅ Implement error handling at each step
✅ Log key data points (jobAccountNumber, orderID) for troubleshooting
✅ Use async/await for better performance
See Also: Sample implementation included with SDK download.
🎯 Common Use Cases#
🛒 Use Case 1: Simple Order Submission - Click to expand
Scenario: User selects products and submits a single order.1.
User authenticates (once per session)
2.
User selects customer account
3.
System validates customer
4.
User selects branch location
5.
User browses products and adds to cart
6.
System fetches real-time pricing
7.
User reviews and confirms order
8.
System submits order and displays confirmation
ExchangeClientCredentialsAsync() - Step 1
ValidateCustomerAsync() - Step 3
GetCustomerBranchLocationsAsync() - Step 4
GetActiveBranchProductsAsync() - Step 5
GetPricingAsync() - Step 6
SubmitOrderV2Async() - Step 8
Typical Response Time: 2-3 seconds total🔄 Use Case 2: Batch Order Processing - Click to expand
Scenario: Process multiple orders from file upload or scheduled job.1.
Authenticate once at job start
2.
Read order data from file/database
3.
Get branch location (cache if same customer)
4.
Log results (success/failure) for each order
Performance Considerations:✅ Reuse bearer token across all orders
✅ Cache customer validation results
✅ Cache branch locations per customer
✅ Process orders in parallel (with rate limiting)
✅ Implement retry logic for transient failures
Recommended Batch Size: 10-50 orders per batchError Handling: Log failures individually, continue processing remaining orders📊 Use Case 3: Product Catalog Integration - Click to expand
Scenario: Sync SRS product catalog with your e-commerce platform.2.
For each branch location:Call GetActiveBranchProductsAsync()
Store products in local database
Update product availability flags
3.
Schedule periodic refresh (daily/weekly)
✅ Cache product catalog (updates daily)
✅ Fetch pricing in real-time at checkout
❌ Don't cache pricing (changes frequently)
Why Branch-Specific:
Product availability varies by branch location. Ensure users only see products available at their selected branch.Pricing: Real-time (per checkout)
Branch locations: Weekly or on-demand
⚙️ Advanced Configuration#
🌐 Environment Configuration (Staging vs Production) - Click to expand
Base URL: https://services-qa.roofhub.pro
Synchronous order processing only
Safe for testing and development
Base URL: https://services.roofhub.pro
Asynchronous order processing (recommended)
Requires production credentials
Best Practice: Use environment-specific configuration files, never hardcode URLs.🔒 Credentials Management with SDK - Click to expand
Where to Store Credentials:❌ NEVER in code or configuration files
Retrieve Credentials at Runtime:
The SDK expects you to provide credentials when calling authentication methods. Always retrieve from secrets manager:⏱️ Timeout & Retry Configuration - Click to expand
Authentication: 10 seconds
Order submission: 30 seconds
Product/pricing queries: 15 seconds
Configure Custom Timeouts:
Set timeout on HttpClient before creating SDK clients:Retry Logic:
Implement retry with exponential backoff for transient failures:Recommended Retry Policy:Retry on: 5xx errors, timeouts
Don't retry: 4xx errors (client errors)
Use Polly for Advanced Retry:📝 Logging & Diagnostics - Click to expand
Built-in Logging:
SDK uses standard .NET ILogger interface for diagnostics.✅ API request URLs (sanitized)
❌ NEVER logs credentials or tokens
Information - Successful operations
Warning - Retries, deprecated methods
Error - Failed operations, exceptions
Best Practice: Set LogLevel.Information in production, LogLevel.Debug during development.Structured Logging:
Use Application Insights or Serilog for production logging with correlation IDs.
❌ Error Handling#
SDK Exception Types#
The SDK throws standard .NET exceptions with detailed error information:| Exception Type | Cause | HTTP Status | Action |
|---|
HttpRequestException | Network/connectivity issues | N/A | Retry with backoff |
TaskCanceledException | Request timeout | N/A | Increase timeout or retry |
UnauthorizedAccessException | Invalid credentials | 401 | Verify credentials, refresh token |
InvalidOperationException | Invalid request data | 400 | Check request parameters |
🚨 Common Errors & Solutions - Click to expand
Cause: Invalid or expired bearer token
Solution: Re-authenticate using ExchangeClientCredentialsAsync()
Prevention: Implement token refresh before 24-hour expiration
Error: 400 Bad Request - "InvoiceNumber is required"Cause: Missing required field in request
Solution: Verify all required fields are populated
Check: Review API documentation for required fields
Error: 404 Not Found - "Failed to Find Invoice"Cause: Invoice/order/resource doesn't exist
Solution: Verify resource identifier is correct
Common Issue: Using staging ID in production (or vice versa)
Error: Timeout / TaskCanceledExceptionCause: Request took too long
Solution: Increase timeout or check API service status
Typical for: Large product catalogs, complex pricing requests
Error: "Customer not validated"Cause: Customer doesn't have API access
Solution: Contact SRS to enable API access for customer
Verify: Call ValidateCustomerAsync() first
Error: HttpRequestException - "Connection refused"Cause: Network connectivity or incorrect base URL
Solution: Verify base URL and network connection
Check: Firewall/proxy settings
General Error Handling Pattern:
🔐 Security Best Practices#
🔑 Managing Credentials Securely - Click to expand
Critical Security Requirements:Store credentials in Azure Key Vault, AWS Secrets Manager, or HashiCorp Vault
Retrieve credentials at runtime (never hardcode)
Use environment variables as a retrieval mechanism only
Rotate credentials every 90 days (SRS enforces 6-month rotation)
Use different credentials for Staging vs Production
Implement RBAC for credential access
Log credential access attempts
Commit credentials to version control
Store in configuration files (appsettings.json)
Share credentials via email/chat
Expose credentials to end users
Log credentials in application logs
Bearer tokens expire after 24 hours
Implement token refresh before expiration
Don't request new token for every API call
Store token securely in memory (not persistent storage)
Compromised Credentials:
If you suspect credential compromise:2.
Subject: "URGENT: Suspected Credential Compromise"
3.
Include: client_id, environment, how/when exposed
4.
SRS will revoke and issue new credentials
📊 SDK vs REST API Comparison#
| Feature | REST API | SDK |
|---|
| Setup Complexity | Manual HTTP client setup, JSON serialization | One-line DI registration |
| Type Safety | Manual JSON parsing, runtime errors | Strongly-typed models, compile-time checks |
| Error Handling | Parse JSON error responses manually | Structured exceptions with detailed messages |
| Token Management | Manual bearer token handling | Automatic token attachment to requests |
| Learning Curve | Must understand HTTP, JSON, REST | Use familiar .NET classes and methods |
| Flexibility | Full control over requests | Predefined methods (extensible) |
| Development Speed | Slower (write HTTP boilerplate) | Faster (pre-built methods) |
| IntelliSense Support | None | Full IntelliSense and documentation |
| Maintenance | Update code for API changes | SDK updates handle API changes |
| Testing | Mock HTTP responses | Mock SDK interfaces |
| Code Volume | 100-200 lines per operation | 10-20 lines per operation |
✅ .NET applications (.NET 6+)
✅ Rapid development required
✅ Team prefers strongly-typed code
✅ Want IntelliSense and compile-time validation
🟡 Non-.NET platforms (Python, Java, Node.js)
🟡 Need maximum flexibility
🟡 Implementing custom retry/circuit breaker logic
🟡 SDK not available for your platform
🔄 Versioning & Updates#
Current Version#
SDK Version: 1.0.0 (Initial Release)
Release Date: May 6, 2026
Target Framework: .NET 6.0+
Compatibility: SRS API v1 and v2 endpoints✅ Authentication Module (AuthenticationClient)
✅ Orders Module (OrdersClient)
✅ Dependency Injection support
✅ Comprehensive error handling
✅ Sample implementation project
Changelog#
📋 Version History - Click to expand
Version 1.0.0 (May 6, 2026)✅ Authentication module with OAuth 2.0 support
✅ Orders module with V1 and V2 endpoint support
✅ Customer validation methods
✅ Branch location queries
✅ Product catalog and pricing methods
✅ Order submission (sync and async)
✅ Dependency injection extensions
✅ Comprehensive XML documentation
✅ Sample implementation project
Upcoming Features (Planned):🕒 Automatic token refresh
🕒 Built-in retry policies
Subscribe to release notifications via SRS API Support
Check documentation portal for SDK announcements
🆘 Troubleshooting#
❓ FAQ - Click to expand
Q: Can I use the SDK with .NET Framework 4.x?
A: No, the SDK requires .NET 6.0 or later. .NET Framework is not supported.Q: Is the SDK open source?
A: No, the SDK is proprietary and distributed privately to registered SRS partners only.Q: How do I get SDK updates?
A: Contact SRS API Support to receive new SDK versions. Check the changelog for latest features.Q: Can I use the SDK with Xamarin/MAUI mobile apps?
A: Yes, as long as your app targets .NET 6.0+. However, ensure credentials are stored securely on mobile devices.Q: Does the SDK work with Blazor WebAssembly?
A: Not recommended for client-side Blazor due to credential exposure. Use Blazor Server or API backend instead.Q: How do I mock the SDK for unit testing?
A: SDK clients implement interfaces that can be mocked. Use Moq or NSubstitute:Q: Can I use the SDK in Azure Functions?
A: Yes! Register SDK clients in your Functions startup class using dependency injection.Q: What happens if my token expires mid-operation?
A: You'll receive a 401 Unauthorized error. Implement token refresh logic to re-authenticate automatically.Q: Is there a NuGet package?
A: Not currently. The SDK is distributed as a private binary download. Contact support for access.Q: Can I extend the SDK with custom methods?
A: Yes, SDK clients are extensible. You can create extension methods or inherit from base clients.🐛 Common Issues - Click to expand
Issue: "Could not load file or assembly 'Sdk.Lib.Crm.Srs'"
Cause: Missing DLL reference or wrong .NET version
Solution:Verify DLL is referenced in project
Ensure project targets .NET 6.0 or later
Issue: "The type or namespace 'Sdk' could not be found"
Cause: Missing using statement
Solution: Add using Sdk.Lib.Crm.Srs.Authentication; and using Sdk.Lib.Crm.Srs.Orders;Issue: Authentication fails with valid credentials
Cause: Wrong environment (Staging credentials used in Production)
Solution: Verify base URL matches credential environmentIssue: Orders submitted but not visible in SRS system
Cause: Using Staging environment
Solution: Staging orders are not real. Use Production credentials for live orders.Issue: "HttpClient disposed" error
Cause: HttpClient lifecycle issue in DI
Solution: Use AddHttpClient() instead of AddSingleton<HttpClient>()Issue: Slow performance / timeouts
Cause: Creating new HttpClient per request
Solution: Use dependency injection to reuse HttpClient instancesIssue: "Access token missing or malformed"
Cause: Token not passed to method or expired
Solution:Verify token is returned from authentication
Check token hasn't expired (24-hour lifetime)
Ensure bearer token is passed to all authenticated methods
Issue: Dependency injection not working
Cause: Services not registered
Solution: Call AddSrsAuthenticationClient() and AddSrsOrdersClient() in startup
💬 Support & Feedback#
Include: Your client_id, environment, SDK version, and issue description
Response Time: 1-2 business days
📚 Quick Reference Checklist#
✅ Before Using SDK#
✅ First Integration#
✅ Production Readiness#
Modified at 2026-05-06 21:11:17