# Nexera Africa - Pi Test (Testnet) Payment Implementation

This guide explains how to **run Pi Network payment transactions in Pi Test (testnet) before going to mainnet**. The implementation includes:

- `pi-test-checkout.html` — A dedicated Pi Test checkout page (0.1 Test-Pi default, matching the Pi Test payment dialog in the example image)
- `pi-test-admin.php` — An admin panel for viewing test transactions, backend health, and resetting test data
- `api/pi_payment.php` — A unified, secure backend with `health`, `list`, `create`, `approve`, `complete`, `verify`, `incomplete`, and `reset_test` endpoints
- `config/env.php` — A `.env` loader (no more hardcoded API keys!)
- `config/db.php` — Database config that reads from env vars with safe defaults

---

## 🚀 Quick Start (5 Steps)

### Step 1: Create your `.env` file

```bash
cd /var/www/html/nexera_africa      # or wherever you deployed
cp .env.example .env
nano .env
```

Set the following values:

```env
PI_API_KEY=your_pi_test_api_key_here
PI_SANDBOX_MODE=true
DB_HOST=localhost
DB_USER=root
DB_PASS=your_real_mysql_password
DB_NAME=nexora_db
```

> ⚠️ **Get a TEST API key first.** Log into https://develop.pi, open your app, and copy the *test/sandbox* API key. **Do NOT** use your mainnet key for testing.

### Step 2: Make sure logs dir is writable

```bash
mkdir -p logs
chmod 775 logs
chown www-data:www-data logs   # or your web server user
```

### Step 3: Test backend health

Open this URL in any browser:

```
https://nexeraafrica.com/api/pi_payment.php?action=health
```

Expected JSON response:

```json
{
    "status": "ok",
    "mode": "test",
    "sandbox": true,
    "checks": {
        "api_key_configured": true,
        "api_url": "https://api.minepi.com/v2",
        "db_connected": true,
        ...
    },
    "message": "Pi TEST mode ready. All systems go."
}
```

If `status` is `degraded`, fix the failing checks before continuing.

### Step 4: Open the Pi Test checkout page in Pi Browser

```
https://nexeraafrica.com/pi-test-checkout.html
```

