upmind/domainnameapi-sdk
A PHP SDK for the DomainNameAPI service, giving Laravel and PHP apps a clean client for domain registration, transfers, renewals, availability checks, and contact management. Wraps API requests and responses so you can integrate registrar operations without writing raw HTTP calls.
psr/log ^2.0 or ^3.0 (widened from the previous constraint). Laravel 9+ apps are fine; if you're on PHP 8.0 or a Laravel version pinned to psr/log ^1.0, either this release won't resolve or you must stay on the 1.0 line. Confirm the soap and openssl PHP extensions are enabled — the package is a SOAP client under the hood.src/ and skip the ServiceType/StructType classes initially. Look for the single "entry-point" class (something like DomainNameApi, Client, or an Upmind\DomainNameApiSdk\... top-level class) that accepts credentials and a logger. That class is the only thing you should touch from your app; everything else is generated plumbing. v1.1 was regenerated against wsdltophp/packagebase v5 and packagegenerator v4, so class signatures and property handling may differ from 1.0 — read the entry point's constructor afresh rather than assuming.Psr\Log\LoggerInterface (e.g. Log::channel('domain')->driver()). The widened psr/log allowance means you can pass Laravel's native logger on current versions without an adapter shim.checkDomain/Checkdomain). This is the lowest-risk call: it has no side effects, exercises auth, and confirms whether you're pointed at the test or production endpoint. Print the raw response object once, then never again.setLocation/constructor URL argument) and wire it to config('services.domainnameapi.endpoint') rather than hardcoding.Wrap it, don't sprinkle it. The generated API is verbose and — as v1.1 proves — regenerated on the vendor's schedule. Create one adapter, e.g. App\Services\DomainRegistrar, that depends on a small interface (checkAvailability, register, renew, transfer, getInfo, getDnsRecords) and hides the SOAP objects. Swap the SDK implementation later without touching controllers.
Laravel service provider + config.
// config/services.php
'domainnameapi' => [
'username' => env('DNA_USERNAME'),
'password' => env('DNA_PASSWORD'),
'endpoint' => env('DNA_ENDPOINT'), // test vs prod
],
Bind the entry point as a singleton with credentials injected and Log::channel('dna') as the logger. Add a thin facade if it's called from many places, but keep the adapter as the real boundary.
Normalize responses into DTOs. Generated StructType objects are nested, historically relied on magic getters, and mirror the WSDL literally (e.g. OperationResult, DomainInfo). v1.1's packagebase v5 regeneration may have introduced native typed properties and stricter constructor parameters, so your toDto() mappers should be written defensively (null-coalesce, cast dates) and are your insulation layer against exactly this kind of churn.
Treat the response body as the source of truth for errors. DomainNameApi commonly returns operational failures inside the response (Result/OperationResult with status codes and messages) rather than throwing SoapFault. Wrap every call:
try {
$response = $this->client->someOperation(...);
} catch (\SoapFault $e) {
throw new DomainRegistrarException('SOAP transport failure', previous: $e);
} catch (\TypeError | \InvalidArgumentException $e) {
// v1.1 generated code is more strictly typed: wrong/null args surface here,
// not as a SoapFault. Don't let these leak to the caller unmapped.
throw new DomainRegistrarException('Invalid SDK call signature', previous: $e);
}
if (! $this->isSuccess($response)) {
throw DomainRegistrarException::fromResult($response); // parse code + message
}
Log the result code and message, not the credentials.
Queue state-changing calls for renewals/transfers/registrations, with idempotency keys. Domain APIs are slow and non-idempotent; a retried registration can double-charge. Record the request (domain, operation, unique key) and check the domain's actual state via getInfo before retrying.
Use operations in this order for a typical registrar flow: check availability → get info (for transfers) → register/transfer (queued) → poll or webhook-free re-fetch to confirm → manage DNS records → renew via scheduled job reading expiry from getInfo.
Testing: assert against the adapter interface with a fake. For integration tests, point at the sandbox endpoint and keep the PSR-3 logger set to debug to capture lastRequest/lastResponse. After any SDK bump (1.0 → 1.1 included), run this smoke test before deploying — regeneration is the vendor's main change vector.
wsdltophp/packagebase v5 / packagegenerator v4. Expect differences in property visibility, constructor arguments, nullability, and return types. Diff src/ between the tags if you have custom code that touches generated objects directly, and re-run your adapter's contract tests before shipping.psr/log widening changes your install matrix. If your app was pinned to psr/log ^1.0 (common on older Laravel), you either can't install v1.1 or you'll pull a second logger implementation via a version conflict workaround. Check composer why psr/log first. Also verify whether ^1.0 is still permitted — the note only says ^2/^3 are now allowed; do not assume v1 is retained.TypeError, not SoapFault. packagebase v5 adds native types. Previously-accepted nulls in optional fields, or loose scalars, may now throw before any request is sent. Map these in the adapter (see pattern above) so callers see one exception type.src/ — v1.1 is proof that a WSDL/packagebase update will overwrite them. All custom logic goes in your adapter. Verify, rather than assume, that __set_state/toArray helpers behave as they did in 1.0 before relying on them for mappers.info level and no full-body logging in production.ini_set('soap.wsdl_cache_enabled', '0')) or clear the cache directory. In prod, leave it on and pin the SDK version.location are both set to the same environment; a test WSDL with a prod location (or vice versa) yields confusing, non-explicit errors.mixed returns). Re-baseline your PHPStan config after the bump; add @property/stubs in your adapter, never by editing generated classes.StructType docblocks; missing fields surface as result-code errors rather than schema validation.v1.1), and keep an integration smoke test against the sandbox so upgrade breakage is caught by you rather than by customers. If the SDK's entry point doesn't expose something (e.g. a raw SOAP call for a new operation), prefer a subclass in your adapter over forking.How can I help you explore Laravel packages today?