AlixFast PerfectPanel v2 — FULL CODE GUIDE (baqi steps, code ke saath)
=====================================================================
Step 1 (alixfast-pay upload), Step 2 (logo) aur Step 4 (SQL) aapko
samajh aa gaye hain — isliye is guide mein sirf baqi steps ka POORA
CODE hai: kahan, kis file mein, kis line ke paas paste karna hai.
Note: PerfectPanel ke versions mein variable/file naam thode alag ho
sakte hain — maujooda stripe/paypal wali lines ko dekh kar usi style
mein adjust karein, logic wahi rahega.

---------------------------------------------------------------------
STEP 3 — config.php KA POORA CODE
File: public_html/alixfast-pay/config.php
Sirf CAPITAL wali jagah apni details dalein, baaki code chhedein nahi.
---------------------------------------------------------------------
<?php
define('AFX_GATEWAY_URL', 'https://alixfast.com');

// AlixFast merchant panel -> Integration se copy karein:
define('AFX_PUBLIC_KEY', 'pk_live_APKI_PUBLIC_KEY');
define('AFX_SECRET_KEY', 'sk_live_APKI_SECRET_KEY');

// Panel ki apni config (public_html/app/config.php) se copy karein:
define('AFX_DB_HOST', 'localhost');
define('AFX_DB_NAME', 'APKI_PANEL_DB');
define('AFX_DB_USER', 'APKI_DB_USER');
define('AFX_DB_PASS', 'APKI_DB_PASSWORD');

// Users table mapping (default Gill setting):
define('AFX_USERS_TABLE', 'clients');
define('AFX_USER_ID_COL', 'id');
define('AFX_BALANCE_COL', 'balance');

define('AFX_PANEL_PAYMENTS_TABLE', 'payments');
define('AFX_CURRENCIES_TABLE', 'currencies');
define('AFX_BASE_CURRENCY', 'USD');   // PKR mein change NA karein
define('AFX_RETURN_PAGE', '/addfunds');

// Log file — public_html ke BAHAR (hosting home folder mein):
define('AFX_LOG_FILE', '/home/APKA_HOSTING_USERNAME/alixfast-callback.log');
?>
Check: callback.php kholne par "bad signature" aaye to config load ho raha hai.

---------------------------------------------------------------------
STEP 5 — INITIATOR KA POORA CODE
File: public_html/app/controller/addfunds/Initiators/alixfast.php
(File ka naam sirf "alixfast.php" rakhein.)
---------------------------------------------------------------------
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');

class Alixfast extends CI_Controller {
    public function index() {
        $amount = (float)($this->input->post('amount') ?? 0);
        $method = $this->db->where('methodId', 110)->get('paymentmethods')->row();
        $min = $method ? (float)$method->methodMin : 10;
        $max = $method ? (float)$method->methodMax : 100000;
        if ($amount < $min || $amount > $max) {
            $this->session->set_flashdata('error', "Amount must be between PKR {$min} and PKR {$max}.");
            redirect('addfunds');
        }
        $ref = 'ALIXFAST-' . time() . '-' . $this->user['id'];
        $this->db->insert('payments', [
            'client_id'        => $this->user['id'],
            'payment_method'   => 110,
            'payment_amount'   => $amount,
            'payment_status'   => 1, // Pending
            'payment_delivery' => 1,
            'payment_mode'     => 'Automatic',
            'payment_extra'    => $ref,
            'payment_note'     => 'AlixFast:' . $ref,
        ]);
        redirect('/alixfast-pay/pay.php?order_ref=' . urlencode($ref) . '&amount=' . urlencode($amount));
    }
}
?>
Agar Step 4 mein methodId 110 ki jagah koi aur id li hai to is file
mein 110 ki jagah wohi id likhein (2 jagah: where() aur payment_method).

---------------------------------------------------------------------
STEP 6 — DISPATCH LINE (addfunds.php)
File: public_html/app/controller/addfunds.php
Jahan baaki methods ki lines hain, wahan ye line lagayein:
---------------------------------------------------------------------
// Stripe/PayPal wali lines ke saath, unke baad:
elseif ($methodId == 110) {
    $this->load->controller('addfunds/Initiators/alixfast');
}
Agar aapke version mein switch-case hai to wahan ye case lagayein:
    case 110:
        $this->load->controller('addfunds/Initiators/alixfast');
        break;
