Recipes · 2 of 6
E-commerce — orders, carts, refunds
Schema
products: {sku, name, price, stock, sold}
carts: {_id, user_id, items:[{sku, qty}], total, status}
orders: {_id, user_id, items, total, status}
accounts: {user_id, balance}
add_to_cart
proc add_to_cart(user_id, sku, qty) {
let p = find_one("products", {sku: sku})
if p == null { abort "product not found" }
if p.stock < qty { abort "out of stock" }
let cart = find_one("carts", {user_id: user_id, status: "open"})
if cart == null {
insert("carts", {
user_id: user_id, status: "open", total: p.price * qty,
items: [{sku: sku, qty: qty, price: p.price}]
})
} else {
update("carts", {_id: cart._id}, {
$push: {items: {sku: sku, qty: qty, price: p.price}},
$inc: {total: p.price * qty}
})
}
return {ok: true}
}
checkout
proc checkout(user_id) {
let cart = find_one("carts", {user_id: user_id, status: "open"})
if cart == null { abort "no open cart" }
if cart.total <= 0 { abort "empty cart" }
let acc = find_one("accounts", {user_id: user_id})
if acc.balance < cart.total { abort "insufficient funds" }
// Reserve stock
for item in cart.items {
update("products", {sku: item.sku}, {$inc: {stock: -item.qty, sold: item.qty}})
}
// Charge buyer
update("accounts", {user_id: user_id}, {$inc: {balance: -cart.total}})
// Convert cart to order
let order_id = insert("orders", {
user_id: user_id, items: cart.items, total: cart.total, status: "confirmed"
})
update("carts", {_id: cart._id}, {$set: {status: "converted", order_id: order_id}})
return {ok: true, order_id: order_id, charged: cart.total}
}
refund
proc refund(order_id, reason, actor) {
let order = find_one("orders", {_id: order_id})
if order == null { abort "order not found" }
if order.status == "refunded" { abort "already refunded" }
// Refund money
update("accounts", {user_id: order.user_id}, {$inc: {balance: order.total}})
// Restock
for item in order.items {
update("products", {sku: item.sku}, {$inc: {stock: item.qty, sold: -item.qty}})
}
update("orders", {_id: order_id}, {$set: {status: "refunded", refund_reason: reason}})
insert("audit_log", {action: "refund", target: order_id, actor: actor, amount: order.total})
return {ok: true, refunded: order.total}
}
cancel_cart
proc cancel_cart(user_id) {
let cart = find_one("carts", {user_id: user_id, status: "open"})
if cart == null { return {ok: true, was_empty: true} }
update("carts", {_id: cart._id}, {$set: {status: "cancelled"}})
return {ok: true}
}
top_products
proc top_products(n) {
return aggregate("products", [
{$match: {sold: {$gt: 0}}},
{$sort: {sold: -1}},
{$limit: n},
{$project: {sku: 1, name: 1, sold: 1}}
])
}