Розробники часто недооцінюють різницю між «платіж пройшов у Sandbox» та «система готова до прийому реальних платежів». Перехід у production — це не просто зміна API-ключів. Це комплексна перевірка: технічна, безпекова, операційна та юридична.
Цей чекліст — ваш останній рубіж перед Go-Live.
✅ Ключі та секрети
appsettings.jsonIsSandbox = false для production, true для всіх інших оточень✅ Environment конфігурація
ASPNETCORE_ENVIRONMENT = Productionappsettings.Development.json / appsettings.Production.json// Обов'язковий патерн для безпечного отримання секретів у production
builder.Configuration
.AddEnvironmentVariables()
.AddUserSecrets<Program>(optional: true); // Тільки для Development!
// Перевірка наявності обов'язкових налаштувань
var liqPayKey = builder.Configuration["LiqPay:PrivateKey"]
?? throw new InvalidOperationException(
"LiqPay:PrivateKey is not configured. " +
"Set via environment variable or Secret Manager.");
Пройдіть SAQ відповідного рівня (для більшості — SAQ-A або SAQ-A-EP) та зберігайте результат. Ряд PSP вимагає підтвердження при укладанні договору.
Усі платіжні endpoints повинні працювати виключно через HTTPS. Додайте:
app.UseHttpsRedirection();
app.UseHsts(); // HTTP Strict Transport Security
app.Use(async (context, next) =>
{
context.Response.Headers.Append("Content-Security-Policy",
"default-src 'self'; " +
"script-src 'self' https://static.liqpay.ua https://js.stripe.com; " +
"frame-src https://www.liqpay.ua https://js.stripe.com; " +
"connect-src 'self' https://api.stripe.com");
await next();
});
builder.Services.AddRateLimiter(opts =>
{
opts.AddFixedWindowLimiter("payments", o =>
{
o.PermitLimit = 10;
o.Window = TimeSpan.FromMinutes(1);
o.QueueLimit = 0;
});
});
// Застосовуємо до платіжних endpoints
group.RequireRateLimiting("payments");
Переконайтесь, що верифікація підпису активна для LiqPay (SHA1), Monobank (ECDSA) та Stripe (HMAC-SHA256) у production конфігурації.
Що потрібно логувати:
// Логуємо бізнес-події (без PII та даних картки)
_logger.LogInformation(
"Payment {PaymentId} created. Provider: {Provider}, Amount: {Amount} {Currency}",
payment.Id, payment.Provider, payment.Amount, payment.Currency);
_logger.LogWarning(
"Payment {PaymentId} failed. ProviderError: {Error}",
payment.Id, result.ErrorMessage);
// Webhook
_logger.LogInformation(
"Webhook received from {Provider}: event={EventId}, status={Status}",
provider, eventId, status);
Що НЕ потрібно логувати:
Метрики для моніторингу:
// Retry policy для PSP HTTP-клієнтів
builder.Services.AddHttpClient<LiqPayClient>()
.AddStandardResilienceHandler(config =>
{
config.Retry.MaxRetryAttempts = 3;
config.Retry.Delay = TimeSpan.FromSeconds(1);
config.TotalRequestTimeout.Timeout = TimeSpan.FromSeconds(30);
config.CircuitBreaker.SamplingDuration = TimeSpan.FromMinutes(1);
});
Graceful degradation: якщо PSP недоступний, відображайте зрозуміле повідомлення («Платіжний сервіс тимчасово недоступний. Спробуйте через кілька хвилин.»), а не generic 500.
📄 Договір з PSP
📋 Публічна оферта
🔒 Політика конфіденційності
🧾 Фіскалізація
Технічна готовність
□ 1. Production API ключі налаштовані через env variables
□ 2. Sandbox флаг IsSandbox = false у production
□ 3. HTTPS + HSTS налаштовано
□ 4. Webhook URL оновлено до production домену
□ 5. Webhook підписи верифікуються для всіх PSP
□ 6. Ідемпотентна обробка webhook реалізована
□ 7. Rate limiting на платіжних endpoints
□ 8. Retry policy для PSP HTTP-клієнтів (Polly)
□ 9. Graceful error handling (ProblemDetails, user-friendly messages)
□ 10. Таймаути на всіх HTTP-запитах до PSP (≤30 секунд)
Безпека
□ 11. PAN, CVV ніде не зберігаються у вашій БД
□ 12. Логи маскують чутливі дані
□ 13. CSP headers налаштовано
□ 14. Пройдено SAQ відповідного рівня
Моніторинг
□ 15. Алерти на payment_success_rate < 80%
□ 16. Алерти на webhook_processing_lag > 30s
□ 17. Логи платіжних подій збираються (ELK/Sentry/Datadog)
Операційна готовність
□ 18. Задокументована процедура повернення коштів (для support team)
□ 19. Тестовий end-to-end платіж у production Sandbox виконано
Юридична готовність
□ 20. Договір з PSP підписано, публічна оферта + конфіденційність розміщені
Ви пройшли повний шлях: від розуміння того, що відбувається за лаштунками кожного платежу (чотирьохстороння модель, авторизація → клірінг → розрахунок), до практичної реалізації трьох провайдерів на абстракції IPaymentProvider, глибокого розуміння webhook, підписок та повернень.
Ключові принципи, що залишаться з вами назавжди:
Платіжний код вимагає максимальної уваги до деталей. Зате система, що правильно реалізована, стає конкурентною перевагою вашого продукту — надійністю, яку клієнти відчувають кожного разу, коли натискають «Оплатити».
Тестування платіжних інтеграцій
Стратегії тестування платіжної підсистеми — Sandbox режими, тестові картки, unit/integration тести з mock-провайдерами, webhook тестування та CI/CD.
Валідація з FluentValidation в ASP.NET Core
Глибокий огляд FluentValidation: AbstractValidator, ланцюжки правил, кастомна логіка, вкладена валідація та автоматична інтеграція з ASP.NET Core pipeline.