> 🔑 **This MUST be opened inside the Pi Browser app** (download from https://www.pi.network/browser). It will not work in Chrome, Safari, Firefox, etc.

Click **Connect Pi Wallet** → authenticate → click **Complete Payment with Pi** → review the 0.1 Test-Pi + 0.01 Test-Pi fee in the Pi Wallet dialog → confirm.

### Step 5: Verify the test transaction was recorded

Open the admin panel:

```
https://nexeraafrica.com/pi-test-admin.php
```

You should see your test transaction with status `completed` and a non-null `txid`.

---

## 🔬 Detailed Workflow

### How Pi Test (testnet) Works

```
┌─────────────────┐       ┌──────────────────┐       ┌─────────────────┐
│  Pi Browser     │       │  Your Backend    │       │  Pi Network API │
│  (Test Wallet)  │       │  (PHP)           │       │  (api.minepi.com)│
└────────┬────────┘       └────────┬─────────┘       └────────┬────────┘
         │                         │                          │
         │ 1. Pi.authenticate()    │                          │
         │ ◄───────────────────────┘                          │
         │                         │                          │
         │ 2. POST ?action=create │                          │
         │ ───────────────────────►│                          │
         │ ◄─── orderId ───────────│                          │
         │                         │                          │
         │ 3. Pi.createPayment()   │                          │
         │ (opens Pi Wallet dialog)│                          │
         │                         │                          │
         │ 4. onReadyForServerApproval(paymentId)             │
         │ ──── POST ?action=approve ──────────────────────►  │
         │                         │  POST /payments/{id}/approve
         │                         │ ◄──── 200 OK ────────────│
         │ ◄── approved ───────────│                          │
         │                         │                          │
         │ 5. onReadyForServerCompletion(paymentId, txid)     │
         │ ──── POST ?action=complete ─────────────────────►  │
         │                         │  POST /payments/{id}/complete
         │                         │ ◄──── 200 OK ────────────│
         │ ◄── completed ──────────│                          │
         │                         │                          │
```

- The frontend SDK is initialized with `Pi.init({ version: "2.0", sandbox: true })`.
- The backend `PI_SANDBOX_MODE=true` flag is stored alongside every payment in the `mode` column (`test` or `mainnet`).
- The Pi Network API endpoint (`https://api.minepi.com/v2`) routes your requests to testnet or mainnet **based on whether your `PI_API_KEY` is a sandbox key or a production key**. Make sure you're using a *test* API key during this phase.

### Endpoints (all on `/api/pi_payment.php`)

| Action     | Method | Body                                                                 | Purpose                                                |
|------------|--------|----------------------------------------------------------------------|--------------------------------------------------------|
| `health`   | GET    | —                                                                    | Backend sanity check (API key, DB, mode)               |
| `list`     | GET    | — (`?limit=50&mode=test`)                                            | List recent transactions                              |
| `create`   | POST   | `{amount, memo, uid?, metadata?}`                                    | Create a new order                                     |
| `approve`  | POST   | `{paymentId, orderId}`                                               | Approve a payment on Pi Network (calls Pi API)         |
| `complete` | POST   | `{paymentId, txid, orderId?}`                                        | Complete a payment on Pi Network (calls Pi API)        |
| `verify`   | POST   | `{paymentId}`                                                        | Verify a payment status on Pi Network                  |
| `incomplete` | POST | `{paymentId, transaction:{txid?}}`                                   | Handle an interrupted/cancelled payment                |
| `reset_test` | POST | —                                                                    | Delete all test-mode transactions (test mode only)     |

### Customizing the Test Payment

Open the checkout page with URL parameters to change the test amount:

```
https://nexeraafrica.com/pi-test-checkout.html?amount=0.5&memo=Hello&item=Premium
```

| Param    | Default                  | Description                       |
|----------|--------------------------|-----------------------------------|
| `amount` | `0.1`                    | Test-Pi amount                    |
| `fee`    | `0.01`                   | Test-Pi fee (display only)        |
| `memo`   | `Nexera Test Payment`    | Memo shown in Pi Wallet           |
| `item`   | `Pi Test Transaction`    | Item name shown in order summary  |

---

## 🛡️ Security Notes

1. **API key** is loaded from the `.env` file via `config/env.php` — never hardcoded in PHP files exposed to the web.
2. **`.env` must be in your `.gitignore`** and excluded from any public downloads.
3. **CORS**: Set `PI_ALLOWED_ORIGIN=https://nexeraafrica.com` in production (instead of `*`).
4. **HTTPS is required** by Pi Network — make sure Certbot SSL is installed.
5. **`reset_test` endpoint is disabled in mainnet mode** to prevent accidental data loss.
6. **Prepared statements** are used everywhere — no SQL injection risk.
7. **Idempotency**: The `complete` endpoint checks if a payment is already completed before calling the Pi API again, so retries won't double-complete.

---

## 🐛 Debugging

### Backend health is "degraded"

- `api_key_configured: false` → Edit your `.env` file and set `PI_API_KEY`.
- `db_connected: false` → Verify `DB_HOST`, `DB_USER`, `DB_PASS`, `DB_NAME` in `.env`.

### "Pi is not defined" in browser console

- You opened the page in a non-Pi browser. Open it in the Pi Browser app.
- Or the SDK script failed to load. Check your network tab.

### "Authentication failed"

- Your app's `Redirect URI` on the Pi Developer Portal doesn't match your deployed URL.
- Set it to `https://nexeraafrica.com/pi-test-checkout.html` (and `https://nexeraafrica.com/checkout.html` as a backup).

### Payment stuck at "Approve"

- Check `/logs/pi_payments.log` on your server.
- The most common cause is an incorrect `PI_API_KEY`. Make sure it's a *sandbox* key.
- Test with cURL:

  ```bash
  curl -X POST https://nexeraafrica.com/api/pi_payment.php?action=approve \
    -H "Content-Type: application/json" \
    -d '{"paymentId":"TEST_PID","orderId":"NEXERA-XXX"}'
  ```

  If the response says "Payment verification failed (HTTP 401)", your API key is wrong.

### Payment approved but not completing

- Check the Pi Network testnet block explorer to confirm the blockchain has the txid.
- Run `?action=verify&paymentId=XXX` to see what Pi reports.

### Database table missing

The `pi_payments` table is auto-created on the first request to any endpoint. If creation fails (permissions, etc.), run this SQL manually:

```sql
CREATE TABLE IF NOT EXISTS pi_payments (
    id          INT AUTO_INCREMENT PRIMARY KEY,
    order_id    VARCHAR(128) NOT NULL UNIQUE,
    payment_id  VARCHAR(255) DEFAULT NULL,
    user_uid    VARCHAR(255) DEFAULT NULL,
    amount      DECIMAL(18,8) NOT NULL DEFAULT 0,
    txid        VARCHAR(255) DEFAULT NULL,
    status      ENUM('initialized','approved','completed','failed','cancelled','interrupted')
                NOT NULL DEFAULT 'initialized',
    metadata    JSON DEFAULT NULL,
    mode        ENUM('test','mainnet') NOT NULL DEFAULT 'test',
    created_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_payment_id (payment_id),
    INDEX idx_status (status),
    INDEX idx_mode (mode)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```

---

## 🚢 Migrating from Pi Test → Mainnet

Once you've thoroughly tested the entire flow in Pi Test (testnet):

1. **Get a production API key** from https://develop.pi for the same app (Pi issues separate sandbox and production keys).
2. **Update your `.env`**:

   ```env
   PI_API_KEY=your_production_api_key_here
   PI_SANDBOX_MODE=false
   ```

3. **Update the SDK init in `pi-test-checkout.html`** (and any other page that calls `Pi.init`):

   ```javascript
   // Change from:
   Pi.init({ version: "2.0", sandbox: true });
   // To:
   Pi.init({ version: "2.0", sandbox: false });
   ```

4. **Update the Pi Developer Portal app** — switch the app from "Sandbox" to "Production".
5. **Verify the redirect URI** still matches your production domain.
6. **Run a small real transaction** to confirm everything works end-to-end.
7. **Monitor `/logs/pi_payments.log`** for any errors.

> ⚠️ **The `reset_test` endpoint is automatically disabled in mainnet mode** — so you cannot accidentally wipe production data.

---

## 📁 Files Modified / Added

| File | Status | Purpose |
|------|--------|---------|
| `config/env.php` | **NEW** | Loads `.env` file, exposes env() helpers |
| `config/db.php` | **MODIFIED** | Uses env vars, keeps backward-compatible defaults |
| `api/pi_payment.php` | **REWRITTEN** | Unified gateway with health/list/reset_test endpoints, better logging, idempotency, sandbox awareness |
| `pi-test-checkout.html` | **NEW** | Dedicated Pi Test (testnet) checkout page with 0.1 Test-Pi default |
| `pi-test-admin.php` | **NEW** | Admin dashboard for viewing/clearing test transactions and health check |
| `.env.example` | **MODIFIED** | Clear template for Pi Test settings |
| `PI_TEST_IMPLEMENTATION.md` | **NEW** | This document |

> **Legacy files kept for backward compatibility** (still work, but recommend migrating to the new flow):
> - `checkout.html` — Original checkout page
> - `payment.php` — Listing purchase page (uses the same backend)
> - `api/pi_handler.php` — Legacy standalone handler (do not use alongside the new `api/pi_payment.php`)

---

## ✅ Pre-Mainnet Checklist

Before flipping `PI_SANDBOX_MODE=false`, make sure ALL of the following pass:

- [ ] `?action=health` returns `status: ok` and `mode: test`
- [ ] Pi Test checkout page opens in Pi Browser without errors
- [ ] Connect Pi Wallet → authentication succeeds → username displays
- [ ] Click "Complete Payment" → Pi Wallet dialog opens with 0.1 Test-Pi + 0.01 fee
- [ ] Confirm payment → backend approve endpoint succeeds (check log)
- [ ] Backend complete endpoint succeeds (check log)
- [ ] Transaction appears in `pi-test-admin.php` with status `completed`
- [ ] `txid` is non-null
- [ ] `?action=verify&paymentId=XXX` returns the same status
- [ ] Reset test data button works (and is disabled in mainnet mode)
- [ ] No JavaScript console errors during the entire flow
- [ ] HTTPS certificate is valid (Pi Browser blocks non-HTTPS)
- [ ] CORS is locked down to your domain (`PI_ALLOWED_ORIGIN=https://nexeraafrica.com`)
- [ ] `.env` file is not web-accessible (add `Deny from all` in `.htaccess` if needed)

When every checkbox is green, you're ready to follow the **Migrating from Pi Test → Mainnet** section above.
