Skip to content

Commit 73a167e

Browse files
authored
Merge pull request #1027 from Timmatt112/feat/950-plan-templates-dynamic-pricing
feat: implement subscription plan templates with dynamic pricing tiers
2 parents fc5ad89 + 04a52a9 commit 73a167e

2 files changed

Lines changed: 137 additions & 0 deletions

File tree

contracts/subscription/src/lib.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ use subtrackr_types::{
1313
Subscription, SubscriptionStatus, TimeRange,
1414
};
1515

16+
mod plan_templates;
17+
1618
/// Billing interval in seconds.
1719
const MAX_PAUSE_DURATION: u64 = 2_592_000; // 30 days
1820
const DEFAULT_COMMIT_REVEAL_THRESHOLD: i128 = i128::MAX;
@@ -648,6 +650,126 @@ impl SubTrackrSubscription {
648650
);
649651
}
650652

653+
// ── Plan Templates ──
654+
655+
pub fn create_plan_template(
656+
env: Env,
657+
proxy: Address,
658+
storage: Address,
659+
owner: Address,
660+
name: String,
661+
description: String,
662+
base_price: i128,
663+
token: Address,
664+
interval: Interval,
665+
tiers: Vec<plan_templates::PricingTier>,
666+
features: Vec<String>,
667+
) -> u64 {
668+
proxy.require_auth();
669+
owner.require_auth();
670+
plan_templates::create_template(
671+
&env, &storage, &owner, name, description, base_price, token, interval, tiers, features,
672+
)
673+
}
674+
675+
pub fn publish_plan_template_version(
676+
env: Env,
677+
proxy: Address,
678+
storage: Address,
679+
owner: Address,
680+
template_id: u64,
681+
name: String,
682+
description: String,
683+
base_price: i128,
684+
tiers: Vec<plan_templates::PricingTier>,
685+
features: Vec<String>,
686+
) -> u64 {
687+
proxy.require_auth();
688+
owner.require_auth();
689+
plan_templates::publish_version(
690+
&env, &storage, &owner, template_id, name, description, base_price, tiers, features,
691+
)
692+
}
693+
694+
pub fn set_plan_template_shared(
695+
env: Env,
696+
proxy: Address,
697+
storage: Address,
698+
owner: Address,
699+
template_id: u64,
700+
shared: bool,
701+
) {
702+
proxy.require_auth();
703+
owner.require_auth();
704+
plan_templates::set_shared(&env, &storage, &owner, template_id, shared);
705+
}
706+
707+
pub fn instantiate_plan_template(
708+
env: Env,
709+
proxy: Address,
710+
storage: Address,
711+
caller: Address,
712+
template_id: u64,
713+
overrides: plan_templates::TemplateOverrides,
714+
) -> plan_templates::ResolvedPlan {
715+
proxy.require_auth();
716+
caller.require_auth();
717+
plan_templates::instantiate(&env, &storage, &caller, template_id, overrides)
718+
}
719+
720+
pub fn quote_plan_template(
721+
env: Env,
722+
proxy: Address,
723+
storage: Address,
724+
template_id: u64,
725+
units: u64,
726+
) -> i128 {
727+
proxy.require_auth();
728+
let template = plan_templates::get_template(&env, &storage, template_id)
729+
.expect("Template not found");
730+
plan_templates::quote_template(&template, units)
731+
}
732+
733+
pub fn get_plan_template(
734+
env: Env,
735+
proxy: Address,
736+
storage: Address,
737+
template_id: u64,
738+
) -> Option<plan_templates::PlanTemplate> {
739+
proxy.require_auth();
740+
plan_templates::get_template(&env, &storage, template_id)
741+
}
742+
743+
pub fn get_plan_template_analytics(
744+
env: Env,
745+
proxy: Address,
746+
storage: Address,
747+
template_id: u64,
748+
) -> plan_templates::TemplateAnalytics {
749+
proxy.require_auth();
750+
plan_templates::get_analytics(&env, &storage, template_id)
751+
}
752+
753+
pub fn record_plan_template_view(
754+
env: Env,
755+
proxy: Address,
756+
storage: Address,
757+
template_id: u64,
758+
) {
759+
proxy.require_auth();
760+
plan_templates::record_view(&env, &storage, template_id);
761+
}
762+
763+
pub fn record_plan_template_subscription(
764+
env: Env,
765+
proxy: Address,
766+
storage: Address,
767+
template_id: u64,
768+
) {
769+
proxy.require_auth();
770+
plan_templates::record_subscription(&env, &storage, template_id);
771+
}
772+
651773
// ── Plan Management ──
652774

653775
pub fn create_plan(

contracts/types/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,18 @@ pub struct UpgradeEvent {
212212
pub type SubscriptionId = u64;
213213
pub type MerchantId = Address;
214214

215+
/// Secondary keys used by the reusable plan-template library.
216+
#[contracttype]
217+
#[derive(Clone, Debug, PartialEq)]
218+
pub enum TemplateKey {
219+
Template(u64),
220+
ByOwner(Address),
221+
Shared,
222+
Versions(u64),
223+
Analytics(u64),
224+
Count,
225+
}
226+
215227
#[contracttype]
216228
#[derive(Clone, Debug, PartialEq)]
217229
pub enum FraudAction {
@@ -476,6 +488,9 @@ pub enum StorageKey {
476488
/// Usage record for a subscription and metric (sub_id, metric -> UsageRecord)
477489
SubscriptionUsage(u64, QuotaMetric),
478490

491+
// ── Plan templates (appended for storage compatibility) ──
492+
PlanTemplate(TemplateKey),
493+
479494
// Added for MEV-resistant subscription charging
480495
MevProtectionConfig,
481496
ChargeCommitment(u64),

0 commit comments

Comments
 (0)