MaksutTilaukset

Tilaussuunnitelma

Tilaussuunnitelma mahdollistaa kauppiaan julkaista laskutusehdot, jotka käyttäjät voivat hyväksyä. Kun käyttäjä tilaa, kauppias tai hyväksytty noutaja voi periä enintään suunnitelman summan jokaiselta laskutusjaksolta.

Tämä opas esittää koko työnkulun rakennuspalikoina. Kauppias luo suunnitelman, tilaaja hyväksyy sen, ja kauppias tai noutaja kerää maksut tuloksena syntyneestä tilaus-PDA:sta.

Asennus

pnpm add @solana/subscriptions @solana/kit @solana/kit-plugin-rpc @solana/kit-plugin-signer @solana-program/token

Suunnitelman luominen

Kauppias omistaa suunnitelman. Suunnitelma-PDA johdetaan kauppiaan osoitteesta ja 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,
});

Suunnitelman päivittäminen

Kauppias voi päivittää muokattavat suunnitelmakentät luomisen jälkeen. Olemassa olevat tilaajat pitävät hyväksymänsä ehdot, kun taas uudet tilaajat hyväksyvät nykyiset suunnitelman ehdot.

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();

Tilaa

Tilaaja hyväksyy nykyiset tilausehdot. Tilauksen PDA johdetaan tilaussuunnitelman PDA:sta ja tilaajan osoitteesta.

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,
});

Kerää maksu

Kauppias tai sallittujen listalla oleva nostaja allekirjoittaa keräyksen. Kun suunnitelmassa käytetään kohdeosoitteiden sallittujen listaa, vastaanottajan token account -tilin omistajan tulee olla lueteltu kohteessa 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();

Peruuta ja kumoa

Peruuttaminen merkitsee tilauksen päättymisen. Kumoaminen sulkee tilauksen PDA:n sen jälkeen, kun peruutuksen voimassaoloaika on kulunut umpeen. Tilaaja allekirjoittaa molemmat tapahtumat.

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();

Huomautukset

  • amount on perusyksiköissä. 6-desimaalisen tokenin kohdalla 5_000_000 tarkoittaa 5 tokenia.
  • TypeScript SDK hakee reaaliaikaiset tilausehdot subscribe-toiminnon aikana, kun jätät ne pois.
  • Rust SubscribeBuilder tarvitsee odotetut tilausehdot. Hae ja dekoodaa tilaustili ensin, ja välitä sitten kyseiset kentät SubscribeData-toiminnon kautta.
  • Vain kauppias tai pullers-listassa oleva lompakko voi kerätä maksuja.
  • Tilaaja allekirjoittaa asetus-, peruutus- ja kumoamistapahtumat. Kauppias tai hyväksytty maksun kerääjä allekirjoittaa keräystapahtumat.

Is this page helpful?

Sisällysluettelo

Muokkaa sivua
© 2026 Solana Foundation. Kaikki oikeudet pidätetään.