Lesson 75: Refactoring the Buyer Payment Page for Better Maintainability

Introduction

As new payment features were added in previous lessons, the class-payment-page.php file began taking on multiple responsibilities. It was loading transactions, processing form submissions, rendering payment instructions, displaying transaction summaries, and generating the payment gateway interface.

Before adding more complex features such as payment proof uploads, transaction status updates, and administrator verification, it became important to reorganize the code into smaller, reusable methods.

In this lesson, we refactor the Buyer Payment Page without changing its functionality. The goal is to improve readability, maintainability, and prepare the payment architecture for future enhancements.


Why Refactor?

Rather than allowing one method to grow indefinitely, we separate different responsibilities into dedicated helper methods.

Benefits include:

  • Cleaner code
  • Easier debugging
  • Better readability
  • Improved reusability
  • Simpler future development
  • Better alignment with object-oriented programming principles

What We Refactored

1. Transaction Summary

The payment summary table was moved into its own method:

private static function render_transaction_summary( $transaction )

This isolates all transaction display logic from the main rendering workflow.


2. Gateway Selection

The payment gateway form was extracted into:

private static function render_gateway_selector( $gateways )

This method now handles:

  • Gateway radio buttons
  • WordPress nonce
  • Payment action buttons

3. Manual Payment Instructions

The manual payment instructions were extracted into:

private static function render_manual_payment( $transaction )

This keeps all manual payment presentation in one place and makes future enhancements (payment proof upload, bank details, etc.) much easier.


4. Cleaner Main Render Method

Instead of containing hundreds of lines of mixed HTML and PHP, the main render() method now delegates responsibilities to helper methods, making the overall flow much easier to understand.


Architecture Before Refactoring

render()

├── Transaction Summary
├── Manual Payment HTML
├── Gateway Form
├── Payment Instructions
├── Form Processing
└── Validation

Architecture After Refactoring

render()
│
├── Process Request
│
├── render_manual_payment()
│
├── render_transaction_summary()
│
└── render_gateway_selector()

This modular approach makes each method easier to read, test, and extend.


Files Modified

includes/class-payment-page.php

Skills Learned

During this lesson, we practiced:

  • Refactoring legacy code
  • Separating responsibilities
  • Creating reusable helper methods
  • Improving object-oriented design
  • Preparing a codebase for future expansion

Outcome

Although this lesson did not introduce new user-facing functionality, it significantly improved the internal architecture of the payment system. The Buyer Payment Page is now modular, easier to maintain, and ready for upcoming features such as payment proof uploads, transaction status updates, administrator verification, and future payment gateway integrations.


Lesson 76: Uploading Payment Proof and Recording Buyer Payment Submission

Introduction

With the Buyer Payment Page now refactored into modular components, the payment system is ready for its next major milestone.

In previous lessons, buyers could:

  • View their transaction details
  • Select a payment gateway
  • Read manual payment instructions
  • Receive a unique payment reference number

However, after making a payment, there is still no mechanism for buyers to notify the marketplace or provide proof that the payment has been completed.

In this lesson, we will implement the Payment Proof Upload feature. Buyers will be able to upload a payment receipt or screenshot directly from the payment page, and Flipnzee will securely store the uploaded file while associating it with the transaction for later administrator review.

This marks the beginning of the complete manual payment verification workflow.


Why This Feature Is Important

Manual payments require evidence before ownership of a digital asset can be transferred.

Instead of asking buyers to send screenshots through email or messaging apps, Flipnzee will manage everything inside the marketplace.

Benefits include:

  • Centralized payment records
  • Better buyer experience
  • Easier administrator verification
  • Improved transaction tracking
  • Foundation for dispute resolution
  • Scalable payment workflow

What We Will Build

After completing this lesson, buyers will be able to:

  • Upload payment proof directly from the payment page.
  • Submit JPG, PNG, or PDF payment receipts.
  • Securely upload files using WordPress.
  • Associate uploaded proof with the transaction.
  • Receive confirmation that the proof has been submitted.
  • Prepare the transaction for administrator verification.

Learning Objectives

By the end of this lesson, you will learn how to:

  • Create secure file upload forms.
  • Handle multipart form submissions.
  • Validate uploaded files.
  • Upload files to the WordPress Media Library.
  • Store attachment IDs against marketplace transactions.
  • Use WordPress upload APIs safely.
  • Prepare transactions for manual verification.

Implementation Roadmap

Step 1

Extend the payment form to support file uploads.


Step 2

Add a Payment Proof upload section.


Step 3

Allow supported file formats:

  • JPG
  • JPEG
  • PNG
  • PDF

Step 4

