Closed deman4ik closed 3 years ago
Поменялся принцип тарифов и способ хранения информации
Принято решение предоставлять единый тариф со всем доступным функционалом и стараться замотивировать пользователя на длительную подписку.
Поэтому в subscriptions
хранятся базовые тарифы - сейчас там 1 тариф с автоматическими торговыми роботами и в дальнейшем появится другой с дополнительным функционалом в виде портфелей роботов.
Колонка options
переехала в отдельную таблицу subscription_options
code -- кодовое обозначение времени подписки "1m" | "6m" | "1y"
subscription_id -- id подписки из subscriptions
name -- имя опции (по сути имя тарифного плана)
description -- дополнительное описание опции (например 1 месяц бесплатно)
sort_order -- порядок сортировки при отображении
price_month -- цена в месяц
price_total -- цена за весь период
discount -- скидка в %
highlight -- признак выделения именно этой опции для привлечения внимания
amount -- количество времени подписки в ед. измерения
unit -- ед. измерения подписка "month" | "year" |
available -- ограничение прав доступа
Поэтому нужно внести следующие изменения:
[x] Вместо выбора периода с помощью радио кнопок, будут выбирать тарифы, а сейчас он один, поэтому этот момент можно опустить
[x] На данный момент получается ровно 3 карточки для выбора тарифа при добавлении робота
В каждой отдельной карточке мы выводим
Имя - subscription_options.name
,
Описание - subscriptions.description
(пока одинаковое для всех, возможно потом будет использовать subscription_options.description
)
Цену итого - subscription_options.price_total
и в скобках минус % (- subscription_options.discount %)
Цену в месяц - subscription_options.price_month
per month
Кнопка - Subscribe
[x] Форма выбора тарифа должна быть универсальной, т.е. она может вызываться как при добавлении робота, так и из профиля - нужно это сразу предусмотреть
subscription_options.discount === null
выводить скобки конечно же не надо${subscription_options.name}
а на следующей строке ${subscription_options.amount} ${subscription_options.unit}Cryptuoso Account
переименовываем в Cryptuoso Subscription
user_subs
по user_id
с сортировкой по created_at desc
берем первую запись
по связям сразу можно отобрать subscriptionOption { subscription { ... } }
subscription.name
на следующей строке ${subscriptionOption.name} (${subscriptionOption.amount} ${subscriptionOption.unit})
и рядом кнопка с иконкой mdiHistory
- dimmed
- ссылка на /profile/subscription-history
на следующей строке subscriptionOption.total_price
далее Status: ${user_subs.status}
Expires: ${user_subs.active_to || user_subs.trial_ended}
если обе даты не указаны - не выводим эту строчку3 кнопки в линию Change plan
- dimmed - иконка шестеренка,
Pay
- primary - иконка mdiBitcoin,
Cancel
- dimmed - иконка крестик
По стилистике ориентируемся на карточку My Exchange API Keys
/profile/subscription-history
Выводится вся доступная информация из user_subs с отбором по user_id + по связям user_payments По стилистике ориентируемся на страницы /open-positions/
[x] Выводится первая строка подзаголовок из user_subs, колонки
Subscription Name
subscription.name
Option
${subscriptionOption.name} (${subscriptionOption.amount} ${subscriptionOption.unit})
Price
subscriptionOption.total_price
Status
Status: ${user_subs.status}
Date from user_subs.active_from || user_subs.trial_started
Date to user_subs.active_to || user_subs.trial_ended
[x] И далее к каждой записи подтаблица с user_payments
Payment Code user_payments.code
Price user_payments.price
Status user_payments.status
Date user_payments. created_at
Cryptuoso Trading Signals
FREE PLAN
Status: Active
кнопкаSTART FREE TRIAL
- primary
- открывает форму выбора тарифного плана.
Когда тарифный план уже выбран:
checkoutUserSub
и считывается из ответа userPayment
Выводим форму с кнопкой оплаты https://commerce.coinbase.com/docs/#using-react
в пропсы передается chargeId = userPayment.id
на onModalClosed
повесить вызов мутации checkPayment
снова получить из ответа userPayment
и вывести userPayment.status
на следующем шаге формы и кнопку "ОК"
если это все заработает - опишу как это правильно стилизовать
- user_payments массив выводится пустой, мой запрос по связям неверный?
нужно создать платеж через checkoutUserSub
subscriptions
т.е. на данные момент будет только 1 карточкаsubscriptions.name
subscription_options - name
как на лендингеsubscription_options.sort_order
subscription_options.highlight === true
сделать нажатой по умолчаниюsubscriptions.name
Amount
и Period
полностью удалитьSubscription
переименовать в Period
Status
выводится с заглавной буквыPrice
стоит 0 то выводить часть после запятой не надоHistory
выровнять по вертикали по центру строкиChange Plan
, Pay
и Cancel
как Password Change
Pay
переименовать в Checkout
и поменять стиль на primary (голубая)Checkout
следующая строка ${userPayment.subscriptions.name} ${userPayment.subscription_options.name}
Price: ${userPayment.price}
Status: ${userPayment.status}
Charge expires: ${userPayment.expired_at} minutes
- преобразовать дату в оставшиеся минутыThe payment processing and validation on the blockchain may take up to 60 minutes. When your payment will be resolved your subscription will be activated. <a href='https://commerce.coinbase.com/faq#customers'>How it works?</a>
Buy with Crypto
Buy with Crypto
меняем на OK
которая закрывает формуДобавляется 3 новых типа нотификаций, которые нужно правильно вывести на странице /notifications пока в упрощенном варианте вот так:
user_sub.error
- просто выводим data.error
user_sub.status
- выводим ${data.subscriptionName} is ${data.status}
user_payment.status
- выводим Payment for ${data.subscriptionName} is ${data.status} ${data.context || ''}
* A. Если тариф еще не выбран кнопку у который признак `subscription_options.highlight === true` сделать нажатой по умолчанию * B. Если тариф уже выбран нажатой по умолчанию делать кнопку с текущей опцией
Речь идет о кнопках 1 или 2 ? Если об 1, то нужна ли 2?
Когда тарифный план еще не выбран, по какому полю смотреть условие? Например в user_subs.status - если "trial", то тариф не выбран, "active"- выбран
или
name -- имя опции (по сути имя тарифного плана)
Если в user_subs.subscriptionOption.name указано имя, то тарифный план выбран, а если нет, то что поле содержит?
или
в user_subs.subscriptionOption.subscription.name - указан TRADER PLAN - тариф выбран, FREE PLAN - тариф не выбран?
change plan
на странице /profile
падает страница/profile
падаетuser_subs(
where: { user_id: { _eq: $userId }, status: { _nin: ["canceled", "expired"] } }
order_by: { created_at: desc_nulls_last }
limit: 1
)
subscription-history
переименовываем в payment-history
subscription-history
выводим таблицу
по следующему запросу
query userPayments($userId: uuid) {
user_payments(where: {user_id: {_eq: $userId}}) {
id
code
url
status
price
created_at
expires_at
subscription_from
subscription_to
user_sub {
subscriptionOption {
name
}
subscription {
name
}
}
}
}
Колонки
Charge Code - выводим code если url не null то выводим <a href=${url}
>${code} иначе просто ${code}
Charge Price - price
Charge Status - status
Created - created_at
Expires - expires_at
Subscription - ${user_sub.subscription.name} ${user_sub.subscriptionOption.name}
Subscription Period - ${subscription_from} - ${subscription_to}
6 months / 1 month free
)$ 33 per month (-15 %)
iphone 5/se 320x568
Адаптация для мобильных завтра.
[x] /profile/payment-history/ убрать заголовок TRADER PLAN
[x] отсортировать по created_at desc
[x] грузить первые 15, остальные подгружать по кнопке
[x] даты не отформатированы!
[x] для мобильного экрана нужен отступ снизу списка
[x] для мобильного экрана выводить все колонки в столбик
[x] тарифные планы не перeключаются
[x] Когда пользователь не залогинен нужна заглушка
[x] все еще падает страница /profile когда не выбран тариф
[x] все еще падает страница если тарифный план еще не выбран при добавлении робота
как определить что тарифный план еще не выбран?
На бэкенде пока не до конца все готово и будут вводиться изменения, но пока ориентируемся на то что есть.
Прием платежей мы будем внедрять с помощью https://commerce.coinbase.com/ Документация https://commerce.coinbase.com/docs/ Документация API https://commerce.coinbase.com/docs/api/#introduction
Тарифные планы (в месяц): FREE - торговые сигналы 15$ - 3 автоматических робота 30$ - 10 роботов 50$ - неограниченное количество роботов
Скидки и бонусы: -20% - при оплате 6 месяцев -30% - при оплате 1 года -50% - при оплате 2 лет
В graphql схеме это реализовано с помощью трех основных таблиц
subscriptions
- список всех доступных тарифных планов (FREE - не хранится в базе, доступен всем по умолчанию)user_subs
- список подписок конкретного пользователяuser_payments
- список платежей конкретного пользователя по конкретной подпискеПоля можно посмотреть в схеме или вот предварительно такая типизация на бэкенде (тут используется camelCase)
Также будут доступны следующие мутации:
Первый этап - оформление подписки
user_subs
поuser_id
subscriptions
.options
. Где хранится объект с различными ценами за разные периоды.createUserSub
гдеsubscriptionId
этоid
строки подписки из таблицыsubscriptions
, аsubscriptionOption
это ключ из объектаoptions
указывающий на период подписки. Например1y