A Laravel-first SDK that defines the service-driver contracts your DGP plugins implement, plus the typed DTO payloads (Requests/Responses/Types) they exchange with the host.
This package is not your plugin system. Your plugin system already:
- installs/enables plugins
- collects config requirements + renders admin settings UI
- loads the plugin’s exported class (default export)
- passes a
dgp_handler/ runtime context (and the plugin can also read its own config)
This SDK’s job is to standardize what that exported class implements, so the Host can call any provider in a uniform way.
Drivers implement only what they support (refill, cancel, bulk, fast-schema, etc.). The Host checks support via instanceof (and/or a capability map).
if ($driver instanceof OrderRefillContract) {
// refill supported
}Every call uses typed Request DTOs and returns typed Response DTOs, wrapped in a consistent Result<T>.
A registry + resolver + manager gives the Host a single way to:
- register available drivers
- resolve a driver by key
- call capability methods safely
- apply boundary wrappers (normalize errors, retry rules, rate-limit hints, etc.)
Using JustAnotherPanel as the reference model, the SDK targets common features:
services → order create/status → balance → optional cancel/refill/bulk.
Providers can integrate at two schema levels:
- Contract:
ServicesCatalogContract(MUST) - Returns:
ServiceDefinition[](raw list) - Host job: normalize raw services into the Host’s internal UI state (tags/fields/options/constraints) using Host rules.
This is the default and works for every provider.
- Contract:
ServiceSchemaContract(OPTIONAL / ADVANCED) - Returns:
ServiceProps(TS-parity UI schema) - Host job: verify + clamp + cache the schema, then serve to frontend.
This lane exists for sophisticated plugins that already compute the full UI schema.
“Fast lane” does not mean blind trust. The Host validates and can reject/fallback to Lane A.
- Result-first return strategy: contract calls return
Result<ResponseDto>so business failures (insufficient funds, rate-limited, invalid params) are first-class outcomes. - Exceptions are internal: throw only for unrecoverable/system/invariant issues (transport, misconfiguration).
DriverManagerconverts them toResultat the boundary. - TS parity for
ServiceProps: schema types must serialize into the exact JSON keys your React UI expects (snake_case + camelCase as designed). - Pre-flight validation: validate DTO invariants before any HTTP call.
- Safe schema execution: any “code-like” fields (e.g., quantity
eval+code) must be treated as a DSL / restricted expression, never raw eval.
Your TS schema uses a mixed key convention (example: pricing_role but quantityDefault).
Do not rely on automatic property names for Lane B. Types/Schema/* should implement JsonSerializable (or your Arrayable) and explicitly output the correct keys:
public function jsonSerialize(): array {
return array_filter([
'id' => $this->id,
'pricing_role' => $this->pricing_role,
'quantityDefault' => $this->quantityDefault,
], fn ($v) => $v !== null);
}src/
DgpSdk.php
DgpSdkServiceProvider.php
Driver/
DriverContext.php // runtime context: config + services (transport/logger/cache/clock)
DriverRegistry.php // registered driver factories + metadata
DriverResolver.php // resolve driver instance by key (registry + context)
DriverManager.php // boundary wrapper: resolve + capability helpers + Result wrapping
AbstractServiceDriver.php // base class: core helpers + HealthCheck default
Contracts/
Catalog/
ServicesCatalogContract.php // CORE (MUST): raw service catalog (Lane A)
ServiceInputSchemaContract.php // OPTIONAL: minimal per-service input schema (Host still normalizes)
ServiceSchemaContract.php // OPTIONAL/ADVANCED: pre-normalized ServiceProps (Lane B fast lane)
OperationInputSchemaContract // OPTIONAL/ADVANCED
Orders/
OrderCreateContract.php // CORE (MUST): place order
OrderStatusContract.php // CORE (MUST): status lookup
OrderCancelContract.php // OPTIONAL: cancel
Balance/
BalanceContract.php // CORE (MUST for panel-like): provider balance
Refill/
OrderRefillContract.php // OPTIONAL: create refill
RefillStatusContract.php // OPTIONAL: refill status
Bulk/
BulkOrderCreateContract.php // OPTIONAL: bulk create
BulkOrderStatusContract.php // OPTIONAL: bulk status
Subscription/
SubscriptionContract.php // OPTIONAL: subscription lifecycle
DripFeed/
DripFeedContract.php // OPTIONAL: dripfeed lifecycle
Infra/
TransportContract.php // HOST-PROVIDED transport interface (Laravel adapter lives in host)
AuthStrategyContract.php // OPTIONAL: driver-specific auth strategy
ErrorNormalizerContract.php // CORE (MUST): normalize provider errors into DgpError
RetryPolicyContract.php // OPTIONAL: retry/backoff decisions
RateLimitPolicyContract.php // OPTIONAL: rate limit hints/windows
IdempotencyContract.php // OPTIONAL: idempotency rules
Discovery/
CapabilitiesContract.php // CORE (MUST): declare supported capabilities
ServiceMapperContract.php // OPTIONAL: host↔provider mapping helper
Ops/
HealthCheckContract.php // CORE (MUST via AbstractServiceDriver): health/ping
AuditTrailContract.php // OPTIONAL: audit hooks
WebhookIngestContract.php // OPTIONAL: webhook parsing/verification
Payloads/
Requests/
Catalog/
ListServicesRequest.php
GetServiceInputSchemaRequest.php
GetServiceSchemaSnapshotRequest.php
GetServiceSchemaForServiceRequest.php
Orders/
CreateOrderRequest.php
GetOrderStatusRequest.php
CancelOrderRequest.php
Balance/
GetBalanceRequest.php
Refill/
CreateRefillRequest.php
GetRefillStatusRequest.php
Bulk/
BulkCreateOrdersRequest.php
BulkGetOrderStatusRequest.php
Subscription/
CreateSubscriptionRequest.php
GetSubscriptionStatusRequest.php
CancelSubscriptionRequest.php
DripFeed/
CreateDripFeedRequest.php
GetDripFeedStatusRequest.php
CancelDripFeedRequest.php
Infra/
HttpRequestDto.php
AuthApplyRequest.php
NormalizeErrorRequest.php
RetryDecisionRequest.php
RateLimitHintRequest.php
MakeIdempotencyKeyRequest.php
Discovery/
GetCapabilitiesRequest.php
ResolveProviderServiceRequest.php
Ops/
HealthCheckRequest.php
AuditRecordRequest.php
ParseWebhookRequest.php
Responses/
Catalog/
ListServicesResponse.php
GetServiceInputSchemaResponse.php
GetServiceSchemaSnapshotResponse.php
GetServiceSchemaForServiceResponse.php
Orders/
CreateOrderResponse.php
GetOrderStatusResponse.php
CancelOrderResponse.php
Balance/
GetBalanceResponse.php
Refill/
CreateRefillResponse.php
GetRefillStatusResponse.php
Bulk/
BulkCreateOrdersResponse.php
BulkGetOrderStatusResponse.php
Subscription/
CreateSubscriptionResponse.php
GetSubscriptionStatusResponse.php
CancelSubscriptionResponse.php
DripFeed/
CreateDripFeedResponse.php
GetDripFeedStatusResponse.php
CancelDripFeedResponse.php
Infra/
HttpResponseDto.php
AuthApplyResponse.php
NormalizeErrorResponse.php
RetryDecisionResponse.php
RateLimitHintResponse.php
MakeIdempotencyKeyResponse.php
Discovery/
GetCapabilitiesResponse.php
ResolveProviderServiceResponse.php
Ops/
HealthCheckResponse.php
AuditRecordResponse.php
ParseWebhookResponse.php
Types/
Money.php
Currency.php
Service/
ServiceDefinition.php // raw baseline service item (strict core + meta bag)
ServiceCategory.php
ServiceTag.php
ServiceInputSchema.php // minimal per-service schema (Lane A helper)
ServiceField.php
ServiceFieldRule.php
Schema/ // TS-parity UI schema (Lane B: ServiceProps)
ServiceProps.php
Tag.php
Field.php
FieldOption.php
ServiceFallback.php
Ui/
UiNode.php
UiString.php
UiNumber.php
UiBoolean.php
UiAnyOf.php
UiArray.php
UiObject.php
Orders/
OrderRef.php
OrderStatus.php
OrderStatusCode.php
Balance/
ProviderBalance.php
Refill/
RefillRef.php
RefillStatus.php
RefillStatusCode.php
Subscription/
SubscriptionRef.php
SubscriptionStatus.php
SubscriptionStatusCode.php
DripFeed/
DripFeedRef.php
DripFeedStatus.php
DripFeedStatusCode.php
Infra/
CapabilityMap.php
ProviderRateLimit.php
ProviderRateLimitWindow.php
IdempotencyKey.php
HttpMethod.php
Ops/
HealthState.php
AuditRecord.php
WebhookEvent.php
WebhookEventType.php
Support/
Result.php // Result<T>: success/failure wrapper
DgpError.php
DgpErrorCode.php
Exceptions/
DgpException.php
TransportException.php
AuthException.php
ProviderException.php
RateLimitedException.php
ValidationException.php
Hydration/
HydratesFromArray.php // trait for DTO ::fromArray(...)
DtoHydrator.php // optional helper for host/controller DTO creation
Validation/
PayloadValidator.php // pre-flight validation + schema verification
Serialization/
Arrayable.php
Normalizes.php
Testing/
FakeTransport.php
FakeClock.php- Host loads a plugin (your existing system) → obtains the exported driver class.
- Host resolves a driver instance via
DriverResolver/DriverManager. - Host calls capabilities (catalog/order/status/balance/etc.) via the driver interfaces.
- Driver returns typed DTO responses wrapped in
Result<T>, with normalized errors.
Stores driver registrations:
driver_key→ factory/closure/class string- optional metadata (label, version, category)
Why: central place to list available drivers and ensure uniqueness.
Creates driver instances from:
- registry entry
- runtime configuration (plugin settings, handler context, etc.)
Why: a single resolution path so the Host never does new directly.
High-level façade used by the Host:
resolve($key)- convenience helpers for “must support X contract”
- safe wrappers for common patterns (error normalization, retry/backoff decisions)
Why: keeps Host code clean and consistent.
An abstract driver with shared core behavior, including Health as a baseline.
Recommended built-ins:
- implements
HealthCheckContract - common helpers:
ok(),fail(),wrapExceptions() - convenience access to handler/config
- shared normalization utilities
Why: eliminates boilerplate and standardizes minimal behavior across drivers.
-
ServicesCatalogContract- Raw services list:
ServiceDefinition[]. - Enables discovery/mapping and Host-owned normalization (Lane A).
- Raw services list:
-
OrderCreateContract- Place an order.
-
OrderStatusContract- Fetch order status.
-
BalanceContract- Fetch provider balance.
-
CapabilitiesContract- Declare supported features (cancel/refill/bulk/schema/etc.).
-
ErrorNormalizerContract- Normalize any provider error shape into
DgpError.
- Normalize any provider error shape into
-
HealthCheckContract(provided byAbstractServiceDriver)- Quick health/ping/config sanity.
-
ServiceInputSchemaContract(optional helper for Lane A)- Returns minimal per-service fields (
ServiceInputSchema). - The Host still owns final UI normalization.
- Returns minimal per-service fields (
-
ServiceSchemaContract(optional/advanced: Lane B fast lane)-
Returns pre-normalized
ServiceProps. -
Must support both shapes:
- Snapshot: provider-wide schema for caching.
- Per-service: focused schema for a single service.
-
Host validates/clamps; can fallback to Lane A if invalid.
-
- Cancel:
OrderCancelContract - Refill:
OrderRefillContract,RefillStatusContract - Bulk:
BulkOrderCreateContract,BulkOrderStatusContract - Subscription:
SubscriptionContract - Drip feed:
DripFeedContract
- Transport:
TransportContract(host-provided interface) - Auth:
AuthStrategyContract - Retry:
RetryPolicyContract - Rate limit:
RateLimitPolicyContract - Idempotency:
IdempotencyContract
- Audit:
AuditTrailContract - Webhooks:
WebhookIngestContract
Input DTOs passed by the Host.
Rules:
- explicit fields, no magic arrays
- allow
metaonly when intentionally flexible
Typed results returned by drivers.
Rules:
- canonical normalized data
- optional
metafor provider-specific extras
Reusable building blocks shared across payloads.
Key split:
Types/Service/*→ raw service list + minimal input schema (Lane A)Types/Schema/*→ TS-parityServicePropsUI schema (Lane B)
A consistent return model:
Result<T>— success/failure wrapperDgpError+DgpErrorCode— canonical error representation
Typed exceptions for internal ergonomics (TransportException, AuthException, etc.). Drivers can throw internally, while DriverManager wraps/normalizes into Result.
- pre-flight validation helpers
- schema verification helpers (Lane B)
- serialization interfaces
- fakes (
FakeTransport,FakeClock) for unit tests
Result<T>+DgpError+DgpErrorCodeDriverContext+DriverManagerboundary wrappingPayloadValidatorfor pre-flight + schema verification
ServicesCatalogContract+ServiceDefinitionOrderCreateContract,OrderStatusContract,BalanceContractErrorNormalizerContract,CapabilitiesContract- health check baseline
ServiceInputSchemaContract+ServiceInputSchema- mapping helpers if needed
Types/Schema/*(TS-parityServiceProps)ServiceSchemaContractsnapshot + per-service- strict validation + versioning + clamp rules
- cancel, refill, bulk
- subscription, dripfeed
- infra hooks (retry/rate-limit/idempotency)
- ops hooks (audit/webhooks)
- install/enable/disable plugins (your system already does this)
- store plugin settings (your system already does this)
- define host database schema
- enforce UI implementation details (it only defines contracts + typed shapes)