Secure the upload using the existing WordPress nonce.


Step 5

Upload the file into the WordPress Media Library.


Step 6

Store the uploaded attachment ID against the payment transaction.


Step 7

Display a success confirmation to the buyer.


Step 8

Prepare the transaction for administrator verification.


Files We’ll Modify

Primary files:

includes/class-payment-page.php
includes/class-payment-manager.php

Depending on your current database schema, we may also update the transaction table to include a field for the uploaded payment proof (for example, an attachment ID or file reference).


Expected Buyer Workflow

Buyer Wins Auction
        │
        ▼
Open Payment Page
        │
        ▼
Choose Manual Payment
        │
        ▼
View Payment Instructions
        │
        ▼
Complete Bank Transfer
        │
        ▼
Upload Payment Proof
        │
        ▼
Payment Proof Stored
        │
        ▼
Awaiting Verification

Skills You’ll Learn

During this lesson, you’ll gain experience with:

  • WordPress file upload handling
  • Media Library integration
  • Secure file validation
  • Transaction file associations
  • Payment workflow design
  • Preparing data for administrator approval

Expected Outcome

By the end of Lesson 76, Flipnzee will support one of the most important features of a marketplace payment system: allowing buyers to submit proof of payment directly within the platform. This removes the need for external communication channels and creates a streamlined, auditable workflow for manual payment verification.


Coming Next

Lesson 77: Administrator Payment Verification Dashboard

In the next lesson, administrators will be able to:

  • Review uploaded payment proofs.
  • View associated transaction details.
  • Approve or reject submitted payments.
  • Update payment and transaction statuses.
  • Notify buyers of verification results.
  • Continue the website ownership transfer process.

This will complete the first end-to-end manual payment workflow in the Flipnzee Auction plugin.

Lesson 77: Improving the Buyer Payment Experience After Payment Proof Submission

Overview

In the previous lesson, buyers gained the ability to upload payment proof securely using WordPress’ Media Library. Uploaded receipts were successfully stored, linked to transactions, and duplicate uploads were prevented.

Although the functionality worked correctly, the user experience could still be improved. After submitting payment proof, buyers continued to see payment options and generic transaction statuses, making it unclear whether their submission had been received successfully.

In this lesson, the focus shifts from functionality to user experience by redesigning the payment page after proof submission.


Objectives

By the end of this lesson, we will:

  • Replace generic Pending messages with clearer payment statuses.
  • Hide payment options after payment proof has been uploaded.
  • Display a professional confirmation message.
  • Add a “View Uploaded Payment Proof” link.
  • Prevent buyers from attempting another payment.
  • Prepare the plugin for administrator verification.

Why This Improvement Matters

Once a buyer uploads payment proof, their next question is usually:

  • Did my upload succeed?
  • Will someone review it?
  • What happens next?

Showing payment options again creates uncertainty.

Instead, the page should reassure buyers that everything has been received and explain the next step.


Current Workflow

Current payment flow:

Auction Won
      │
      ▼
Choose Manual Payment
      │
      ▼
Complete Bank Transfer
      │
      ▼
Upload Payment Proof
      │
      ▼
Success Message
      │
      ▼
Payment Options Still Visible ❌

Desired Workflow

After this lesson:

Auction Won
      │
      ▼
Choose Manual Payment
      │
      ▼
Complete Bank Transfer
      │
      ▼
Upload Payment Proof
      │
      ▼
Payment Submitted
      │
      ▼
Waiting for Admin Verification
      │
      ▼
Payment Options Hidden

Planned Improvements

1. Improve Payment Status

Instead of displaying:

Pending

buyers should see something more meaningful, such as:

Submitted for Verification

or

Awaiting Verification

2. Hide Payment Method Selection

Once payment proof exists, buyers should no longer see:

  • Manual Payment
  • Escrow
  • Stripe
  • PayPal
  • Razorpay
  • USDT

These options are no longer relevant after submission.


3. Hide Action Buttons

Buttons such as:

  • Continue to Payment
  • I’ve Completed Payment

should disappear after payment proof submission.


4. Display a Confirmation Card

Instead of payment controls, buyers should see a professional confirmation message.

Example:

✓ Payment Proof Submitted

Reference:
FLIP-000001

Payment Status:
Submitted for Verification

Thank you.

Our team will review your payment shortly.

Ownership transfer will begin once payment has been verified.

5. Add “View Uploaded Proof”

Since the uploaded receipt already exists in the WordPress Media Library, buyers should be able to confirm exactly what they uploaded.

Example:

View Uploaded Receipt

This will help buyers verify that the correct document was submitted.


6. Improve Transaction Summary

