Skip to content

Customer::$deleted not declared as a property on Stripe\Customer #2059

@jakubmikita

Description

@jakubmikita

Describe the bug

When retrieving a customer via $stripe->customers->retrieve($id), Stripe returns a stub {id, deleted: true} object if the customer was deleted — this is documented API behavior.

However, the SDK's Stripe\Customer class does not declare $deleted as a @property, which forces consumers using PHPStan/Psalm to add @phpstan-ignore property.notFound around the check:

$customer = $stripe->customers->retrieve($user->stripe_id);

/** @phpstan-ignore property.notFound */
if (isset($customer->deleted) && $customer->deleted === true) {
    // handle deleted customer — clear local reference, recreate, etc.
}

To Reproduce

  1. Call $stripe->customers->retrieve(...) on a customer you deleted.
  2. Static-analyze the return with PHPStan on max level.
  3. Observe Access to an undefined property Stripe\Customer::$deleted.

Verified on stripe/stripe-php v17.6.0 and checked the stubs on master as of April 2026 — $deleted is still absent on Customer.

Expected behavior

Either:

  1. Add @property null|bool \$deleted to Stripe\Customer (simplest, matches the existing pattern used by Apps\Secret), or

  2. Model the deleted-customer response as a distinct DeletedCustomer class and reflect that in CustomerService::retrieve()'s return type (\Stripe\Customer|\Stripe\DeletedCustomer). This would be the most explicit, but it's a breaking-ish change for static analyzers that would require every consumer to narrow the union.

Option 1 is the pragmatic fix — no runtime change, just a docblock addition that accurately describes the API contract.

Context

Workaround

Add a one-line `@phpstan-ignore property.notFound` above the check. Works, but every library consumer hits it on first encounter.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions