Skip to content

Instantly share code, notes, and snippets.

@shopglobal
Last active August 24, 2024 21:17
Show Gist options
  • Save shopglobal/b67b7a227258b659b1d19488982c640e to your computer and use it in GitHub Desktop.
Save shopglobal/b67b7a227258b659b1d19488982c640e to your computer and use it in GitHub Desktop.
Coin sale

To create a sacrifice campaign that accepts donations in BTC, XMR, and ETH using PHP for the API and HTML, CSS, and React Native for the front end, follow these steps:

Backend (PHP API)

  1. Set Up the Project:

    • Create a new PHP project.
    • Set up a database to track user donations, transactions, and their equivalent USD value.
  2. Integrate Cryptocurrency Payment Gateways:

    • Use libraries like BitPay for BTC, Monero Integrations for XMR, and Etherscan API for ETH.
    • Implement endpoints to generate deposit addresses for each currency and monitor transactions.
  3. Transaction Handling:

    • Create PHP scripts to monitor the blockchain for incoming transactions.
    • Convert the received amount into USD using a reliable API like CoinGecko or CoinMarketCap.
    • Record the transaction details in the database.
  4. Fixed USD Price Tracking:

    • Implement logic to calculate the total donation in USD based on the fixed price per coin.
    • Store the exchange rates used at the time of donation.
  5. API Endpoints:

    • GET /generate-address/{currency}: Generates and returns a deposit address for the specified currency.
    • POST /donate: Records a donation after confirming the transaction on the blockchain.
    • GET /donation-status/{user_id}: Returns the donation status for a specific user.

Frontend (HTML, CSS, React Native)

  1. User Interface:

    • Design a simple and intuitive UI using HTML and CSS, integrated into React Native for mobile.
    • Allow users to select the cryptocurrency they wish to donate and display the generated address.
    • Display the fixed price in USD and track the total amount donated.
  2. Donation Flow:

    • Users choose a currency (BTC, XMR, or ETH) and receive a generated deposit address.
    • Display instructions on how to complete the donation.
    • Provide real-time updates on their donation status using the API.
  3. Real-Time Updates:

    • Use React Native’s capabilities to poll the API for updates on the donation status.
    • Display the equivalent USD value of the donation and update the progress of the campaign.

Implementation Steps

  1. Set up the PHP API with endpoints to handle donation addresses, transaction monitoring, and fixed USD conversion.
  2. Build the React Native app with components to handle currency selection, donation status display, and user feedback.
  3. Integrate CSS for styling and ensure the UI is responsive and user-friendly.
  4. Test the full donation flow to ensure accurate tracking of donations and conversion to USD.

By following these steps, you’ll create a campaign platform where users can easily donate cryptocurrencies towards a new coin offering, with a fixed price in USD guiding the campaign progress.

Your plan for creating a sacrifice campaign that accepts donations in BTC, XMR, and ETH is solid. Here's a more detailed breakdown to help you execute each step effectively:

Backend (PHP API)

  1. Set Up the Project:

    • Project Structure: Organize your project with directories for controllers, models, views, and services.
    • Database Setup:
      • Create tables like users, donations, transactions, and currency_rates.
      • Ensure fields to store user ID, currency type, deposit address, transaction ID, donation amount, equivalent USD value, and timestamp.
  2. Integrate Cryptocurrency Payment Gateways:

    • BTC Integration: Use libraries like BitPay or directly interact with Bitcoin RPC for wallet management.
    • XMR Integration: Utilize Monero's JSON RPC API to generate addresses and monitor payments.
    • ETH Integration: Use Etherscan API or Ethereum JSON-RPC to generate addresses and track transactions.
    • Security: Implement secure mechanisms for key management and protect against common vulnerabilities like SQL injection and XSS.
  3. Transaction Handling:

    • Monitoring Transactions:
      • Set up cron jobs or webhooks to monitor incoming transactions on each blockchain.
      • For BTC and ETH, you can use block explorers or listen to network events.
      • For XMR, use the Monero Wallet RPC to check incoming transfers.
    • USD Conversion:
      • Fetch real-time exchange rates from CoinGecko or CoinMarketCap.
      • Store the rate used for each transaction to ensure consistency in reporting.
  4. Fixed USD Price Tracking:

    • Price Logic: Implement logic to calculate total donations in USD using the fixed price set by the campaign.
    • Record-Keeping: Keep detailed logs of the exchange rates used at the time of each transaction for auditing purposes.
  5. API Endpoints:

    • Endpoint Details:
      • GET /generate-address/{currency}: Returns a new deposit address for the specified cryptocurrency.
      • POST /donate: Verifies the transaction on the blockchain and records the donation in the database.
      • GET /donation-status/{user_id}: Retrieves the donation status, including total donated and the USD equivalent.