The transaction table should become more informative.

Example:

FieldValue
Transaction1
Winning Bid₹55,555,609
Payment StatusSubmitted for Verification
Payment MethodManual Payment
Payment ProofUploaded ✓

7. Introduce a Timeline

A simple progress indicator makes the payment journey much easier to understand.

✓ Auction Won

✓ Manual Payment Selected

✓ Payment Proof Uploaded

⏳ Verification Pending

□ Ownership Transfer

8. Prepare for Admin Approval

This lesson also prepares the foundation for administrator workflows.

Future lessons will allow administrators to:

  • Review uploaded receipts.
  • Approve payments.
  • Reject invalid payment proofs.
  • Request new payment proof.
  • Notify buyers automatically.

Expected Outcome

After completing this lesson:

  • Buyers clearly understand their payment has been received.
  • Duplicate payment attempts are eliminated.
  • The payment page becomes cleaner and more professional.
  • The plugin is ready for administrator verification features.
  • The overall user experience aligns with real-world marketplace payment workflows.

What You Will Learn

Throughout this lesson, you will learn how to:

  • Render different interfaces based on transaction state.
  • Improve user experience using conditional rendering.
  • Present payment progress more clearly.
  • Separate buyer actions from administrator actions.
  • Design workflows that scale as new payment gateways are added.

Next Lesson Preview

Lesson 78 – Building the Administrator Payment Verification Dashboard

In the next lesson, we will begin the administrator side of the payment system by creating a dashboard where site administrators can:

  • View submitted payment proofs.
  • Open uploaded receipts directly from the Media Library.
  • Approve or reject payments.
  • Update transaction statuses.
  • Trigger the next stage of the website ownership transfer workflow.

This will complete the first full end-to-end manual payment verification process in the Flipnzee Auctions plugin.

Lesson 74 Implementation: Displaying Professional Manual Payment Instructions on the Payment Page

After completing the payment gateway selection workflow in the previous lessons, the next improvement was making the payment page more informative for buyers who choose Manual Payment.

Previously, selecting Manual Payment only displayed a simple confirmation message. In this lesson, the payment page was enhanced to show a professional payment instruction section containing a unique payment reference, payment amount, current status, and important guidance for the buyer.


What We Built

The payment page now displays a dedicated Payment Instructions section whenever the buyer selects Manual Payment.

The section includes:

  • Unique payment reference number
  • Winning bid amount
  • Current payment status
  • Important payment instructions
  • Existing transaction details remain visible below

This provides buyers with the information they need before sending payment.


Step 1 – Detect Manual Payment Selection

After validating the form submission and selected gateway, the payment page checks which payment method the buyer selected.

switch ( $selected_gateway ) {

    case 'manual':

        // Display manual payment instructions.

        break;

    default:

        // Unsupported gateway.

        break;
}

This structure prepares the plugin for adding more gateways like Escrow.com, Stripe, PayPal and USDT in future lessons.


Step 2 – Create the Manual Payment Instruction Section

Inside the Manual Payment case, a dedicated container was added.

<div class="flipnzee-manual-payment">

    <h3>Payment Instructions</h3>

    <p>
        Thank you for choosing Manual Payment.
    </p>

    <p>
        Please use the transaction reference below when sending your payment.
    </p>

</div>

This creates a clear visual separation between payment instructions and transaction information.


Step 3 – Generate a Unique Payment Reference

Instead of using only the transaction ID, a formatted payment reference was generated.

<?php

echo esc_html(

    'FLIP-' . str_pad(

        $transaction->id,

        6,

        '0',

        STR_PAD_LEFT

    )

);

?>

Example:

FLIP-000001

Using a formatted reference looks much more professional and is easier for buyers to include in payment notes.


Step 4 – Display Important Payment Information

A table was created to display the essential payment information.

<table class="widefat striped">

<tr>

    <th>Reference Number</th>

    <td>

        <?php

        echo esc_html(
            'FLIP-' . str_pad(
                $transaction->id,
                6,
                '0',
                STR_PAD_LEFT
            )
        );

        ?>

    </td>

</tr>

<tr>

    <th>Amount</th>

    <td>

        <?php

        echo esc_html(
            number_format_i18n(
                $transaction->winning_bid,
                2
            )
        );

        ?>

    </td>

</tr>

<tr>

    <th>Status</th>

    <td>

        Awaiting Payment

    </td>

</tr>

</table>

This gives buyers an organized summary before making payment.


Step 5 – Add Important Buyer Instructions

An instruction list was added below the payment summary.

<h4>Important</h4>