Check: Add Funds form mein AlixFast select karke submit karein —
Initiator wali pending row payments table mein banani chahiye.

---------------------------------------------------------------------
STEP 7 — GETFORM CODE (getForm.php)
File: public_html/app/controller/addfunds/getForm.php
Method 110 ke liye ye branch lagayein:
---------------------------------------------------------------------
if ($methodId == 110) {
    $method = $this->db->where('methodId', 110)->get('paymentmethods')->row();
    $min = $method ? (float)$method->methodMin : 10;
    $max = $method ? (float)$method->methodMax : 100000;
    echo '
    <div class="form-group">
        <label>Amount (PKR)</label>
        <input type="number" name="amount" class="form-control"
               min="' . $min . '" max="' . $max . '" required
               placeholder="Enter amount in PKR">
        <small class="form-text text-muted">
            Amount is entered in PKR only. It is converted to USD at the
            panel rate when credited.
            Minimum: PKR ' . $min . ' | Maximum: PKR ' . $max . '
        </small>
    </div>
    <button type="submit" class="btn btn-primary btn-block">Initiate Payment</button>';
}
Agar aapka getForm JSON return karta hai to wahi fields JSON mein dein:
  {"label":"Amount (PKR)","min":10,"max":100000,
   "note":"Amount is entered in PKR only. It is converted to USD at the panel rate when credited."}
Check: form mein "Amount (PKR)" aur min/max note dikhna chahiye.

---------------------------------------------------------------------
STEP 8 — METHODS LIST MEIN MIN/MAX (addfunds.php)
Ye v1 ka asal bug tha: list mein min/max tha hi nahi.
Maujooda methods wali loop mein ye 4 fields ADD karein:
---------------------------------------------------------------------
// PEHLE (v1 — ghalat, min/max missing):
//   $methods[] = ['id'=>$row->methodId, 'name'=>$row->methodName,
//                  'instructions'=>$row->methodInstructions, 'fee'=>$row->methodFee];

// AB (v2 — sahi):
$methods[] = [
    'id'           => $row->methodId,
    'name'         => $row->methodName,
    'instructions' => $row->methodInstructions,
    'fee'          => $row->methodFee,
    'min'          => (float)$row->methodMin,
    'max'          => (float)$row->methodMax,
    'methodMin'    => (float)$row->methodMin,
    'methodMax'    => (float)$row->methodMax,
];
Template (addfunds.twig) mein form note is tarah banayein:
  Minimum: PKR {{ method.min }} | Maximum: PKR {{ method.max }}
Check: Admin mein min badlein, form reload karein — naya min turant
aana chahiye, file dobara edit kiye baghair.

---------------------------------------------------------------------
STEP 9 — ADDFUNDS.TWIG KA CODE (Quick Card + History + Banner)
File: public_html/app/views/<THEME>/addfunds.twig
---------------------------------------------------------------------
(a) QUICK DEPOSIT CARD — sab se pehle, baaki cards se pehle:
<div class="quick-method" data-method-id="110"
     onclick="selectPaymentMethod(110)">
    <img src="/assets/alixfast-logo.png" alt="AlixFast" style="height:32px;">
    <span>AlixFast</span>
</div>
<!-- Agar aapke theme mein quick cards kisi aur function se select hote
     hain to wahi function use karein — bas data-method-id="110" hona
     chahiye, taake dropdown mein AlixFast select ho aur form load ho. -->

(b) RETURN BANNER — Add Funds page ke top par, form se pehle:
{% if app.request.get('alixfast') == 'credited' %}
<div class="alert alert-success">
    Paid PKR {{ app.request.get('paid_pkr') }} &rarr;
    credited ${{ app.request.get('credited_usd') }} (converted to USD).
</div>
{% endif %}

