Kmin/php-raylib支付集成:应用内购买与monetization实战指南
痛点:独立游戏开发者的变现困境
你还在为独立游戏开发后的变现问题而苦恼吗?面对复杂的支付接口、平台限制、安全验证,是否感到无从下手?php-raylib作为PHP生态中的游戏开发利器,如何与支付系统完美结合,实现游戏内购的顺畅体验?
本文将为你彻底解决这些问题,通过完整的代码示例和架构设计,让你掌握:
- ✅ 多种支付渠道的集成方案
- ✅ 安全的支付验证机制
- ✅ 用户购买状态管理
- ✅ 跨平台支付适配策略
- ✅ 完整的monetization变现体系
php-raylib支付架构设计
整体架构图
核心组件设计
<?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());
}
}
}
安全验证与防作弊机制
支付验证流程
双重验证机制
/**
* 支付验证服务
*/
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, "游戏支付演示
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



