# Shop sales in your integration (/developers/shop-sales)

A merchant's [shop](/merchants/shop) sells through its own application, named "Shop", which the
merchant's first shop creates, or the first accepted press of the pay button on one of their open
[payment links](/merchants/payment-links), whichever comes first. Every shop purchase is an ordinary checkout session of that application, so your
code sees it the way it sees any session: through webhooks. The shop added no v1 endpoint, no webhook
event type and no error code to the API, so the SDK is unchanged.

## The Shop application [#the-shop-application]

The Shop application is listed in **Developers** with the merchant's other applications, but it has no
secret: it cannot be given API keys, renamed or disabled. In the dashboard, a rename, a disable or a
secret roll is refused with HTTP 400 and the code `shop_application_locked`: "Your shop sells through
this application, so it cannot be renamed, disabled or given API keys. You can still set its webhook
URL." The v1 API never answers this code.

Its webhook URL can be set like any other application's: see
[Developer settings](/merchants/developers-settings). It does not count toward the application limit.

## What a shop session looks like [#what-a-shop-session-looks-like]

| Field            | Value                                                                     |
| ---------------- | ------------------------------------------------------------------------- |
| `order_id`       | `shop_` followed by a random UUID, one per click on the shop's button     |
| mode             | `payment` for a one-time price, `subscription` for a recurring one        |
| `metadata`       | `{ "source": "shop", "shop_slug": "<the shop's name at purchase time>" }` |
| `success_url`    | the shop's receipt page, `https://<name>.fianto.xyz/thanks/fian_rcpt_…`   |
| `cancel_url`     | the product's page on the shop                                            |
| expiry           | 30 minutes                                                                |
| `customer_email` | the email the buyer typed on the shop, when they gave one                 |

A payment-mode order takes the session's metadata, so an order event carries `source: shop` too.

## Receive shop sales [#receive-shop-sales]

A shop sale sends exactly the events of any checkout session of its mode, to the **Shop application's**
endpoint. Point that endpoint at a route that verifies the signature like any other, and use the
metadata when you need to tell shop sales apart:

```ts
// app/api/webhooks/fianto-shop/route.ts
import { Webhooks } from '@fianto/nextjs';

export const POST = Webhooks({
  secret: process.env.FIANTO_SHOP_WEBHOOK_SECRET!,
  onOrderPaid: async (event) => {
    if (event.data.metadata?.source === 'shop') {
      console.log('shop sale', event.data.metadata.shop_slug, event.data.order_id);
    }
  },
});
```

Each application has its own webhook endpoint with its own signing secret, so the Shop application's endpoint uses the Shop
application's secret.

The merchant's payment links sell through the same application, so once they have links, this
endpoint also receives link payments. Tell them apart by `metadata.source` (`shop` or
`payment_link`), or by the order ID prefix (`shop_` or `plink_`). See
[Payment link sales in your integration](/developers/payment-link-sales).

## When Fianto suspends a shop [#when-fianto-suspends-a-shop]

Each checkout of the shop that nobody has started paying is expired at once: you receive
`checkout.session.expired`, plus `order.expired` for a one-time purchase. A checkout already being
paid stays open and can still complete. Payment link sessions on the same application are left
alone.

## What the API does not show [#what-the-api-does-not-show]

Every v1 read of orders, payments, checkout sessions, subscriptions and events is scoped to the
calling application, and the Shop application can never hold a secret. So no API key can read a shop
sale through v1: shop sales reach you only through the Shop application's webhooks and the dashboard.
Products and prices are shared by all of a merchant's applications, as before.

## See also [#see-also]

- [Webhooks](/developers/webhooks/overview): Endpoints, verification and deliveries.

- [Event types](/developers/webhooks/events): Every event and its payload.

- [Your shop](/merchants/shop): What the merchant builds and publishes.