Een abonnementsplan stelt een handelaar in staat factureringsvoorwaarden te publiceren die gebruikers kunnen accepteren. Nadat een gebruiker zich heeft geabonneerd, kan de handelaar of een goedgekeurde puller tot het planbedrag per factureringsperiode innen.
Deze handleiding toont de volledige flow als bouwstenen. De handelaar creëert een plan, de abonnee accepteert het, en de handelaar of puller int betalingen van de resulterende abonnements-PDA.
Installeren
pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token
Een Plan Creëren
De handelaar is eigenaar van het plan. De plan-PDA wordt afgeleid van het
handelaarsadres en planId.
import { address, createClient } from '@solana/kit';import { solanaLocalRpc } from '@solana/kit-plugin-rpc';import { signer } from '@solana/kit-plugin-signer';import { findPlanPda, subscriptionsProgram } from '@solana/subscriptions';const merchantClient = createClient().use(signer(merchantSigner)).use(solanaLocalRpc({ rpcUrl: 'http://127.0.0.1:8899' })).use(subscriptionsProgram());const planId = 1n;const tokenMint = address('TOKEN_MINT_ADDRESS_HERE');const amount = 5_000_000n;const periodHours = 720n;const metadataUri = 'https://example.com/plan.json';const destinations = [merchantSigner.address];const pullers = [address('PULLER_WALLET_ADDRESS_HERE')];await merchantClient.subscriptions.instructions.createPlan({planId,mint: tokenMint,amount,periodHours,endTs: 0n,destinations,pullers,metadataUri,}).sendTransaction();const [planPda] = await findPlanPda({owner: merchantSigner.address,planId,});
Een Plan Bijwerken
De handelaar kan muteerbare planvelden bijwerken na aanmaak. Bestaande abonnees behouden de voorwaarden die zij hebben geaccepteerd, terwijl nieuwe abonnees de huidige planvoorwaarden accepteren.
Een aantal regels zijn van toepassing:
- Een eindige
endTskan alleen worden ingekort, nooit verlengd of gewist (PlanEndTsCannotExtend). - Bij een
Sunsetplan kun je pullers verwijderen (de nieuwe set moet een subset zijn van de huidige) om een gecompromitteerde puller in te trekken; status,endTsen metadata blijven bevroren. - Wijzigingen werken tijdens de laatste factureringsperiode van een plan, zolang
endTsongewijzigd blijft.
import { PlanStatus } from '@solana/subscriptions';const updatedMetadataUri = 'https://example.com/updated-plan.json';const updatedPullers = [address('NEW_PULLER_WALLET_ADDRESS_HERE')];await merchantClient.subscriptions.instructions.updatePlan({owner: merchantSigner,planPda,status: PlanStatus.Active,endTs: 0n,pullers: updatedPullers,metadataUri: updatedMetadataUri,}).sendTransaction();
Abonneren
De abonnee accepteert de huidige planvoorwaarden. De abonnements-PDA wordt afgeleid van de plan-PDA en het adres van de abonnee.
import { createClient } from '@solana/kit';import { solanaLocalRpc } from '@solana/kit-plugin-rpc';import { signer } from '@solana/kit-plugin-signer';import { findAssociatedTokenPda, TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';import {fetchMaybeSubscriptionAuthority,findSubscriptionAuthorityPda,findSubscriptionDelegationPda,subscriptionsProgram,} from '@solana/subscriptions';const subscriberClient = createClient().use(signer(subscriberSigner)).use(solanaLocalRpc({ rpcUrl: 'http://127.0.0.1:8899' })).use(subscriptionsProgram());const [subscriberAta] = await findAssociatedTokenPda({mint: tokenMint,owner: subscriberSigner.address,tokenProgram: TOKEN_PROGRAM_ADDRESS,});const [subscriptionAuthorityPda] = await findSubscriptionAuthorityPda({user: subscriberSigner.address,tokenMint,});const subscriptionAuthority = await fetchMaybeSubscriptionAuthority(subscriberClient.rpc,subscriptionAuthorityPda,);if (!subscriptionAuthority.exists) {await subscriberClient.subscriptions.instructions.initSubscriptionAuthority({tokenMint,tokenProgram: TOKEN_PROGRAM_ADDRESS,userAta: subscriberAta,}).sendTransaction();}await subscriberClient.subscriptions.instructions.subscribe({merchant: merchantSigner.address,planId,tokenMint,}).sendTransaction();const [subscriptionPda] = await findSubscriptionDelegationPda({planPda,subscriber: subscriberSigner.address,});
Een Betaling Innen
De merchant of een gewhitelistte puller ondertekent de inning. Wanneer het plan
gebruikmaakt van een bestemming-allowlist, moet de eigenaar van de ontvanger
token account worden vermeld in destinations.
const receiverAta = address('MERCHANT_TOKEN_ACCOUNT_ADDRESS_HERE');await merchantClient.subscriptions.instructions.transferSubscription({caller: merchantOrPullerSigner,delegator: subscriberSigner.address,tokenMint,subscriptionPda,planPda,amount: 200_000n,receiverAta,tokenProgram: TOKEN_PROGRAM_ADDRESS,}).sendTransaction();
Annuleren en Intrekken
Annuleren markeert het abonnement als eindigend. Intrekken sluit de abonnements- PDA nadat de annuleringstermijn is verstreken. De abonnee ondertekent beide transacties.
await subscriberClient.subscriptions.instructions.cancelSubscription({subscriber: subscriberSigner,planPda,subscriptionPda,}).sendTransaction();// Run this after the cancelled subscription's expiresAtTs has elapsed.await subscriberClient.subscriptions.instructions.revokeSubscription({authority: subscriberSigner,planPda,subscriptionPda,}).sendTransaction();
Een Abonnement Hervatten
Een geannuleerd abonnement kan opnieuw worden geactiveerd voordat het wordt
ingetrokken. Zodra het is ingetrokken, wordt het abonnementsaccount gesloten en
moet de abonnee opnieuw abonneren. Hervatten vereist het
SubscriptionAuthority van de abonnee voor de mint van het plan, dat het
programma valideert (eigenaar, mint en init_id) en afwijst als het verouderd
of opnieuw geïnitialiseerd is.
await subscriberClient.subscriptions.instructions.resumeSubscription({subscriber: subscriberSigner,planPda,tokenMint,}).sendTransaction();
Opmerkingen
amountis in basiseenheden. Voor een token met 6 decimalen betekent5_000_0005tokens.- De TypeScript SDK haalt live plantermijnen op tijdens
subscribewanneer u deze weglaat. - De Rust
SubscribeBuilderheeft de verwachte plantermijnen nodig. Haal het planaccount op en decodeer het eerst, geef die velden vervolgens door viaSubscribeData. - Alleen de handelaar of een wallet vermeld in
pullerskan betalingen innen. - De abonnee ondertekent setup-, annulerings- en intrekkingstransacties. De handelaar of goedgekeurde puller ondertekent incassotransacties.
Is this page helpful?