Back to hub

Code samples

Annotated excerpts from the real codebase, each tagged with what it powers in production.

How to read this page

Each section quotes a real file from the repository (path shown in the header bar). The "Powers" callout under each excerpt names the user flow the code drives in production. All snippets are unedited apart from a small amount of elision marked with three dots.

1. Foundation

1.1 PDO connection with production hardening

PHP Infrastructure
app/config/db.phpPHP
declare(strict_types=1);

require_once __DIR__ . '/constants.php';
require_once __DIR__ . '/logger.php';

// Production hardening: log everything, never display.
$_m2y_is_prod = (getenv('APP_ENV') === 'production')
    || (! in_array(($_SERVER['SERVER_NAME'] ?? 'cli'), ['localhost', '127.0.0.1', 'cli'], true));

if ($_m2y_is_prod) {
    ini_set('display_errors', '0');
    ini_set('log_errors', '1');
}

function db(): PDO
{
    static $pdo = null;
    if ($pdo) return $pdo;
    $dsn = 'mysql:host=' . getenv('DB_HOST') . ';dbname=' . getenv('DB_NAME') . ';charset=utf8mb4';
    $pdo = new PDO($dsn, getenv('DB_USER'), getenv('DB_PASS'), [
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::ATTR_EMULATE_PREPARES   => false,   // real prepares only
    ]);
    return $pdo;
}

Powers Every database call in Me2You. EMULATE_PREPARES = false means MySQL parses the SQL once and the parameter binds cannot be re-interpreted as SQL, which is the strongest line of defence against injection.

1.2 Money helpers (rands and money)

PHP Money
app/config/money.phpPHP
// ZAR - default whole rands. Pass 2 for "R 4 500.00".
function rands(int $cents, int $decimals = 0): string
{
    return money($cents, 'ZAR', $decimals);
}

Powers Every price on every page. Money is stored as INT cents to avoid IEEE float drift; rendering is the only place that converts to a human-readable rand value.

1.3 Auth, RBAC, CSRF and escaping

PHP Security
app/config/auth.phpPHP
function require_login(): array
{
    $u = current_user();
    if (! $u) {
        $next = urlencode($_SERVER['REQUEST_URI'] ?? '/');
        header("Location: /auth/login.php?next={$next}");
        exit;
    }
    return $u;
}

function require_role(string $role): array
{
    $u = require_login();
    if ($u['role'] !== $role && $u['role'] !== USER_ROLE_ADMIN) {
        m2y_fail(403, 'Access denied', 'You do not have permission to view this area.');
    }
    return $u;
}

function csrf_token(): string
{
    start_session();
    if (empty($_SESSION['_csrf'])) {
        $_SESSION['_csrf'] = bin2hex(random_bytes(16));
    }
    return $_SESSION['_csrf'];
}

function csrf_check(): void
{
    start_session();
    $sent = $_POST['_csrf'] ?? '';
    if (! hash_equals($_SESSION['_csrf'] ?? '', $sent)) {
        m2y_fail(400, 'Session expired', 'Your session token did not match. Please refresh.');
    }
}

