feat(ecommerce): ADR 0009 - checkout con direccion y seleccion de envio
Siguiente corte tras el carrito real: pagina /checkout de 3 pasos (direccion -> envio -> confirmar) contra el Store API real, usando la shipping option que ya se verifico en produccion. Endpoints nuevos (setShippingAddress, getShippingOptions, addShippingMethod) probados en vivo con un carrito de prueba real antes de escribir el codigo -- direccion, opciones de envio y total ya confirmados correctos (80.000 + 5.000 = 95.000). El pago (PayU custom) sigue sin existir, asi que el ultimo paso sigue siendo WhatsApp -- pero ahora el mensaje incluye direccion, metodo de envio y total real en vez de solo la lista de productos. El boton del CartDrawer pasa de abrir WhatsApp directo a llevar a /checkout.
This commit is contained in:
1 parent
cdab538cfb
commit
bb2c0bbe85
7 files changed
+310
-8
No files matched your search
@@ -33,9 +33,27 @@ export interface CartSummary {
|
||||
cartId: string;
|
||||
currency: string;
|
||||
subtotal: number;
|
||||
shippingTotal: number;
|
||||
total: number;
|
||||
items: CartLine[];
|
||||
}
|
||||
|
||||
export interface ShippingAddressInput {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
address1: string;
|
||||
city: string;
|
||||
province?: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface ShippingOption {
|
||||
id: string;
|
||||
name: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
function backendUrl(): string {
|
||||
const value = process.env.MEDUSA_BACKEND_URL;
|
||||
if (!value) {
|
||||
@@ -68,6 +86,8 @@ type MedusaCart = {
|
||||
id: string;
|
||||
currency_code: string;
|
||||
subtotal?: number | null;
|
||||
shipping_total?: number | null;
|
||||
total?: number | null;
|
||||
items?: MedusaLineItem[] | null;
|
||||
};
|
||||
|
||||
@@ -76,6 +96,8 @@ function mapCart(cart: MedusaCart): CartSummary {
|
||||
cartId: cart.id,
|
||||
currency: cart.currency_code,
|
||||
subtotal: cart.subtotal ?? 0,
|
||||
shippingTotal: cart.shipping_total ?? 0,
|
||||
total: cart.total ?? cart.subtotal ?? 0,
|
||||
items: (cart.items ?? []).map((item) => ({
|
||||
lineItemId: item.id,
|
||||
variantId: item.variant_id,
|
||||
@@ -171,3 +193,50 @@ export async function removeLineItem(cartId: string, lineItemId: string): Promis
|
||||
// "parent", no en "cart" -- verificado en vivo, no documentado.
|
||||
return mapCart(data.parent as MedusaCart);
|
||||
}
|
||||
|
||||
export async function setShippingAddress(
|
||||
cartId: string,
|
||||
address: ShippingAddressInput,
|
||||
): Promise<CartSummary> {
|
||||
const data = await medusaCartFetch(`/store/carts/${cartId}?${ITEMS_FIELDS}`, {
|
||||
method: "POST",
|
||||
body: {
|
||||
email: address.email,
|
||||
shipping_address: {
|
||||
first_name: address.firstName,
|
||||
last_name: address.lastName,
|
||||
address_1: address.address1,
|
||||
city: address.city,
|
||||
province: address.province || undefined,
|
||||
country_code: "co",
|
||||
phone: address.phone,
|
||||
},
|
||||
},
|
||||
});
|
||||
return mapCart(data.cart as MedusaCart);
|
||||
}
|
||||
|
||||
type MedusaShippingOption = {
|
||||
id: string;
|
||||
name: string;
|
||||
amount?: number | null;
|
||||
calculated_price?: { calculated_amount?: number | null } | null;
|
||||
};
|
||||
|
||||
export async function getShippingOptions(cartId: string): Promise<ShippingOption[]> {
|
||||
const data = await medusaCartFetch(`/store/shipping-options?cart_id=${cartId}`);
|
||||
const options = (data.shipping_options as MedusaShippingOption[] | undefined) ?? [];
|
||||
return options.map((option) => ({
|
||||
id: option.id,
|
||||
name: option.name,
|
||||
amount: option.calculated_price?.calculated_amount ?? option.amount ?? 0,
|
||||
}));
|
||||
}
|
||||
|
||||
export async function addShippingMethod(cartId: string, optionId: string): Promise<CartSummary> {
|
||||
const data = await medusaCartFetch(`/store/carts/${cartId}/shipping-methods?${ITEMS_FIELDS}`, {
|
||||
method: "POST",
|
||||
body: { option_id: optionId },
|
||||
});
|
||||
return mapCart(data.cart as MedusaCart);
|
||||
}
|
||||
Reference in new issue
Block a user