Skip to content

Reusing an existing store on installation

On the authorization screen the merchant reaches when installing your app — the redirect to /appstore/integration/HASH, step 3 of the installation — they can select a store that already exists in their account, instead of always creating a new one.

What changed

Previously, every installation necessarily created a new store. Whenever the merchant installed more than one app, or reinstalled the same one, the account piled up duplicate stores — each with its own external_id and its own credentials, with no obvious relationship between them.

Now the authorization screen offers a store selection field. The merchant chooses between reusing an existing store and creating a new one.

INFO

Nothing changes in the API contract. The four installation steps, the validation URL contract, and the credentials/tokens process remain exactly the same. No new parameter is required from the partner app.

Store and site are the same thing

This is the main source of confusion, so it's worth spelling out:

Where you see itTerm used
Merchant-facing screens (Appmax panel, authorization screen)store ("loja")
API and webhookssite (site_id)

It is the same entity with two names. When this page says "existing store", the API equivalent is a site that already has a site_id. If a webhook arrives with a site_id you already know, it's because the installation was bound to a store that already existed.

What the merchant sees

The screen's behavior depends on what the merchant picks:

Scenario"Store name" field"Select Company" fieldDomainStore created?
Picked an existing storeNot shown (the store already has a name)Pre-filled and locked with that store's companyPre-filled with the store's registered domainNo
Picked "Create new store"Shown, the merchant fills it inThe merchant choosesThe merchant fills it inYes
Merchant has no storesShown, the merchant fills it inThe merchant choosesThe merchant fills it inYes

When the merchant does not have any store yet, the selection field does not appear — the flow is the previous one, unchanged.

Only eligible stores show up in the list: active, belonging to the merchant themselves, and with a company in good standing at Appmax. A store that does not meet these criteria is simply not offered.

What changes for your integration

In the contract, nothing. The implication is conceptual: the store bound to the installation may be one that already existed — including one where your app was installed before.

Revisit the "one installation = one new store" assumption

If your system creates local records assuming each installation corresponds to a freshly created store, that assumption no longer holds. Treat the installation as idempotent per store: when the health check arrives, check whether you already have a record for that store and update it instead of inserting a new row.

Without that, you accumulate orphan records pointing at the same store, holding old external_id values that Appmax no longer recognizes.

Reinstalling at the same store

When the merchant reinstalls your app picking the same store:

What happensDetail
The app ↔ store binding is updatedNot duplicated — there is still a single binding between your app and that store.
The external_id replaces the previous oneThe value your validation URL returns on the new health check becomes the store's. The old value ceases to exist.
A new client_id is generatedEvery installation generates new credentials. The store accumulates credentials over time — always use the most recent one.

Always persist the latest external_id

If your front-end keeps sending the old external_id in the external-id header, the requests answer 404 Merchant not found.

On every health check, store the new value and discard the previous one. And remember: you must generate a new UUID on every health check request — repeated values are rejected by Appmax. Full life cycle at external-id.

The usual recommendation still applies: read the external_id from your database on every checkout render, keyed by the store. If you cache that value in session state or in an environment variable, invalidate the cache when a new health check arrives.

Availability

The feature is rolled out gradually. While it is not active for an account, the authorization screen keeps the previous behavior — every installation creates a new store — and nothing changes for existing integrations.

In other words: you don't need to wait for the rollout to adjust your code. An integration that already treats the installation as idempotent per store works in both modes.

See also