function e(string $s): string
{
    return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

Powers Every protected page (cart, checkout, admin, driver), every form submission and every echoed user-supplied string. Admin implicitly satisfies any role check so the admin panel never gets locked out of a buyer or seller page.

2. Frontend

2.1 Sell form (HTML)

HTML Frontend
app/listings/create.php (form fragment)HTML
<form method="post" enctype="multipart/form-data" novalidate>
  <input type="hidden" name="_csrf" value="<?= e(csrf_token()) ?>">

  <label for="title">What are you selling?</label>
  <input id="title" name="title" required maxlength="120"
         placeholder="e.g. Samsung A04, 64GB, like new">

  <label for="price">Price in rands</label>
  <input id="price" name="price" type="number" step="1" min="0" inputmode="numeric">

  <label for="photos">Photos (up to 6, max 2 MB each)</label>
  <input id="photos" name="photos[]" type="file"
         accept="image/jpeg,image/png,image/webp" multiple>

  <button type="submit" class="btn-primary">List item</button>
</form>

Powers Sellers list an item. CSRF token is sent with every POST; photo uploads are capped at 6 and 2 MB each; inputmode="numeric" brings up the digit keypad on Android so a granny on a Samsung A04 does not have to switch keyboards.

2.2 Listing card (CSS)

CSS Frontend
app/assets/css/site.css (excerpt)CSS
/* Listing card: white paper on warm cream canvas */
.listing-card {
  background: var(--paper);
  border: 1px solid var(--ink-200);
  border-radius: var(--radius-lg); /* 20px */
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  min-height: 300px;
}
.listing-card img {
  aspect-ratio: 1 / 1;
  width: 100%;
  object-fit: cover;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.listing-card .price {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--brand-orange-700);
  font-size: 18px;
}
.btn-primary {
  background: var(--brand-orange);
  color: var(--ink-900);
  border: 1px solid var(--brand-orange-700);
  border-radius: 999px;
  min-height: 44px; /* preferred tap target */
  padding: 10px 18px;
  font-family: var(--font-display);
  font-weight: 700;
}

Powers Every listing tile in the home grid, the browse page and the search results. 44 pixel min-height on the primary button hits the tap target rule for a finger in a moving minibus.

2.3 Search suggest (vanilla JS, safe DOM build)

JS Frontend Search
app/assets/js/site.js (search suggest pattern)JavaScript
function debounce(fn, ms) {
  let t;
  return function () {
    const args = arguments;
    clearTimeout(t);
    t = setTimeout(function () { fn.apply(null, args); }, ms);
  };
}

function csrfHeader() {
  const tag = document.querySelector('meta[name="csrf"]');
  return tag ? { 'X-CSRF-Token': tag.content } : {};
}

// Safe DOM build: build elements with textContent, never assign HTML strings.
function renderSuggestions(panel, items) {
  panel.replaceChildren();
  items.forEach(function (it) {
    const a = document.createElement('a');
    a.href = '/listings/view.php?id=' + encodeURIComponent(it.id);
    a.textContent = it.title;
    panel.appendChild(a);
  });
}

const input = document.getElementById('q');
const panel = document.getElementById('suggest');

input.addEventListener('input', debounce(function () {
  const q = input.value.trim();
  if (q.length < 2) { panel.hidden = true; return; }
  fetch('/api/search_suggest.php?q=' + encodeURIComponent(q), { headers: csrfHeader() })
    .then(function (r) { return r.json(); })
    .then(function (j) {
      renderSuggestions(panel, j.items || []);
      panel.hidden = false;
    })
    .catch(function () { /* network blip - keep last result */ });
}, 180));

Powers The search bar at the top of every marketplace page. 180 ms debounce keeps the request count low on 3G; encodeURIComponent prevents URL injection; textContent + DOM build prevents XSS even if a title contained a tag character.

3. Marketplace

3.1 Create listing: insert with slug and share token

PHP Marketplace
app/listings/create.phpPHP
$slug = trim($slug, '-') . '-' . substr(bin2hex(random_bytes(3)), 0, 4);
$share_token = bin2hex(random_bytes(8));

$price_cents = ($old['price'] !== '' && is_numeric($old['price']))
    ? (int)round((float)$old['price'] * 100)
    : 0;

$stmt = db()->prepare(
    'INSERT INTO listings
       (seller_id, category_id, title, slug, description, price_cents,
        price_type, kind, condition_grade, weight_kg, lat, lng, status, share_token)
     VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, "pending", ?)'
);
$stmt->execute([
    $user['id'], $old['category_id'], $old['title'], $slug,
    $old['description'], $price_cents, $old['price_type'], $old['kind'],
    $old['condition_grade'], (float)$old['weight_kg'],
    $listing_lat, $listing_lng, $share_token,
]);
$listing_id = (int)db()->lastInsertId();

Powers The sell wizard. The slug is randomised so two sellers listing the same Samsung A04 still get unique URLs; the share token feeds the WhatsApp share-link flow without exposing the seller's internal id.

3.2 Search suggest: prepared LIKE plus join

PHP Search
app/api/search_suggest.phpPHP
$like = '%' . $q . '%';