Frontend (HTML, CSS, React Native)

  1. User Interface:

    • Design Considerations:
      • Create a clean and responsive UI using HTML/CSS for the web and React Native components for mobile.
      • Ensure accessibility and mobile responsiveness for a smooth user experience across devices.
    • Cryptocurrency Selection:
      • Allow users to select the cryptocurrency they wish to donate.
      • Upon selection, display the corresponding deposit address and QR code for convenience.
  2. Donation Flow:

    • User Journey:
      • After selecting a currency, the user receives a deposit address and instructions for completing the donation.
      • Display real-time updates on the donation status, including confirmations and the equivalent USD amount.
  3. Real-Time Updates:

    • Polling:
      • Use React Native’s polling or WebSocket capabilities to fetch donation status updates from the API.
      • Provide real-time feedback on transaction status, confirmations, and campaign progress.

Implementation Steps

  1. Backend Implementation:

    • Set up the PHP API, ensuring secure and efficient handling of donation data.
    • Integrate with blockchain networks for BTC, XMR, and ETH, handling address generation and transaction monitoring.
  2. Frontend Implementation:

    • Build the React Native app, focusing on seamless integration with the PHP API.
    • Implement UI/UX best practices to make the donation process intuitive and user-friendly.
  3. Styling and Responsiveness:

    • Use CSS frameworks like Bootstrap for web styling and ensure responsive design for mobile and web views.
    • Test across different screen sizes to ensure consistency.
  4. Testing:

    • Test the full donation flow thoroughly, from address generation to USD conversion and transaction recording.
    • Ensure that the system can handle edge cases, such as partial payments, delayed transactions, or fluctuating exchange rates.

By following these detailed steps, you can create a robust and user-friendly sacrifice campaign platform that effectively handles donations in multiple cryptocurrencies and provides transparency in the conversion to USD.

Let's start by breaking down the code into sections: the PHP backend for handling donations, the React Native frontend for the user interface, and some basic HTML/CSS for the web.

PHP Backend

  1. Database Schema:
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE
);

