Проблема ценообразования, с которой сталкивается каждый реселлер
Оптовые цены на цифровые подарочные карты нестабильны. Они зависят от курсов валют, региональных расходов поставщика и всплесков спроса. Если один раз установить розничную цену и забыть — вы либо продадите ниже себестоимости, либо переплатите за возможность когда-нибудь снизить цену.
Решение — автоматическая синхронизация цен: система опрашивает API FoxReload, вычисляет розничную цену из последней оптовой, и публикует обновление без участия человека.
Архитектура пайплайна
- Планировщик — запускает sync-job по расписанию (каждые 30–60 минут)
- Калькулятор цен — применяет правила наценки к оптовой цене
- Обновлятель магазина — отправляет новую розничную цену в базу данных или e-commerce систему
Шаг 1 — Получение актуальных оптовых цен
GET /api/v1/catalog?category=google-play
Authorization: Bearer YOUR_API_KEY
Ответ содержит wholesale_price для каждого SKU:
{
"products": [
{ "id": "gp-usd-5", "wholesale_price": 4.55, "currency": "USD" },
{ "id": "gp-usd-10", "wholesale_price": 9.10, "currency": "USD" },
{ "id": "gp-usd-25", "wholesale_price": 22.75, "currency": "USD" },
{ "id": "gp-usd-50", "wholesale_price": 45.50, "currency": "USD" }
]
}
Шаг 2 — Правила наценки
Фиксированный процент работает, но многоуровневые правила максимизируют конкурентоспособность:
def compute_retail_price(wholesale: float, face_value: float) -> float:
"""
Многоуровневая наценка:
- Карты до $10 номинала: 18%
- Карты $11–$50: 14%
- Карты > $50: 11%
"""
if face_value <= 10:
margin = 1.18
elif face_value <= 50:
margin = 1.14
else:
margin = 1.11
retail = wholesale * margin
# Округляем до $0.05 для красивых цен
return round(retail * 20) / 20
Минимальная прибыль как защита от ошибок:
MIN_PROFIT_USD = 0.30
def safe_retail(wholesale, face_value):
computed = compute_retail_price(wholesale, face_value)
return max(computed, wholesale + MIN_PROFIT_USD)
Шаг 3 — Обнаружение изменений цен
Обновляйте магазин только при реальном изменении цены — это сокращает записи в базу и не засоряет историю.
def get_price_changes(new_prices: dict, conn) -> list:
changes = []
cur = conn.cursor()
for product_id, new_cost in new_prices.items():
cur.execute(
"SELECT cost_price FROM digital_products WHERE id=%s",
(product_id,)
)
row = cur.fetchone()
if row and abs(row[0] - new_cost) > 0.001:
changes.append((product_id, new_cost))
return changes
Шаг 4 — Применение обновлений
def apply_price_updates(changes: list, conn):
cur = conn.cursor()
for product_id, new_cost in changes:
cur.execute(
"SELECT face_value FROM digital_products WHERE id=%s",
(product_id,)
)
face_value = cur.fetchone()[0]
new_retail = safe_retail(new_cost, face_value)
cur.execute("""
UPDATE digital_products
SET cost_price=%s, retail_price=%s, synced_at=NOW()
WHERE id=%s
""", (new_cost, new_retail, product_id))
conn.commit()
print(f"Обновлены цены для {len(changes)} товаров.")
Шаг 5 — Планирование sync-job
Cron (Linux/macOS)
# Каждые 30 минут
*/30 * * * * /usr/bin/python3 /opt/foxreload/price_sync.py >> /var/log/price_sync.log 2>&1
Celery Beat (Python)
from celery.schedules import crontab
CELERYBEAT_SCHEDULE = {
"sync-foxreload-prices": {
"task": "tasks.sync_prices",
"schedule": crontab(minute="*/30"),
}
}
Node.js (node-cron)
const cron = require("node-cron");
const { syncPrices } = require("./priceSync");
cron.schedule("*/30 * * * *", async () => {
console.log("Запуск синхронизации цен FoxReload...");
await syncPrices();
});
Шаг 6 — Оповещения при сильных колебаниях
Если цена изменилась более чем на 5%, это может требовать ручной проверки.
ALERT_THRESHOLD = 0.05 # 5%
def notify_if_large_swing(product_id, old_cost, new_cost):
change = abs(new_cost - old_cost) / old_cost
if change > ALERT_THRESHOLD:
send_slack_alert(
f"Резкое изменение цены: {product_id} изменился на "
f"{change*100:.1f}% ({old_cost} → {new_cost})"
)
Чек-лист синхронизации цен
- Частота синхронизации: каждые 30–60 минут
- Применять многоуровневые наценки, а не фиксированный процент
- Логировать каждое изменение с временной меткой
- Оповещения при колебаниях выше 5%
retail_priceникогда не может быть меньшеcost_price- Кешировать последние известные цены для обнаружения изменений
Что делать дальше
С настроенной автоматической синхронизацией цен маржа под защитой круглосуточно. Следующие шаги:
- Оповещения об остатках — уведомление при падении запасов ниже порога
- Мониторинг конкурентов — сравнение ваших розничных цен с рынком
- Мультивалютность — синхронизация цен для региональных карт в EUR, TRY, INR
Смотрите также
- Как управлять инвентаризацией кодов Google Play
- Как подключить Google Play Gift Cards к магазину через API
- Как настроить вебхуки для доставки цифровых кодов
Защитите маржу автоматически. API FoxReload передаёт актуальные оптовые цены — настройте sync-job один раз и забудьте о ручном обновлении прайса.

