as2aas / php-client
PHP client library for AS2aaS - Making AS2 messaging as simple as sending an email
Installs: 33
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/as2aas/php-client
Requires
- php: ^8.0
- ext-json: *
- ext-openssl: *
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- mockery/mockery: ^1.4
- orchestra/testbench: ^6.0|^7.0|^8.0
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^9.0
- squizlabs/php_codesniffer: ^3.6
This package is auto-updated.
Last update: 2025-09-28 15:53:51 UTC
README
A comprehensive PHP client library for AS2aaS (AS2 as a Service), designed to simplify AS2 messaging integration for business applications. This library abstracts the complexity of AS2 protocol implementation, enabling developers to integrate secure B2B messaging with just a few lines of code.
Overview
AS2aaS provides a cloud-based AS2 messaging service that handles the complex technical requirements of AS2 protocol implementation. This PHP client library offers a clean, intuitive API for integrating AS2 messaging capabilities into your business applications.
Key Use Cases:
- Healthcare and pharmaceutical supply chain (DSCSA compliance)
- Retail and manufacturing EDI transactions
- Financial services secure document exchange
- Any B2B integration requiring AS2 protocol compliance
Installation
Install the package via Composer:
composer require as2aas/php-client
Laravel Installation
For Laravel applications, the service provider is automatically registered via package discovery. Publish the configuration file:
php artisan vendor:publish --tag=as2aas-config
Add your API key to your .env
file:
AS2AAS_API_KEY=pk_live_your_api_key AS2AAS_TIMEOUT=30000 AS2AAS_RETRIES=3
Quick Start
<?php use AS2aaS\Client; // Initialize the client (environment auto-detected from API key) $as2 = new Client('pk_live_your_api_key'); // Production environment // $as2 = new Client('pk_test_your_api_key'); // Test environment // Get a trading partner $partner = $as2->partners()->getByAs2Id('MCKESSON'); // Send a message $message = $as2->messages()->send( $partner, file_get_contents('purchase-order.edi'), 'Purchase Order #PO-2024-001' ); echo "Message sent! Status: " . $message->getStatus();
Laravel Quick Start
// Using Facade use AS2aaS\Laravel\Facades\AS2; $partner = AS2::partners()->getByAs2Id('MCKESSON'); $message = AS2::messages()->send($partner, $content, 'Purchase Order'); // Using Dependency Injection use AS2aaS\Client; class OrderController extends Controller { public function sendOrder(Client $as2) { $partner = $as2->partners()->getByAs2Id('MCKESSON'); $message = $as2->messages()->send($partner, $ediContent, 'Purchase Order'); return response()->json(['message_id' => $message->getId()]); } }
Features
- Simple API: Send AS2 messages with minimal code complexity
- Laravel Ready: First-class Laravel integration with service provider and facades
- Enterprise Architecture: Account-based multi-tenant support
- Master Partner Management: Centralized partner configuration with inheritance
- Automatic Security: Built-in signing, encryption, and compression handling
- Real-time Notifications: Webhook integration for message status updates
- Comprehensive Error Handling: Detailed exception management with retry logic
- Content Detection: Automatic EDI, XML, and JSON content type recognition
Configuration
Environment Variables
Configure your API key using environment variables:
AS2AAS_API_KEY=pk_live_your_api_key
Advanced Configuration
use AS2aaS\Client; $as2 = new Client([ 'apiKey' => 'pk_live_your_api_key', 'timeout' => 30000, 'retries' => 3, 'defaultMdnMode' => 'async', 'defaultSigning' => true, 'defaultEncryption' => true, ]); // API endpoint: https://api.as2aas.com/v1 // Test vs Live environment auto-detected by API from your key type
Global Configuration
Client::configure([ 'timeout' => 45000, 'retries' => 5, 'defaultMdnMode' => 'sync', ]);
Core Usage Examples
Partner Management
// List all partners $partners = $as2->partners()->list(); // Search for specific partners $partners = $as2->partners()->list(['search' => 'McKesson']); // Get partner by AS2 ID $partner = $as2->partners()->getByAs2Id('MCKESSON'); // Get partner by name (supports partial matching) $partner = $as2->partners()->getByName('McKesson Corporation'); // Create new partner $partner = $as2->partners()->create([ 'name' => 'Regional Supplier', 'as2_id' => 'REGIONAL-001', 'url' => 'https://supplier.example.com/as2' // Uses sensible defaults: sign=true, encrypt=true, mdn_mode='async' ]); // Test partner connectivity $result = $as2->partners()->test($partner); if ($result['success']) { echo 'Partner connectivity verified'; }
Message Operations
// Send message with content $message = $as2->messages()->send( $partner, $ediContent, 'Invoice #12345' ); // Send file directly $message = $as2->messages()->sendFile( $partner, './purchase-order.edi', 'Purchase Order #PO-2024-001' ); // Send with advanced options $message = $as2->messages()->send($partner, $content, 'Urgent Order', [ 'priority' => 'high', 'compress' => true, 'metadata' => ['orderId' => 'PO-2024-001', 'department' => 'procurement'] ]); // Send batch messages $results = $as2->messages()->sendBatch([ [ 'partner' => 'MCKESSON', 'content' => file_get_contents('order1.edi'), 'subject' => 'Order #1' ], [ 'partner' => 'CARDINAL', 'content' => file_get_contents('order2.edi'), 'subject' => 'Order #2' ] ]); // List messages $recent = $as2->messages()->list(['limit' => 10]); $failed = $as2->messages()->list(['status' => 'failed']); $fromPartner = $as2->messages()->list(['partner' => 'MCKESSON']); // Get message payload $content = $as2->messages()->getPayload('msg_000001'); // Wait for delivery confirmation try { $delivered = $as2->messages()->waitForDelivery($message->getId(), 60000); echo 'Message delivered successfully'; } catch (Exception $e) { echo 'Message delivery failed or timed out'; } // Validate content before sending $result = $as2->messages()->validate($ediContent); if ($result['valid']) { echo "Valid {$result['format']} document"; } // Send test message $testResult = $as2->messages()->sendTest($partner, [ 'messageType' => 'sample_edi', 'encrypt' => true, 'sign' => true ]);
Certificate Management
// Upload certificate $cert = $as2->certificates()->upload([ 'name' => 'My Company Identity', 'file' => './certificates/identity.pem', 'type' => 'identity' ]); // List certificates $certs = $as2->certificates()->list(); $expiring = $as2->certificates()->list(['expiringWithin' => 30]); // Generate identity certificate $cert = $as2->certificates()->generateIdentity([ 'commonName' => 'My Company AS2', 'organization' => 'My Company Inc', 'country' => 'US', 'email' => 'admin@mycompany.com' ]); // Download certificate $files = $as2->certificates()->download('cert_000001');
Webhook Event Handling
// Verify webhook signature (in your webhook handler) $isValid = $as2->webhooks()->verifySignature($payload, $signature, $secret); // Handle webhook events $as2->webhooks()->handleEvent($eventData, [ 'message.delivered' => function($data) { echo "Message {$data['id']} delivered to {$data['partner']['name']}"; }, 'message.failed' => function($data) { echo "Message {$data['id']} failed: {$data['error']['message']}"; } ]);
Enterprise Features and Tenant Management
// Account management (account-level operations) $account = $as2->accounts()->get(); $tenants = $as2->accounts()->listTenants(); // Create tenant $tenant = $as2->accounts()->createTenant([ 'name' => 'European Operations', 'slug' => 'europe' ]); // Tenant Switching - Method 1: Client-level switching $as2->setTenant('1'); // Set tenant context $partners = $as2->partners()->list(); // Now scoped to this tenant $messages = $as2->messages()->list(); // Also scoped to this tenant // Tenant Switching - Method 2: Tenants module switching $as2->tenants()->switch('1'); // Also updates client context $partners = $as2->partners()->list(); // Scoped to switched tenant // Check current tenant $currentTenantId = $as2->getCurrentTenant(); // Clear tenant context (for account-level operations) $as2->setTenant(null); $allTenants = $as2->accounts()->listTenants(); // Works without tenant context // Tenant-specific API keys (automatically scoped) $tenantClient = new Client('tk_live_your_tenant_key'); // Pre-scoped to tenant $partners = $tenantClient->partners()->list(); // No switching needed // Master Partner Inheritance Flow (7 Steps) // Step 1: Create master partner (account-level) $masterPartner = $as2->accounts()->masterPartners()->create([ 'name' => 'ACME Corporation', 'as2_id' => 'ACME-CORP-001', 'url' => 'https://acme.example.com/as2', 'mdn_mode' => 'async', 'sign' => true, 'encrypt' => true, 'compress' => false ]); // Step 2: List master partners $masterPartners = $as2->accounts()->masterPartners()->list(); // Step 3: Check inheritance status $status = $as2->accounts()->masterPartners()->getInheritanceStatus($masterPartner->getId()); // Step 4: Inherit to tenants $as2->accounts()->masterPartners()->inherit($masterPartner->getId(), [ 'tenant_ids' => ['1', '2', '3'], 'override_settings' => [ 'url' => 'https://tenant-specific.acme.com/as2', 'mdn_mode' => 'sync' ] ]); // Step 5: View tenant partners (inherited + specific) $as2->setTenant('1'); $tenantPartners = $as2->partners()->list(); // Shows both inherited and tenant-specific // Step 6: Remove inheritance (optional) $as2->accounts()->masterPartners()->removeInheritance($masterPartner->getId(), ['2', '3']); // Step 7: Update master partner (propagates to inherited) $as2->accounts()->masterPartners()->update($masterPartner->getId(), [ 'name' => 'ACME Corporation (Updated)', 'url' => 'https://new-acme.example.com/as2' ]); // Billing (account-level operations) $usage = $as2->billing()->getUsage(); $transactions = $as2->billing()->getTransactions();
Tenant Context Rules
- Account-level modules (accounts, tenants, billing): No
X-Tenant-ID
header needed - Tenant-scoped modules (partners, messages, certificates, webhooks): Require
X-Tenant-ID
header - Automatic header management: Client automatically adds header based on current tenant context
- Default behavior:
- Account keys (
pk_*
): Defaults to first tenant if no tenant set - Tenant keys (
tk_*
): Automatically scoped to their specific tenant
- Account keys (
Master Partner Inheritance Flow
The complete 7-step inheritance process:
- Create Master Partner: Account-level partner creation
- List Master Partners: View all master partners with inheritance stats
- Check Inheritance Status: See which tenants inherit which partners
- Inherit to Tenants: Bulk or individual inheritance with custom settings
- View Tenant Partners: Combined view of inherited + tenant-specific partners
- Remove Inheritance: Selective removal from specific tenants
- Update Master Partner: Changes automatically propagate to inherited partners
Benefits:
- Centralized Management: Create once, inherit everywhere
- Tenant Customization: Override settings per tenant (URL, MDN mode, etc.)
- Automatic Sync: Master partner changes propagate automatically
- Selective Control: Choose which tenants inherit which partners
- Audit Trail: Track all inheritance relationships and changes
Testing
Unit Testing with Mock Client
For unit testing your application without making actual API calls, use the built-in mock client:
use AS2aaS\Client; // Create mock client (no API calls) $mockAs2 = Client::createMock(); // Mock client has same interface as real client $partner = $mockAs2->partners()->create([ 'name' => 'Test Partner', 'as2_id' => 'TEST-PARTNER', 'url' => 'https://test.example.com/as2' ]); $message = $mockAs2->messages()->send($partner, 'test content', 'Test Subject'); echo $message->getStatus(); // 'delivered' (simulated) // Access mock data for assertions $mockData = $mockAs2->getMockData(); $this->assertCount(1, $mockData->partners);
Integration Testing with Test Environment
For integration testing against the AS2aaS test environment:
// Use test environment with test API key (API auto-detects from key) $as2 = new Client('pk_test_your_key'); // Or use the createTest helper for clarity $as2 = Client::createTest('pk_test_your_key'); // Sandbox operations for testing $info = $as2->sandbox()->getInfo(); $samples = $as2->sandbox()->getSample('edi-850'); // Send test messages to verify partner setup $testResult = $as2->messages()->sendTest($partner, [ 'messageType' => 'sample_edi' ]);
Laravel Testing
// In your Laravel tests use AS2aaS\Client; use AS2aaS\Testing\MockClient; class OrderTest extends TestCase { public function test_can_send_order() { // Bind mock client $this->app->singleton(Client::class, function () { return Client::createMock(); }); // Your test code $response = $this->post('/orders/send', ['partner_id' => 'MCKESSON']); $response->assertStatus(200); } }
Utility Functions
// Validate EDI $result = $as2->utils()->validateEDI($ediContent); // Detect content type $contentType = $as2->utils()->detectContentType($content, 'invoice.edi'); // Format file size echo $as2->utils()->formatFileSize(1048576); // "1.0 MB" // Generate AS2 ID $as2Id = $as2->utils()->generateAs2Id('Acme Corporation'); // "ACME-CORP-AS2"
Laravel Integration
Installation
The service provider is automatically registered. Publish the configuration:
php artisan vendor:publish --tag=as2aas-config
Configuration
Add to your .env
file:
AS2AAS_API_KEY=pk_live_your_api_key AS2AAS_TIMEOUT=30000 AS2AAS_RETRIES=3 AS2AAS_DEFAULT_MDN_MODE=async
Usage in Laravel
// Using dependency injection use AS2aaS\Client; class OrderController extends Controller { public function sendOrder(Client $as2) { $partner = $as2->partners()->getByAs2Id('MCKESSON'); $message = $as2->messages()->send($partner, $ediContent, 'Purchase Order'); return response()->json(['message_id' => $message->getId()]); } } // Using facade use AS2aaS\Laravel\Facades\AS2; $partner = AS2::partners()->getByAs2Id('MCKESSON'); $message = AS2::messages()->send($partner, $content, $subject); // Using service container $as2 = app('as2aas'); $partners = $as2->partners()->list();
Webhook Handling in Laravel
// routes/web.php Route::post('/webhooks/as2', [WebhookController::class, 'handle']); // WebhookController.php use AS2aaS\Laravel\Facades\AS2; class WebhookController extends Controller { public function handle(Request $request) { $signature = $request->header('X-Signature'); $payload = $request->getContent(); if (!AS2::webhooks()->verifySignature($payload, $signature, config('as2aas.webhooks.secret'))) { abort(401, 'Invalid signature'); } $event = json_decode($payload, true); AS2::webhooks()->handleEvent($event, [ 'message.delivered' => function($data) { // Update order status Order::where('as2_message_id', $data['id'])->update(['status' => 'delivered']); }, 'message.failed' => function($data) { // Send notification Mail::to('admin@company.com')->send(new MessageFailedMail($data)); } ]); return response('OK'); } }
Error Handling
The client provides comprehensive error handling with specific exception types:
use AS2aaS\Exceptions\AS2AuthenticationError; use AS2aaS\Exceptions\AS2ValidationError; use AS2aaS\Exceptions\AS2NetworkError; use AS2aaS\Exceptions\AS2PartnerError; use AS2aaS\Exceptions\AS2RateLimitError; try { $message = $as2->messages()->send($partner, $content, $subject); } catch (AS2PartnerError $e) { echo 'Partner issue: ' . $e->getMessage(); } catch (AS2RateLimitError $e) { echo 'Rate limited, retry in: ' . $e->getRetryAfter() . ' seconds'; } catch (AS2ValidationError $e) { echo 'Validation errors: ' . json_encode($e->getValidationErrors()); } catch (AS2NetworkError $e) { if ($e->isRetryable()) { echo 'Retryable network error'; } } catch (AS2AuthenticationError $e) { echo 'Authentication failed: ' . $e->getMessage(); }
Multi-Tenant Architecture
AS2aaS supports enterprise multi-tenant architectures where you can manage multiple business entities or customers within a single account:
Account and Tenant Management
// Account-level operations $account = $as2->accounts()->get(); $tenants = $as2->accounts()->listTenants(); // Create new tenant for a customer $tenant = $as2->accounts()->createTenant([ 'name' => 'East Coast Division', 'slug' => 'east-coast' ]); // Switch tenant context for operations $as2->setTenant($tenant->getId()); // All subsequent operations are scoped to this tenant $partners = $as2->partners()->list(); $messages = $as2->messages()->list();
Master Partner Inheritance
Create master partners at the account level and inherit them to specific tenants:
// Create master partner (account-level) $masterPartner = $as2->accounts()->masterPartners()->create([ 'name' => 'McKesson Corporation', 'as2_id' => 'MCKESSON', 'url' => 'https://as2.mckesson.com/receive' ]); // Inherit to specific tenants with custom settings $as2->accounts()->masterPartners()->inherit($masterPartner->getId(), [ 'tenant_ids' => ['1', '2'], 'override_settings' => [ 'url' => 'https://tenant-specific.mckesson.com/as2', 'mdn_mode' => 'sync' ] ]); // View inherited partners from tenant perspective $as2->setTenant('1'); $tenantPartners = $as2->partners()->list(); // Shows inherited + tenant-specific
Industry-Specific Integration
Healthcare and Pharmaceutical (DSCSA)
The client is designed to support Drug Supply Chain Security Act (DSCSA) compliance requirements:
// Create trading account for pharmacy chain $tenant = $as2->accounts()->createTenant([ 'name' => 'Regional Pharmacy Chain' ]); // Set up major pharmaceutical partners $mckesson = $as2->accounts()->masterPartners()->create([ 'name' => 'McKesson Pharmaceutical', 'as2_id' => 'MCKESSON-PHARMA', 'url' => 'https://as2.mckesson.com/dscsa' ]); // Inherit to trading account $as2->accounts()->masterPartners()->inherit($mckesson->getId(), [ 'tenant_ids' => [$tenant->getId()] ]); // Send DSCSA transaction $as2->setTenant($tenant->getId()); $dscsaData = json_encode([ 'transaction_type' => 'T3_VERIFICATION_REQUEST', 'ndc' => '12345-678-90', 'serial_number' => 'SN789012345' ]); $message = $as2->messages()->send($partner, $dscsaData, 'T3 Verification Request');
Testing
Run the test suite:
composer test
Run with coverage:
composer test-coverage
Run static analysis:
composer analyse
Check code style:
composer cs-check
API Reference
Client Initialization
new Client(string $apiKey)
- Initialize with API keynew Client(array $config)
- Initialize with configuration arrayClient::createTest(string $apiKey)
- Create test environment clientClient::configure(array $config)
- Set global configuration
Core Modules
partners()
- Partner management and lookupmessages()
- Message sending and receivingcertificates()
- Certificate upload and managementaccounts()
- Account-level operations (enterprise)tenants()
- Tenant management and context switchingwebhooks()
- Webhook event handlingbilling()
- Subscription and usage managementsandbox()
- Testing and development utilitiespartnerships()
- Advanced partner onboardingutils()
- Helper functions and content detection
Requirements
- PHP 8.0 or higher
- Guzzle HTTP client 7.0+
- OpenSSL extension for certificate operations
- JSON extension for API communication
Contributing
Please see CONTRIBUTING for details on our code of conduct and the process for submitting pull requests.
Security
If you discover any security-related issues, please email security@as2aas.com instead of using the issue tracker.
License
The MIT License (MIT). Please see License File for more information.
Support
- Documentation: https://docs.as2aas.com
- Support: support@as2aas.com
- Issues: https://github.com/as2aas/php-client/issues
About AS2aaS
AS2aaS is a cloud-based AS2 messaging service that eliminates the complexity of implementing and maintaining AS2 infrastructure. Our platform handles the technical requirements of AS2 protocol compliance while providing a simple, developer-friendly API for integration.
Perfect for businesses requiring secure B2B document exchange, including healthcare organizations needing DSCSA compliance, retail companies managing EDI transactions, and any enterprise requiring AS2 protocol support.