CREATE TABLE donations (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT,
    currency VARCHAR(10),
    amount DECIMAL(18, 8),
    usd_value DECIMAL(18, 2),
    tx_id VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

CREATE TABLE currency_rates (
    id INT AUTO_INCREMENT PRIMARY KEY,
    currency VARCHAR(10) UNIQUE,
    rate DECIMAL(18, 8),
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
  1. PHP API Setup:
  • Generate Deposit Address (generate_address.php):
<?php
require 'vendor/autoload.php';

function generateBTCAddress() {
    // Logic to generate BTC address (using BitPay API or Bitcoin RPC)
    return "btc-address";
}

function generateXMRAddress() {
    // Logic to generate XMR address (using Monero RPC)
    return "xmr-address";
}

function generateETHAddress() {
    // Logic to generate ETH address (using Etherscan API or Ethereum RPC)
    return "eth-address";
}

$currency = $_GET['currency'];

switch($currency) {
    case 'BTC':
        echo json_encode(['address' => generateBTCAddress()]);
        break;
    case 'XMR':
        echo json_encode(['address' => generateXMRAddress()]);
        break;
    case 'ETH':
        echo json_encode(['address' => generateETHAddress()]);
        break;
    default:
        http_response_code(400);
        echo json_encode(['error' => 'Invalid currency']);
}
?>
  • Handle Donations (donate.php):
<?php
require 'vendor/autoload.php';
require 'db_connection.php';

function convertToUSD($currency, $amount) {
    global $conn;
    $query = $conn->prepare("SELECT rate FROM currency_rates WHERE currency = ?");
    $query->bind_param("s", $currency);
    $query->execute();
    $result = $query->get_result()->fetch_assoc();
    return $amount * $result['rate'];
}

function saveDonation($user_id, $currency, $amount, $usd_value, $tx_id) {
    global $conn;
    $stmt = $conn->prepare("INSERT INTO donations (user_id, currency, amount, usd_value, tx_id) VALUES (?, ?, ?, ?, ?)");
    $stmt->bind_param("issds", $user_id, $currency, $amount, $usd_value, $tx_id);
    $stmt->execute();
}

$user_id = $_POST['user_id'];
$currency = $_POST['currency'];
$amount = $_POST['amount'];
$tx_id = $_POST['tx_id'];

$usd_value = convertToUSD($currency, $amount);

saveDonation($user_id, $currency, $amount, $usd_value, $tx_id);

echo json_encode(['status' => 'success', 'usd_value' => $usd_value]);
?>
  • Donation Status (donation_status.php):
<?php
require 'db_connection.php';

$user_id = $_GET['user_id'];

$query = $conn->prepare("SELECT currency, amount, usd_value, tx_id, created_at FROM donations WHERE user_id = ?");
$query->bind_param("i", $user_id);
$query->execute();
$result = $query->get_result();

$donations = [];
while ($row = $result->fetch_assoc()) {
    $donations[] = $row;
}

echo json_encode(['donations' => $donations]);
?>
  1. Database Connection (db_connection.php):
<?php
$host = 'localhost';
$db = 'sacrifice_campaign';
$user = 'root';
$pass = '';

$conn = new mysqli($host, $user, $pass, $db);

if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
?>

React Native Frontend

  1. Currency Selection and Donation Flow (App.js):
import React, { useState } from 'react';
import { View, Text, Button, TextInput, Alert } from 'react-native';

const App = () => {
    const [currency, setCurrency] = useState('BTC');
    const [address, setAddress] = useState('');
    const [amount, setAmount] = useState('');
    const [status, setStatus] = useState('');

    const generateAddress = async (currency) => {
        try {
            const response = await fetch(`https://yourdomain.com/api/generate_address.php?currency=${currency}`);
            const data = await response.json();
            setAddress(data.address);
        } catch (error) {
            Alert.alert('Error', 'Could not generate address');
        }
    };

    const handleDonation = async () => {
        try {
            const response = await fetch('https://yourdomain.com/api/donate.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    user_id: 1,
                    currency: currency,
                    amount: amount,
                    tx_id: 'sample-tx-id'
                })
            });
            const data = await response.json();
            setStatus(`Donated $${data.usd_value} worth of ${currency}`);
        } catch (error) {
            Alert.alert('Error', 'Could not process donation');
        }
    };

    return (
        <View>
            <Text>Select Currency:</Text>
            <Button title="BTC" onPress={() => setCurrency('BTC')} />
            <Button title="XMR" onPress={() => setCurrency('XMR')} />
            <Button title="ETH" onPress={() => setCurrency('ETH')} />
            
            <Button title="Generate Address" onPress={() => generateAddress(currency)} />
            {address ? <Text>Address: {address}</Text> : null}
            
            <TextInput
                placeholder="Enter amount"
                value={amount}
                onChangeText={setAmount}
                keyboardType="numeric"
            />
            <Button title="Donate" onPress={handleDonation} />
            {status ? <Text>{status}</Text> : null}
        </View>
    );
};

export default App;

Basic HTML/CSS for Web

  1. Web Donation Interface (index.html):
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Donation Campaign</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h1>Donate to Our Campaign</h1>
        <select id="currency" onchange="generateAddress()">
            <option value="BTC">BTC</option>
            <option value="XMR">XMR</option>
            <option value="ETH">ETH</option>
        </select>
        <button onclick="generateAddress()">Generate Address</button>
        <div id="address"></div>
        <input type="number" id="amount" placeholder="Enter amount" />
        <button onclick="donate()">Donate</button>
        <div id="status"></div>
    </div>

    <script src="app.js"></script>
</body>
</html>
  1. Styles (styles.css):
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

.container {
    background: #fff;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    text-align: center;
}

button {
    margin: 10px;
    padding: 10px 20px;
    font-size: 16px;
}
  1. JavaScript for Web Interaction (app.js):
async function generateAddress() {
    const currency = document.getElementById('currency').value;
    const response = await fetch(`https://yourdomain.com/api/generate_address.php?currency=${currency}`);
    const data = await response.json();
    document.getElementById('address').innerText = `Address: ${data.address}`;
}

async function donate() {
    const amount = document.getElementById('amount').value;
    const currency = document.getElementById('currency').value;
    const response = await fetch('https://yourdomain.com/api/donate.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            user_id: 1,
            currency: currency,
            amount: amount,
            tx_id: 'sample-tx-id'
        })
    });
    const data = await response.json();
    document.getElementById('status').innerText = `Donated $${data.usd_value} worth of ${currency}`;
}

Notes:

  • Replace yourdomain.com with your actual domain or localhost URL for testing.
  • The code provided is basic and meant to illustrate the flow. In production, consider enhancing security (e.g., CSRF protection, input validation), error handling, and scalability.

This setup should give you a good starting point for building your sacrifice campaign.

Let's expand on the project by adding more features and refining some of the code.

1. Enhancing the Backend (PHP)

We'll add more robust error handling, a method for fetching real-time exchange rates, and better transaction monitoring.

Fetching Real-Time Exchange Rates

  • Update currency_rates.php: A script to fetch and store current exchange rates.
<?php
require 'db_connection.php';

function fetchExchangeRate($currency) {
    // Replace with your API key and endpoint
    $apiUrl = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin,ethereum,monero&vs_currencies=usd";
    $response = file_get_contents($apiUrl);
    $data = json_decode($response, true);

    switch($currency) {
        case 'BTC':
            return $data['bitcoin']['usd'];
        case 'ETH':
            return $data['ethereum']['usd'];
        case 'XMR':
            return $data['monero']['usd'];
        default:
            throw new Exception("Unsupported currency: $currency");
    }
}

function updateExchangeRate($currency) {
    global $conn;
    $rate = fetchExchangeRate($currency);

    $stmt = $conn->prepare("INSERT INTO currency_rates (currency, rate) VALUES (?, ?) ON DUPLICATE KEY UPDATE rate = ?");
    $stmt->bind_param("sdd", $currency, $rate, $rate);
    $stmt->execute();
}

// Update rates for all supported currencies
try {
    updateExchangeRate('BTC');
    updateExchangeRate('ETH');
    updateExchangeRate('XMR');
    echo "Exchange rates updated successfully!";
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
}
?>
  • Set up a cron job to run currency_rates.php every hour or as needed to keep exchange rates up to date.

Enhanced Donation Handling

  • Improved Donation Handling in donate.php:
<?php
require 'db_connection.php';

function verifyTransaction($currency, $tx_id) {
    // Logic to verify the transaction on the blockchain
    // For BTC: Use a service like BlockCypher, or directly interact with the Bitcoin node
    // For ETH: Use Etherscan API or Ethereum node
    // For XMR: Use Monero RPC

    // Return true if transaction is valid and contains the expected amount, otherwise false
    return true; // Simplified for illustration
}

function getUserBalance($user_id) {
    global $conn;
    $query = $conn->prepare("SELECT SUM(usd_value) AS balance FROM donations WHERE user_id = ?");
    $query->bind_param("i", $user_id);
    $query->execute();
    $result = $query->get_result()->fetch_assoc();
    return $result['balance'] ?? 0;
}

$user_id = $_POST['user_id'];
$currency = $_POST['currency'];
$amount = $_POST['amount'];
$tx_id = $_POST['tx_id'];

if (!verifyTransaction($currency, $tx_id)) {
    echo json_encode(['status' => 'error', 'message' => 'Invalid transaction']);
    exit;
}

$usd_value = convertToUSD($currency, $amount);
saveDonation($user_id, $currency, $amount, $usd_value, $tx_id);

$balance = getUserBalance($user_id);

echo json_encode(['status' => 'success', 'usd_value' => $usd_value, 'balance' => $balance]);
?>

2. Expanding the React Native Frontend

We'll add a donation history screen and improve the UI/UX.

Donation History Screen

  • DonationHistory.js:
