Skip to content

Threshold-Based Rewards Distribution

This guide outlines how to programmatically distribute rewards for conversions linked to referral links with pending rewards exceeding a predefined payout threshold in USDC using SoyCap.io. The process involves fetching referral links for campaigns, checking their pending rewards, retrieving unpaid conversions, and distributing rewards programmatically.

Prerequisites

  1. Merchant Authentication: Obtain an auth_token using the /merchants/authenticate endpoint.
  2. Campaign Owner’s Keypair: Ensure the campaign owner’s keypair is securely loaded and ready to sign transactions.
  3. Positive SOL Balance: Ensure the campaign owner’s wallet has sufficient SOL for transaction fees.
  4. Sufficient USDC Balance: The campaign’s rewards pool must have enough USDC to cover the payouts.

Process Overview

  1. Retrieve Merchant Campaigns: Use the SoyCap.io API to fetch the merchant campaigns.
  2. Fetch Referral Links: Use the SoyCap.io API to fetch referral links for each campaign.
  3. Check Threshold and Fetch Conversions: For referral links with rewardsPendingUSDC exceeding the threshold, fetch conversions.
  4. Filter Unpaid Conversions: Filter conversions with status equal to 0 (unpaid).
  5. Distribute Rewards: Use the SoyCap.io API to get reward distribution transaction details and sign and send the transactions.
  6. Automate with Cron Job: Schedule the script using cron to execute at regular intervals.

Let’s begin by creating some helpful functions.

Step 1: Retrieve Merchant Campaigns

You can use SoyCap.io API merchants/:merchantId/campaigns endpoint get all merchant campaigns.

const fetchMerchantCampaigns = async (merchantId, token) => {
const url = `https://soycap.io/merchants/${merchantId}/campaigns`;
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
if (!response.ok) {
throw new Error('Failed to fetch merchant campaigns');
}
return response.json(); // Returns an array of campaigns
};

You can use SoyCap.io API campaigns/:campaignId/referrals endpoint get all campaign referral links.

const fetchReferralLinks = async (campaignId, token) => {
const url = `https://soycap.io/campaigns/${campaignId}/referrals`;
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
if (!response.ok) {
throw new Error('Failed to fetch referral links');
}
return response.json(); // Returns an array of referral links
};

You can use SoyCap.io API referrals/:referralId/conversions/unpaid endpoint get all unpaid conversions for referral link.

const fetchUnpaidReferralConversions = async (campaignId, referralId, token) => {
const url = `https://soycap.io/referrals/${referralId}/conversions/unpaid`;
const response = await fetch(url, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
if (!response.ok) {
throw new Error('Failed to fetch referral conversions');
}
const conversions = await response.json();
};

Step 4: Automate Distribution with Cron Job

Install the node-cron package for scheduling:

Terminal window
npm install node-cron

Once fetching merchant campaigns and filter referrals based on rewards threshold, iterate over all unpaid conversions and use getRewardDistributionTransactionInstruction() and signAndSendTransaction() functions provided in the Reward Distribution Guide.

Here’s the complete threshold-based reward distribution script scheduled to run daily:

import cron from 'node-cron';
import { Connection, clusterApiUrl } from '@solana/web3.js';
const connection = new Connection(clusterApiUrl('mainnet'), 'confirmed');
const distributeThresholdBasedRewards = async () => {
try {
console.log('Starting daily threshold-based reward distribution...');
const authToken = 'YOUR_AUTH_TOKEN';
const merchantId = 'YOUR_MERCHANT_ID';
const publicKey = 'YOUR_PUBLIC_KEY';
const keypair = loadKeypair(); // Load the keypair securely
const rewardThreshold = 100; // Set your threshold value (in USDC)
// Fetch merchant campaigns
const campaigns = await fetchMerchantCampaigns(merchantId, authToken);
for (const campaign of campaigns) {
// Fetch referral links
const referralLinks = await fetchReferralLinks(campaign.id, authToken);
for (const referral of referralLinks) {
if (referral.rewardsPendingUSDC > rewardThreshold) {
// Fetch unpaid conversions for this referral link
const unpaidConversions = await fetchUnpaidReferralConversions(campaign.id, referral.id, authToken);
for (const conversion of unpaidConversions) {
// Prepare transaction instruction
const txnInstruction = await getRewardDistributionTransactionInstruction(
campaign.id,
conversion.id,
publicKey,
authToken
);
// Sign and send transaction
const txnSignature = await signAndSendTransaction(txnInstruction.instruction, keypair, connection);
console.log(`Distributed reward for conversion ${conversion.id}: ${txnSignature}`);
}
}
}
}
console.log('Daily threshold-based reward distribution completed successfully.');
} catch (error) {
console.error('Error in daily threshold-based reward distribution:', error);
}
};
// Schedule the task to run daily at midnight
cron.schedule('0 0 * * *', distributeThresholdBasedRewards);