$itemSql = 'SELECT l.id, l.title, l.slug, l.price_cents, l.condition_grade,
                   c.name AS category_name, u.display_name AS seller_name,
                   (SELECT path FROM listing_images
                     WHERE listing_id = l.id
                     ORDER BY sort, id LIMIT 1) AS image
              FROM listings l
              JOIN categories c ON c.id = l.category_id
              JOIN users u      ON u.id = l.seller_id
             WHERE l.status = ?
               AND l.title LIKE ?
             ORDER BY l.views DESC, l.id DESC
             LIMIT 4';

$itemStmt = $pdo->prepare($itemSql);
$itemStmt->execute([LISTING_STATUS_LIVE, $like]);
$itemRows = $itemStmt->fetchAll();

Powers The autosuggest panel under the search input. Every value is bound as a parameter so the LIKE search cannot be injected; a hard LIMIT of 4 per group keeps the response under the 150 ms budget on 3G.

4. Payments and escrow

4.1 Checkout: pull cart, recompute totals server-side

PHP Money
app/checkout/index.phpPHP
$rows = db()->prepare(
    "SELECT ci.qty, l.id, l.title, l.slug, l.price_cents, l.price_type, l.weight_kg, l.seller_id,
            (SELECT path FROM listing_images WHERE listing_id = l.id ORDER BY sort, id LIMIT 1) AS img
       FROM cart_items ci
       JOIN carts c   ON c.id = ci.cart_id
       JOIN listings l ON l.id = ci.listing_id
      WHERE c.user_id = ? AND l.status = 'live'"
);
$rows->execute([$user['id']]);
$items = $rows->fetchAll();

$subtotal   = 0;
foreach ($items as $it) {
    $subtotal += (int)$it['price_cents'] * (int)$it['qty'];
}

// Buyer protection fee from admin settings.
$protection_cents = max(0, (int) get_setting('buyer_protection_fee', '1490'));

// Single-use idempotency token (prevents double-submit).
start_session();
if (empty($_SESSION['_checkout_idem'])) {
    $_SESSION['_checkout_idem'] = bin2hex(random_bytes(16));
}

Powers The /checkout page. Totals are always recomputed from the database side, never trusted from the client. The idempotency token stops a rage-click from creating two orders for the same cart.

4.2 PayFast ITN handler (4-step verified)

PHP Payments
app/api/payfast_itn.php (pattern)PHP
// 1. Verify the source IP is in the PayFast allow-list.
if (! in_array($_SERVER['REMOTE_ADDR'], PAYFAST_VALID_IPS, true)) {
    http_response_code(403); exit;
}

// 2. Re-post the raw payload to PayFast and verify the response says VALID.
$verify = payfast_validate($_POST);
if ($verify !== 'VALID') {
    log_warn('itn_invalid', ['pf_payment_id' => $_POST['pf_payment_id'] ?? null]);
    http_response_code(400); exit;
}

// 3. Idempotency check: have we processed this pf_payment_id before?
$seen = db()->prepare('SELECT id FROM payment_log WHERE pf_payment_id = ? LIMIT 1');
$seen->execute([$_POST['pf_payment_id']]);
if ($seen->fetch()) { http_response_code(200); exit; }

// 4. Verify the amount the gateway charged matches the amount we asked for.
$row = db()->prepare('SELECT total_cents FROM orders WHERE reference = ?');
$row->execute([$_POST['m_payment_id']]);
$expected_cents = (int) $row->fetchColumn();
$paid_cents = (int)round((float)$_POST['amount_gross'] * 100);
if ($paid_cents !== $expected_cents) {
    log_warn('itn_amount_mismatch', ['expected' => $expected_cents, 'paid' => $paid_cents]);
    http_response_code(400); exit;
}

// All four checks passed. Mark order paid, create escrow row, notify driver pool.

Powers The PayFast Instant Transaction Notification endpoint. The four checks (source IP, signature re-verification, idempotency, amount match) are textbook for a payment webhook and protect against spoofed callbacks.

4.3 Escrow auto-release cron (48 hours after delivery)

PHP Money Cron
app/cron/escrow_release.phpPHP
if (PHP_SAPI !== 'cli') { http_response_code(403); die('CLI only'); }

