> ## Documentation Index
> Fetch the complete documentation index at: https://storekit.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Journal des ruptures et digest matinal

> Consigner chaque plat en rupture avec raison et source via item.out_of_stock, classer les 30 derniers jours et envoyer un digest Slack chaque matin.

Chaque fois qu'un plat passe en rupture — mis en pause par l'équipe, écoulé via l'inventaire ou désactivé par ta caisse — storekit envoie un événement. Cette recette les stocke, te montre les tendances (quels plats, quels jours, à quelle heure) et publie chaque matin un digest dans Slack pour que l'acheteur et le chef commencent la journée en sachant ce qui a manqué.

> [!TIP]
>
> Le dashboard dispose déjà d'un rapport de snooze sous **Reports** (voir [Rapport de snooze](/docs/fr/guides/menu/availability-snoozing#rapport-des-mises-en-pause)). Construis cette recette quand tu veux aussi que les ruptures d'inventaire et les changements pilotés par la caisse figurent dans la même liste, ou que le digest soit poussé dans Slack plutôt que consulté.

## Comment ça marche

1. storekit envoie `item.out_of_stock` à ton application chaque fois qu'un article devient indisponible.
2. Ton application enregistre l'article, l'heure, la raison et ce qui l'a provoqué.
3. Une tâche planifiée s'exécute à l'heure que tu choisis chaque matin et publie la liste de la veille, plus un tableau glissant des « plus mis en rupture ce mois-ci », dans Slack.

## Ce dont tu as besoin