(c) USER HISTORY — sirf Successful Credit rows (loop mein filter):
<table>
  <thead><tr>
    <th>ID</th><th>DATE</th><th>METHOD</th><th>AMOUNT</th>
    <th>TRANSACTION ID</th><th>STATUS</th>
  </tr></thead>
  <tbody>
  {% for payment in payments %}
    {% if payment.payment_status == 3 and payment.payment_delivery == 2 %}
    <tr>
      <td>{{ payment.payment_id }}</td>
      <td>{{ payment.payment_created_at }}</td>
      <td>{{ payment.methodName }}</td>
      <td>PKR {{ payment.payment_amount }}</td>
      <td>
        {# Transaction ID: "AlixFast:38" note se 38 nikalna #}
        {{ payment.payment_note|replace({'AlixFast:': ''}) }}
      </td>
      <td>Successful Credit</td>
    </tr>
    {% endif %}
  {% else %}
    <tr><td colspan="6">No successful credits found.</td></tr>
  {% endfor %}
  </tbody>
</table>
Zaroori: loop ke andar if lagayein — Pending/Failed rows render hi
na hon, CSS se chhupana kaafi nahi. Agar aapka template status ke
liye alag field use karta hai to wahi field check karein
(3 = Completed/Successful, 1 = Pending).
Admin ki history file edit NA karein — wahan sab kuch waisa hi rahe.

---------------------------------------------------------------------
STEP 10 — ADMIN SETTINGS CODE (keys + webhook field)
File: Admin -> Payments -> payment settings (method 37 pattern follow karein)
---------------------------------------------------------------------
// 1. Automatic methods wali list mein 110 add karein:
//    $automatic_methods = [..., 37, 110];

// 2. AlixFast edit dialog mein ye 3 fields dikhayein:
//    - Public Key  (input, naam: public_key)
//    - Secret Key  (input, naam: secret_key)
//    - Webhook URL (read-only input, value neeche wali line se):
<input type="text" readonly
       value="https://YOURPANEL.com/alixfast-pay/callback.php">

// 3. Save hone par methodExtras mein is tarah save hon:
//    {"public_key":"pk_live_...","secret_key":"sk_live_..."}

// 4. alixfast-pay/config.php mein keys parhne ka order ye rakhein:
//    PEHLE Admin methodExtras, PHIR constants (fallback):
//    (Is ke liye config.php ke top par ye snippet lagayein — sirf tab
//     jab aapke panel mein methodExtras kaam karta ho, warna constants
//     hi kaafi hain.)
$extras = json_decode($row->methodExtras ?? '{}', true);
if (!empty($extras['public_key']))  define('AFX_PUBLIC_KEY',  $extras['public_key']);
if (!empty($extras['secret_key']))  define('AFX_SECRET_KEY',  $extras['secret_key']);
Check: Admin mein key badal kar save karein, phir dobara edit kholne
par nayi key dikhni chahiye — aur payment bhi nayi key se chalni chahiye.

---------------------------------------------------------------------
STEP 11 — WEBHOOK URL (code nahi, setting hai)
AlixFast merchant panel -> Integration -> Webhook URL mein ye paste karein:
  https://YOURPANEL.com/alixfast-pay/callback.php
Ye step chhoota to webhook kabhi nahi aayega — payment hamesha
pending rahegi, chahe baaki sab kuch sahi ho.

---------------------------------------------------------------------
STEP 12 — TEST KA CHECKLIST (code nahi, verification hai)
[ ] Quick Deposit mein AlixFast pehle, logo ke saath
[ ] Form mein "Amount (PKR)" + min/max note
[ ] PKR 10 payment -> checkout par Total PKR mein
[ ] Wapas Add Funds par green banner: Paid PKR 10 -> credited $0.0361
      (rate panel ki currencies table se aata hai, thoda farq normal hai)
[ ] History mein EK Successful Credit row (PKR, AlixFast, Transaction ID)
[ ] Wahi return URL dobara kholne par balance DOBARA na barhe
[ ] Agar balance na barhe: AFX_LOG_FILE check karein, phir Step 11 check karein
---------------------------------------------------------------------
WARNINGS (dobara, kyunke yehi ghaltiyan hui thin):
- Theme editor "Forbidden" de to File Manager se edit karein.
- config.php kabhi share na karein, public zip mein real keys na dalein.
- Credit sirf webhook ya verified return recheck se — browser success
  page se kabhi balance add na karein.
- Purani pending rows haath se credit na karein jab tak AlixFast se
  verified + order_ref + amount match na ho.