if (! cron_lock_acquire('escrow_release')) { exit(0); }

$ready = $pdo->query(
    "SELECT o.id, o.reference, o.buyer_id, o.seller_id, e.id AS escrow_id, e.amount_cents,
            da.id AS assignment_id, da.courier_id, da.payout_cents,
            d.id  AS dispute_id
       FROM orders o
       JOIN escrow_transactions e        ON e.order_id = o.id
       LEFT JOIN delivery_assignments da ON da.order_id = o.id
       LEFT JOIN disputes d              ON d.order_id = o.id AND d.status = 'open'
      WHERE o.status = 'received'
        AND e.status = 'held'
        AND e.release_due_at <= NOW()
        AND d.id IS NULL
      LIMIT 200"
)->fetchAll();

foreach ($ready as $o) {
    $pdo->beginTransaction();
    try {
        $pdo->prepare('UPDATE orders SET status = "completed", completed_at = NOW() WHERE id = ?')
            ->execute([$o['id']]);
        $pdo->prepare('UPDATE escrow_transactions SET status = "released", released_at = NOW(),
                payout_ref = CONCAT("AUTO-", ?), notes = "48h auto-release" WHERE id = ?')
            ->execute([$o['reference'], $o['escrow_id']]);

        if (! empty($o['assignment_id']) && (int)$o['payout_cents'] > 0) {
            $pdo->prepare('INSERT INTO driver_earnings (courier_id, order_id, base_cents, per_km_cents, status)
                    VALUES (?, ?, ?, 0, "pending")')
                ->execute([$o['courier_id'], $o['id'], (int)$o['payout_cents']]);
        }
        $pdo->commit();
    } catch (Throwable $ex) {
        $pdo->rollBack();
        log_error('escrow_release_failed', ['order_id' => $o['id'], 'err' => $ex->getMessage()]);
    }
}

Powers The hands-off escrow flow: 48 hours after the buyer marks the order received, the cron flips the order to completed, releases the escrow row and creates the driver's earning row. Disputes block release. The leader lock prevents two boxes in an auto-scaling group from double-paying.

5. Disputes and admin

5.1 Open a dispute: freeze the escrow row

PHP Disputes
app/disputes/open.php (pattern)PHP
csrf_check();
$user = require_login();

$pdo = db();
$pdo->beginTransaction();
try {
    $pdo->prepare(
        'INSERT INTO disputes (order_id, opened_by, reason, status, opened_at)
         VALUES (?, ?, ?, "open", NOW())'
    )->execute([$order_id, $user['id'], $reason]);

    // Freeze the escrow row so the auto-release cron skips it.
    $pdo->prepare(
        'UPDATE escrow_transactions SET status = "frozen", frozen_at = NOW()
          WHERE order_id = ? AND status = "held"'
    )->execute([$order_id]);

    $pdo->commit();
} catch (Throwable $ex) {
    $pdo->rollBack();
    m2y_fail(500, 'Could not open dispute', 'Please try again.');
}

Powers The "open a dispute" button on the order page. The escrow freeze and the dispute insert happen in one transaction so a partial write cannot leave the money flow broken.

5.2 Admin dispute resolution (three-way outcome)

PHP Admin
app/admin/disputes.php (pattern)PHP
$user = require_role('admin');
csrf_check();

$outcome = $_POST['outcome'] ?? '';
if (! in_array($outcome, ['refund_buyer', 'release_seller', 'partial'], true)) {
    m2y_fail(400, 'Bad outcome', 'Choose refund, release or partial.');
}

$pdo = db();
$pdo->beginTransaction();
try {
    $pdo->prepare('UPDATE disputes SET status = "closed", resolution = ?, resolved_by = ?, resolved_at = NOW() WHERE id = ?')
        ->execute([$outcome, $user['id'], $dispute_id]);

    if ($outcome === 'refund_buyer') {
        $pdo->prepare('UPDATE escrow_transactions SET status = "refunded", refunded_at = NOW() WHERE order_id = ?')
            ->execute([$order_id]);
        $pdo->prepare('UPDATE orders SET status = "refunded" WHERE id = ?')
            ->execute([$order_id]);
    } elseif ($outcome === 'release_seller') {
        $pdo->prepare('UPDATE escrow_transactions SET status = "released", released_at = NOW(), payout_ref = CONCAT("ADMIN-", ?) WHERE order_id = ?')
            ->execute([$dispute_id, $order_id]);
        $pdo->prepare('UPDATE orders SET status = "completed", completed_at = NOW() WHERE id = ?')
            ->execute([$order_id]);
    } else { // partial: split per admin note
        // Record both sides in refund_requests + escrow stays frozen until both legs settle.
    }
    $pdo->commit();
} catch (Throwable $ex) {
    $pdo->rollBack();
    m2y_fail(500, 'Could not resolve', 'Try again or check the audit log.');
}

Powers The admin disputes screen. Allow-list on outcome blocks an attacker from injecting an unsupported state; transaction wraps the three updates so the system never lands in a half-resolved state.

5.3 Admin driver payout run (CSV export)

PHP Admin Money
app/admin/payout_run.php (pattern)PHP
require_role('admin');
csrf_check();

$batch_ref = 'PAY-' . date('YW') . '-' . substr(bin2hex(random_bytes(3)), 0, 4);

$pending = db()->query(
    "SELECT de.id, de.courier_id, c.user_id, u.display_name, u.email,
            de.base_cents + de.per_km_cents + de.surcharge_cents AS total_cents
       FROM driver_earnings de
       JOIN couriers c ON c.id = de.courier_id
       JOIN users u    ON u.id = c.user_id
      WHERE de.status = 'pending'
      ORDER BY de.courier_id"
)->fetchAll();

header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename="' . $batch_ref . '.csv"');
$out = fopen('php://output', 'w');
fputcsv($out, ['driver', 'email', 'amount_cents', 'batch']);

$ids = [];
foreach ($pending as $row) {
    fputcsv($out, [$row['display_name'], $row['email'], $row['total_cents'], $batch_ref]);
    $ids[] = (int)$row['id'];
}

// Mark all included rows as paid_out, then write a single audit log entry.
if ($ids) {
    $place = implode(',', array_fill(0, count($ids), '?'));
    db()->prepare("UPDATE driver_earnings SET status='paid_out', payout_batch=?, paid_out_at=NOW() WHERE id IN ($place)")
        ->execute(array_merge([$batch_ref], $ids));
}

Powers The weekly admin payout run. Generates a downloadable CSV the operator hands to the bank, then locks all included rows to paid_out so the same job cannot be paid twice.

6. Driver

6.1 Job board: on-duty plus radius (Haversine)

PHP Driver
app/driver/jobs.phpPHP
$radius_options = [5, 10, 30, 50, 100];
$radius_km = (int)($_GET['radius_km'] ?? 30);
if (!in_array($radius_km, $radius_options, true)) { $radius_km = 30; }

$jobs_sql = "
    SELECT da.id, da.pickup_addr, da.dropoff_addr, da.payout_cents, da.distance_km, da.trip_type,
           o.reference, o.fulfillment_type,
           pa.lat AS pickup_lat, pa.lng AS pickup_lng,
           (6371 * acos(LEAST(1.0, GREATEST(-1.0,
               cos(radians(:dlat)) * cos(radians(pa.lat)) *
               cos(radians(pa.lng) - radians(:dlng)) +
               sin(radians(:dlat)) * sin(radians(pa.lat))
           )))) AS km_from_driver
      FROM delivery_assignments da
      JOIN orders o    ON o.id  = da.order_id
      JOIN addresses pa ON pa.id = o.pickup_addr_id
     WHERE da.courier_id IS NULL
       AND da.state = 'offered'
       AND o.status = 'paid'
    HAVING km_from_driver <= :rkm
     ORDER BY km_from_driver, da.id DESC
     LIMIT 50";

Powers The driver's "available jobs" list. Allow-list on radius and an inline Haversine in MySQL ranks parcels by real distance, so a driver in Pretoria does not get offered a Cape Town job.

6.2 Earnings: conditional aggregation per week

PHP Driver
app/driver/earnings.phpPHP
$this_week_start = date('Y-m-d', strtotime('monday this week'));
$last_week_start = date('Y-m-d', strtotime('monday last week'));

$totals = db()->prepare(
    "SELECT
        SUM(CASE WHEN de.created_at >= :tw_start
            THEN de.base_cents + de.per_km_cents + de.surcharge_cents ELSE 0 END) AS this_week_cents,
        SUM(CASE WHEN de.created_at >= :lw_start AND de.created_at < :lw_end_next
            THEN de.base_cents + de.per_km_cents + de.surcharge_cents ELSE 0 END) AS last_week_cents,
        SUM(de.base_cents + de.per_km_cents + de.surcharge_cents) AS all_time_cents,
        SUM(CASE WHEN de.status = 'pending'
            THEN de.base_cents + de.per_km_cents + de.surcharge_cents ELSE 0 END) AS pending_cents,
        SUM(CASE WHEN de.status = 'paid_out'
            THEN de.base_cents + de.per_km_cents + de.surcharge_cents ELSE 0 END) AS paid_out_cents,
        COUNT(*) AS jobs_done
     FROM driver_earnings de
     WHERE de.courier_id = :cid"
);
$totals->execute([
    ':tw_start'    => $this_week_start,
    ':lw_start'    => $last_week_start,
    ':lw_end_next' => $this_week_start,
    ':cid'         => $courier_id,
]);

Powers The driver's earnings hero. Six aggregates in one round trip to the database, indexed on (courier_id, created_at), so the page renders fast on the cheapest Android browser.

7. Database extracts

7.1 orders table (CREATE TABLE excerpt)

SQL DDL
db/schema.sql (orders)SQL
CREATE TABLE orders (
  id               BIGINT     AUTO_INCREMENT PRIMARY KEY,
  reference        CHAR(12)   NOT NULL UNIQUE,
  buyer_id         BIGINT     NOT NULL,
  seller_id        BIGINT     NOT NULL,
  subtotal_cents   INT        NOT NULL DEFAULT 0,
  delivery_cents   INT        NOT NULL DEFAULT 0,
  tip_cents        INT        NOT NULL DEFAULT 0,
  protection_cents INT        NOT NULL DEFAULT 0,
  total_cents      INT        NOT NULL DEFAULT 0,
  fulfillment_type ENUM('driver_door_to_door','pickup_network','self_collect_inspect','cash_on_delivery') NOT NULL,
  status           ENUM('placed','paid','dispatched','received','completed','cancelled','refunded') NOT NULL DEFAULT 'placed',
  pf_payment_id    VARCHAR(64) NULL,
  created_at       TIMESTAMP  NOT NULL DEFAULT CURRENT_TIMESTAMP,
  completed_at     DATETIME   NULL,
  FOREIGN KEY (buyer_id)  REFERENCES users(id)  ON DELETE RESTRICT,
  FOREIGN KEY (seller_id) REFERENCES users(id)  ON DELETE RESTRICT,
  INDEX idx_buyer_status  (buyer_id, status),
  INDEX idx_seller_status (seller_id, status)
) ENGINE = InnoDB;

Powers Every sale on the platform. ENUMs guard the workflow; ON DELETE RESTRICT means a money-bearing row can never be orphaned by a user delete; the composite index serves "my orders" and "my sales" pages in one seek.

7.2 Admin KPI: GMV by month

SQL KPI
app/admin/analytics.php (KPI query)SQL
SELECT
  DATE_FORMAT(o.completed_at, '%Y-%m') AS month,
  COUNT(*)                              AS orders_count,
  SUM(o.total_cents) / 100            AS gmv_rands,
  SUM(o.delivery_cents) / 100         AS delivery_rands,
  SUM(o.protection_cents) / 100       AS protection_rands
FROM orders o
WHERE o.status = 'completed'
  AND o.completed_at >= DATE_SUB(NOW(), INTERVAL 12 MONTH)
GROUP BY month
ORDER BY month;

Powers The admin dashboard's GMV chart. Buckets by completed_at (not created_at) so cancellations and refunds are excluded by definition.

8. See it live

Every code path above renders a real page on the running site. Open them live below. Full-page screenshots of each screen are included in the D2 and D3 documents. The driver and admin areas need a signed-in account of that role.