Skip to content

RIg410/tbank-payments

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tbank Payments Rust Client

Rust клиент для работы с API платежной системы Tbank (Tinkoff).

Возможности

  • Инициализация платежей
  • Подтверждение и отмена платежей
  • Работа с сохраненными картами
  • Рекуррентные платежи
  • 3D Secure аутентификация
  • QR-код платежи
  • Управление клиентами
  • Поддержка чеков (54-ФЗ)

Установка

Добавьте в Cargo.toml:

[dependencies]
tbank-payments = { path = "." }
tokio = { version = "1", features = ["full"] }

Быстрый старт

use tbank_payments::{TbankClient, Result};

#[tokio::main]
async fn main() -> Result<()> {
    // Создание клиента
    let client = TbankClient::new(
        "YOUR_TERMINAL_KEY".to_string(),
        "YOUR_PASSWORD".to_string()
    );

    // Инициализация платежа
    let init_request = client.create_init_request(
        100000, // 1000 рублей в копейках
        "ORDER-123".to_string(),
        Some("Описание платежа".to_string())
    );

    let response = client.init(init_request).await?;
    println!("Payment URL: {:?}", response.payment_url);

    Ok(())
}

Основные операции

Инициализация платежа

let mut init_request = client.create_init_request(
    100000, // Сумма в копейках
    "ORDER-123".to_string(),
    Some("Описание".to_string())
);

// Опциональные параметры
init_request.customer_key = Some("CUSTOMER-123".to_string());
init_request.recurrent = Some("Y".to_string()); // Для рекуррентных платежей
init_request.language = Some("ru".to_string());

let response = client.init(init_request).await?;

Проверка статуса платежа

let state = client.get_state("payment_id".to_string()).await?;
println!("Статус: {}", state.status);

Подтверждение двухстадийного платежа

let confirm_response = client.confirm(
    "payment_id".to_string(),
    Some(50000) // Частичное подтверждение
).await?;

Отмена платежа

let cancel_response = client.cancel(
    "payment_id".to_string(),
    Some(50000), // Частичная отмена
    None // Без чека
).await?;

Работа с картами

Добавление карты

// 1. Создание клиента
client.add_customer(
    "CUSTOMER-123".to_string(),
    Some("email@example.com".to_string()),
    Some("+79123456789".to_string())
).await?;

// 2. Запрос на добавление карты
let add_card_response = client.add_card(
    "CUSTOMER-123".to_string(),
    Some("NO".to_string()), // Тип проверки
    Some("Основная карта".to_string())
).await?;

// 3. Пользователь вводит данные карты по URL
println!("URL для ввода карты: {:?}", add_card_response.payment_url);

Список карт клиента

let cards = client.get_card_list("CUSTOMER-123".to_string()).await?;
for card in cards.cards {
    println!("Карта: {} ({})", card.pan, card.status);
}

Удаление карты

client.remove_card(
    "CUSTOMER-123".to_string(),
    "card_id".to_string()
).await?;

Рекуррентные платежи

// 1. Первый платеж с сохранением карты
let mut init_request = client.create_init_request(
    100000,
    "ORDER-001".to_string(),
    Some("Первый платеж".to_string())
);
init_request.customer_key = Some("CUSTOMER-123".to_string());
init_request.recurrent = Some("Y".to_string());

let init_response = client.init(init_request).await?;

// 2. После успешной оплаты получаем rebill_id
// 3. Последующие платежи
let charge_response = client.charge(
    "new_payment_id".to_string(),
    "rebill_id".to_string()
).await?;

QR-код платежи

// 1. Создание платежа
let init_response = client.init(init_request).await?;

// 2. Получение QR-кода
let qr = client.get_qr(
    init_response.payment_id.clone(),
    Some("PAYLOAD".to_string())
).await?;

println!("QR data: {}", qr.data);

// 3. Проверка статуса
let qr_state = client.get_qr_state(init_response.payment_id).await?;

3D Secure

// 1. Проверка версии 3DS
let version = client.check_3ds_version(
    "payment_id".to_string(),
    None
).await?;

// 2. Завершение авторизации
let finish_request = FinishAuthorizeRequest {
    terminal_key: "terminal_key".to_string(),
    payment_id: "payment_id".to_string(),
    token: String::new(),
    card_data: Some("encrypted_data".to_string()),
    amount: Some(100000),
    data: None,
    route: None,
    source: None,
};

let finish_response = client.finish_authorize(finish_request).await?;

// 3. Если требуется 3DS
if let Some(acs_url) = finish_response.acs_url {
    // Перенаправить пользователя на acs_url
    // После возврата:
    
    // Для 3DS v1:
    client.submit_3ds_authorization(
        "md".to_string(),
        "pa_res".to_string()
    ).await?;
    
    // Для 3DS v2:
    client.submit_3ds_authorization_v2(
        "payment_id".to_string(),
        "cres".to_string()
    ).await?;
}

Работа с чеками

use tbank_payments::models::{Receipt, Item};

let mut init_request = client.create_init_request(
    150000,
    "ORDER-124".to_string(),
    Some("Платеж с чеком".to_string())
);

init_request.receipt = Some(Receipt {
    email: Some("customer@example.com".to_string()),
    phone: Some("+79123456789".to_string()),
    taxation: "osn".to_string(), // Система налогообложения
    items: vec![
        Item {
            name: "Товар 1".to_string(),
            price: 50000, // Цена за единицу
            quantity: 2.0,
            amount: 100000, // Общая сумма
            tax: "vat20".to_string(), // НДС 20%
            ean13: None,
        },
        Item {
            name: "Товар 2".to_string(),
            price: 50000,
            quantity: 1.0,
            amount: 50000,
            tax: "vat10".to_string(), // НДС 10%
            ean13: None,
        },
    ],
});

Обработка ошибок

use tbank_payments::TbankError;

match client.init(request).await {
    Ok(response) => {
        // Успешно
    }
    Err(TbankError::Api { code, message }) => {
        println!("API ошибка {}: {}", code, message);
    }
    Err(TbankError::Http(e)) => {
        println!("HTTP ошибка: {}", e);
    }
    Err(e) => {
        println!("Другая ошибка: {}", e);
    }
}

Тестирование

Для тестирования используйте тестовое окружение:

let client = TbankClient::with_api_url(
    "TinkoffBankTest".to_string(),
    "TinkoffBankTest".to_string(),
    "https://rest-api-test.tinkoff.ru/v2".to_string()
);

Примеры

Полные примеры использования находятся в директории examples/:

  • examples/advanced.rs - расширенные примеры всех возможностей

Запуск примеров:

cargo run --example advanced

Безопасность

  • Никогда не храните пароль терминала в коде
  • Используйте переменные окружения для хранения секретных данных
  • Всегда используйте HTTPS
  • Валидируйте входные данные перед отправкой

Лицензия

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages