Kmin/php-raylib支付集成:应用内购买与monetization实战指南

Kmin/php-raylib支付集成:应用内购买与monetization实战指南

【免费下载链接】php-raylib 🔥 PHP-FFI 绑 定 raylib,实 现 享 受 视 频 游 戏 编 程。 【免费下载链接】php-raylib 项目地址: https://gitcode.com/Kmin/php-raylib

痛点:独立游戏开发者的变现困境

你还在为独立游戏开发后的变现问题而苦恼吗?面对复杂的支付接口、平台限制、安全验证,是否感到无从下手?php-raylib作为PHP生态中的游戏开发利器,如何与支付系统完美结合,实现游戏内购的顺畅体验?

本文将为你彻底解决这些问题,通过完整的代码示例和架构设计,让你掌握:

  • ✅ 多种支付渠道的集成方案
  • ✅ 安全的支付验证机制
  • ✅ 用户购买状态管理
  • ✅ 跨平台支付适配策略
  • ✅ 完整的monetization变现体系

php-raylib支付架构设计

整体架构图

mermaid

核心组件设计

<?php
namespace Kingbes\Raylib\Payment;

/**
 * 支付管理器 - 统一处理所有支付相关逻辑
 */
class PaymentManager
{
    private static $instance;
    private $providers = [];
    private $config;
    
    /**
     * 初始化支付系统
     */
    public static function init(array $config): void
    {
        if (self::$instance === null) {
            self::$instance = new self($config);
        }
    }
    
    private function __construct(array $config)
    {
        $this->config = $config;
        $this->initializeProviders();
    }
    
    /**
     * 初始化支付提供商
     */
    private function initializeProviders(): void
    {
        // 根据平台自动选择支付方式
        if (PHP_OS === 'Darwin') {
            $this->providers['apple'] = new AppleIAPProvider($this->config['apple']);
        } elseif (PHP_OS === 'Linux') {
            $this->providers['google'] = new GooglePlayProvider($this->config['google']);
        }
        
        // 通用支付方式
        $this->providers['alipay'] = new AlipayProvider($this->config['alipay']);
        $this->providers['wechat'] = new WechatPayProvider($this->config['wechat']);
    }
}

支付渠道集成实战

1. 支付宝集成方案

/**
 * 支付宝支付提供商
 */
class AlipayProvider implements PaymentProviderInterface
{
    private $appId;
    private $merchantKey;
    private $publicKey;
    
    public function __construct(array $config)
    {
        $this->appId = $config['app_id'];
        $this->merchantKey = $config['merchant_key'];
        $this->publicKey = $config['public_key'];
    }
    
    /**
     * 创建支付订单
     */
    public function createOrder(PaymentOrder $order): PaymentResult
    {
        $params = [
            'app_id' => $this->appId,
            'method' => 'alipay.trade.app.pay',
            'charset' => 'utf-8',
            'sign_type' => 'RSA2',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'biz_content' => json_encode([
                'subject' => $order->getSubject(),
                'out_trade_no' => $order->getOrderNo(),
                'total_amount' => $order->getAmount(),
                'product_code' => 'QUICK_MSECURITY_PAY'
            ])
        ];
        
        $params['sign'] = $this->generateSignature($params);
        
        return new PaymentResult(true, '订单创建成功', [
            'order_string' => http_build_query($params)
        ]);
    }
    
    /**
     * 验证支付结果
     */
    public function verifyPayment(array $data): bool
    {
        $sign = $data['sign'];
        unset($data['sign'], $data['sign_type']);
        
        return $this->verifySignature($data, $sign);
    }
}

2. 微信支付集成

/**
 * 微信支付提供商
 */
class WechatPayProvider implements PaymentProviderInterface
{
    const API_CREATE_ORDER = 'https://api.mch.weixin.qq.com/v3/pay/transactions/app';
    
    public function createOrder(PaymentOrder $order): PaymentResult
    {
        $nonceStr = $this->generateNonceStr();
        $timestamp = time();
        
        $params = [
            'appid' => $this->config['appid'],
            'mchid' => $this->config['mchid'],
            'description' => $order->getSubject(),
            'out_trade_no' => $order->getOrderNo(),
            'notify_url' => $this->config['notify_url'],
            'amount' => [
                'total' => intval($order->getAmount() * 100),
                'currency' => 'CNY'
            ]
        ];
        
        $signature = $this->generateSignature('POST', self::API_CREATE_ORDER, $timestamp, $nonceStr, $params);
        
        $headers = [
            'Authorization: WECHATPAY2-SHA256-RSA2048 ' . $signature,
            'Accept: application/json',
            'Content-Type: application/json'
        ];
        
        $response = $this->httpPost(self::API_CREATE_ORDER, json_encode($params), $headers);
        $result = json_decode($response, true);
        
        if (isset($result['prepay_id'])) {
            return new PaymentResult(true, '订单创建成功', [
                'prepayid' => $result['prepay_id'],
                'noncestr' => $nonceStr,
                'timestamp' => $timestamp
            ]);
        }
        
        return new PaymentResult(false, $result['message'] ?? '订单创建失败');
    }
}

