= {
+ home: "خانه",
+ work: "محل کار",
+ other: "سایر",
+};
+
+/**
+ * "افزودن آدرس" / "تغییر آدرس" both just go to /addresses for now — the picker step
+ * in between (per the design) is a later task.
+ */
+export function CheckoutAddress({ address }: { address: Address | null }) {
+ return (
+
+ آدرس تحویل
+
+ {address ? (
+
+ {/* DOM order intentionally mirrors the screenshot's left→right layout — see the
+ inherited dir="rtl" note on the /cart page. */}
+
+
+ تغییر آدرس
+
+
+
+ {address.title || ADDRESS_LABEL_FA[address.label]}
+
+
+
+
+
{address.full_address}
+
+ ) : (
+
+
+
+
+
+ هنوز آدرسی ثبت نکردهاید. برای ادامه سفارش، لطفاً یک آدرس اضافه کنید.
+
+
+
+ افزودن آدرس
+
+
+
+ )}
+
+ );
+}
diff --git a/src/components/customer/checkout-fulfillment.tsx b/src/components/customer/checkout-fulfillment.tsx
index a3e638a..202b38e 100644
--- a/src/components/customer/checkout-fulfillment.tsx
+++ b/src/components/customer/checkout-fulfillment.tsx
@@ -94,9 +94,12 @@ export function CheckoutFulfillment({ group }: { group: CartGroup }) {
- {/* Pickup has its own confirm+pay screen (no address needed); delivery still
- goes to the general /checkout form until that flow's design is provided. */}
-
+ {/* Same confirm+pay screen either way — it shows the address section only for
+ delivery, and folds the delivery fee into the total only for delivery. */}
+
("wallet");
const [error, setError] = useState(null);
const [isPending, startTransition] = useTransition();
- // Pickup flow — no delivery fee, matches the fulfillment screen's "دریافت حضوری" total.
- const payable = group.items_subtotal;
+ // Pickup — no delivery fee, matches the fulfillment screen's "دریافت حضوری" total.
+ const payable = group.items_subtotal + (isDelivery ? group.delivery_fee : 0);
function handlePay() {
setError(null);
diff --git a/src/lib/api/gooyal-accounts.ts b/src/lib/api/gooyal-accounts.ts
index 92a0e16..c1f1f5f 100644
--- a/src/lib/api/gooyal-accounts.ts
+++ b/src/lib/api/gooyal-accounts.ts
@@ -1,7 +1,7 @@
import "server-only";
import { getValidSession } from "@/lib/auth/session";
import { ApiError, type WinofyErrorDetails } from "./errors";
-import { logWinofyRequest, logWinofyResponse } from "./dev-logger";
+import { logApiRequest, logApiResponse } from "./dev-logger";
const BASE_URL = process.env.GOOYAL_ACCOUNTS_BASE_URL!;
@@ -35,7 +35,7 @@ export async function gooyalFetch(path: string, options: GooyalFetchOptions =
}
}
- logWinofyRequest?.(method, url.toString(), body);
+ logApiRequest("gooyal", method, url.toString(), body);
const res = await fetch(url.toString(), {
...rest,
@@ -45,12 +45,12 @@ export async function gooyalFetch(path: string, options: GooyalFetchOptions =
});
if (res.status === 204) {
- logWinofyResponse?.(method, url.toString(), res.status, null);
+ logApiResponse("gooyal", method, url.toString(), res.status, null);
return undefined as T;
}
const data = await res.json().catch(() => null);
- logWinofyResponse?.(method, url.toString(), res.status, data);
+ logApiResponse("gooyal", method, url.toString(), res.status, data);
if (!res.ok) {
const envelope = data as { status_message?: string; details?: WinofyErrorDetails } | null;