Paket langganan memungkinkan pedagang menerbitkan ketentuan penagihan yang dapat diterima oleh pengguna. Setelah pengguna berlangganan, pedagang atau penarik yang disetujui dapat mengumpulkan hingga jumlah paket setiap periode penagihan.
Panduan ini menunjukkan alur lengkap sebagai blok bangunan. Pedagang membuat paket, pelanggan menerimanya, dan pedagang atau penarik mengumpulkan pembayaran dari PDA langganan yang dihasilkan.
Instalasi
pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token
Membuat Paket
Pedagang memiliki paket tersebut. PDA paket diturunkan dari alamat pedagang dan
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,});
Memperbarui Paket
Pedagang dapat memperbarui kolom paket yang dapat diubah setelah pembuatan. Pelanggan yang sudah ada tetap mempertahankan ketentuan yang telah mereka terima, sementara pelanggan baru menerima ketentuan paket saat ini.
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();
Berlangganan
Pelanggan menerima ketentuan paket saat ini. PDA langganan diturunkan dari PDA paket dan alamat pelanggan.
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,});
Mengumpulkan Pembayaran
Pedagang atau penarik yang masuk daftar putih menandatangani pengumpulan. Ketika
paket menggunakan daftar izin tujuan, pemilik token account penerima harus
terdaftar dalam 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();
Membatalkan Dan Mencabut
Pembatalan menandai langganan sebagai berakhir. Pencabutan menutup PDA langganan setelah masa berlaku pembatalan telah lewat. Pelanggan menandatangani kedua transaksi.
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();
Catatan
amountdalam unit dasar. Untuk token 6-desimal,5_000_000berarti5token.- TypeScript SDK mengambil ketentuan paket secara langsung selama
subscribeketika Anda tidak menyertakannya. - Rust
SubscribeBuildermemerlukan ketentuan paket yang diharapkan. Ambil dan decode akun paket terlebih dahulu, lalu teruskan field tersebut melaluiSubscribeData. - Hanya merchant atau dompet yang terdaftar di
pullersyang dapat mengumpulkan pembayaran. - Subscriber menandatangani transaksi setup, cancel, dan revoke. Merchant atau puller yang disetujui menandatangani transaksi pengumpulan.
Is this page helpful?