Method.tempo.subscription
Recurring stablecoin payments
Creates a Tempo subscription method for server-side activation, access reuse, and renewal.
Usage
import { , , } from 'mppx/server'
const = .()
const = .({
: [
.({
: '1.00',
: '0x20c0000000000000000000000000000000000000',
: '1',
: 'week',
: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
: true,
: async ({ }) => {
if (!) return null
return { : `payer:${.}:${.}:plan:pro` }
},
,
: new ('2027-01-01T00:00:00.000Z'),
}),
],
})
export async function (: Request) {
const = await ..({})()
if (. === 402) return .
return .(.({ : 'pro' }))
}With background renewals
Use a durable store and call tempo.renewSubscription from a worker.
import { , , } from 'mppx/server'
const = .()
const = .({
: [
.({
: '1.00',
: '0x20c0000000000000000000000000000000000000',
: '1',
: 'week',
: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
: true,
: async ({ }) => {
if (!) return null
return { : `payer:${.}:${.}:plan:pro` }
},
,
: new ('2027-01-01T00:00:00.000Z'),
}),
],
})
await .({
,
: 'sub_abc123',
})With custom activation
Pass activate when your app owns first-period settlement and subscription record creation.
import { , , } from 'mppx/server'
const = .()
const = .({
: [
.({
: async ({ , }) => {
const = new ().()
return {
: {
: 'tempo',
: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
: 'success',
: 'sub_abc123',
,
},
: {
: .,
: ,
: .,
: 0,
: .,
: .,
: .,
: .,
: '0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
: .,
: 'sub_abc123',
,
},
}
},
: '1.00',
: '0x20c0000000000000000000000000000000000000',
: '1',
: 'week',
: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
: async () => ({ : 'user:123:plan:pro' }),
,
: new ('2027-01-01T00:00:00.000Z'),
}),
],
})With cancellation
Mark the stored subscription record with canceledAt. mppx no longer reuses or renews that record, and the next protected request returns a new subscription Challenge. If the client also revokes the Tempo access key, still update the server record so access and billing state stay aligned.
import { } from 'mppx/server'
import { } from 'mppx/tempo'
const = .()
const = .()
export async function (: string) {
const = await .(`user:${}:plan:pro`)
if (!) return false
await .({
...,
: new ().(),
})
return true
}Return type
import type { Method } from 'mppx'
type ReturnType = Method.ServerConfiguration
These parameters configure tempo.subscription().
accessKey (optional)
- Type:
(parameters: { input: Request; request: SubscriptionRequest; resolved: SubscriptionLookup }) => MaybePromise<SubscriptionAccessKey>
Returns the access key to include in the Challenge. Omit this for the recommended path: mppx generates and stores a server-owned access key per resolved subscription key.
account (optional)
- Type:
Account
Account used as the default recipient and local transaction signer.
activationTimeoutMs (optional)
- Type:
number - Default:
900000
Milliseconds before an in-flight activation lock can be replaced.
amount (optional)
- Type:
string
Default amount to charge per period.
canOffer (optional)
- Type:
Method.CanOfferFn
Returns whether this configured subscription offer is available when an HTTP handler composes multiple offers. The hook receives the normalized, immutable payment request and a clone of the incoming Request.
chainId (optional)
- Type:
number
Tempo chain ID. Use 4217 for mainnet and 42431 for testnet.
currency (optional)
- Type:
Address
Default TIP-20 token address.
decimals (optional)
- Type:
number - Default:
6
Decimal places for amount parsing.
description (optional)
- Type:
string
Human-readable subscription description.
externalId (optional)
- Type:
string
Application-defined identifier for reconciliation.
getClient (optional)
- Type:
(parameters: { chainId?: number }) => MaybePromise<Client>
Function that returns a viem client for the given Tempo chain ID.
hooks (optional)
- Type:
{ activated?: (parameters) => MaybePromise<void>; renewed?: (parameters) => MaybePromise<void> }
Callbacks that run after activation or renewal commits.
onPaymentSuccess (optional)
- Type:
Method.OnPaymentSuccessFn<typeof tempo.Methods.subscription>
Runs after this subscription method returns a successful result. The hook receives the normalized request, its Receipt, and the HTTP input when available. Errors don't change payment handling.
periodCount (optional)
- Type:
string
Number of period units per billing period.
periodUnit (optional)
- Type:
'day' | 'week'
Billing period unit.
recipient (optional)
- Type:
Address
Address that receives subscription payments.
renew (optional)
- Type:
(parameters: { inFlightReference: string; periodIndex: number; subscription: SubscriptionRecord }) => Promise<RenewalResult>
Custom renewal hook. Use this when your app owns period settlement and subscription record updates.
renewalTimeoutMs (optional)
- Type:
number - Default:
900000
Milliseconds before an in-flight renewal lock can be replaced.
requireCredential (optional)
- Type:
boolean
Requires a fresh subscription Credential even when a subscription is active. Use this when access reuse must be bound to the stored payer instead of request metadata.
resolve
- Type:
(parameters: { input: Request; request: SubscriptionRequest; source?: { address: Address; chainId: number } }) => MaybePromise<SubscriptionLookup | null>
Maps a request to a subscription lookup key. With requireCredential, use source to derive the key from the verified payer.
store (optional)
- Type:
Store.AtomicStore<Record<string, unknown>> - Default:
Store.memory()
Atomic store for access keys, activation locks, renewal locks, and subscription records. Use Subscription.fromStore from mppx/tempo when you need to update subscription records directly, such as marking canceledAt.
subscriptionExpires (optional)
- Type:
string | Date
Maximum authorization expiry. The client authorization cannot outlive this timestamp.
testnet (optional)
- Type:
boolean
Uses Tempo testnet defaults. Testnet chain ID is 42431.
waitForConfirmation (optional)
- Type:
boolean - Default:
true
Whether to wait for activation and automatic renewal transfers to confirm before returning a Receipt.
Request parameters
These parameters configure each mppx.tempo.subscription() call.
accessKey (optional)
- Type:
SubscriptionAccessKey
Access key to authorize. Most apps let the server method generate this value.
amount (optional)
- Type:
string
Amount to charge per billing period.
chainId (optional)
- Type:
number
Tempo chain ID for the subscription.
currency (optional)
- Type:
Address
TIP-20 token address for payments.
decimals (optional)
- Type:
number
Decimal places for amount parsing.
description (optional)
- Type:
string
Human-readable subscription description.
expires (optional)
- Type:
string
Challenge expiry timestamp.
externalId (optional)
- Type:
string
Application-defined identifier for reconciliation.
meta (optional)
- Type:
Record<string, string>
Server-defined correlation data serialized as the Challenge opaque auth-param.
periodCount (optional)
- Type:
string
Number of period units per billing period.
periodUnit (optional)
- Type:
'day' | 'week'
Billing period unit.
recipient (optional)
- Type:
Address
Address that receives payments.
scope (optional)
- Type:
string
Route or resource scope bound into the Challenge metadata.
subscriptionExpires (optional)
- Type:
string | Date
Maximum authorization expiry.
Related
tempo.renewSubscription
Renews an overdue subscription outside the request path. See tempo.renewSubscription.