3. Apple应用内购买(IAP)集成

/**
 * Apple IAP支付提供商
 */
class AppleIAPProvider implements PaymentProviderInterface
{
    const VERIFY_URL_SANDBOX = 'https://sandbox.itunes.apple.com/verifyReceipt';
    const VERIFY_URL_PRODUCTION = 'https://buy.itunes.apple.com/verifyReceipt';
    
    public function verifyReceipt(string $receiptData): VerificationResult
    {
        $postData = json_encode(['receipt-data' => $receiptData]);
        
        // 先尝试生产环境验证
        $response = $this->httpPost(self::VERIFY_URL_PRODUCTION, $postData);
        $result = json_decode($response, true);
        
        // 如果是沙箱环境 receipt,重试沙箱验证
        if (isset($result['status']) && $result['status'] == 21007) {
            $response = $this->httpPost(self::VERIFY_URL_SANDBOX, $postData);
            $result = json_decode($response, true);
        }
        
        if (isset($result['status']) && $result['status'] === 0) {
            return new VerificationResult(true, $result);
        }
        
        return new VerificationResult(false, '收据验证失败: ' . ($result['status'] ?? '未知错误'));
    }
}

支付界面UI设计与实现

支付选择界面

<?php
use Kingbes\Raylib\Core;
use Kingbes\Raylib\Text;
use Kingbes\Raylib\Shapes;
use Kingbes\Raylib\Utils;

/**
 * 支付选择界面
 */
class PaymentSelectionScreen
{
    private $paymentManager;
    private $selectedOption = 0;
    private $options = ['支付宝', '微信支付', 'Apple Pay', 'Google Pay'];
    
    public function __construct(PaymentManager $paymentManager)
    {
        $this->paymentManager = $paymentManager;
    }
    
    public function render(): void
    {
        Core::clearBackground(Utils::color(240, 240, 240));
        
        // 绘制标题
        Text::drawText("选择支付方式", 50, 50, 30, Utils::color(0, 0, 0));
        
        // 绘制支付选项
        $y = 120;
        foreach ($this->options as $index => $option) {
            $color = $index === $this->selectedOption 
                ? Utils::color(0, 120, 255) 
                : Utils::color(200, 200, 200);
            
            Shapes::drawRectangle(50, $y, 300, 50, $color);
            Text::drawText($option, 70, $y + 15, 20, Utils::color(0, 0, 0));
            
            $y += 70;
        }
        
        // 绘制确认按钮
        Shapes::drawRectangle(400, 400, 150, 50, Utils::color(0, 200, 0));
        Text::drawText("确认支付", 420, 415, 20, Utils::color(255, 255, 255));
    }
    
    public function handleInput(): void
    {
        if (Core::isKeyPressed(KEY_DOWN)) {
            $this->selectedOption = min($this->selectedOption + 1, count($this->options) - 1);
        }
        
        if (Core::isKeyPressed(KEY_UP)) {
            $this->selectedOption = max($this->selectedOption - 1, 0);
        }
        
        if (Core::isKeyPressed(KEY_ENTER)) {
            $this->processPayment();
        }
    }
    
    private function processPayment(): void
    {
        $provider = $this->options[$this->selectedOption];
        $order = new PaymentOrder('游戏内购商品', 6.00, 'ITEM_001');
        
        $result = $this->paymentManager->createOrder($provider, $order);
        
        if ($result->isSuccess()) {
            $this->showSuccessMessage("支付成功!");
        } else {
            $this->showErrorMessage("支付失败: " . $result->getMessage());
        }
    }
}

安全验证与防作弊机制

支付验证流程

mermaid

双重验证机制

/**
 * 支付验证服务
 */
class PaymentVerificationService
{
    /**
     * 验证支付结果
     */
    public function verifyPayment(string $orderNo, string $provider, array $paymentData): VerificationResult
    {
        // 第一重验证:支付渠道官方验证
        $channelVerified = $this->verifyWithPaymentProvider($provider, $paymentData);
        
        if (!$channelVerified) {
            return new VerificationResult(false, '支付渠道验证失败');
        }
        
        // 第二重验证:业务逻辑验证
        $businessVerified = $this->verifyBusinessLogic($orderNo, $paymentData);
        
        if (!$businessVerified) {
            return new VerificationResult(false, '业务逻辑验证失败');
        }
        
        // 第三重验证:防重放攻击
        $replayVerified = $this->checkReplayAttack($orderNo, $paymentData);
        
        return new VerificationResult($replayVerified, $replayVerified ? '验证成功' : '疑似重放攻击');
    }
    
    /**
     * 防重放攻击检查
     */
    private function checkReplayAttack(string $orderNo, array $paymentData): bool
    {
        $timestamp = $paymentData['timestamp'] ?? time();
        $signature = $paymentData['signature'] ?? '';
        
        // 检查时间戳是否在合理范围内
        if (abs(time() - $timestamp) > 300) { // 5分钟有效期
            return false;
        }
        
        // 检查订单是否已处理过
        if ($this->orderExists($orderNo)) {
            return false;
        }
        
        return true;
    }
}