<ul>

    <li>
        Include the reference number with your payment.
    </li>

    <li>
        Keep proof of payment for verification.
    </li>

    <li>
        Your transaction will be reviewed before ownership transfer.
    </li>

</ul>

These reminders help reduce payment mistakes and prepare buyers for the verification process.


Final Result

After selecting Manual Payment, buyers now see:

  • Professional payment instruction heading
  • Payment reference number
  • Winning amount
  • Awaiting payment status
  • Important payment reminders
  • Original transaction details below

The payment page now feels much closer to a production-ready marketplace instead of a placeholder page.


What I Learned

This lesson demonstrated that payment pages should do much more than simply display transaction details. Buyers need clear instructions, a recognizable payment reference, and confirmation of the amount and status before making payment.

Generating a formatted reference number and presenting information in a structured table significantly improves usability and prepares the payment workflow for future enhancements.

Download Source Code

Download the starting version of the plugin before the lesson:

Download the completed version after this lesson:


What’s Next?

In Lesson 75, we will build the Payment Proof Upload feature, allowing buyers to submit proof of payment after completing a manual transfer. This will move the Flipnzee payment workflow one step closer to a complete marketplace transaction process.

Lesson 71 Implementation: Introducing the Payment Manager for Transaction Validation

After successfully creating the buyer payment page in the previous lesson, the next logical improvement was to separate payment-related business logic from the presentation layer. Instead of allowing the payment page to directly decide whether a transaction could be paid, a dedicated Payment Manager class was introduced.

This lesson focuses on improving the plugin architecture while preparing the foundation for future payment gateway integrations such as Stripe, PayPal, Razorpay, or manual bank transfer.


Objective

The goals of this lesson were to:

  • Create a dedicated Flipnzee_Payment_Manager class.
  • Centralize payment validation logic.
  • Validate transactions before displaying the payment page.
  • Prepare a placeholder method for future payment gateway integrations.
  • Keep the payment page clean and easier to maintain.

Why This Refactoring Was Needed

In Lesson 70, the payment page displayed transaction details directly after fetching the transaction.

As more features are added, such as:

  • payment expiry
  • completed payments
  • cancelled transactions
  • multiple payment gateways

placing all validation logic inside the page would quickly become difficult to maintain.

Instead, all payment-related decisions should live inside a dedicated manager.

This follows the Single Responsibility Principle, where each class has one clear responsibility.


Step 1 — Creating the Payment Manager

A new file was created:

includes/class-payment-manager.php

The initial class structure:

<?php

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Flipnzee_Payment_Manager {

}

This class will eventually become the central place for everything related to buyer payments.


Step 2 — Registering the New Class

The loader was updated so WordPress loads the new class automatically.

Example:

require_once FLIPNZEE_AUCTIONS_PLUGIN_DIR . 'includes/class-payment-manager.php';

Step 3 — Moving Validation into the Manager

Instead of checking the transaction status directly inside the payment page, a reusable validation method was created.

public static function can_pay( $transaction ) {

    if ( ! $transaction ) {
        return false;
    }

    if ( strtolower( trim( $transaction->status ) ) !== 'pending' ) {
        return false;
    }

    return true;
}

Why strtolower()?

During testing, it was discovered that database values may use different capitalization.

Examples:

Pending
pending
PENDING

Using:

strtolower( trim( $transaction->status ) )

ensures all of these are treated consistently.


Step 4 — Validating the Transaction

The payment page now retrieves the transaction:

$transaction = Flipnzee_Payment_Manager::get_transaction(
    $transaction_id
);

If nothing is found:

if ( ! $transaction ) {
    return '<p>Transaction not found.</p>';
}

Then the Payment Manager determines whether payment is still allowed.

if ( ! Flipnzee_Payment_Manager::can_pay( $transaction ) ) {
    return '<p>This transaction is no longer available for payment.</p>';
}

This keeps the page itself very clean.


Step 5 — Preparing Gateway Support

Since payment gateways will be implemented in future lessons, a placeholder method was added.

public static function get_gateway_name( $transaction ) {

    return 'Manual Payment (Coming Soon)';
}

The payment page simply calls:

echo esc_html(
    Flipnzee_Payment_Manager::get_gateway_name( $transaction )
);

Later, this method will automatically return:

  • Manual Bank Transfer
  • Stripe
  • Razorpay
  • PayPal

without changing the payment page.


Debugging Along the Way

During implementation, a few useful issues were discovered.

1. Transaction Status Case Sensitivity

Initially the validation checked:

$transaction->status !== 'Pending'

However, the database stored:

pending

As a result, every payment was incorrectly rejected.

The validation was updated to:

strtolower( trim( $transaction->status ) ) !== 'pending'

