Skip to content

Customers — Impersonate & GDPR (Admin)

Most of the Customers menu is straight CRUD — customers, groups, review moderation, notes, addresses — covered in the blueprint. Two flows need explaining because they don't map to a simple call: impersonation (the headless version of "login as customer") and GDPR (approving a request can cascade a delete, and the data download dumps every related table).

Agent-ask inputs

  • Integration token — ask the user; send as Authorization: Bearer <id>|<token>. Impersonate and GDPR need their permissions (customer-edit, GDPR-view/edit/delete), else the call returns 403.
  • Server URL — ask the user for their Bagisto server's base URL (e.g. https://store.example.com) and prefix every endpoint path with it. Never assume localhost or a demo domain.

Impersonate ("Login as Customer")

The admin panel's "Login as Customer" does a session login and redirects to the storefront — which can't translate to a stateless API. Instead, impersonate issues a short-lived customer token that the client then uses to act as that customer against the Shop API.

POST /api/admin/customers/{customerId}/impersonate returns the customer token plus the customer's id, email, and name, the impersonating admin's id, and an expiry. The plaintext token is shown once.

That token behaves exactly like a storefront login token: send it as Authorization: Bearer <token> alongside the storefront key on Shop API calls. It expires in one hour and carries an audit marker naming the admin who issued it. So "login as customer" becomes "get a customer token" — the correct headless translation. Requires the customer-edit permission.

GDPR data requests

The queue has a list and a detail view, plus status updates and two actions. A request has a type (update or delete) and a status (pending, processing, declined, approved, or revoked).

Update status

Update (a PUT) is a pure metadata change — it sets the status and an optional message, and fires the status-update email listener. Use it for moves like pending → processing or pending → declined. An invalid status is rejected with 422.

Process (the destructive action)

Process (POST /gdpr-requests/{id}/process) is where a request is actually carried out:

  • A delete request is approved and cascades a real customer delete — it runs the core delete so the GDPR module's own listeners fire.
  • An update request is marked approved but leaves the customer untouched. The request only carries a free-form message describing what to change; apply the actual edit through the normal customer-update endpoint afterward.

Processing an already-approved or revoked request is refused with 422. Over GraphQL the input field is requestId (the plain id is shadowed on mutation inputs). Requires the GDPR-edit permission.

Download data

Download data (POST /customers/{customerId}/gdpr-download-data) is ad-hoc — it isn't tied to a request. It returns the customer's full footprint (profile, addresses, orders, reviews, wishlist, notes) with the password and remember-token stripped. Requires the GDPR-view permission.

Delete

Delete removes the request row (a hard delete). Requires the GDPR-delete permission.

Gotcha: deleting a customer with active orders

The plain customer delete is guarded — a customer with pending or processing orders can't be deleted, and the call returns 400. The GDPR delete-request path runs that same core delete, so the same guard applies. Resolve or cancel the customer's active orders first.

GraphQL notes

Impersonate, GDPR process, and download-data are action / result mutations — select the documented result fields (the token, the customer id, requestId, success, and so on), not a generic id. See the result-field rule.

Status codes to handle

200 / 201 success · 400 delete guard (active orders) · 401 unauthenticated · 403 permission · 404 not found · 422 invalid status or an already-processed GDPR request.

Released under the MIT License.