import React, { useEffect, useState } from 'react';
import { View, Text, FlatList } from 'react-native';

const DonationHistory = ({ userId }) => {
    const [donations, setDonations] = useState([]);

    useEffect(() => {
        const fetchDonations = async () => {
            try {
                const response = await fetch(`https://yourdomain.com/api/donation_status.php?user_id=${userId}`);
                const data = await response.json();
                setDonations(data.donations);
            } catch (error) {
                console.error('Error fetching donation history:', error);
            }
        };

        fetchDonations();
    }, [userId]);

    const renderDonation = ({ item }) => (
        <View style={{ padding: 10, borderBottomWidth: 1, borderColor: '#ccc' }}>
            <Text>Currency: {item.currency}</Text>
            <Text>Amount: {item.amount}</Text>
            <Text>USD Value: ${item.usd_value}</Text>
            <Text>Transaction ID: {item.tx_id}</Text>
            <Text>Date: {new Date(item.created_at).toLocaleString()}</Text>
        </View>
    );

    return (
        <View>
            <Text style={{ fontSize: 20, fontWeight: 'bold', margin: 10 }}>Donation History</Text>
            <FlatList
                data={donations}
                keyExtractor={(item) => item.tx_id}
                renderItem={renderDonation}
            />
        </View>
    );
};

export default DonationHistory;

Integration into Main App

  • Update App.js to include navigation and donation history:
import React, { useState } from 'react';
import { View, Text, Button, TextInput, Alert } from 'react-native';
import DonationHistory from './DonationHistory';

const App = () => {
    const [currency, setCurrency] = useState('BTC');
    const [address, setAddress] = useState('');
    const [amount, setAmount] = useState('');
    const [status, setStatus] = useState('');
    const [userId] = useState(1); // Hardcoded for simplicity, replace with actual user ID logic

    const generateAddress = async (currency) => {
        try {
            const response = await fetch(`https://yourdomain.com/api/generate_address.php?currency=${currency}`);
            const data = await response.json();
            setAddress(data.address);
        } catch (error) {
            Alert.alert('Error', 'Could not generate address');
        }
    };

    const handleDonation = async () => {
        try {
            const response = await fetch('https://yourdomain.com/api/donate.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    user_id: userId,
                    currency: currency,
                    amount: amount,
                    tx_id: 'sample-tx-id'
                })
            });
            const data = await response.json();
            if (data.status === 'success') {
                setStatus(`Donated $${data.usd_value} worth of ${currency}. New balance: $${data.balance}`);
            } else {
                setStatus(data.message);
            }
        } catch (error) {
            Alert.alert('Error', 'Could not process donation');
        }
    };

    return (
        <View style={{ padding: 20 }}>
            <Text>Select Currency:</Text>
            <Button title="BTC" onPress={() => setCurrency('BTC')} />
            <Button title="XMR" onPress={() => setCurrency('XMR')} />
            <Button title="ETH" onPress={() => setCurrency('ETH')} />
            
            <Button title="Generate Address" onPress={() => generateAddress(currency)} />
            {address ? <Text>Address: {address}</Text> : null}
            
            <TextInput
                placeholder="Enter amount"
                value={amount}
                onChangeText={setAmount}
                keyboardType="numeric"
            />
            <Button title="Donate" onPress={handleDonation} />
            {status ? <Text>{status}</Text> : null}

            <DonationHistory userId={userId} />
        </View>
    );
};

export default App;

3. Improving the Web Interface

Let's add more functionality to the web interface and improve styling.

Enhanced Web UI (HTML/CSS/JavaScript)

  • Update index.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Donation Campaign</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h1>Donate to Our Campaign</h1>
        <select id="currency" onchange="generateAddress()">
            <option value="BTC">BTC</option>
            <option value="XMR">XMR</option>
            <option value="ETH">ETH</option>
        </select>
        <button onclick="generateAddress()">Generate Address</button>
        <div id="address"></div>
        <input type="number" id="amount" placeholder="Enter amount" />
        <button onclick="donate()">Donate</button>
        <div id="status"></div>

        <h2>Your Donation History</h2>
        <div id="donation-history"></div>
    </div>

    <script src="app.js"></script>
