Добавить в корзинуПозвонить
Найти в Дзене

On-chain сервис для приёма криптоплатежей и выдачи доступа к торговым сигналам, чатам и закрытым трейдинг-сообществам

Самая востребованная и простая задача в крипте — контракт платной подписки (subscription):
люди платят USDT, ты даёшь доступ к чату / сигналам / сервису. Это то, что реально используют: Контракт: Без сложной логики, но полностью рабочий on-chain. use anchor_lang::prelude::*;
use anchor_spl::token::{self, Token, TokenAccount, Transfer};
declare_id!("Subscr1ption111111111111111111111111111111");
#[program]
pub mod subscription {
use super::*;
// Создание аккаунта подписки
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let sub = &mut ctx.accounts.subscription;
sub.owner = ctx.accounts.owner.key();
sub.price = 10_000_000; // 10 USDT (6 знаков)
Ok(())
}
// Оплата подписки (продлевает на 30 дней)
pub fn pay(ctx: Context<Pay>) -> Result<()> {
let sub = &mut ctx.accounts.subscription;
let user_sub = &mut ctx.accounts.user_subscription;
// перевод USDT владельцу
let cpi_accounts = Transf
Оглавление

Самая востребованная и простая задача в крипте — контракт платной подписки (subscription):

люди платят USDT, ты даёшь доступ к чату / сигналам / сервису.

Это то, что реально используют:

  • платные Telegram-чаты
  • сигналы
  • доступ к сайтам
  • API
  • закрытые группы

🔹 Задача

Контракт:

  • принимает оплату в USDT (SPL-токен)
  • записывает дату окончания подписки
  • позволяет проверять: активна ли подписка у пользователя

Без сложной логики, но полностью рабочий on-chain.

🔹 Реальный смарт-контракт Solana (Anchor + Rust)

programs/subscription/src/lib.rs

use anchor_lang::prelude::*;
use anchor_spl::token::{self, Token, TokenAccount, Transfer};

declare_id!("Subscr1ption111111111111111111111111111111");

#[program]
pub mod subscription {
use super::*;

// Создание аккаунта подписки
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let sub = &mut ctx.accounts.subscription;
sub.owner = ctx.accounts.owner.key();
sub.price = 10_000_000; // 10 USDT (6 знаков)
Ok(())
}

// Оплата подписки (продлевает на 30 дней)
pub fn pay(ctx: Context<Pay>) -> Result<()> {
let sub = &mut ctx.accounts.subscription;
let user_sub = &mut ctx.accounts.user_subscription;

// перевод USDT владельцу
let cpi_accounts = Transfer {
from: ctx.accounts.user_token.to_account_info(),
to: ctx.accounts.owner_token.to_account_info(),
authority: ctx.accounts.user.to_account_info(),
};
let cpi_ctx = CpiContext::new(ctx.accounts.token_program.to_account_info(), cpi_accounts);
token::transfer(cpi_ctx, sub.price)?;

let now = Clock::get()?.unix_timestamp;

// если подписка ещё активна — продлеваем
if user_sub.expires_at > now {
user_sub.expires_at += 30 * 24 * 60 * 60;
} else {
user_sub.expires_at = now + 30 * 24 * 60 * 60;
}

user_sub.user = ctx.accounts.user.key();
user_sub.subscription = sub.key();

Ok(())
}
}

🔹 Структуры данных

#[account]
pub struct Subscription {
pub owner: Pubkey,
pub price: u64, // цена в USDT (6 decimals)
}

#[account]
pub struct UserSubscription {
pub user: Pubkey,
pub subscription: Pubkey,
pub expires_at: i64, // unix время окончания
}

🔹 Контексты

#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(init, payer = owner, space = 8 + 32 + 8)]
pub subscription: Account<'info, Subscription>,
#[account(mut)]
pub owner: Signer<'info>,
pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Pay<'info> {
#[account(mut)]
pub subscription: Account<'info, Subscription>,

#[account(init_if_needed, payer = user, space = 8 + 32 + 32 + 8)]
pub user_subscription: Account<'info, UserSubscription>,

#[account(mut)]
pub user: Signer<'info>,

// токен-аккаунты USDT
#[account(mut)]
pub user_token: Account<'info, TokenAccount>,
#[account(mut)]
pub owner_token: Account<'info, TokenAccount>,

pub token_program: Program<'info, Token>,
pub system_program: Program<'info, System>,
}

🔹 Как это используется на практике

Схема рабочая:

  1. Ты деплоишь контракт
  2. У тебя есть USDT-кошелёк (SPL)
  3. Пользователь вызывает pay
  4. Контракт:
    переводит USDT тебе
    записывает дату окончания

На сайте / в боте ты просто делаешь:

check: expires_at > now ? доступ есть : доступ закрыт

🔹 Где это реально применяют

Это используют:

  • платные трейдинг-чаты
  • сигнальные сервисы
  • VPN-доступ
  • API-доступ
  • закрытые сайты

И это юридически проще, чем принимать карты и банки.

Если хочешь, могу следующим шагом дать:

  • 🔹 версию с автопродлением
  • 🔹 вариант с NFT-подпиской
  • 🔹 escrow-контракт (депозит → результат → выплата)
  • 🔹 контракт для приёма оплат за сигналы
  • 🔹 готовый фронт (JS) для подключения кошелька

Скажи в комментариях под какую задачу тебе реально нужно — сделаю максимально прикладной вариант.