### 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}}