* Les webhooks activés sur ton plan storekit (**Settings** → **Developers**).
* Un compte [Replit](https://replit.com). Cette recette a besoin d'une URL publique qui reste en ligne, d'une base de données, et d'un planificateur pour la tâche matinale, que Replit fournit au même endroit.
* Une URL Slack incoming webhook pour le canal qui doit recevoir le digest.

## Étape 1 : construire l'application

Colle tout le bloc dans le builder en un seul message.

[![Open in Replit](https://replit.com/badge?caption=Open%20in%20Replit)](https://replit.com/?stack=Build\&prompt=JIAg7ghgdgLiEgM4FsIBs3gKYCN4Ad8QYALCOAayy30XhDQHsBzERgMxCwDcsAnAJ4hkWKAFcQASxhZkxMnGaMsdRmLgckMRgGMK8OMiF8VMCGL7QYAGnhQAJklH26CRCUZ849yc1PFGEABlNAg9Ll5BYU8oSShmADotTywKaWIsDDpSLAIiCBw1OERtPQBaIrocITBcD0YKJIAVElyIQmExEpAoHn4GRkQ2qAjRGx6+vhAdNVh5XMQIEVG5mDBJHSxbaEdeyOEIKmSTNLhIaQSAKEuAITFJNEd09dJ6e3ICiCGkQJyB1kQFm4kl4dBMJQgXkQ2xG6EgAkQFRG+DEODQGxAAAkmk0AApBEAAVQASgAZGGONw6Vr2MRoLCOABWjDw7E88xAPj8JSulwAwgB5AByTQAogANJogACCNwFhKlQSaAuJooA0sAmtdQHwxLCQB5EPhpOhpEIcF04ipVCMSilTiAABR2k4XGbIACUMLYUHRvTYfHs-DirB2IHwEAEIlgdHwoRgbL4ckTIHBZgsVmh0wg7AAl64HCAcJDEEkXal0jpoD1GDBJOwhEY2GBYR0CkV5CHsgoDe18KIpCMm+Wi0Ihg4Q9gcPUKKXrpjGGBjhWznVGA06GBPBQAFyXMogUVhEgrOCSAtYnG4kC4gVK8DSE8IABSQWFRcY9iE2noJNJIB1LBmHPGQpjiDlywdd53EKSF7CuA8WlyQov17bsFjIfsQAAbxAAAiPpYDwnd8IAHkIuAYAEfsAD48NsPD3jMYicJABJ2JAABfLjmi3LgAA9NnwOtGCgRASL+elmDCIRPCDPgEh0ExyAZU8nXsQIoFrEAulyaQAG4dO+OT+EU5SZHg7gACYPScBx0KLSFchMqYWUZLAdHGMM-hchITHYPV4KUrAVMcAB6AN5L8rAAocBJAR0TYGVUiLfP8wKEnYCAHlUijY3USL+FsHQum0EQ+FsXhxGGRx0sLXp+MowIKMHEoQscTQ4kQSQg05D4EJAYksAARzEUxXBMJBfF6RwXhPIJgX4pJRUiYwRrG7oqz4PhJBUDlWggeS6EQRayh62wTskfiyjrEQIWQfJC0u67uuYKByAsLAkgANWDBt5jkOaOQ4dgNkkdAQAAA2eyGGEkHBLCiFMBDUKZQniMQID8WxLXieghmCuBQHWDBwz4RhgV68Dq1EYFyagaM4G4SFwbRXIqwwVSlRVdVNQAfQAdVFG5MQFAU1T5oJRT5VUmiSIb3M8uwBFISdSHIEAsoeOhInrDZyEkUSH1ebE8RAAAWAAGS2BoAWSEZx8EYOJDFK1MVCdwsgYQKz+P4rQPs3R9wIARgAVicGZ7KSIIIF4DkWp-P4mM+b5Qb4EpbHBT3HCs63bByEYNI5Lc+H0dhybkP5Fl4RwZnwAQBoFKBNgA3t4+z0Sg1z-PlwdEnMC04pnHkDWWqx7KoAu35WnAbdOm6Iei1yJgShIkcQupNTvYDmAuidfsJ3iWwNN6WwtfpexbLDUS0EbSF9HSU+2nYUCS-nshXE8zGMDHMREuoN3JIzcA5eDEI9Dq+pbpFXDBsfQ4DlaqzxiUB4mBD4+DxuyC+qkwwmBgFEC4IAhSTE5DPXIpd9C3yEOBEQyBPBCBzG-TuR9Ej7hAEhJASxcgtSrCMXQVZuqiXQHfZenJMggn4KpOhk11Z8Jbl9Ik3xq6nR6gadq-Qvgcj1JIUauQqBCBTNXOOuUqowBIggEw-YNaaBpqY+AaBlKoRrqpc8Ug3opHsLYMACgSHSGOmYPec4DzSigEICMfgAxcAcE7F2ZNaweQsqOegEZECIFLo4ZAbscALH4LXNg+xTb4h9HfQyJgfAmCVuydK3w4yT0vHiO2oksAGN2o8OgjptBmDQAXSQ+AT7iNWgAMWoCfc8Mw9QwCaLWdAthpCyDJhsLY0QfCg36PgHamxr6TRdkBfgdAaFxHZNomA4kQBWTDtbYQIUxIgAAMXnISNbAaLkmjUT0jaZynAAAiAz+ACFsLiOB4DbDACgEEbQJhbB8gsDgbqQYoUqR2vEH56JVoItAiGQFegEHshuKgiMjc2FmDZlIG0Ij1kqDGJrdkcQygjhcogQyQZUV-OlPYew4ICyOGNHoQk+AmiSGWFQ6lUxmUSKiAypIAtWgjByEIYuS8+wiL+Po0lbBkDSAstPYg5l6AatSZOVVRjliaPEBgJIQ89phjmcgRAABtAAugkS12YRjZJ6HSTA7JZDCUbtMUqjByqKUDRGUJQouF2DrgGoNzMYBCjEMgbJUw+whVcr6GoMqkDgLjLteC1xRT8SWHGZygZTLBVCgkay4ZIxMEOnuS42FLggHwhRFieFfLlospWqy9Em34RTixRtzbm14R6m2uSfMCg6BDlZAAzL24d+EZhBjbdKEONwe3WD7SOr47QWL4LGluxdeFOnoBYuc-O278J1nwOei5R7h2MV+YIYZWBz0AE530PpHT4RA4zYBTK6SxS2378IvLeW2lF4qBALsfTyigfKBUiDbXnKy5syiWxDmUcOTQQ6Wx3ObMOO5rYAC1YMjupNAXoaA21CxuOR-CTt42Jv4CxM13Sr14U7QyaUMAUOWzQxhrDOG8M7lnfh0jDGn0ssEEht9JE8KofQ5h7DYdcMh2IxJy2ZHQN4UtYgNtxJJwaU8NkjAUmSp2nKoOq9I704lHDchhTz5GAkCgAxkdoQHNcMg8oDzLbUAPDbcyNzAABLAhaHr0mDcgfzeF8AeF6G2gA1Obc2M7Z2EYAGwAHYAAc764uoDLlgOs8Q+SiXHHxiSuosBXs4rpm1BmSJ2tszhNrI73pOfwrbSEzBWg7TMDeSQAAvEbEB-MjvWS7Rz8met9YGyaSbjGNlzZnZexdx7RpWDNCxEOoHj1xjEGxz1B24ODGAPYE7GAzsjrMPxYkKlz0gY6-hS112OObcfXQlZu0M4sVa19xduE9M+YUwW-BCBqTUCGPRFbM2wf4T5K0SlcP4urb2-e-C23YC7ZIvtxjaBjskXYwxJ2iBLsfYYvdx7MhntcVew6trnEr0Ot01VMaNmvujqu-jud5szug+63he2g1TDmEsERQXiAifMDbUYMoaYJdWDi4dDl1oudA7wiUEwpWQ5toyyAXr4FwXLe1-g6gMAe0KbNzoPH+FSRd1Emb8nMAKsroUwLEO0oQDe+lLb2Y+CYMKcJGqAPD1oACFm220XQ0IQZjmKSGAV3btLvXIGOIKlmusTwvGaQYgPcgDDiHBIFycsC-wkweI+fC8YYSDO-LDOvss8XQ1zjYrVpsvV6kzXx6deW-1wp7LIABSHBlLwOL-fSvW-woM+MZy4t26om2x3DhneC9d+7ubeFRQhxAFl6UQpF+B8EG20PcX9NU7a1x9PGCs+DsrwbPehfi+l-DmHBiVfgLP7m3Xy2OWrIrIm9h0W8GcWdLgOEApSZ0RuhNBE43kuVq0BBa0XA1UNYSAYAYBaAdwwowpII3RA0woNIdBEAiC+gmB+wM4wpahpx1xZxqC1wGgyg8prgmhMRRRDxvpRQRR2FMRgACRpRcRrxCQpYggSIbUEgig+YOA+Y7Q9BtR3EZFZ4XIBIi16R4BCheBDJVZXAOhhUtorVCgCoJCpCZC5CKAvESANgTwmANw4YjgdD60h0W1TE20TD1BpD2BZDSgKBYNGIPhe98IOc5sQcx0+dMsGIutt9Y9xcE8+MuJGsZBYsSJQjeci9cs8tIjEcRcFtgwhtAUxsJsycic21cRSRCQMNMM0dydKcFNyc+YbU+ZzZN18JEAKBid8Igg1QKjbZpRiQABxSo-XBIzjZSRAZ3BTRALSRgEbBkKTcYiwTYeXaAH+KTIMMwbWB-bXaY2Y0UBwfjQTFTETPLTTTTMjYAlncAg8MYo2VxJpNgdgdeHY1SDpH1TwFmERKw9lAcaoAOdgdgL0QcUxehPmIMYtRJZ0RgR4NgAqUgcmMQfrIEsYehaYQPRAQE39AoS+J0NJaQaHDqf4j0AaBYvgVuO4-0DgEiVAcQCGSEkQe48CZOL4EgWCQMQElQx0KHaNfoFQ3SRwSSL4DQXoDE59BJWwdEfrE5fsBkWwEbIRbpcMQYWQgQFuA+LoGkTWSuegOsUmGlWAICSwESKAIkthdY7KNAUsKY9cXYwsck8lcEKlFMG420Z4ykQsXhURUnK5aAScK0mYlxBwGKOIOZO+AaI7WwGot0xwNoiQD091djAaJCbZOgLSfCYscIcCcwvCU8ZoWePsd2GYQMTcTNJBZgTcKlIoQySsKjbSCgLSJcbxAcOVbMZYdMxoa4AWTEaUKUZUEAG4QkYAUkL5a4EvG8O8KUBg2gjcPAiFFcEAQAFAIQBdZ-o-gForopo3oPpJogYfJ-iwYIZno4YEZIQGFCxuZVQNQmhBZhZRZxZJZpZZZ4BpIupKJZ5LAlwTBdFugUIBBDIrZLYfRNZzTPoY5jEE47FcFSsLARg84ALBURAfAVJQyAJFDhgxwVFKQHF2oxxjF4IsQdh1D3CYBPDvDdAKBDJnFI14A9B6zL4IlI82Acgph4CsILRvBNJawrC8YgYLhLgrIkgfcmBWBiV1C5oSIKksAJF+TBVchnRZyiQmg+RRkjRQhqERgmhgBbZRQSNhRRRATgieguFZkkjDKRBjL5lzpwwicLp2is4Qpxip4fhFilk-SbS8KhpCz+TZ4KIABybIGS+AByaBEuRg-QSEHaWuK4WdJIfo0UCchcuJGQTyVSX4wpRybqHQeAdQE8IGaUL5W2YAIUPmXEaUIIIIAWFUL5XM3XTseIG0H0XIcJLAPcYdCAJIPCAATVMH4HeFPP5M-EjBYgQBgI0E4HMIqHUGOjiFbmrjMC8AeJAAEG6sDEjEHHYU0u0t0tsF6FqG6Hs3GHcEXDVhkvMuQDsq+CNjDBJLJORFCHAnSXaTwiCFdKSQhH+J0lx0wBDhOOtjRyCChI6lhJIHhMRLiGBKiEYQ0T4VLT4D+peHxIeM4ArkDRABI3lLwhNOHRwHattkGGKABphPGC8zgHEz6gRBYia1TGgCoEcF+PEBY1cjGp8ImpOS8UfA5H-TgG8lnjoU2kDToRGA8AsAWt6qkDgEwkPjnGHR0CSEGQeFAjoBTAMsdHrDbjIHjmkVyFkQasBOdKooQCYlyEl2xn1pAC+UXF9EYEOhAD5CCG+iLHUG0FlR7AiydihHAB8X2FcVBjQFAlUh3NnhmCJ2QBuWRrkBiTmH4suHNgEr6geHlV8H8Fd1Uh-BCDCH0GBAQCCFJGlD5Aljo1vIlj-AMDNuAFiqVD5g0q0qdExExB3FtltjWqrs2qFFFH6SyjpDgH-zE0tiJJttEhkFgFmRGDTvCGQDLnsBbBaubQACp-roSOwlq2oVqhBFzSIDKoiaJbBSJDaaIZ7t1m4V4rRwx+gbVh7iAAqXIFMQ5zYdw85m1es+B+s8iEACjxsErxiF6CoVaoBwaBAPRsz2Q8JvriMI5ggQo+yvg6BFzXKUqxwzB3qJkHgzkNNfqYr4SiBfiDLVamL3loglDqwmkrhh0kJ9Q0Rqa4Z-Qww8IZ7cbuhP7AbXzXEBbSAZ7sy2QMBFw4GORtAiBQZ45KagZOapbm1gBOAh4uKAQCbF7lreqIy8b8IhROLfTpGCol7QJeqEhsyYGdS0E8btVQA6zFwOR8zXFTReBiHm1cQFHk5E7YD5ET7RVVrCIpBOA-h8ylcoRxKPI5IORDaFqBTuguR-AqsqK2jelXGxa0J7FHFzRqBbRHT2R1ZvAVIrgw5Y6nqR5gnF5Fxsy2KnbAK-gmqRUMgUFj4PbrDFSSgHJsm4BkZZHVqTBpJAx6RUkFrGymKonIBXAsLDoxwxgrgssYq4qQAwoDpfaTxkn3Y94+AblYKqKQcGh91asuIqKJHJxMghheRCRvhm6dLW6SnJh5VVqjCHATyqLf1aklrpKRAkhzaaxFANpXAxEO7fbxDOA9ndK1U9QhhxhqktbAgIR5qwwhL6AdB6RIQrlUksYvprgvlRRBlCrNRgB3wBRBkzbdLrgDw7UQAHUZQNyZoxbZBJCPCzCfC1IU0Sw1rJIWBjYuL8YfHCxubuFolnY5g8FoLVJYKBocW8WOFFhlgWoO9JF+T1hW5uMPlUxFweXcX8XixozpotyjaoLZm6B-yqKhKUzlH4gZW+XvLIti0kCUCNCKYMJFxXA6Acin7Ft8jRt36YGXrfi3rOAkGvqfrLY8JdX2FZ5amqmTkS6vky7RQK7m61ntIJ5GSew5HBxwWC9JxIbk13YgWYAvXMnCxfX6zszXdshAhR7H5kAELwYZBQy2FeXvXchbb7aNIWxjXGBJa1q3AKVDp3BLc6WGqpWlxKCKXCw-gg6E0bkRqGQvW485qythK8yOhV49p1mdWOyuyeyBQQB+jgAuCjcODOzuCQAOr5QZRVQMXW6RzczGrUR0RMqaCZwiQyQnRAAyAknJnFIPwJgGvh7dnmKb-CuH4vLaiTplEkZiXJZixL2h-F+adHPN5ivILrFglilhljitsDyoKqKpKrKoquJC+VsGztzvzpvKg75j-FsE+dbtsEDfLqvObufdmgGwBacFfPmSNh0KsvIETGQCiqSAqygHTlQCNNHlo7yADgRB0iIDQwNFRmedFu5o1mrnxLpFUmZDwF1BuUbJGC0h-OiaKZhbYEPiuCAA\&referrer=docs.storekit.com)

[![](https://mintcdn.com/storekit/IGeB_84apyho3Z6U/images/logos/lovable.svg?fit=max\&auto=format\&n=IGeB_84apyho3Z6U\&q=85\&s=cc21d11769d5e6b686fed56390a88f5e) Build with Lovable](https://lovable.dev/#prompt=I%20want%20a%20small%20web%20app%20that%20keeps%20a%20log%20of%20every%20menu%20item%20that%20goes%20out%20of%20stock%20at%20my%20restaurant%2C%20and%20sends%20a%20short%20digest%20to%20Slack%20every%20morning.%20storekit%20tells%20the%20app%20about%20stock-outs%20by%20webhook.%20The%20app%20must%20never%20lose%20an%20event%2C%20never%20count%20the%20same%20event%20twice%2C%20and%20never%20make%20storekit%20wait.%0A%0ABuild%20it%20with%20a%20database%20so%20the%20log%20survives%20restarts%2C%20an%20always-on%20public%20HTTPS%20URL%2C%20and%20a%20scheduled%20job%20for%20the%20digest.%0A%0ACONTEXT%20ABOUT%20STOREKIT%0A%0AI%20run%20a%20hospitality%20business%20on%20storekit%20\(storekit.com\)%2C%20an%20online%20ordering%20and%20payments%20platform%20for%20restaurants%2C%20caf%C3%A9s%20and%20bars.%20storekit%20can%20notify%20my%20own%20app%20about%20things%20that%20happen%20in%20my%20store%20by%20sending%20webhooks.%0A%0AHow%20storekit%20webhooks%20work%3A%0A-%20Each%20event%20is%20an%20HTTP%20POST%20with%20a%20JSON%20body%20to%20a%20URL%20I%20register%20in%20the%20storekit%20dashboard.%0A-%20The%20body%20has%20the%20shape%20%7B%20%22event%22%3A%20%22%3Cevent%20type%3E%22%2C%20%22data%22%3A%20%7B%20...%20%7D%20%7D.%20Two%20exceptions%3A%20the%20legacy%20order.created%20event%20\(do%20not%20use%20it%3B%20use%20order.created.v2\)%20sends%20the%20bare%20order%20object%2C%20and%20the%20order.refund.created%20%2F%20order.refund.succeeded%20%2F%20order.refund.failed%20events%20put%20order%2C%20customer%2C%20venue%20and%20refund%20next%20to%20event%20instead%20of%20inside%20data.%0A-%20Requests%20are%20signed%20with%20Svix.%20Every%20request%20carries%20the%20headers%20svix-id%2C%20svix-timestamp%20and%20svix-signature.%20Verify%20them%20with%20the%20official%20%60svix%60%20library%20for%20your%20language%2C%20using%20a%20secret%20I%20will%20provide%20in%20an%20environment%20variable%20called%20STOREKIT_WEBHOOK_SECRET.%20Reject%20anything%20that%20fails%20verification%20with%20HTTP%20400.%0A-%20My%20endpoint%20must%20respond%20with%20a%202xx%20status%20within%2015%20seconds.%20Save%20the%20event%20to%20the%20database%20first%2C%20respond%20200%2C%20then%20do%20the%20work%20from%20the%20saved%20copy.%0A-%20Once%20I%20have%20responded%20200%2C%20storekit%20will%20not%20send%20that%20event%20again%2C%20so%20the%20work%20must%20not%20be%20lost%3A%20store%20each%20event%20with%20a%20status%20\(pending%2C%20done%2C%20failed\)%20and%20only%20mark%20it%20done%20after%20the%20work%20has%20actually%20succeeded.%20On%20startup%20and%20on%20a%20timer%2C%20pick%20up%20anything%20still%20pending%20or%20failed%20and%20retry%20it.%20Never%20do%20the%20work%20only%20in%20memory%20after%20responding.%0A-%20The%20same%20event%20can%20occasionally%20be%20delivered%20more%20than%20once.%20Use%20the%20svix-id%20header%20as%20the%20unique%20key%20for%20the%20saved%20event%3A%20a%20repeat%20of%20an%20event%20already%20saved%20is%20ignored%2C%20whatever%20its%20status.%0A-%20Any%20page%20or%20endpoint%20protected%20by%20a%20password%20must%20be%20served%20over%20HTTPS%20only%3B%20redirect%20or%20refuse%20plain%20HTTP.%0A-%20Money%20fields%20\(total%2C%20tip%2C%20deliveryFee%2C%20discountTotal%2C%20item%20price%2C%20modifier%20price\)%20are%20integers%20in%20minor%20units%3A%202500%20means%20%C2%A325.00.%0A-%20orderType%20is%20one%20of%20Delivery%2C%20Pickup%2C%20InStore%2C%20Curbside%2C%20CateringDelivery%2C%20CateringPickup%20or%20Billpay.%0A-%20table%20is%20only%20present%20for%20in-store%20orders%3B%20deliveryAddress%20and%20pickUpTime%20only%20for%20delivery%20orders.%20When%20they%20do%20not%20apply%20the%20key%20is%20omitted%2C%20so%20treat%20a%20missing%20key%20the%20same%20as%20null.%20notes%20and%20items%5B%5D.note%20can%20be%20null%20or%20empty.%20customer.companyName%20and%20customer.vatNumber%20appear%20only%20when%20supplied.%0A%0AExample%20order.created.v2%20payload%3A%0A%0A%7B%0A%20%20%22event%22%3A%20%22order.created.v2%22%2C%0A%20%20%22data%22%3A%20%7B%0A%20%20%20%20%22id%22%3A%20%22ord_abc123%22%2C%0A%20%20%20%20%22code%22%3A%20%22A1B2%22%2C%0A%20%20%20%20%22asap%22%3A%20true%2C%0A%20%20%20%20%22total%22%3A%202500%2C%0A%20%20%20%20%22tip%22%3A%20250%2C%0A%20%20%20%20%22deliveryFee%22%3A%20299%2C%0A%20%20%20%20%22discountTotal%22%3A%200%2C%0A%20%20%20%20%22orderType%22%3A%20%22Delivery%22%2C%0A%20%20%20%20%22pickUpTime%22%3A%20%222024-01-15T10%3A45%3A00Z%22%2C%0A%20%20%20%20%22channel%22%3A%20%22WEB%22%2C%0A%20%20%20%20%22poNumber%22%3A%20null%2C%0A%20%20%20%20%22createdAt%22%3A%20%222024-01-15T10%3A30%3A00Z%22%2C%0A%20%20%20%20%22deliveryTime%22%3A%20%222024-01-15T11%3A00%3A00Z%22%2C%0A%20%20%20%20%22notes%22%3A%20%22Ring%20doorbell%22%2C%0A%20%20%20%20%22customer%22%3A%20%7B%0A%20%20%20%20%20%20%22firstName%22%3A%20%22John%22%2C%0A%20%20%20%20%20%20%22lastName%22%3A%20%22Doe%22%2C%0A%20%20%20%20%20%20%22email%22%3A%20%22john%40example.com%22%2C%0A%20%20%20%20%20%20%22phone%22%3A%20%22%2B44123456789%22%2C%0A%20%20%20%20%20%20%22marketingConsent%22%3A%20true%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22items%22%3A%20%5B%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22name%22%3A%20%22Margherita%20Pizza%22%2C%0A%20%20%20%20%20%20%20%20%22printName%22%3A%20%22Margherita%22%2C%0A%20%20%20%20%20%20%20%20%22price%22%3A%201200%2C%0A%20%20%20%20%20%20%20%20%22quantity%22%3A%201%2C%0A%20%20%20%20%20%20%20%20%22plu%22%3A%20null%2C%0A%20%20%20%20%20%20%20%20%22posId%22%3A%20null%2C%0A%20%20%20%20%20%20%20%20%22taxRate%22%3A%2020%2C%0A%20%20%20%20%20%20%20%20%22note%22%3A%20null%2C%0A%20%20%20%20%20%20%20%20%22modifiers%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%7B%20%22name%22%3A%20%22Extra%20cheese%22%2C%20%22printName%22%3A%20%22Cheese%22%2C%20%22price%22%3A%20150%2C%20%22quantity%22%3A%201%2C%20%22plu%22%3A%20null%2C%20%22posId%22%3A%20null%2C%20%22taxRate%22%3A%2020%20%7D%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%2C%0A%20%20%20%20%22venue%22%3A%20%7B%0A%20%20%20%20%20%20%22id%22%3A%201234%2C%0A%20%20%20%20%20%20%22name%22%3A%20%22My%20Restaurant%22%2C%0A%20%20%20%20%20%20%22slug%22%3A%20%22my-restaurant%22%2C%0A%20%20%20%20%20%20%22address%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22street1%22%3A%20%22123%20Main%20St%22%2C%0A%20%20%20%20%20%20%20%20%22street2%22%3A%20%22%22%2C%0A%20%20%20%20%20%20%20%20%22city%22%3A%20%22London%22%2C%0A%20%20%20%20%20%20%20%20%22postCode%22%3A%20%22W1A%201AA%22%2C%0A%20%20%20%20%20%20%20%20%22country%22%3A%20%22UK%22%2C%0A%20%20%20%20%20%20%20%20%22companyName%22%3A%20%22My%20Restaurant%20Ltd%22%2C%0A%20%20%20%20%20%20%20%20%22coordinates%22%3A%20%7B%20%22latitude%22%3A%2051.5074%2C%20%22longitude%22%3A%20-0.1278%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%2C%0A%20%20%20%20%22deliveryAddress%22%3A%20%7B%0A%20%20%20%20%20%20%22street1%22%3A%20%22456%20Oak%20Ave%22%2C%0A%20%20%20%20%20%20%22street2%22%3A%20%22Flat%202%22%2C%0A%20%20%20%20%20%20%22city%22%3A%20%22London%22%2C%0A%20%20%20%20%20%20%22postCode%22%3A%20%22E1%206AN%22%2C%0A%20%20%20%20%20%20%22country%22%3A%20%22UK%22%2C%0A%20%20%20%20%20%20%22notes%22%3A%20null%2C%0A%20%20%20%20%20%20%22coordinates%22%3A%20%7B%20%22latitude%22%3A%2051.5155%2C%20%22longitude%22%3A%20-0.0722%20%7D%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A%0AThe%20full%20list%20of%20event%20types%20and%20payloads%20is%20at%20https%3A%2F%2Fstorekit.com%2Fdocs%2Fdevelopers%2Fwebhooks%2Fwebhook-events%0A%0ATHE%20EVENT%20THIS%20APP%20USES%3A%20item.out_of_stock%0A%0AIgnore%20the%20order%20example%20above%3B%20this%20app%20only%20cares%20about%20item.out_of_stock%2C%20which%20looks%20like%20this%3A%0A%0A%7B%0A%20%20%22event%22%3A%20%22item.out_of_stock%22%2C%0A%20%20%22data%22%3A%20%7B%0A%20%20%20%20%22venue%22%3A%20%7B%20%22id%22%3A%201234%2C%20%22name%22%3A%20%22My%20Restaurant%22%20%7D%2C%0A%20%20%20%20%22item%22%3A%20%7B%20%22id%22%3A%205678%2C%20%22name%22%3A%20%22Margherita%20Pizza%22%2C%20%22plu%22%3A%20%22PLU-001%22%2C%20%22posId%22%3A%20%22pos_item_42%22%2C%20%22sku%22%3A%20%22SKU-MARG-001%22%20%7D%2C%0A%20%20%20%20%22reason%22%3A%20%22snoozed%22%2C%0A%20%20%20%20%22source%22%3A%20%22manual%22%2C%0A%20%20%20%20%22details%22%3A%20%7B%20%22snoozeEnd%22%3A%20%222024-01-15T18%3A00%3A00Z%22%20%7D%0A%20%20%7D%0A%7D%0A%0A-%20reason%20is%20one%20of%3A%20snoozed%20\(temporarily%20hidden%20by%20staff\)%2C%20inventory_depleted%20\(sold%20out%20through%20inventory%20counts\)%2C%20disabled%20\(switched%20off\).%0A-%20source%20is%20one%20of%3A%20manual%20\(someone%20in%20the%20dashboard\)%2C%20order%20\(a%20customer%20order%20used%20the%20last%20one\)%2C%20deliverect%2C%20lightspeed%2C%20zonal%2C%20pos_sync%20\(pushed%20from%20a%20till%20or%20integration\).%0A-%20details.snoozeEnd%20is%20only%20present%20for%20reason%20snoozed%20and%20can%20be%20null%2C%20meaning%20snoozed%20indefinitely.%0A-%20plu%2C%20posId%20and%20sku%20can%20be%20null.%0A-%20There%20is%20no%20%22back%20in%20stock%22%20event.%20The%20app%20records%20when%20things%20went%20out%3B%20it%20cannot%20know%20when%20they%20came%20back.%0A%0AWHAT%20TO%20BUILD%0A%0A1.%20POST%20%2Fwebhooks%2Fstorekit%20%E2%80%94%20verify%20the%20Svix%20signature%20with%20the%20official%20svix%20library%20and%20STOREKIT_WEBHOOK_SECRET%20against%20the%20raw%20request%20body%3B%20400%20on%20failure.%20Save%20the%20event%20and%20return%20200%20immediately.%20Ignore%20any%20svix-id%20already%20saved.%20Handle%20item.out_of_stock%3B%20save%20and%20acknowledge%20any%20other%20event%20type%20but%20do%20nothing%20with%20it.%0A2.%20A%20log%20table%20with%3A%20received%20time%20\(store%20UTC%2C%20display%20in%20TIMEZONE\)%2C%20venue%20name%2C%20item%20name%2C%20item%20id%2C%20plu%2C%20sku%2C%20reason%2C%20source%2C%20snoozeEnd.%20Record%20the%20event's%20time%20as%20the%20time%20the%20webhook%20arrived.%0A3.%20GET%20%2F%20%E2%80%94%20protected%20by%20HTTP%20basic%20auth%20with%20ADMIN_PASSWORD.%20Three%20things%20on%20one%20page%3A%0A%20%20%20a.%20%22Yesterday%20and%20today%22%3A%20a%20list%20of%20stock-outs%20since%20the%20start%20of%20yesterday%20in%20TIMEZONE%2C%20newest%20first%2C%20showing%20time%2C%20item%2C%20reason%20and%20source%20in%20plain%20words%20\(%22Snoozed%20by%20staff%20until%2018%3A00%22%2C%20%22Sold%20out%20through%20inventory%20after%20an%20order%22%2C%20%22Switched%20off%20from%20Zonal%22\).%0A%20%20%20b.%20%22Most%20sold%20out%2C%20last%2030%20days%22%3A%20items%20ranked%20by%20number%20of%20stock-outs%2C%20with%20the%20count%20and%20the%20most%20common%20hour%20of%20day%20it%20happens.%0A%20%20%20c.%20Filters%20for%20venue%20\(if%20I%20have%20more%20than%20one\)%2C%20reason%20and%20a%20date%20range%2C%20and%20a%20Download%20CSV%20button%20that%20exports%20whatever%20is%20filtered%20with%20the%20columns%20from%20point%202.%0A4.%20A%20daily%20digest%20posted%20to%20Slack%20via%20SLACK_WEBHOOK_URL%20at%20DIGEST_TIME%20\(HH%3AMM%20in%20TIMEZONE%2C%20default%2007%3A30\).%20Content%2C%20in%20Slack%20mrkdwn%3A%0A%20%20%20*Sold%20out%20yesterday%20%E2%80%94%20%3Cvenue%20name%3E%2C%20%3Cdate%3E*%0A%20%20%20One%20line%20per%20item%2C%20in%20time%20order%3A%20%2214%3A20%20%20Margherita%20Pizza%20%E2%80%94%20sold%20out%20\(inventory\)%22%20or%20%2218%3A05%20%20Sea%20Bass%20%E2%80%94%20snoozed%20by%20staff%20until%2021%3A00%22.%20Group%20by%20venue%20if%20there%20is%20more%20than%20one.%0A%20%20%20Then%20a%20blank%20line%20and%20%22*Most%20sold%20out%20this%20month*%22%20followed%20by%20the%20top%20five%20items%20with%20counts.%0A%20%20%20If%20nothing%20sold%20out%20yesterday%2C%20post%20%22Nothing%20sold%20out%20yesterday.%22%20%E2%80%94%20still%20post%2C%20so%20I%20know%20the%20app%20is%20alive.%0A%20%20%20Post%20the%20digest%20once%20per%20day%20even%20if%20the%20app%20restarts%3A%20record%20the%20date%20of%20the%20last%20digest%20sent%20and%20skip%20if%20it%20has%20already%20been%20sent%20for%20that%20date.%0A5.%20A%20%22Send%20digest%20now%22%20button%20on%20the%20page%20for%20testing%2C%20which%20posts%20the%20digest%20for%20yesterday%20regardless%20of%20whether%20it%20was%20already%20sent.%0A6.%20GET%20%2Fhealth%20that%20returns%20200%20and%20%7B%20%22ok%22%3A%20true%20%7D%20and%20nothing%20else.%0A%0AUse%20TIMEZONE%20for%20every%20day%20boundary%20and%20displayed%20time.%20Do%20not%20guess%20a%20default%3A%20if%20TIMEZONE%20is%20unset%2C%20refuse%20to%20start%20and%20log%20a%20clear%20message.%0A%0ADEFINITION%20OF%20DONE%0A%0A-%20%5B%20%5D%20A%20signed%20item.out_of_stock%20event%20appears%20in%20the%20log%20within%20a%20second%20and%20the%20endpoint%20returned%20200.%0A-%20%5B%20%5D%20The%20same%20event%20delivered%20twice%20creates%20one%20row.%0A-%20%5B%20%5D%20A%20bad%20signature%20returns%20400%20and%20logs%20nothing.%0A-%20%5B%20%5D%20The%20example%20payload%20above%20shows%20as%20%22Margherita%20Pizza%20%E2%80%94%20snoozed%20by%20staff%20until%2018%3A00%22.%0A-%20%5B%20%5D%20The%20digest%20posts%20at%20DIGEST_TIME%20and%20not%20again%20that%20day%2C%20including%20after%20a%20restart.%0A-%20%5B%20%5D%20%22Send%20digest%20now%22%20posts%20to%20Slack%20immediately.%0A-%20%5B%20%5D%20The%20CSV%20download%20opens%20in%20a%20spreadsheet%20with%20one%20row%20per%20event%20and%20the%20columns%20listed.%0A-%20%5B%20%5D%20Restarting%20the%20app%20loses%20nothing.%0A%0AWHAT%20TO%20GIVE%20ME%20WHEN%20YOU%20ARE%20DONE%0A%0A1.%20The%20public%20webhook%20URL%20\(%E2%80%A6%2Fwebhooks%2Fstorekit\)%20and%20the%20page%20URL.%0A2.%20The%20environment%20variables%20to%20set%20\(STOREKIT_WEBHOOK_SECRET%2C%20ADMIN_PASSWORD%2C%20SLACK_WEBHOOK_URL%2C%20TIMEZONE%2C%20DIGEST_TIME\)%20and%20where%20to%20set%20them%20on%20this%20platform.%0A3.%20Confirmation%20that%20the%20app%20stays%20up%2024%20hours%20a%20day%20and%20that%20the%20scheduled%20job%20runs%20when%20nobody%20has%20the%20page%20open.%0A)

Either button opens the builder with the whole prompt below already filled in. Nothing starts until you press send, so read it through and edit the parts marked as yours first.

> **Prompt complet (clique pour développer)**
>
> ```text theme={null}
> I want a small web app that keeps a log of every menu item that goes out of stock at my restaurant, and sends a short digest to Slack every morning. storekit tells the app about stock-outs by webhook. The app must never lose an event, never count the same event twice, and never make storekit wait.
>
> Build it with a database so the log survives restarts, an always-on public HTTPS URL, and a scheduled job for the digest.
>
> ```
>
> ```text theme={null}
> CONTEXT ABOUT STOREKIT
>
> I run a hospitality business on storekit (storekit.com), an online ordering and payments platform for restaurants, cafés and bars. storekit can notify my own app about things that happen in my store by sending webhooks.
>
> How storekit webhooks work:
> - Each event is an HTTP POST with a JSON body to a URL I register in the storekit dashboard.
> - The body has the shape { "event": "<event type>", "data": { ... } }. Two exceptions: the legacy order.created event (do not use it; use order.created.v2) sends the bare order object, and the order.refund.created / order.refund.succeeded / order.refund.failed events put order, customer, venue and refund next to event instead of inside data.
> - Requests are signed with Svix. Every request carries the headers svix-id, svix-timestamp and svix-signature. Verify them with the official `svix` library for your language, using a secret I will provide in an environment variable called STOREKIT_WEBHOOK_SECRET. Reject anything that fails verification with HTTP 400.
> - My endpoint must respond with a 2xx status within 15 seconds. Save the event to the database first, respond 200, then do the work from the saved copy.
> - Once I have responded 200, storekit will not send that event again, so the work must not be lost: store each event with a status (pending, done, failed) and only mark it done after the work has actually succeeded. On startup and on a timer, pick up anything still pending or failed and retry it. Never do the work only in memory after responding.
> - The same event can occasionally be delivered more than once. Use the svix-id header as the unique key for the saved event: a repeat of an event already saved is ignored, whatever its status.
> - Any page or endpoint protected by a password must be served over HTTPS only; redirect or refuse plain HTTP.
> - Money fields (total, tip, deliveryFee, discountTotal, item price, modifier price) are integers in minor units: 2500 means £25.00.
> - orderType is one of Delivery, Pickup, InStore, Curbside, CateringDelivery, CateringPickup or Billpay.
> - table is only present for in-store orders; deliveryAddress and pickUpTime only for delivery orders. When they do not apply the key is omitted, so treat a missing key the same as null. notes and items[].note can be null or empty. customer.companyName and customer.vatNumber appear only when supplied.
>
> Example order.created.v2 payload:
>
> {
>   "event": "order.created.v2",
>   "data": {
>     "id": "ord_abc123",
>     "code": "A1B2",
>     "asap": true,
>     "total": 2500,
>     "tip": 250,
>     "deliveryFee": 299,
>     "discountTotal": 0,
>     "orderType": "Delivery",
>     "pickUpTime": "2024-01-15T10:45:00Z",
>     "channel": "WEB",
>     "poNumber": null,
>     "createdAt": "2024-01-15T10:30:00Z",
>     "deliveryTime": "2024-01-15T11:00:00Z",
>     "notes": "Ring doorbell",
>     "customer": {
>       "firstName": "John",
>       "lastName": "Doe",
>       "email": "john@example.com",
>       "phone": "+44123456789",
>       "marketingConsent": true
>     },
>     "items": [
>       {
>         "name": "Margherita Pizza",
>         "printName": "Margherita",
>         "price": 1200,
>         "quantity": 1,
>         "plu": null,
>         "posId": null,
>         "taxRate": 20,
>         "note": null,
>         "modifiers": [
>           { "name": "Extra cheese", "printName": "Cheese", "price": 150, "quantity": 1, "plu": null, "posId": null, "taxRate": 20 }
>         ]
>       }
>     ],
>     "venue": {
>       "id": 1234,
>       "name": "My Restaurant",
>       "slug": "my-restaurant",
>       "address": {
>         "street1": "123 Main St",
>         "street2": "",
>         "city": "London",
>         "postCode": "W1A 1AA",
>         "country": "UK",
>         "companyName": "My Restaurant Ltd",
>         "coordinates": { "latitude": 51.5074, "longitude": -0.1278 }
>       }
>     },
>     "deliveryAddress": {
>       "street1": "456 Oak Ave",
>       "street2": "Flat 2",
>       "city": "London",
>       "postCode": "E1 6AN",
>       "country": "UK",
>       "notes": null,
>       "coordinates": { "latitude": 51.5155, "longitude": -0.0722 }
>     }
>   }
> }
>
> The full list of event types and payloads is at https://storekit.com/docs/developers/webhooks/webhook-events
> ```
>
> ```text theme={null}
> THE EVENT THIS APP USES: item.out_of_stock
>
> Ignore the order example above; this app only cares about item.out_of_stock, which looks like this:
>
> {
>   "event": "item.out_of_stock",
>   "data": {
>     "venue": { "id": 1234, "name": "My Restaurant" },
>     "item": { "id": 5678, "name": "Margherita Pizza", "plu": "PLU-001", "posId": "pos_item_42", "sku": "SKU-MARG-001" },
>     "reason": "snoozed",
>     "source": "manual",
>     "details": { "snoozeEnd": "2024-01-15T18:00:00Z" }
>   }
> }
>
> - reason is one of: snoozed (temporarily hidden by staff), inventory_depleted (sold out through inventory counts), disabled (switched off).
> - source is one of: manual (someone in the dashboard), order (a customer order used the last one), deliverect, lightspeed, zonal, pos_sync (pushed from a till or integration).
> - details.snoozeEnd is only present for reason snoozed and can be null, meaning snoozed indefinitely.
> - plu, posId and sku can be null.
> - There is no "back in stock" event. The app records when things went out; it cannot know when they came back.
>
> WHAT TO BUILD
>
> 1. POST /webhooks/storekit — verify the Svix signature with the official svix library and STOREKIT_WEBHOOK_SECRET against the raw request body; 400 on failure. Save the event and return 200 immediately. Ignore any svix-id already saved. Handle item.out_of_stock; save and acknowledge any other event type but do nothing with it.
> 2. A log table with: received time (store UTC, display in TIMEZONE), venue name, item name, item id, plu, sku, reason, source, snoozeEnd. Record the event's time as the time the webhook arrived.
> 3. GET / — protected by HTTP basic auth with ADMIN_PASSWORD. Three things on one page:
>    a. "Yesterday and today": a list of stock-outs since the start of yesterday in TIMEZONE, newest first, showing time, item, reason and source in plain words ("Snoozed by staff until 18:00", "Sold out through inventory after an order", "Switched off from Zonal").
>    b. "Most sold out, last 30 days": items ranked by number of stock-outs, with the count and the most common hour of day it happens.
>    c. Filters for venue (if I have more than one), reason and a date range, and a Download CSV button that exports whatever is filtered with the columns from point 2.
> 4. A daily digest posted to Slack via SLACK_WEBHOOK_URL at DIGEST_TIME (HH:MM in TIMEZONE, default 07:30). Content, in Slack mrkdwn:
>    *Sold out yesterday — <venue name>, <date>*
>    One line per item, in time order: "14:20  Margherita Pizza — sold out (inventory)" or "18:05  Sea Bass — snoozed by staff until 21:00". Group by venue if there is more than one.
>    Then a blank line and "*Most sold out this month*" followed by the top five items with counts.
>    If nothing sold out yesterday, post "Nothing sold out yesterday." — still post, so I know the app is alive.
>    Post the digest once per day even if the app restarts: record the date of the last digest sent and skip if it has already been sent for that date.
> 5. A "Send digest now" button on the page for testing, which posts the digest for yesterday regardless of whether it was already sent.
> 6. GET /health that returns 200 and { "ok": true } and nothing else.
>
> Use TIMEZONE for every day boundary and displayed time. Do not guess a default: if TIMEZONE is unset, refuse to start and log a clear message.
>
> DEFINITION OF DONE
>
> - [ ] A signed item.out_of_stock event appears in the log within a second and the endpoint returned 200.
> - [ ] The same event delivered twice creates one row.
> - [ ] A bad signature returns 400 and logs nothing.
> - [ ] The example payload above shows as "Margherita Pizza — snoozed by staff until 18:00".
> - [ ] The digest posts at DIGEST_TIME and not again that day, including after a restart.
> - [ ] "Send digest now" posts to Slack immediately.
> - [ ] The CSV download opens in a spreadsheet with one row per event and the columns listed.
> - [ ] Restarting the app loses nothing.
>
> WHAT TO GIVE ME WHEN YOU ARE DONE
>
> 1. The public webhook URL (…/webhooks/storekit) and the page URL.
> 2. The environment variables to set (STOREKIT_WEBHOOK_SECRET, ADMIN_PASSWORD, SLACK_WEBHOOK_URL, TIMEZONE, DIGEST_TIME) and where to set them on this platform.
> 3. Confirmation that the app stays up 24 hours a day and that the scheduled job runs when nobody has the page open.
> ```

Ouvre l'application, appuie sur « Send digest now » et vérifie que Slack affiche « Nothing sold out yesterday. » avant de connecter storekit.

## Étape 2 : connecter storekit

**1. Open the webhooks portal**

In the dashboard sidebar, go to **Settings** → **Webhooks**. If your plan includes webhooks and they are not yet enabled, click **Enable Webhooks**. If the page shows **Upgrade to enable webhooks**, [contact support](/docs/getting-started/contact-support) to discuss adding webhooks to your plan.

**2. Add your app as an endpoint**

In the embedded portal, add a new endpoint, paste the webhook URL your app builder gave you, and tick only the event types the recipe needs.

**3. Copy the signing secret into your app**

Open the endpoint you just created and copy its signing secret. In your app builder, save it as the environment variable `STOREKIT_WEBHOOK_SECRET` (builders call this "secrets" or "environment variables"). Redeploy if the builder asks you to.

**4. Send a test event**

Use the portal's test option on the endpoint to send a sample event. The delivery log shows the response code from your app. A `2xx` means your app accepted it; anything else, read the response body in the log — it is usually a missing secret.

Coche uniquement `item.out_of_stock` pour cet endpoint.

## Étape 3 : tester avec une vraie rupture

Mets un article en pause dans le menu builder (voir [Mettre en pause des produits](/docs/fr/guides/menu/availability-snoozing#mettre-des-produits-en-pause)). En quelques secondes, une ligne apparaît dans l'application avec la raison « snoozed » et la source « manual ». Réactive ensuite l'article — l'application ne le consigne pas, ce qui est attendu.

## Idées

* **E-mail hebdomadaire à l'acheteur** : demande au builder d'ajouter un e-mail du lundi (via un service comme Resend ou Postmark) avec le tableau des 30 jours joint en CSV.
* **Liste de prep** : marque les articles qui s'écoulent avant 20h trois fois dans la semaine comme « sous-préparés » et liste-les séparément.
* **Vérification croisée avec la caisse** : filtre par `source` pour voir combien de fois ton POS cache des articles que tu pensais en vente.

## Ce que cette recette ne fait pas

* **Elle ne peut pas te dire quand un article est revenu**, car il n'y a pas d'événement « back in stock ». Lis le journal comme « est parti à », pas « a été absent pendant ».
* **Elle ne modifie pas la disponibilité.** Sortir de pause et réapprovisionner se font dans le dashboard ou sur ta caisse comme avant.
* **Les événements commencent au moment où tu connectes l'endpoint.** Il n'y a pas d'historique antérieur ; le tableau des 30 jours se remplit au fil du premier mois.
* **C'est ton service.** Le support storekit peut confirmer qu'un événement `item.out_of_stock` a atteint ton URL et le code de réponse ; le journal et le digest sont à toi.

## Voir aussi

> **[Payload item.out\_of\_stock](/docs/fr/developers/webhooks/webhook-events#item-out-of-stock)**
>
> Chaque valeur de raison et de source que l'événement peut porter.

> **[Rédiger un prompt qui fonctionne](/docs/fr/guides/build/prompting-guide)**
>
> La structure derrière ce prompt, et quoi dire quand le builder se trompe.

> **[Alertes de commande vers Slack ou ton téléphone](/docs/fr/guides/build/recipes/order-alerts)**
>
> Le même motif pour les commandes plutôt que le stock.

> **[Disponibilité et snooze](/docs/fr/guides/menu/availability-snoozing)**
>
> Le snooze, l'inventaire et le rapport de snooze intégré.


## Related topics

- [Créer tes propres outils sur storekit](/docs/fr/guides/build/overview.md)
- [Journal des commandes bloquées storekit](/docs/fr/guides/orders/advanced/blocked-orders.md)
- [Journal d'audit](/docs/fr/privacy-security/audit-log.md)
- [Food trucks et pop-ups](/docs/fr/guides/use-cases/food-trucks.md)
- [Stock et disponibilité Syrve](/docs/fr/guides/integrations/pos/syrve/stock-and-availability.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.