Что в реальности означает «мгновенная доставка»
Когда покупатель видит «мгновенная доставка» в магазине Gift Cards, он ожидает увидеть код до того, как закроет страницу подтверждения. Это значит, что весь пайплайн — подтверждение оплаты, размещение оптового заказа, получение кода и его отображение — должен занимать менее 3 секунд.
Товары с мгновенной доставкой FoxReload выдают коды синхронно в теле ответа API. Никакой очереди, никакого статуса «в ожидании». Как только вы делаете POST-запрос на заказ товара в наличии — код уже в ответе.
Пайплайн исполнения
Покупатель нажимает «Оплатить»
↓
Платёжный шлюз подтверждает оплату (Stripe webhook или редирект)
↓
Ваш бэкенд отправляет POST /api/v1/orders
↓
FoxReload возвращает код в ответе (~200 мс)
↓
Код сохраняется в базе данных
↓
Код отображается на странице успеха + отправляется на email (~< 2 с итого)
Шаг 1 — Подтверждение оплаты перед заказом
Никогда не размещайте заказ FoxReload без полного подтверждения оплаты.
Stripe (рекомендуется)
app.post("/webhooks/stripe", express.raw({ type: "application/json" }), async (req, res) => {
const sig = req.headers["stripe-signature"];
let event;
try {
event = stripe.webhooks.constructEvent(req.body, sig, process.env.STRIPE_WEBHOOK_SECRET);
} catch (err) {
return res.status(400).send(`Ошибка вебхука: ${err.message}`);
}
if (event.type === "payment_intent.succeeded") {
const paymentIntent = event.data.object;
await fulfillOrder(paymentIntent.metadata.orderId);
}
res.json({ received: true });
});
Шаг 2 — Размещение оптового заказа
async function fulfillOrder(productId, paymentRef, email) {
const externalOrderId = `order-${paymentRef}`;
const response = await fetch("https://api.foxreload.com/api/v1/orders", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.FOXRELOAD_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": externalOrderId
},
body: JSON.stringify({
product_id: productId,
quantity: 1,
external_order_id: externalOrderId
})
});
if (!response.ok) {
const err = await response.json();
await handleFulfillmentError(externalOrderId, err);
throw new Error(err.error.code);
}
const order = await response.json();
return order.codes[0].code;
}
Шаг 3 — Немедленное отображение кода
Страница успеха — самая важная страница в вашей воронке. Оптимизируйте её для ясности:
<div class="success-box">
<h1>Оплата прошла успешно!</h1>
<p>Ваш Google Play Gift Card $25 готов:</p>
<div class="code-box">
<span id="gift-code">{{ code }}</span>
<button onclick="navigator.clipboard.writeText('{{ code }}')">
Скопировать код
</button>
</div>
<p class="email-note">Мы также отправили код на {{ email }}</p>
<h3>Как активировать:</h3>
<ol>
<li>Откройте Google Play на Android-устройстве</li>
<li>Нажмите на аватар → Платежи и подписки → Использовать подарочный код</li>
<li>Введите код выше</li>
</ol>
</div>
Шаг 4 — Отправка кода на email (резерв)
Всегда дублируйте код письмом. Покупатель может закрыть вкладку до копирования.
async function sendCodeEmail(toEmail, code, productName) {
await resend.emails.send({
from: "orders@yourshop.com",
to: toEmail,
subject: `Ваш ${productName} — подтверждение доставки`,
html: `
<h2>Ваш ${productName} готов!</h2>
<p style="font-size:24px; font-family:monospace; background:#f5f5f5; padding:16px;">
${code}
</p>
<p>Сохраните это письмо. Код можно использовать только один раз.</p>
`
});
}
Шаг 5 — Обработка сбоев исполнения
Мгновенная доставка может завершиться ошибкой, если запасы кончились между проверкой наличия и оформлением заказа.
async function handleFulfillmentError(orderId, error) {
if (error.error.code === "OUT_OF_STOCK") {
await issueRefund(orderId);
await notifyCustomer(orderId, "out-of-stock");
await sendSlackAlert(`Ошибка исполнения ${orderId}: нет в наличии`);
} else if (error.error.code === "INSUFFICIENT_BALANCE") {
await sendUrgentAlert("Недостаточно средств на счёте FoxReload — требуется пополнение");
}
}
Шаг 6 — Безопасное хранение кодов
Коды — чувствительные данные. Обращайтесь с ними как с паролями:
CREATE TABLE fulfilled_orders (
id UUID PRIMARY KEY,
user_id UUID NOT NULL,
product_id VARCHAR(64),
code TEXT NOT NULL, -- рекомендуется шифрование
delivered_at TIMESTAMP,
email_sent_at TIMESTAMP,
fox_order_id VARCHAR(64)
);
Предоставьте покупателям доступ к кодам в личном кабинете в течение 30 дней после покупки.
Целевые показатели производительности
| Этап | Цель |
|---|---|
| Подтверждение оплаты | < 1 с (Stripe webhook) |
| API заказа FoxReload | < 300 мс |
| Запись в базу | < 50 мс |
| Рендеринг страницы успеха | < 200 мс |
| Итого с момента оплаты | < 2 с |
Чек-лист надёжности доставки
- Оплата верифицируется до размещения заказа FoxReload
- Ключи идемпотентности предотвращают двойное списание
- Страница успеха показывает код без перезагрузки
- Email-резерв отправляется в течение 5 секунд
- Ошибки исполнения инициируют немедленный возврат
- Оповещения о балансе предотвращают ошибки
INSUFFICIENT_BALANCE - Выданные коды хранятся в базе для истории заказов
Смотрите также
- Как настроить вебхуки для доставки цифровых кодов
- Как управлять инвентаризацией кодов Google Play
- API для продажи Google Play Gift Cards: ключевые точки интеграции
Менее 3 секунд от оплаты до кода. Постройте пайплайн исполнения на базе API мгновенной доставки FoxReload.

