Digistore24 API Client for PHP
Modern, type-safe PHP API client for Digistore24 with PHP 8.4 property hooks and clean architecture.
✨ PHP 8.4 Property Hooks - Automatic validation on property assignment
🎯 Type-Safe - Full type hints, enums, and generics throughout
🏗️ Clean Architecture - Resource-based design with separation of concerns
🔄 Automatic Retry - Built-in exponential backoff for failed requests
🚦 Rate Limiting - Handles API rate limits gracefully
📝 Fully Documented - Comprehensive PHPDoc with examples
🧪 Exception Handling - Typed exceptions for different error scenarios
✅ 122 Endpoints - Complete coverage of Digistore24 API
🎉 Optional Request Parameters - Clean API calls without explicit Request objects
PHP 8.4.0 or higher (for property hooks support)
cURL extension
mbstring extension
composer require gosuccess/digistore24-api
<?php
use GoSuccess \Digistore24 \Api \Digistore24 ;
use GoSuccess \Digistore24 \Api \Client \Configuration ;
use GoSuccess \Digistore24 \Api \Request \BuyUrl \CreateBuyUrlRequest ;
use GoSuccess \Digistore24 \Api \DTO \BuyerData ;
// Initialize configuration
$ config = new Configuration ('YOUR-API-KEY ' );
// Or with advanced options
$ config = new Configuration (
apiKey: 'YOUR-API-KEY ' ,
timeout: 60 ,
debug: true
);
// Create client
$ ds24 = new Digistore24 ($ config );
// Create a buy URL
$ request = new CreateBuyUrlRequest ();
$ request ->productId = 12345 ;
$ request ->validUntil = '48h ' ;
// Add buyer data (with automatic validation)
$ buyer = new BuyerData ();
$ buyer ->email = 'customer@example.com ' ; // Validates email format
$ buyer ->firstName = 'John ' ;
$ buyer ->country = 'de ' ; // Auto-uppercased to 'DE'
$ request ->buyer = $ buyer ;
// Execute request
$ response = $ ds24 ->buyUrls ->create ($ request );
echo "Buy URL: {$ response ->url }\n" ;
This wrapper uses a resource-based architecture with typed requests and responses:
$ ds24 ->buyUrls ->create() // Buy URL management
$ ds24 ->products ->get() // Product information
$ ds24 ->purchases ->list() // Order management
$ ds24 ->rebilling ->start() // Subscription management
$ ds24 ->affiliates ->getCommission() // Affiliate management
$ ds24 ->ipns ->setup() // Webhook management
$ ds24 ->monitoring ->ping () // Health checks
src/
├── Base/ # Abstract base classes
│ ├── AbstractRequest.php # Base for all API requests
│ ├── AbstractResource.php # Base for all resources
│ └── AbstractResponse.php # Base for all API responses
│
├── Client/ # HTTP client implementation
│ ├── ApiClient.php # Main HTTP client with retry logic
│ └── Configuration.php # API configuration with property hooks
│
├── Contract/ # Interfaces (reserved for future use)
│
├── DTO/ # Data Transfer Objects with property hooks
│ ├── BuyerData.php # Buyer information (email validation)
│ ├── PaymentPlanData.php # Payment plan (currency validation)
│ └── TrackingData.php # Tracking parameters
│
├── Enum/ # Type-safe enumerations
│ ├── HttpMethod.php # HTTP methods (GET, POST, PUT, DELETE, PATCH)
│ └── StatusCode.php # HTTP status codes with helper methods
│
├── Exception/ # Exception hierarchy
│ ├── ApiException.php # Base exception
│ ├── AuthenticationException.php
│ ├── ForbiddenException.php
│ ├── NotFoundException.php
│ ├── RateLimitException.php
│ ├── RequestException.php
│ └── ValidationException.php
│
├── Http/ # HTTP-related classes
│ └── Response.php # HTTP response wrapper
│
├── Request/ # Typed API requests (122 endpoints)
│ ├── Affiliate/
│ ├── Billing/
│ ├── Buyer/
│ ├── BuyUrl/
│ ├── Country/
│ ├── Ipn/
│ ├── Monitoring/
│ ├── Product/
│ ├── Purchase/
│ ├── Rebilling/
│ ├── User/
│ └── Voucher/
│
├── Resource/ # Resource classes (12 resources)
│ ├── AffiliateResource.php
│ ├── BillingResource.php
│ ├── BuyerResource.php
│ ├── BuyUrlResource.php
│ ├── CountryResource.php
│ ├── IpnResource.php
│ ├── MonitoringResource.php
│ ├── ProductResource.php
│ ├── PurchaseResource.php
│ ├── RebillingResource.php
│ ├── UserResource.php
│ └── VoucherResource.php
│
├── Response/ # Typed API responses
│ ├── AccountAccess/
│ │ └── AccountAccessEntry.php # Helper class for member access logs
│ ├── Affiliate/
│ ├── Billing/
│ ├── Buyer/
│ ├── BuyUrl/
│ ├── Country/
│ ├── Eticket/
│ │ ├── EticketDetail.php # Helper class for e-ticket details
│ │ └── EticketListItem.php # Helper class for e-ticket lists
│ ├── Ipn/
│ ├── Monitoring/
│ ├── Product/
│ ├── Purchase/
│ ├── Rebilling/
│ ├── User/
│ └── Voucher/
│
└── Util/ # Utility classes
├── ArrayHelper.php # Array operations
├── TypeConverter.php # Type conversions
└── Validator.php # Validation utilities
Directories:
✅ Singular form : Exception/, Request/, Response/
❌ NOT plural: Exceptions/, Requests/, Responses/
Classes:
Abstract classes : AbstractRequest, AbstractResponse → in Base/
Interfaces : RequestInterface, ResponseInterface → in Contract/
DTOs : BuyerData, PaymentPlanData → in DTO/
Exceptions : ApiException, NotFoundException → in Exception/
Enums : HttpMethod, StatusCode → in Enum/
Helper classes : AccountAccessEntry, EticketDetail → in Response/*/
Namespaces:
GoSuccess \Digistore24 \Api \Base \AbstractRequest
GoSuccess\Digistore24 \Api \Contract \RequestInterface
GoSuccess\Digistore24 \Api \DTO \BuyerData
GoSuccess\Digistore24 \Api \Enum \HttpMethod
GoSuccess\Digistore24 \Api \Enum \StatusCode
GoSuccess\Digistore24 \Api \Exception \ApiException
GoSuccess\Digistore24 \Api \Request \BuyUrl \CreateBuyUrlRequest
GoSuccess\Digistore24 \Api \Response \Eticket \EticketDetail
Singular directories - More consistent with PSR standards
Property hooks - Eliminate constructors where possible
final classes - Not readonly (allow mutation)
Typed constants - Enums instead of magic values
String interpolation - "{$var}" instead of concatenation
Single class per file - Helper classes in separate files
Use imports - Never use fully-qualified class names (FQCN)
Dedicated Enum directory - HttpMethod, StatusCode in Enum/
Property hooks provide automatic validation without constructors:
final class BuyerData
{
public string $ email {
set {
if (!filter_var ($ value , FILTER_VALIDATE_EMAIL )) {
throw new \InvalidArgumentException ("Invalid email " );
}
$ this ->email = $ value ;
}
}
public string $ country {
set {
$ upper = strtoupper ($ value );
if (!in_array ($ upper , ['DE ' , 'AT ' , 'CH ' , 'US ' , ...])) {
throw new \InvalidArgumentException ("Invalid country code " );
}
$ this ->country = $ upper ;
}
}
}
Benefits:
✅ No boilerplate constructors
✅ Automatic validation on assignment
✅ Mutable properties (read AND write)
✅ Clean, maintainable code
Usage:
$ buyer = new BuyerData ();
$ buyer ->email = 'test@example.com ' ; // ✅ Valid
$ buyer ->email = 'invalid ' ; // ❌ Throws InvalidArgumentException
$ buyer ->country = 'de ' ; // ✅ Auto-uppercased to 'DE'
$ buyer ->country = 'invalid ' ; // ❌ Throws InvalidArgumentException
Simple API Calls (No Request Object Needed)
Many methods with all-optional parameters can now be called without creating a Request object:
// List all products (no parameters needed)
$ products = $ ds24 ->products ->list ();
// Get user information (no parameters needed)
$ userInfo = $ ds24 ->users ->getInfo ();
// List all countries (no parameters needed)
$ countries = $ ds24 ->countries ->listCountries ();
// Test API connection (no parameters needed)
$ ping = $ ds24 ->system ->ping ();
// List purchases with default filters (no parameters needed)
$ purchases = $ ds24 ->purchases ->list ();
Advanced API Calls (With Request Objects for Filters)
When you need filters or custom parameters, use Request objects:
use GoSuccess \Digistore24 \Api \Request \Product \ListProductsRequest ;
use GoSuccess \Digistore24 \Api \Request \Purchase \ListPurchasesRequest ;
// List products sorted by name
$ products = $ ds24 ->products ->list (
new ListProductsRequest (sortBy: 'name ' )
);
// List purchases from last 7 days
$ purchases = $ ds24 ->purchases ->list (
new ListPurchasesRequest (
fromDate: new DateTime ('-7 days ' ),
toDate: new DateTime ('now ' )
)
);
Create Buy URL with Payment Plan
use GoSuccess \Digistore24 \Api \DTO \PaymentPlanData ;
$ request = new CreateBuyUrlRequest ();
$ request ->productId = 12345 ;
$ paymentPlan = new PaymentPlanData ();
$ paymentPlan ->firstAmount = 9.99 ;
$ paymentPlan ->otherAmounts = 29.99 ;
$ paymentPlan ->currency = 'eur ' ; // Auto-uppercased
$ paymentPlan ->numberOfInstallments = 12 ;
$ request ->paymentPlan = $ paymentPlan ;
$ response = $ ds24 ->buyUrls ->create ($ request );
use GoSuccess \Digistore24 \Api \DTO \TrackingData ;
$ tracking = new TrackingData ();
$ tracking ->affiliate = 'partner123 ' ;
$ tracking ->utmSource = 'newsletter ' ;
$ tracking ->utmMedium = 'email ' ;
$ tracking ->utmCampaign = 'summer2024 ' ;
$ request ->tracking = $ tracking ;
use GoSuccess \Digistore24 \Api \Exception \{
ApiException ,
AuthenticationException ,
ValidationException ,
RateLimitException
};
try {
$ response = $ ds24 ->buyUrls ->create ($ request );
} catch (AuthenticationException $ e ) {
echo "Invalid API key: {$ e ->getMessage ()}\n" ;
} catch (ValidationException $ e ) {
echo "Validation error: {$ e ->getMessage ()}\n" ;
} catch (RateLimitException $ e ) {
echo "Rate limit exceeded, retry after: {$ e ->getContextValue ('retry_after ' )}\n" ;
} catch (ApiException $ e ) {
echo "API error: {$ e ->getMessage ()}\n" ;
}
Performance tests conducted on PHP 8.4.12 with 16GB RAM:
Operation
Time
Memory
Notes
Create Buy URL
~150ms
2.1 MB
Including validation
List Products (100 items)
~320ms
4.5 MB
With pagination
Get Purchase Details
~95ms
1.8 MB
Single request
Batch Operations (10x)
~1.2s
12 MB
Parallel requests
Property Hook Validation
<1ms
Negligible
Zero overhead
Key Performance Features:
✅ Zero-copy property hooks - No constructor overhead
✅ Lazy loading - Resources instantiated on demand
✅ Memory efficient - ~2MB per request average
✅ Fast validation - Inline property hook checks
Rate Limiting & Retry Logic
The client automatically handles Digistore24 API rate limits with exponential backoff :
use GoSuccess \Digistore24 \Api \Client \Configuration ;
use GoSuccess \Digistore24 \Api \Exception \RateLimitException ;
// Configure retry behavior
$ config = new Configuration (
apiKey: 'YOUR-API-KEY ' ,
timeout: 30 , // Request timeout
maxRetries: 3 , // Max retry attempts
retryDelay: 1000 // Initial delay in ms (exponential backoff)
);
$ ds24 = new Digistore24 ($ config );
// Automatic retry on rate limit (429) or server errors (500-599)
try {
$ response = $ ds24 ->products ->list ();
echo "Retrieved {$ response ->total } products \n" ;
} catch (RateLimitException $ e ) {
// Thrown after all retries exhausted
$ retryAfter = $ e ->getContextValue ('retry_after ' );
echo "Rate limit exceeded. Retry after {$ retryAfter } seconds \n" ;
}
Retry Strategy:
1st retry : Wait 1 second
2nd retry : Wait 2 seconds (exponential)
3rd retry : Wait 4 seconds (exponential)
After 3 attempts : Throw RateLimitException
Status codes with automatic retry:
429 Too Many Requests - Rate limit hit
500 Internal Server Error - Server error
502 Bad Gateway - Temporary unavailability
503 Service Unavailable - Service down
504 Gateway Timeout - Request timeout
Status codes WITHOUT retry:
400 Bad Request - Invalid parameters
401 Unauthorized - Invalid API key
403 Forbidden - Insufficient permissions
404 Not Found - Resource not found
Manual Rate Limit Handling
For fine-grained control, you can implement custom retry logic:
use GoSuccess \Digistore24 \Api \Exception \RateLimitException ;
$ maxAttempts = 5 ;
$ attempt = 0 ;
while ($ attempt < $ maxAttempts ) {
try {
$ response = $ ds24 ->purchases ->list ();
break ; // Success
} catch (RateLimitException $ e ) {
$ attempt ++;
$ retryAfter = $ e ->getContextValue ('retry_after ' ) ?? 60 ;
if ($ attempt >= $ maxAttempts ) {
throw $ e ; // Give up
}
echo "Rate limited. Waiting {$ retryAfter }s before retry {$ attempt }/ {$ maxAttempts }... \n" ;
sleep ($ retryAfter );
}
}
Resource
Description
Endpoints
Status
affiliates
Commission management
8
✅ Complete
billing
On-demand invoicing
1
✅ Complete
buyers
Customer information
8
✅ Complete
buyUrls
Order form URL management
3
✅ Complete
countries
Country/region data
2
✅ Complete
ipns
Webhook management
3
✅ Complete
monitoring
Health checks
1
✅ Complete
products
Product management
59
✅ Complete
purchases
Order information
24
✅ Complete
rebilling
Subscription management
4
✅ Complete
users
Authentication
3
✅ Complete
vouchers
Discount codes
6
✅ Complete
Total
122
✅ 100%
API Endpoints Documentation
Endpoint
Documentation
getAffiliateCommission
View
updateAffiliateCommission
View
getAffiliateForEmail
View
setAffiliateForEmail
View
getReferringAffiliate
View
setReferringAffiliate
View
validateAffiliate
View
statsAffiliateToplist
View
Endpoint
Documentation
createBillingOnDemand
View
listInvoices
View
resendInvoiceMail
View
Endpoint
Documentation
createBuyUrl
View
listBuyUrls
View
deleteBuyUrl
View
Endpoint
Documentation
getBuyer
View
updateBuyer
View
listBuyers
View
getCustomerToAffiliateBuyerDetails
View
Endpoint
Documentation
listCountries
View
listCurrencies
View
Endpoint
Documentation
getDelivery
View
updateDelivery
View
listDeliveries
View
Endpoint
Documentation
createEticket
View
getEticket
View
listEtickets
View
validateEticket
View
getEticketSettings
View
listEticketLocations
View
listEticketTemplates
View
Endpoint
Documentation
listCustomFormRecords
View
Endpoint
Documentation
createImage
View
getImage
View
listImages
View
deleteImage
View
Endpoint
Documentation
ipnSetup
View
ipnInfo
View
ipnDelete
View
Endpoint
Documentation
validateLicenseKey
View
Endpoint
Documentation
getMarketplaceEntry
View
listMarketplaceEntries
View
Endpoint
Documentation
listAccountAccess
View
logMemberAccess
View
Endpoint
Documentation
ping
View
Endpoint
Documentation
createOrderform
View
getOrderform
View
updateOrderform
View
deleteOrderform
View
listOrderforms
View
getOrderformMetas
View
Endpoint
Documentation
createPaymentplan
View
updatePaymentplan
View
deletePaymentplan
View
listPaymentPlans
View
Endpoint
Documentation
listPayouts
View
listCommissions
View
Endpoint
Documentation
createProductGroup
View
getProductGroup
View
updateProductGroup
View
deleteProductGroup
View
listProductGroups
View
Endpoint
Documentation
createProduct
View
getProduct
View
updateProduct
View
deleteProduct
View
copyProduct
View
listProducts
View
listProductTypes
View
Endpoint
Documentation
getPurchase
View
updatePurchase
View
listPurchases
View
listPurchasesOfEmail
View
getPurchaseTracking
View
addBalanceToPurchase
View
createUpgradePurchase
View
createAddonChangePurchase
View
getPurchaseDownloads
View
refundPurchase
View
refundPartially
View
resendPurchaseConfirmationMail
View
Endpoint
Documentation
startRebilling
View
stopRebilling
View
createRebillingPayment
View
listRebillingStatusChanges
View
Endpoint
Documentation
getServiceProofRequest
View
updateServiceProofRequest
View
listServiceProofRequests
View
Endpoint
Documentation
createShippingCostPolicy
View
getShippingCostPolicy
View
updateShippingCostPolicy
View
deleteShippingCostPolicy
View
listShippingCostPolicies
View
Endpoint
Documentation
statsSales
View
statsSalesSummary
View
statsDailyAmounts
View
statsExpectedPayouts
View
statsMarketplace
View
Endpoint
Documentation
renderJsTrackingCode
View
listConversionTools
View
Endpoint
Documentation
listTransactions
View
refundTransaction
View
reportFraud
View
Endpoint
Documentation
createUpgrade
View
getUpgrade
View
deleteUpgrade
View
listUpgrades
View
getSmartupgrade
View
listSmartUpgrades
View
Endpoint
Documentation
getUpsells
View
updateUpsells
View
deleteUpsells
View
Endpoint
Documentation
requestApiKey
View
retrieveApiKey
View
unregister
View
getUserInfo
View
getGlobalSettings
View
Endpoint
Documentation
createVoucher
View
getVoucher
View
updateVoucher
View
deleteVoucher
View
listVouchers
View
validateCouponCode
View
Upgrading from gosuccess/php-ds24-api-wrapper? See MIGRATION.md for detailed instructions on namespace changes, constructor updates, and breaking changes.
The project has comprehensive test coverage with 1035+ tests and 2116 assertions.
# Run all tests
composer test
# Run tests with coverage (requires PCOV or Xdebug)
composer test:coverage
# Run mutation testing (validates test quality)
composer mutation
# Run specific test suites
composer test:unit
composer test:integration
Quality Metrics:
Tests : 1035 tests, 2116 assertions
Coverage : Lines ~98%, Functions ~99%, Classes 100%
Mutation Score : 85%+ MSI (test quality indicator)
PHPStan : Level 9 (maximum strictness)
See TESTING.md for detailed testing guide, coverage setup, mutation testing, and best practices.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please read our documentation:
Quick Start for Contributors
# Clone repository
git clone https://github.com/GoSuccessHQ/digistore24-api.git
cd digistore24-api
# Install dependencies (requires PHP 8.4+)
composer install
# Verify setup
php -v # Should show PHP 8.4.x
# Run tests
composer test
# Check code quality
composer cs:fix
composer analyse
See DEVELOPER_SETUP.md for detailed IDE setup instructions.
Documentation : Check the docs/ directory for endpoint-specific guides
Testing Guide : See TESTING.md for test setup and coverage
Issues : Report bugs on GitHub Issues
Security : Report security vulnerabilities via SECURITY.md
Migration Guide : See MIGRATION.md for upgrading from v1.x
Changelog : See CHANGELOG.md for version history