Repository navigation
Releases: GoSuccessHQ/digistore24-api
Release list
v3.0.0 β Complete, fully-typed binding to the Digistore24 API
This major release turns the SDK into a complete, fully-typed binding to the entire Digistore24 API and fixes a long list of inconsistencies β many of which meant requests silently did nothing or responses came back empty. Every change was derived from the per-endpoint OpenAPI specs and verified live against a real account and order.
β¨ Highlights
- Fully-typed, complete binding. Every response now exposes every API field as a typed property β with nested DTOs for objects like the buyer, line items, and transactions β plus a
dataarray with the full raw payload so no field is ever lost. Every request exposes a settable property for every spec parameter. (+41 DTOs, +14 enums.) - All 9 product languages.
createProduct/updateProduct/copyProductnow acceptname,description,access_instructions,optin_text, etc. in all nine API languages (de, en, es, fr, pt, pl, it, nl, sl) β previously only de/en/es. - Spec-aligned HTTP methods. Reads use GET, updates PUT, deletes DELETE (previously almost everything was POST).
SpecConformanceTestfreezes the endpoint β HTTP-method mapping for all 122 endpoints and guards against future drift.
π Notable fixes
data[]wrapping β many create/update endpoints (productGroup, orderform, voucher, paymentplan, shippingCostPolicy, product, buyer, upsells, affiliateCommission, purchase, β¦) sent their fields flat, so the API silently ignored the update (modified:N) or rejected the call. They now nest the fields underdata[]as required.- Wrong response field mapping β
getPurchase,getProduct,getImage,statsSales,getGlobalSettingsand others read wrong or non-existent keys and surfaced only a fraction of the data; all corrected to the real keys. - Empty responses β ten parsers (createOrderform, createUpgrade, getOrderform, getPurchaseTracking, β¦) returned nothing because they unwrapped the
dataenvelope twice. Fixed. - Parsing crashes β response parsing no longer throws when the API legitimately returns a value a strict input validator would reject (e.g.
getVoucher'svalid_from). - Correct parameter names where they differed from the SDK (
policy_id,service_proof_id, β¦).
β οΈ Breaking changes
Most "breaking" changes touch code paths that were previously broken. The key ones:
CreatePaymentplanRequestnow takes$productIdbefore$paymentPlan.- Several request constructors changed to the real API parameters:
UpdateAffiliateCommissionRequesttakesproductIds(string);GetEticketRequest/ValidateEticketRequestuseeticketId; the service-proof requests useserviceProofId(int);ListAccountAccessRequestis parameterless;ListPaymentPlansRequestrequires aproductId; the eticket/service-proof/delivery list endpoints take a search DTO. - Some response properties moved β e.g.
GetPurchaseResponseno longer has$productId/$buyerEmail; use$response->buyer->emailand$response->items[0]->productId, or the full$response->data. UpdateBuyerRequesttakes individual address fields instead of an$addressarray.refundPartiallymoved from$ds24->billingto$ds24->purchases.- Invalid requests now throw a
ValidationException(HTTP 400) before any HTTP call.
π See MIGRATION.md for step-by-step upgrade instructions and CHANGELOG.md for the full list.
Requirements
- PHP 8.4+ (the SDK uses property hooks)
v2.0.6
Fixed
ValidateAffiliateRequest Parameter Correction
- Fixed HTTP method from POST to GET (per OpenAPI specification)
- Corrected parameter name from
affiliateIdtoaffiliateName - Added missing required parameter
productIds - Fixed API parameter names to
affiliate_nameandproduct_ids
Before:
$request = new ValidateAffiliateRequest(affiliateId: 'AFF123');After:
$request = new ValidateAffiliateRequest(
affiliateName: 'testaffiliate',
productIds: '123,456'
);v2.0.5
IpnSetupResponse Structure Correction
Updated IpnSetupResponse to match the actual Digistore24 API response structure.
Changed Properties:
created: Changed fromstringtobool(converts Y/N automatically)updated: Changed fromstringtobool(converts Y/N automatically)deleted: Changed fromstringtobool(converts Y/N automatically)
Added Properties:
domainId: Domain ID identifying the IPN connectionshaPassphrase: SHA passphrase for parameter signingipnConfigId: IPN configuration IDipnId: IPN ID
Removed Properties:
accountId: Not present in actual API responsefullResponse: Not present in actual API response
Implementation:
- Now uses
TypeConverterutility for Y/N to boolean conversion - Follows project conventions and utility class usage
created, updated, and deleted are now bool instead of string.
Migration:
// Before
if ($response->created === 'Y') { }
// After
if ($response->created) { }π§ Patch Release v2.0.4 - HTTP 411 Error Fix
Bug Fix
Fixed HTTP 411 error for POST requests with empty body.
Problem:
/unregister endpoint failed with "411 Length Required" because POST requests without body didn't send Content-Length header.
Solution:
API client now sets Content-Length: 0 automatically for empty POST/PUT/PATCH/DELETE requests.
Impact:
/unregister and similar endpoints now work correctly. No code changes needed.
Changelog: v2.0.3...v2.0.4
π§ Patch Release v2.0.3 - Error Handling & Response Validation
π Overview
This patch release improves error handling for malformed JSON responses and corrects the UnregisterResponse class to match real API response structure with proper type conversion.
β¨ Improvements
Enhanced JSON Error Messages
Improved error messages when the API returns invalid JSON responses:
Before:
ApiException: Invalid JSON response from API
After:
ApiException: Invalid JSON response from API: Syntax error. Body: {"api_version":"1.2",...}
Benefits:
- Full response body included in error message (no truncation)
- JSON error details immediately visible
- HTTP status code in error context
- Faster debugging of API issues
Modified: src/Client/ApiClient.php
π Bug Fixes
UnregisterResponse Type Correction
Fixed UnregisterResponse to match actual API response structure:
Before (Incorrect):
public string $modified; // Was expecting string 'Y' or 'N'
public ?string $note; // Using is_string() checkAfter (Correct):
public bool $modified; // Properly converted from 'Y'/'N' to boolean
public ?string $note; // Using TypeConverter::toString()Changes:
modifiedproperty now correctly typed asbool- Uses
TypeConverter::toBool()to convert 'Y'/'N' βtrue/false - Uses
TypeConverter::toString()fornotefield - Added test with real production API response
Modified: src/Response/ApiKey/UnregisterResponse.php
π Migration Guide
For JSON Error Handling
No code changes required. Error messages are now more informative automatically.
For UnregisterResponse Users
If you were checking the modified property:
// Before (string comparison)
if ($response->modified === 'Y') {
// API key was deleted
}
// After (boolean check)
if ($response->modified) {
// API key was deleted
}π§ͺ Quality Assurance
- β 1146/1146 Unit Tests Passing (2296 assertions)
- β PHPStan Level 9: 0 errors (654 files analyzed)
- β PHP CS Fixer: 0 violations
- β New Test: Real production API response validation
π¦ Files Changed
3 files changed: 23 insertions(+), 22 deletions(-)
Modified Files
src/Client/ApiClient.php- Enhanced JSON error messagessrc/Response/ApiKey/UnregisterResponse.php- Correct type conversiontests/Unit/Response/ApiKey/UnregisterResponseTest.php- Boolean assertions
π― Impact
Low Impact
- JSON error improvements: Automatic, no code changes needed
- UnregisterResponse: Only affects users checking
modifiedproperty with string comparison
Recommended Actions
- Update any string comparisons on
modifiedproperty to boolean checks - Benefit from improved error messages automatically
Full Changelog: v2.0.2...v2.0.3
π§ Patch Release v2.0.2 - ApiPermission Enum Enhancement
π Overview
This patch release enhances the ApiPermission enum by adding a new DELIVERY permission level and normalizing case naming conventions.
β οΈ BREAKING CHANGES
ApiPermission Enum
Case Name Change:
// v2.0.1 (Old)
ApiPermission::READ_ONLY
// v2.0.2 (New)
ApiPermission::READONLYValue Change:
// v2.0.1 (Old)
'read-only'
// v2.0.2 (New)
'readonly'β¨ New Features
New Permission Level: DELIVERY
Added a new permission level specifically for delivery-only API access:
use GoSuccess\Digistore24\Api\Enum\ApiPermission;
// Available permission levels
ApiPermission::READONLY // Value: 'readonly' - Read-only access
ApiPermission::DELIVERY // Value: 'delivery' - Delivery operations only
ApiPermission::WRITABLE // Value: 'writable' - Full write accessUse Cases for DELIVERY Permission:
- API keys used exclusively for order delivery/fulfillment
- Limited access scope for third-party integrations
- Separation of concerns between read, delivery, and write operations
π§ͺ Quality Assurance
- β 1145/1145 Unit Tests Passing (+8 new tests, 2294 assertions)
- β PHPStan Level 9: 0 errors (654 files analyzed, +1 file)
- β PHP CS Fixer: 0 violations (PSR-12 compliant)
- β
New Test File:
ApiPermissionTest.phpwith comprehensive coverage
π Test Coverage
The new ApiPermissionTest includes:
- β Value Validation - All cases have correct string values
- β Label Testing - All cases return proper human-readable labels
- β
Case-Insensitive Conversion -
fromString()handles mixed case - β Invalid Input Handling - Graceful null returns for invalid values
- β Labels Mapping - Complete value-to-label array generation
- β Values Array - All valid string values extraction
- β
Validation Method -
isValid()checks for valid permissions - β Edge Cases - Null, empty string, and invalid value handling
π§ Migration Guide
For users upgrading from v2.0.1 β v2.0.2
If you're using ApiPermission enum directly in your code:
// Old (v2.0.1)
if ($permission === ApiPermission::READ_ONLY) {
// read-only logic
}
// New (v2.0.2)
if ($permission === ApiPermission::READONLY) {
// read-only logic
}
// New DELIVERY case
if ($permission === ApiPermission::DELIVERY) {
// delivery-only logic
}String Value Changes:
// Old (v2.0.1)
ApiPermission::fromString('read-only'); // β
Worked
// New (v2.0.2)
ApiPermission::fromString('readonly'); // β
Now works
ApiPermission::fromString('read-only'); // β Returns null
ApiPermission::fromString('delivery'); // β
New DELIVERY caseNote: The fromString() method is case-insensitive, so 'READONLY', 'ReadOnly', and 'readonly' all work.
π¦ Files Changed
3 files changed: 81 insertions(+), 3 deletions(-)
Modified Files (2)
src/Enum/ApiPermission.php- Added DELIVERY case, renamed READ_ONLY β READONLYRELEASE_NOTES.md- Updated release documentation
New Files (1)
tests/Unit/Enum/ApiPermissionTest.php- Comprehensive test suite (8 tests)
π‘ Why This Change?
1. Consistency
- PHP property naming convention: use
readonlykeyword (notread_only) - Hyphenated values (
'read-only') are inconsistent with camelCase/PascalCase - Aligns with modern PHP 8.4 conventions
2. Separation of Concerns
READONLY- View data only (GET operations)DELIVERY- Fulfill orders, update delivery status (limited POST/PUT)WRITABLE- Full CRUD operations (unrestricted access)
3. Security
- Granular permission control for API keys
- Minimize attack surface by limiting key capabilities
- Better audit trail with specific permission levels
π― Impact Analysis
Who is affected?
- Low Impact: Most users don't directly interact with
ApiPermissionenum - Medium Impact: Users with custom permission checking logic
- High Impact: Users storing permission strings in databases (migration required)
Database Migration (if storing permissions):
-- Update existing 'read-only' values to 'readonly'
UPDATE api_keys SET permission = 'readonly' WHERE permission = 'read-only';
-- Verify no old values remain
SELECT * FROM api_keys WHERE permission = 'read-only';π Changelog Summary
Added
ApiPermission::DELIVERYcase for delivery-only operationsApiPermissionTestwith 8 comprehensive test methods- Label for DELIVERY permission: "Delivery"
Changed (Breaking)
ApiPermission::READ_ONLYβApiPermission::READONLY- String value:
'read-only'β'readonly'
Improved
- Test coverage increased from 1137 to 1145 tests (+8)
- Assertions increased from 2286 to 2294 (+8)
- PHPStan now analyzes 654 files (was 653)
Full Changelog: v2.0.1...v2.0.2
π v2.0.1 - Complete IPN Implementation & List Operations Enhancement
π Overview
This patch release completes the implementation of IPN (Instant Payment Notification) endpoints and enhances List operations with comprehensive search capabilities. All Request classes now fully match the OpenAPI specification with type-safe DTOs and Enums.
β οΈ BREAKING CHANGES
Note: These breaking changes were introduced in v2.0.0 and are documented here for reference. If you're upgrading from v2.0.0 to v2.0.1, there are no additional breaking changes.
IPN Request Classes
IpnSetupRequest
v2.0.0 (Previous): Only 2 parameters (incomplete implementation)
$request = new IpnSetupRequest(
url: 'https://yoursite.com/webhook',
ipnPassword: 'secret123'
);v2.0.1 (Current): Complete with 9 parameters
$request = new IpnSetupRequest(
ipnUrl: 'https://yoursite.com/webhook',
name: 'My Platform',
productIds: 'all',
domainId: 'my-platform',
categories: [IpnTransactionCategory::ORDERS, IpnTransactionCategory::AFFILIATIONS],
transactions: [IpnTransactionType::PAYMENT, IpnTransactionType::REFUND],
timing: IpnTiming::DELAYED,
shaPassphrase: 'random',
newsletterSendPolicy: IpnNewsletterSendPolicy::SEND_IF_OPTIN
);- β Changed from 2 parameters to 9 comprehensive parameters
- β Added type-safe Enums for categories, transactions, timing, and newsletter policy
- β
Renamed
urlβipnUrl, removedipnPassword
IpnInfoRequest
v2.0.0 (Previous): HTTP POST, no parameters
$response = $api->ipn()->info(); // Incompletev2.0.1 (Current): HTTP GET with optional filter
$request = new IpnInfoRequest(domainId: 'my-platform'); // HTTP GET
$response = $api->ipn()->info($request);- β Changed from HTTP POST to HTTP GET
- β
Added optional
domainIdparameter for filtering
IpnDeleteRequest
v2.0.0 (Previous): HTTP POST, no parameters
$request = new IpnDeleteRequest(); // Incomplete
$response = $api->ipn()->delete($request);v2.0.1 (Current): HTTP DELETE with required domainId
$response = $api->ipn()->delete('my-platform'); // HTTP DELETE, required domainId- β Changed from HTTP POST to HTTP DELETE
- β
Now requires
domainIdparameter (string) - β
IpnResource::delete()signature changed fromdelete(?IpnDeleteRequest)todelete(string $domainId)
List Request Classes
ListPurchasesRequest
v2.0.0 (Previous): Basic 4 parameters
$request = new ListPurchasesRequest(
productId: 123,
buyerEmail: 'buyer@example.com',
fromDate: '2025-01-01',
toDate: '2025-12-31'
);v2.0.1 (Current): Enhanced with 8 comprehensive parameters
$search = new PurchaseSearchData(
productId: 123,
email: 'buyer@example.com',
role: 'buyer'
);
$request = new ListPurchasesRequest(
from: '2025-01-01',
to: '2025-12-31',
search: $search,
sortBy: PurchaseSortBy::DATE,
sortOrder: SortOrder::DESC,
loadTransactions: true,
pageNo: 1,
pageSize: 500
);- β Replaced 4 basic parameters with 8 comprehensive parameters
- β
Introduced
PurchaseSearchDataDTO with 13 search criteria - β
Added type-safe
PurchaseSortByandSortOrderEnums - β
Added pagination support (
pageNo,pageSize) - β
Added
loadTransactionsflag for detailed data
ListProductsRequest
v2.0.0 (Previous): Parameters not matching OpenAPI spec
$request = new ListProductsRequest(
productType: 'digital',
onlyPublished: true
);v2.0.1 (Current): Corrected to match OpenAPI spec
$request = new ListProductsRequest(
sortBy: ProductSortBy::NAME
);- β
Simplified to single
sortByparameter withProductSortByEnum - β
Removed
productTypeandonlyPublished(not in OpenAPI spec)
ListTransactionsRequest
v2.0.0 (Previous): Generic arrays, no type safety
$request = new ListTransactionsRequest(
search: ['product_id' => 123], // Generic array
sort: ['date' => 'desc'] // Generic array
);v2.0.1 (Current): Type-safe with DTOs and Enums
$search = new TransactionSearchData(
productId: 123,
email: 'buyer@example.com'
);
$request = new ListTransactionsRequest(
from: '2025-01-01',
to: '2025-12-31',
search: $search,
sortBy: TransactionSortBy::DATE,
sortOrder: SortOrder::DESC
);- β
Replaced generic arrays with
TransactionSearchDataDTO - β
Added type-safe
TransactionSortByandSortOrderEnums
β¨ New Features
π― 5 New Enums for Type Safety
-
SortOrder- Universal sort directionASC,DESC
-
PurchaseSortBy- Purchase list sortingDATE,EARNING,AMOUNT
-
ProductSortBy- Product list sortingNAME,GROUP
-
TransactionSortBy- Transaction list sortingDATE,EARNING,AMOUNT
-
OrderType- Live vs Test ordersLIVE,TEST
All Enums implement StringBackedEnum interface with StringBackedEnumTrait for consistency.
π¦ 2 New DTOs for Structured Search
-
PurchaseSearchData- 13 search criteriarole,productId,firstName,lastName,emailhasAffiliate,affiliateName,orderType,payMethodbillingType,transactionType,currency,purchaseId
-
TransactionSearchData- 12 search criteria- Same as
PurchaseSearchDataminusorderType
- Same as
Both extend AbstractDataTransferObject with toArray() method.
π Documentation Updates
Updated documentation for all IPN endpoints:
- β
ipnSetup.md- Complete rewrite with all 9 parameters and Enum examples - β
ipnInfo.md- Updated withdomainIdparameter and HTTP GET method - β
ipnDelete.md- Updated with requireddomainIdparameter and HTTP DELETE method
All docs now include:
- Modern named arguments syntax
- Type-safe Enum usage examples
- Breaking changes warnings
- Error handling examples
π§ͺ Quality Assurance
- β 1137/1137 Unit Tests Passing (2271 assertions)
- β PHPStan Level 9: 0 errors (653 files analyzed)
- β PHP CS Fixer: 0 violations (PSR-12 compliant)
- β 6 Test Files Completely Rewritten with comprehensive coverage
π§ Migration Guide
For users upgrading from v2.0.0 β v2.0.1
Good news! If you're already on v2.0.0, you only need to update your IPN and List operations code to use the new comprehensive parameters. The breaking changes were already introduced in v2.0.0.
Step 1: Update IPN Setup
// v2.0.0 (Incomplete)
$api->ipn()->setup(
url: 'https://example.com/webhook',
ipnPassword: 'secret'
);
// v2.0.1 (Complete)
use GoSuccess\Digistore24\Api\Enum\IpnTiming;
use GoSuccess\Digistore24\Api\Enum\IpnTransactionType;
$api->ipn()->setup(new IpnSetupRequest(
ipnUrl: 'https://example.com/webhook',
name: 'My Platform',
productIds: 'all',
timing: IpnTiming::BEFORE_THANKYOU,
transactions: [IpnTransactionType::PAYMENT, IpnTransactionType::REFUND]
));Step 2: Update IPN Delete
// v2.0.0 (Incomplete)
$api->ipn()->delete(new IpnDeleteRequest());
// v2.0.1 (Complete)
$api->ipn()->delete('my-platform'); // Direct string parameterStep 3: Update List Purchases
// v2.0.0 (Basic)
$api->purchase()->list(
productId: 123,
buyerEmail: 'test@example.com'
);
// v2.0.1 (Enhanced)
use GoSuccess\Digistore24\Api\DTO\PurchaseSearchData;
use GoSuccess\Digistore24\Api\Enum\PurchaseSortBy;
use GoSuccess\Digistore24\Api\Enum\SortOrder;
$search = new PurchaseSearchData(
productId: 123,
email: 'test@example.com'
);
$api->purchase()->list(new ListPurchasesRequest(
search: $search,
sortBy: PurchaseSortBy::DATE,
sortOrder: SortOrder::DESC
));π¦ Files Changed
24 files changed: 824 insertions(+), 214 deletions(-)
New Files (7)
src/DTO/PurchaseSearchData.phpsrc/DTO/TransactionSearchData.phpsrc/Enum/OrderType.phpsrc/Enum/ProductSortBy.phpsrc/Enum/PurchaseSortBy.phpsrc/Enum/SortOrder.phpsrc/Enum/TransactionSortBy.php
Modified Files (17)
- Request Classes:
IpnSetupRequest,IpnInfoRequest,IpnDeleteRequest,ListPurchasesRequest,ListProductsRequest,ListTransactionsRequest - Resource:
IpnResource - Tests: 6 test files completely rewritten
- Documentation:
ipnSetup.md,ipnInfo.md,ipnDelete.md
π‘ Notes
- This release prioritizes type safety over backward compatibility
- All changes validated against OpenAPI specification
- OpenAPI spec contained errors (e.g.,
IpnNewsletterSendPolicyvalues) - corrected based on actual API behavior - Default values preserved for optional parameters (e.g., last 24 hours for date ranges)
- Parameter naming changed from snake_case to camelCase for PHP conventions
Full Changelog: v2.0.0...v2.0.1
π Digistore24 API Client v2.0.0
Major Release - Complete rewrite with PHP 8.4 property hooks, modern architecture, and extensive quality improvements.
π Highlights
PHP 8.4 Property Hooks
Automatic validation on property assignment - no more boilerplate constructors:
$buyer = new BuyerData();
$buyer->email = 'test@example.com'; // β
Auto-validated
$buyer->country = 'de'; // β
Auto-uppercased to 'DE'Cleaner API Calls
Methods with optional parameters no longer require explicit Request objects:
// v1.x - Always needed Request object
$products = $ds24->products->list(new ListProductsRequest());
// v2.0 - Much cleaner!
$products = $ds24->products->list();Enterprise-Grade Quality
- β 1,130 passing unit tests (100% success rate)
- β PHPStan Level 9 (maximum strictness) - 0 errors
- β 98% code coverage (lines), 99% functions, 100% classes
- β 85%+ mutation score (test quality validation)
- β PSR-12 compliant (0 code style violations)
Complete API Coverage
- β 122 endpoints fully implemented
- β 12 resource categories (Affiliates, Products, Purchases, etc.)
- β Comprehensive documentation for every endpoint
π₯ Breaking Changes
1. Namespace Change
// OLD
use GoSuccess\Digistore24\Digistore24;
// NEW
use GoSuccess\Digistore24\Api\Digistore24;2. Constructor Signature
// OLD
$ds24 = new Digistore24(apiKey: 'YOUR-KEY');
// NEW
$config = new Configuration(apiKey: 'YOUR-KEY');
$ds24 = new Digistore24($config);3. PHP Version Requirement
- Minimum PHP 8.4.0 (required for property hooks)
π Full migration guide: See MIGRATION.md
β¨ What's New
Architecture & Quality
- ποΈ Resource-based architecture with clean separation of concerns
- π― Type-safe - Full type hints, enums, and strict typing throughout
- π Automatic retry - Built-in exponential backoff for failed requests
- π¦ Rate limiting - Graceful handling of API rate limits
- π Fully documented - Comprehensive PHPDoc with examples
Developer Experience
- β GitHub Actions CI/CD - Automated testing, static analysis, code style checks
- β PHPStan Level 9 - Maximum type safety with baseline tracking
- β PHP CS Fixer - PSR-12 + PHP 8.4 rules enforced
- β Infection - Mutation testing for test quality validation
- β Dependabot - Automated dependency updates
Documentation
- π 122 endpoint docs organized in 29 categories
- π Migration guide with find-replace instructions
- π§ͺ Testing guide with coverage setup
- π οΈ Developer setup with IDE configuration
- π Changelog with complete version history
- π Security policy with vulnerability reporting
New Features
- π Optional Request parameters - 39+ methods across 27 Resources
- π¨ 15 typed DTOs with property hooks (BuyerData, PaymentPlanData, etc.)
- π§ Configuration object - Centralized config with validation
- β‘ Lazy loading - Resources initialized on-demand
π¦ Installation
# Fresh install
composer require gosuccess/digistore24-api
# Upgrade from v1.x
composer remove gosuccess/php-ds24-api-wrapper
composer require gosuccess/digistore24-apiπ― Quick Start
use GoSuccess\Digistore24\Api\Digistore24;
use GoSuccess\Digistore24\Api\Client\Configuration;
// Initialize
$config = new Configuration(apiKey: 'YOUR-API-KEY');
$ds24 = new Digistore24($config);
// Simple calls (no Request object needed)
$products = $ds24->products->list();
$userInfo = $ds24->users->getInfo();
$ping = $ds24->monitoring->ping();
// Advanced calls (with Request object for filters)
$purchases = $ds24->purchases->list(
new ListPurchasesRequest(
fromDate: new DateTime('-7 days'),
toDate: new DateTime('now')
)
);π Quality Metrics
| Metric | Value | Status |
|---|---|---|
| Unit Tests | 1,130 passing | β 100% |
| Assertions | 2,227 | β |
| Code Coverage | Lines ~98%, Functions ~99% | β |
| Mutation Score | 85%+ MSI | β |
| PHPStan | Level 9 (max) | β 0 errors |
| Code Style | PSR-12 | β 0 violations |
| Endpoints | 122 implemented | β 100% |
π§ Infrastructure
GitHub Actions Workflows
- β Tests - PHPUnit with coverage reporting
- β Static Analysis - PHPStan Level 9
- β Code Style - PHP CS Fixer with PSR-12
Composer Scripts
composer test # Run all tests
composer test:coverage # Coverage report
composer analyse # PHPStan analysis
composer cs:check # Code style check
composer cs:fix # Auto-fix code style
composer check # All quality checksDependency Management
- π€ Dependabot - Weekly Composer updates, monthly GitHub Actions
- π¦ Automated PRs - Security and version updates
π οΈ API Resources
| Resource | Endpoints | Documentation |
|---|---|---|
| Affiliates | 8 | Commission management |
| Billing | 3 | Invoicing & payments |
| Buyers | 8 | Customer information |
| Buy URLs | 3 | Order form management |
| Countries | 2 | Country & currency data |
| IPNs | 3 | Webhook management |
| Monitoring | 1 | Health checks |
| Products | 59 | Product management |
| Purchases | 24 | Order information |
| Rebilling | 4 | Subscription management |
| Users | 3 | Authentication & settings |
| Vouchers | 6 | Discount codes |
Total: 122 endpoints across 12 resource categories
π Documentation
- π README.md - Complete usage guide
- π MIGRATION.md - v1.x β v2.0 upgrade guide
- π§ͺ TESTING.md - Test setup & coverage
- π οΈ DEVELOPER_SETUP.md - IDE configuration
- π CHANGELOG.md - Version history
- π€ CONTRIBUTING.md - Contribution guidelines
- π SECURITY.md - Security policy
π Thank You
Special thanks to all contributors who helped make v2.0 possible! This release represents months of refactoring, testing, and quality improvements.
π Found a Bug?
Report issues: https://github.com/GoSuccessHQ/digistore24-api/issues
π License
MIT License - see LICENSE
Full Changelog: https://github.com/GoSuccessHQ/digistore24-api/blob/main/docs/CHANGELOG.md