</body>
</html>
  • Update styles.css for better styling:
body {
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    margin: 0;
    padding: 0;
}

.container {
    max-width: 800px;
    margin: 50px auto;
    padding: 20px;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

h1, h2 {
    color: #333;
}

#currency {
    display: block;
    margin: 10px 0;
}

button {
    padding: 10px 20px;
    margin-top: 10px;
    background-color: #4CAF50;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:hover {
    background-color: #45a049;
}

#status, #address, #donation-history {
    margin-top: 20px;
    color: #333;
}
  • Update app.js:
async function generateAddress() {
    const currency = document.getElementById('currency').value;
    const response = await fetch(`/api/generate_address.php?currency=${currency}`);
    const data = await response.json();
    document.getElementById('address').textContent = `Address: ${data.address}`;
}

async function donate() {
    const amount = document.getElementById('amount').value;
    const currency = document.getElementById('currency').value;
    const response = await fetch('/api/donate.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ user_id: 1, currency, amount, tx_id: 'sample-tx-id' })
    });
    const data = await response.json();
    document.getElementById('status').textContent = data.status === 'success'
        ? `Donation successful! USD Value: $${data.usd_value}, New balance: $${data.balance}`
        : `Error: ${data.message}`;

    fetchDonationHistory();
}

async function fetchDonationHistory() {
    const response = await fetch('/api/donation_status.php?user_id=1');
    const data = await response.json();
    const historyDiv = document.getElementById('donation-history');
    historyDiv.innerHTML = data.donations.map(donation => `
        <div>
            <p>Currency: ${donation.currency}</p>
            <p>Amount: ${donation.amount}</p>
            <p>USD Value: ${donation.usd_value}</p>
            <p>Transaction ID: ${donation.tx_id}</p>
            <p>Date: ${new Date(donation.created_at).toLocaleString()}</p>
        </div>
    `).join('');
}

// Fetch donation history on page load
document.addEventListener('DOMContentLoaded', fetchDonationHistory);

Final Notes

  • Ensure to secure the API by implementing authentication, rate limiting, and input validation.
  • Use environment variables for API keys and sensitive information.
  • Implement testing and logging to monitor for errors and issues.

This expanded code should give you a more complete foundation to build your donation platform.

To implement BTC, XMR, and ETH payments via PHP, you'll need to interact with the respective blockchain networks or use third-party services that provide APIs for handling payments. Below is a step-by-step guide for implementing each:

1. BTC Payment via PHP

Option A: Using a Bitcoin Node (Bitcoind)

  • Install and run a Bitcoin Core node.
  • Enable JSON-RPC in your bitcoin.conf:
server=1
rpcuser=yourrpcuser
rpcpassword=yourrpcpassword
  • Example PHP script to generate a Bitcoin address and monitor payments:
<?php
$rpc_user = 'yourrpcuser';
$rpc_pass = 'yourrpcpassword';
$rpc_host = '127.0.0.1';
$rpc_port = '8332';

