Source Code


;; subscription-payments.clar
;; Allows users to subscribe to a service and enables the service provider to pull payments periodically.
;; Clarity 4

(define-constant err-subscription-not-found (err u800))
(define-constant err-payment-too-early (err u801))
(define-constant err-amount-too-high (err u802))
(define-constant err-unauthorized (err u803))

(define-map subscriptions 
    { subscriber: principal, provider: principal }
    {
        max-amount: uint,
        period: uint, ;; in blocks
        last-payment-block: uint,
        active: bool
    }
)

(define-public (subscribe (provider principal) (max-amount uint) (period uint))
    (begin
        (map-set subscriptions { subscriber: tx-sender, provider: provider } {
            max-amount: max-amount,
            period: period,
            last-payment-block: burn-block-height,
            active: true
        })
        (ok true)
    )
)

(define-public (unsubscribe (provider principal))
    (let
        (
            (sub (unwrap! (map-get? subscriptions { subscriber: tx-sender, provider: provider }) err-subscription-not-found))
        )
        (map-set subscriptions { subscriber: tx-sender, provider: provider } (merge sub { active: false }))
        (ok true)
    )
)

(define-public (process-payment (subscriber principal) (amount uint))
    (let
        (
            (sub (unwrap! (map-get? subscriptions { subscriber: subscriber, provider: tx-sender }) err-subscription-not-found))
            (next-valid-block (+ (get last-payment-block sub) (get period sub)))
        )
        (asserts! (get active sub) err-subscription-not-found)
        (asserts! (>= burn-block-height next-valid-block) err-payment-too-early)
        (asserts! (<= amount (get max-amount sub)) err-amount-too-high)
        
        (try! (stx-transfer? amount subscriber tx-sender))
        
        (map-set subscriptions { subscriber: subscriber, provider: tx-sender } (merge sub { last-payment-block: burn-block-height }))
        (ok true)
    )
)

Functions (3)

FunctionAccessArgs
subscribepublicprovider: principal, max-amount: uint, period: uint
unsubscribepublicprovider: principal
process-paymentpublicsubscriber: principal, amount: uint