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.
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 handelaar of een gewhiteliste puller ondertekent de incasso. Wanneer het plan
gebruikmaakt van een bestemmingsallowlist, moet de eigenaar van het ontvangende
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();
Opmerkingen
amountis in basiseenheden. Voor een token met 6 decimalen betekent5_000_000eigenlijk5tokens.- De TypeScript SDK haalt live plantermen op tijdens
subscribewanneer je deze weglaat. - De Rust
SubscribeBuilderheeft de verwachte plantermen nodig. Haal eerst het planaccount op en decodeer het, en geef die velden vervolgens door viaSubscribeData. - Alleen de merchant of een wallet die vermeld staat in
pullerskan betalingen innen. - De abonnee ondertekent setup-, cancel- en revoke-transacties. De merchant of goedgekeurde puller ondertekent incassotransacties.
Is this page helpful?