Stepback Store
2025
An online store backend covering carts, checkout with tax and shipping, Midtrans payments, and order status updates.
Links
In a nutshell
In short: customers can browse an online shop, pay with the payment methods they already use (bank transfer, GoPay, QRIS, minimarket), see real delivery prices for their address, and get an order email. My job was making sure all of that works reliably behind the scenes, even when a payment is late or fails and the shop has to put stock back automatically.
Why I built this
This was the final project (UAS) for a course at my university, built in a small team where I owned the backend. I treated it as a test of how far past a CRUD demo I could get: what really happens the moment someone clicks "pay", how inventory stays sane when two people buy the last unit, and how a third-party payment always finds its way back into our system.
What it solves
The scenario we picked: a small shop owner would normally juggle different tools for cart, shipping quotes, and payments, and those tools never talk to each other. Stepback connects the whole journey: someone can shop and pay step by step through one website, and whenever a payment goes through, fails, or never comes back, the order and the stock update by themselves with no manual fixing.
How it's built
- Cart system
- Guest carts keyed by a session UUID, then merged into one active cart per user on login (enforced at the database level), with expiry and abandonment tracking built in.
- Checkout
- Order creation runs in a single atomic transaction: shipping address snapshot, 11% tax, and a fixed app fee are computed server-side. Guests can also checkout just with an email address.
- Payments
- Midtrans via the Core API: BCA/BRI/BNI/CIMB/Permata virtual accounts, Mandiri e-channel, GoPay, QRIS, Indomaret/Alfamart, and Akulaku. The notification webhook flips orders to success, or cancels them and restocks, for cancel/deny/expire.
- Shipping
- Live rates from the Biteship API across 13+ couriers (JNE, J&T, SiCepat, etc.), resolved against each address's Biteship area id or postal code, so the customer picks a real service, not a flat fee.
- Stock & email
- Every buy, cancel, and restock moves through a StockMovement ledger, so the variant stock is an audit trail, not just a column that gets incremented. Order emails are rendered from Django templates.
- Infrastructure
- JWT auth with SimpleJWT, MariaDB behind Django 5, Docker Compose for local and prod, gunicorn + whitenoise deployment, and a set of API smoke-test scripts.
Result
For a coursework deadline, it went further than it had to. The full buying journey works: add items, see real shipping prices, pay with popular local options, and if a payment fails, the system reverses the order and puts stock back on its own. Watching a test payment turn into a real order was the most satisfying thing I built that semester. It never saw real customers, and with more time I would clean up a payment file that got too big and make the shipping price lookups faster, since they are the slowest parts of the flow.
Screenshots