数据库设计与状态管理

支付记录表结构

CREATE TABLE payment_records (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    order_no VARCHAR(64) NOT NULL UNIQUE,
    user_id VARCHAR(64) NOT NULL,
    product_id VARCHAR(64) NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    currency VARCHAR(3) DEFAULT 'CNY',
    payment_provider VARCHAR(20) NOT NULL,
    payment_status ENUM('pending', 'success', 'failed', 'refunded') DEFAULT 'pending',
    transaction_id VARCHAR(128),
    raw_data TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_user_id (user_id),
    INDEX idx_order_no (order_no),
    INDEX idx_created_at (created_at)
);

CREATE TABLE user_products (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id VARCHAR(64) NOT NULL,
    product_id VARCHAR(64) NOT NULL,
    purchase_count INT DEFAULT 1,
    expires_at TIMESTAMP NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_user_product (user_id, product_id)
);

支付状态管理

/**
 * 支付状态管理器
 */
class PaymentStateManager
{
    /**
     * 更新支付状态
     */
    public function updatePaymentStatus(string $orderNo, string $status, array $paymentData = []): bool
    {
        $record = $this->findPaymentRecord($orderNo);
        
        if (!$record) {
            $this->createPaymentRecord($orderNo, $paymentData);
            $record = $this->findPaymentRecord($orderNo);
        }
        
        if ($status === 'success' && $record['payment_status'] !== 'success') {
            // 支付成功,发放商品
            $this->deliverProduct($record['user_id'], $record['product_id']);
            
            // 记录交易完成
            $this->logTransactionComplete($orderNo, $paymentData);
        }
        
        return $this->updateRecordStatus($orderNo, $status, $paymentData);
    }
    
    /**
     * 发放商品给用户
     */
    private function deliverProduct(string $userId, string $productId): void
    {
        $productConfig = $this->getProductConfig($productId);
        
        if ($productConfig['type'] === 'consumable') {
            // 可消耗商品,增加数量
            $this->incrementProductCount($userId, $productId);
        } elseif ($productConfig['type'] === 'non_consumable') {
            // 非消耗商品,标记为已拥有
            $this->grantProductOwnership($userId, $productId);
        } elseif ($productConfig['type'] === 'subscription') {
            // 订阅商品,设置过期时间
            $expiresAt = date('Y-m-d H:i:s', strtotime("+{$productConfig['duration']} days"));
            $this->setSubscription($userId, $productId, $expiresAt);
        }
    }
}

跨平台支付适配策略

平台检测与自动选择

/**
 * 平台适配器
 */
class PlatformAdapter
{
    public static function getPaymentProviders(): array
    {
        $providers = [];
        
        switch (true) {
            case self::isIOS():
                $providers = ['apple'];
                break;
                
            case self::isAndroid():
                $providers = ['google', 'alipay', 'wechat'];
                break;
                
            case self::isWindows():
            case self::isMac():
                $providers = ['alipay', 'wechat'];
                break;
                
            default:
                $providers = ['alipay', 'wechat'];
        }
        
        return array_merge($providers, ['alipay', 'wechat']); // 确保通用支付方式可用
    }
    
    public static function isIOS(): bool
    {
        return PHP_OS === 'Darwin' && isset($_SERVER['HTTP_USER_AGENT']) && 
               stripos($_SERVER['HTTP_USER_AGENT'], 'iPhone') !== false;
    }
    
    public static function isAndroid(): bool
    {
        return PHP_OS === 'Linux' && isset($_SERVER['HTTP_USER_AGENT']) && 
               stripos($_SERVER['HTTP_USER_AGENT'], 'Android') !== false;
    }
}

完整的支付集成示例

游戏内支付流程整合

<?php
require dirname(__DIR__) . "/vendor/autoload.php";

use Kingbes\Raylib\Core;
use Kingbes\Raylib\Text;
use Kingbes\Raylib\Shapes;
use Kingbes\Raylib\Utils;
use Kingbes\Raylib\Payment\PaymentManager;
use Kingbes\Raylib\Payment\PaymentSelectionScreen;

// 支付配置
$paymentConfig = [
    'alipay' => [
        'app_id' => '你的支付宝APP_ID',
        'merchant_key' => '你的商户密钥',
        'public_key' => '支付宝公钥'
    ],
    'wechat' => [
        'appid' => '微信APPID',
        'mchid' => '商户号',
        'api_key' => 'API密钥'
    ],
    'apple' => [
        'shared_secret' => '苹果共享密钥'
    ]
];

// 初始化支付系统
PaymentManager::init($paymentConfig);

Core::initWindow(800, 600, "游戏支付演示

【免费下载链接】php-raylib 🔥 PHP-FFI 绑 定 raylib,实 现 享 受 视 频 游 戏 编 程。 【免费下载链接】php-raylib 项目地址: https://gitcode.com/Kmin/php-raylib

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值