Files
iti-technology/apps/api/http/shop.http
T
Lorenzo SanesiandClaude Opus 5.5 b83ce039fb
Deploy stack su Proxmox / deploy (push) Failing after 3s
Piattaforma ITI TECHNOLOGY: monorepo, Medusa, API, sito, area riservata e deploy
Monorepo npm con apps/public (Angular SSR), apps/private (Angular SPA),
apps/api (Fastify), packages/shared e packages/styles; Medusa 2.21 in medusa/;
infrastruttura Docker (Postgres PostGIS+pgvector, Redis, Caddy, backup) e
workflow Gitea Actions per il deploy via SSH a ogni push su master.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018jQyT6dR9czzGwqb7FkG6u
2026-10-20 09:30:48 +02:00

148 lines
5.0 KiB
HTTP

### Proxy shop (/shop/*) — HTTP Client JetBrains/WebStorm, ambiente "dev".
### Variabili: http-client.env.json + http-client.private.env.json (non committato, modello in
### http-client.private.env.example.json). Il client conserva i cookie (cart_id) tra le richieste.
### Prerequisiti: infra su, Medusa avviato con una chiave Stripe di TEST reale (STRIPE_API_KEY), apps/api avviata.
### Eseguire in ordine. Parte A: checkout guest completo. Parte B: installatore approvato (prezzi riservati).
### A0. Catalogo
GET {{baseUrl}}/shop/products?limit=12
### A1. Dettaglio prodotto (prezzo standard in centesimi: 549000)
GET {{baseUrl}}/shop/products/{{productHandle}}
> {%
client.global.set("variantId", response.body.variants[0].id)
client.test("prezzo standard", () => client.assert(response.body.variants[0].price === 549000))
%}
### A2. Categorie
GET {{baseUrl}}/shop/categories
### A3. Crea il carrello (cookie cart_id httpOnly)
POST {{baseUrl}}/shop/cart
### A4. Aggiungi il prodotto
POST {{baseUrl}}/shop/cart/items
Content-Type: application/json
{ "variantId": "{{variantId}}", "quantity": 1 }
> {% client.global.set("itemId", response.body.items[0].id) %}
### A5. Cambia quantità
PATCH {{baseUrl}}/shop/cart/items/{{itemId}}
Content-Type: application/json
{ "quantity": 1 }
### A6. Email (obbligatoria per il guest) e indirizzo; fatturazione = spedizione
POST {{baseUrl}}/shop/cart/address
Content-Type: application/json
{
"email": "{{guestEmail}}",
"shippingAddress": {
"firstName": "Mario", "lastName": "Rossi", "address1": "Via Roma 1",
"city": "Milano", "postalCode": "20100", "province": "MI", "phone": "3330000000"
},
"invoice": { "companyName": "Rossi Srl", "vatNumber": "00743110157", "sdiCode": "0000000" },
"acceptPrivacy": true
}
### A7. Opzioni di spedizione
GET {{baseUrl}}/shop/cart/shipping-options
> {% client.global.set("shippingOptionId", response.body[0].id) %}
### A8. Scegli la spedizione → readyForPayment = true
POST {{baseUrl}}/shop/cart/shipping
Content-Type: application/json
{ "optionId": "{{shippingOptionId}}" }
> {% client.test("pronto per il pagamento", () => client.assert(response.body.readyForPayment === true)) %}
### A9. Payment session Stripe → client_secret
POST {{baseUrl}}/shop/cart/payment
> {%
client.global.set("clientSecret", response.body.clientSecret)
client.global.set("paymentIntentId", response.body.clientSecret.split("_secret_")[0])
%}
### A10. Conferma con carta di test (al posto di Stripe.js nel browser): API Stripe con la chiave segreta di TEST
POST https://api.stripe.com/v1/payment_intents/{{paymentIntentId}}/confirm
Authorization: Bearer {{stripeSecretKey}}
Content-Type: application/x-www-form-urlencoded
payment_method=pm_card_visa&return_url=https%3A%2F%2Fexample.com%2Fcheckout
### A11. Completa → ordine creato, cookie cart_id cancellato
POST {{baseUrl}}/shop/cart/complete
> {% client.test("ordine creato", () => client.assert(response.status === 200 && response.body.number > 0)) %}
### A12. Dopo il completamento non c'è più un carrello → 404
GET {{baseUrl}}/shop/cart
### B1. Carrello guest prima del login (prezzo standard)
POST {{baseUrl}}/shop/cart/items
Content-Type: application/json
{ "variantId": "{{variantId}}", "quantity": 1 }
### B2. Login installatore approvato: il carrello guest aperto viene associato
POST {{baseUrl}}/auth/login
Content-Type: application/json
{ "email": "{{installerEmail}}", "password": "{{installerPassword}}" }
> {% client.global.set("accessToken", response.body.accessToken) %}
### B3. Carrello riprezzato col listino installatori (465000)
GET {{baseUrl}}/shop/cart
Authorization: Bearer {{accessToken}}
> {% client.test("prezzo installatore", () => client.assert(response.body.items[0].unitPrice === 465000)) %}
### B4. Catalogo con prezzi riservati (priceType "installer", originalPrice = listino pubblico)
GET {{baseUrl}}/shop/products/{{productHandle}}
Authorization: Bearer {{accessToken}}
### B5. Indirizzo (email dell'account, non serve inviarla)
POST {{baseUrl}}/shop/cart/address
Authorization: Bearer {{accessToken}}
Content-Type: application/json
{
"shippingAddress": {
"firstName": "Ina", "lastName": "Stallatore", "company": "Impianti Srl", "address1": "Via Milano 10",
"city": "Torino", "postalCode": "10100", "province": "TO"
},
"acceptPrivacy": true
}
### B6. Spedizione
POST {{baseUrl}}/shop/cart/shipping
Authorization: Bearer {{accessToken}}
Content-Type: application/json
{ "optionId": "{{shippingOptionId}}" }
### B7. Pagamento
POST {{baseUrl}}/shop/cart/payment
Authorization: Bearer {{accessToken}}
> {% client.global.set("paymentIntentId", response.body.clientSecret.split("_secret_")[0]) %}
### B8. Conferma carta di test
POST https://api.stripe.com/v1/payment_intents/{{paymentIntentId}}/confirm
Authorization: Bearer {{stripeSecretKey}}
Content-Type: application/x-www-form-urlencoded
payment_method=pm_card_visa&return_url=https%3A%2F%2Fexample.com%2Fcheckout
### B9. Completa → ordine con prezzi installatore, collegato al customer dell'account
POST {{baseUrl}}/shop/cart/complete
Authorization: Bearer {{accessToken}}