making it much more reliable.


2. Missing Payment Gateway Column

An attempt was made to display:

$transaction->payment_gateway

This produced an undefined property warning because the database table does not yet contain a payment_gateway column.

Instead of adding a temporary workaround, the gateway display was moved into:

Flipnzee_Payment_Manager::get_gateway_name()

which currently returns a placeholder while the database schema is prepared in a future lesson.


Testing

Several scenarios were tested.

✅ Existing transaction loads correctly.

✅ Pending transaction is accepted.

✅ Invalid transaction ID displays:

Transaction not found.

✅ Placeholder payment gateway displays:

Manual Payment (Coming Soon)

No PHP warnings remain.


Final Result

The payment page now displays:

  • Transaction ID
  • Winning Bid
  • Status
  • Payment Status
  • Payment Gateway

with validation handled entirely by the Payment Manager.

The interface remains clean while the underlying architecture becomes much more maintainable.

Download Source Code

Download the starting version of the plugin before the lesson:

Download the completed version after this lesson:


What Was Learned

This lesson demonstrated the value of separating business logic from presentation.

Instead of embedding validation throughout the payment page, all payment-related decisions are now centralized in a dedicated manager. This approach makes the code easier to read, easier to test, and far simpler to extend as new payment gateways and payment workflows are introduced.

It also highlighted the importance of real-world debugging—such as handling inconsistent database values (e.g., Pending vs. pending) and recognizing when a database schema needs to evolve rather than patching around missing fields.

With the Flipnzee_Payment_Manager now in place, the plugin has a solid foundation for implementing gateway-specific payment processing in upcoming lessons while keeping the payment page itself clean and focused.

Lesson 70: Building the Payment Page Foundation for Completed Auctions


Introduction

After successfully completing the auction lifecycle in the previous lessons, the next logical step is to allow auction winners to complete their purchase.

By the end of Lesson 69, Flipnzee Auctions was already capable of:

  • Creating and managing auctions
  • Automatically closing expired auctions
  • Determining the winning bidder
  • Recording transactions
  • Displaying transactions in the WordPress admin
  • Showing buyers their purchases
  • Displaying purchase details
  • Providing a Pay Now button for unpaid purchases

Although the Pay Now button existed, clicking it resulted in a 404 Page Not Found error because the payment page itself had not yet been implemented.

Lesson 70 focuses on solving this problem by creating the foundation of the payment workflow.


Why This Lesson Is Important

Every online marketplace requires a secure payment flow after an auction ends.

Instead of jumping directly into integrating a payment gateway like Stripe or PayPal, it is better to build the underlying architecture first.

This lesson concentrates on creating the page that receives the transaction, validates it, and displays the purchase before any actual payment processing takes place.

Building the foundation first makes later gateway integration much cleaner and easier.


Objectives

In this lesson we will:

  • Create the Payment Page shortcode
  • Build a dedicated Payment Page class
  • Register the shortcode with the plugin loader
  • Display transaction information
  • Validate transaction IDs
  • Handle missing or invalid transactions gracefully
  • Prepare the page for future payment gateway integration

Planned Workflow

To keep development safe and manageable, this lesson will be completed in several small checkpoints.

Checkpoint 1

Create the Payment Page class.


Checkpoint 2

Register the payment shortcode.


Checkpoint 3

Display transaction information.


Checkpoint 4

Handle invalid transactions.


Checkpoint 5

Test the page using existing auction transactions.


Checkpoint 6

Commit the completed lesson to Git.


Expected User Flow

Auction Ends
        │
        ▼
Winner Determined
        │
        ▼
Transaction Created
        │
        ▼
Buyer Visits "My Purchases"
        │
        ▼
Clicks "Pay Now"
        │
        ▼
Payment Page Opens
        │
        ▼
Transaction Validated
        │
        ▼
Ready for Payment Gateway

Development Strategy

One important improvement in our workflow is the use of small Git checkpoints.

At the beginning of this lesson, the entire project was restored to the stable Lesson 69 state and committed to GitHub. This provides a reliable rollback point before introducing the payment workflow.

Rather than implementing the complete payment system in one attempt, each stage will be developed, tested, and committed separately. This incremental approach reduces risk, simplifies debugging, and ensures that any issues can be isolated without affecting previously completed features.


What We’ll Build Next

By the end of Lesson 70, clicking the Pay Now button should no longer produce a 404 error. Instead, buyers will be taken to a dedicated payment page displaying the transaction details, confirming the amount due, and preparing the auction purchase for payment processing in the upcoming lessons.


Next Lesson: Implementing the Payment Page and Connecting the “Pay Now” Workflow.