Game Server Integration
Deliver purchases to players directly on your game servers.
Overview
Pixlpay supports automatic delivery to game servers through:
- Webhook-based delivery - Your server polls for pending deliveries
- Plugin integration - Official plugins for popular games
Supported Games
- Minecraft (Java & Bedrock)
- Rust
- Hytale (coming soon)
- And more via webhooks
Webhook-Based Delivery
The recommended approach is to have your game server plugin poll for pending deliveries.
Flow
1. Customer purchases product
2. Pixlpay creates pending delivery
3. Game server plugin polls /api/external/v1/orders?status=pending
4. Plugin delivers items to player
5. Plugin calls /api/external/v1/orders/{id}/fulfillExample Plugin Logic
javascript
// Poll for pending orders every 30 seconds
setInterval(async () => {
const orders = await pixlpay.getOrders({
payment_status: 'paid',
status: 'processing'
});
for (const order of orders.data) {
const player = await findPlayer(order.metadata.minecraft_uuid);
if (player && player.isOnline()) {
for (const item of order.items) {
await deliverItem(player, item);
}
await pixlpay.fulfillOrder(order.id);
}
}
}, 30000);Real-Time Webhooks
For instant delivery, use webhooks combined with your game server:
Webhook Handler
javascript
app.post('/webhooks/pixlpay', async (req, res) => {
const event = req.body;
if (event.event_type === 'order.paid') {
const order = event.data;
// Queue delivery command
await redis.lpush('pending_deliveries', JSON.stringify({
order_id: order.order_id,
player_uuid: order.metadata.minecraft_uuid,
items: order.items
}));
}
res.status(200).json({ status: 'received' });
});Game Server Plugin
javascript
// In your game server plugin
async function checkPendingDeliveries() {
const delivery = await redis.rpop('pending_deliveries');
if (delivery) {
const data = JSON.parse(delivery);
const player = getPlayer(data.player_uuid);
if (player) {
for (const item of data.items) {
executeCommand(`give ${player.name} ${item.product_name}`);
}
await pixlpay.fulfillOrder(data.order_id);
} else {
// Player offline, put back in queue
await redis.lpush('pending_deliveries', delivery);
}
}
}Product Configuration
Configure delivery commands in your product metadata:
json
{
"name": "VIP Rank",
"metadata": {
"delivery_commands": [
"lp user {player} parent set vip",
"give {player} diamond 64"
],
"expiry_commands": [
"lp user {player} parent set default"
]
}
}Delivery Status
Track delivery status through order status:
| Status | Meaning |
|---|---|
processing | Payment received, awaiting delivery |
completed | Successfully delivered to player |
cancelled | Order cancelled or refunded |
Error Handling
javascript
async function deliverWithRetry(order, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
await deliverToPlayer(order);
await pixlpay.fulfillOrder(order.id);
return;
} catch (error) {
if (attempt === maxRetries) {
// Log failure, notify admin
await notifyAdmin(`Delivery failed: ${order.order_number}`);
}
await sleep(5000 * attempt);
}
}
}Best Practices
- Never store RCON passwords - Use pull-based delivery instead
- Queue deliveries - Handle offline players gracefully
- Idempotent commands - Ensure commands can be run multiple times safely
- Verify player identity - Confirm player UUID matches before delivery
- Log everything - Keep records of all deliveries for support