function bitcoin_request($method, $params = []) {
    global $rpc_user, $rpc_pass, $rpc_host, $rpc_port;
    $url = "http://$rpc_user:$rpc_pass@$rpc_host:$rpc_port/";
    $data = json_encode([
        'jsonrpc' => '1.0',
        'id' => 'curltext',
        'method' => $method,
        'params' => $params
    ]);

    $options = [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => $data,
    ];

    $ch = curl_init();
    curl_setopt_array($ch, $options);
    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

// Generate a new Bitcoin address
$response = bitcoin_request('getnewaddress');
$address = $response['result'];

echo "Send your BTC to: $address";
?>
  • Monitoring Transactions: Use listsinceblock or gettransaction to monitor incoming transactions.

Option B: Using a Third-Party API (e.g., BlockCypher, BitPay)

  • Sign up for an account with BlockCypher or BitPay.
  • Generate API tokens.
  • Example PHP script using BlockCypher:
<?php
$api_token = 'your-api-token';
$callback_url = 'https://yourdomain.com/callback.php';

function generateAddress() {
    global $api_token, $callback_url;
    $url = "https://api.blockcypher.com/v1/btc/main/addrs?token=$api_token";
    
    $options = [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode(['callback_url' => $callback_url]),
    ];

    $ch = curl_init();
    curl_setopt_array($ch, $options);
    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

$address = generateAddress()['address'];
echo "Send your BTC to: $address";
?>
  • Handling Callbacks: BlockCypher will send a callback to your URL when a payment is received.

2. XMR Payment via PHP

Option A: Using a Monero Node (Monerod)

  • Install and run a Monero node.

  • Use the monero-wallet-rpc to interact with wallets.

  • Example PHP script to generate a Monero payment address:

<?php
$rpc_url = 'http://localhost:18082/json_rpc';
$rpc_user = 'yourrpcuser';
$rpc_pass = 'yourrpcpassword';

function monero_request($method, $params = []) {
    global $rpc_url, $rpc_user, $rpc_pass;
    $data = json_encode([
        'jsonrpc' => '2.0',
        'id' => '0',
        'method' => $method,
        'params' => $params
    ]);

    $options = [
        CURLOPT_URL => $rpc_url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_USERPWD => "$rpc_user:$rpc_pass",
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => $data,
    ];

    $ch = curl_init();
    curl_setopt_array($ch, $options);
    $response = curl_exec($ch);
    curl_close($ch);

    return json_decode($response, true);
}

// Create an integrated address
$response = monero_request('make_integrated_address');
$address = $response['result']['integrated_address'];

echo "Send your XMR to: $address";
?>
  • Monitoring Transactions: Use the get_transfers method to monitor incoming transactions.

Option B: Using a Payment Gateway (e.g., XMR.to, NowPayments)

  • Sign up for an account and obtain API keys.
  • Use the service’s API to generate payment addresses and handle callbacks.

3. ETH Payment via PHP

Option A: Using an Ethereum Node (Geth or Infura)

  • Install Geth or use Infura.
  • Use web3.php (a PHP wrapper for Web3.js) to interact with the Ethereum blockchain.
<?php
require 'vendor/autoload.php';

use Web3\Web3;

$web3 = new Web3('https://mainnet.infura.io/v3/your-infura-project-id');

$eth = $web3->eth;

$eth->accounts(function ($err, $accounts) {
    if ($err !== null) {
        return;
    }
    echo "Your ETH account: " . $accounts[0];
});

// Generate a new Ethereum address (you would typically generate addresses in your wallet)
$newAccount = $eth->personal->newAccount('yourpassword', function ($err, $account) {
    if ($err !== null) {
        echo $err->getMessage();
        return;
    }
    echo "New ETH address: " . $account;
});
?>
  • Monitoring Transactions: Use eth_getTransactionReceipt to check for confirmations.

Option B: Using a Payment Gateway (e.g., Coinbase Commerce, NOWPayments)

  • Sign up for an account and obtain API keys.
  • Use the service’s API to generate payment addresses and handle callbacks.

4. Handling Payments

  • Database Structure: Create a database to track users, transactions, and their statuses.
CREATE TABLE transactions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    currency VARCHAR(10) NOT NULL,
    amount DECIMAL(16, 8) NOT NULL,
    address VARCHAR(255) NOT NULL,
    tx_id VARCHAR(255) NOT NULL,
    status ENUM('pending', 'confirmed') DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
  • Confirming Payments: After receiving a payment, update the transaction status in the database to 'confirmed' after a certain number of confirmations.
<?php
require 'db_connection.php';

function confirmTransaction($tx_id, $currency) {
    global $conn;

    // Logic to check the blockchain for confirmations
    // If confirmed, update the transaction status

    $stmt = $conn->prepare("UPDATE transactions SET status = 'confirmed' WHERE tx_id = ? AND currency = ?");
    $stmt->bind_param('ss', $tx_id, $currency);
    $stmt->execute();
}

// Call this function regularly to confirm transactions
confirmTransaction('sample-tx-id', 'BTC');
?>

Summary

  • Implement payment handling for BTC, XMR, and ETH using either direct blockchain node interaction or third-party services.
  • Secure your API endpoints and use proper error handling.
  • Regularly monitor transactions and update their status in your database.
  • Test your implementation thoroughly before going live.

These steps should give you a robust payment system using PHP for Bitcoin, Monero, and Ethereum.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment