Skip to content

Conversion Registration

This guide explains how to programmatically register a conversion with SoyCap.io, which is essential for tracking conversions associated with your affiliate campaigns. The process involves retrieving transaction details via the SoyCap.io API and then signing the transaction using the campaign owner’s keypair using @solana/web3.js.

Prerequisites

  1. Merchant Authentication: Ensure you have an auth_token by authenticating your merchant with the /merchants/authenticate endpoint. This token will be required to authorize the SoyCap.io API requests.
  2. Campaign Owner’s Keypair: The campaign owner’s keypair must be securely loaded and ready to sign the transaction.
  3. Positive SOL balance on campaign owner’s wallet.

Process Overview

The process for registering a conversion with SoyCap.io involves the following steps:

  1. Retrieve Conversion Transaction Details: Use the SoyCap.io API to fetch transaction instructions for registering a conversion. These details are required to create an on-chain transaction.
  2. Extract Metadata: Parse the metadata returned by the API to retrieve key identifiers, such as the campaignId, referralId, and newly created conversionId.
  3. Sign and Send Transaction: Use Solana’s @solana/web3.js library to sign and submit the transaction to the blockchain using the campaign owner’s keypair.
  4. Optional: Update Conversion Business Value: For more accurate representation of the campaign performance (ROI), the conversion’s business value (eg. gross revenue) can be updated post-registration.

Step 1: Get Register Conversion Transaction Details

With the auth_token, request transaction details from SoyCap.io’s /conversions/onchain/create endpoint. This information is needed to construct the on-chain transaction for conversion registration.

Endpoint: /conversions/onchain/create/:referralId/:publicKey/:amount

  • referralId: The ID of the referral associated with the conversion extracted from affiliate attribution.
  • publicKey: The public key of the merchant’s keypair.
  • amount: The reward amount in USDC.
const getRegisterConversionTransactionInstruction = async (referralId, amount, publicKey, token) => {
const requestUrl = `${apiUrl}/conversions/onchain/create/${referralId}/${publicKey}/${amount}`;
const response = await fetch(requestUrl, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
});
if (!response.ok) {
const errorResponse = await response.json();
throw new Error(`Error: ${errorResponse.error} - ${errorResponse.message}`);
}
const data = await response.json();
return data; // Contains transaction instruction and metadata
};
// Usage
const referralId = '01JA2SZ20RX8WWGX1360HVPKMD';
const amount = 2; // Reward amount in USDC
const transactionData = await getRegisterConversionTransactionInstruction(referralId, amount, publicKey, auth_token);

Step 2. Extract New Conversion Details

The result of the getRegisterConversionTransactionInstruction function (transactionData object above) will be returned in the following format:

Terminal window
{
instruction: {
keys: [ [Object], [Object], [Object], [Object], [Object] ],
programId: '9Tp67R...N4Tstu86snaYw',
data: [
120, 28, 123, 9, 31, 138, 104, 59, 26, 0, 0, 0,
48, 49, 74, 67, 77, 75, 49, 50, 82, 83, 52, 65,
53, 80, 81, 80, 70, 67, 83, 89, 68, 69, 52, 72,
68, 84, 26, 0, 0, 0, 48, 49, 74, 65, 50, 83,
90, 50, 48, 82, 88, 56, 87, 87, 71, 88, 49, 51,
54, 48, 72, 86, 80, 75, 77, 68, 26, 0, 0, 0,
48, 49, 74, 65, 50, 83, 88, 81, 71, 80, 49, 90,
52, 88, 77, 82, 52, 77, 88, 84, 89, 90, 71, 67,
55, 54, 0, 148,
... 6 more items
]
},
metadata: {
campaignId: '01JA2SXQGP1Z4XMR4MXTYZGC76',
referralId: '01JA2SZ20RX8WWGX1360HVPKMD',
conversionId: '01JCMK12RS4A5PQPFCSYDE4HDT'
}
}

You can get the following details from it’s transactionData.metadata node:

  • campaignId - campaign that conversion will be registered for (shall be same as per conversion affiliate attribution)
  • referralId - referral link that conversion will be registered for (shall be same as per conversion affiliate attribution)
  • conversionId - new conversion id that shall be created (once transaction is signed and confirmed)

Step 3: Sign and Send the Transaction

Once you have the transaction details, use the Solana @solana/web3.js library to sign and send the transaction on-chain. The transaction should be signed by the campaign owner’s keypair. That will create conversion on blockchain and (after some delay) in SoyCap.io offchain DB.

import { Connection, sendAndConfirmTransaction, Transaction, TransactionInstruction } from '@solana/web3.js';
const connection = new Connection(clusterApiUrl('mainnet'), 'confirmed');
const signAndSendTransaction = async (txnInstruction, keypair) => {
const { blockhash } = await connection.getLatestBlockhash();
const feePayer = keypair.publicKey;
const instruction = new TransactionInstruction({
keys: txnInstruction.keys.map(key => ({
pubkey: new PublicKey(key.pubkey),
isSigner: key.isSigner,
isWritable: key.isWritable,
})),
programId: new PublicKey(txnInstruction.programId),
data: Buffer.from(txnInstruction.data)
});
const transaction = new Transaction().add(instruction);
transaction.feePayer = feePayer;
transaction.recentBlockhash = blockhash;
const signature = await sendAndConfirmTransaction(connection, transaction, [keypair]);
return signature;
};
// Usage
const keypair = loadKeypair(); // Ensure the keypair is securely loaded
const txnSignature = await signAndSendTransaction(transactionData.instruction, keypair);
console.log('Transaction successful with signature:', txnSignature);
// Now you can store new conversion details in your DB or update conversion businessValue
console.log('New conversion details:', transactionData.metadata);

Step 4: Update Conversion Business Value (Optional)

The /conversions/:conversionId/value API endpoint allows you to update the business value (eg. gross revenue) of a specific conversion. This is particularly useful for campaign ROI calculations, as it ensures that conversions are accurately valued based on real business impact. For instance, if a sale amount is dynamically determined after the initial conversion is logged, this endpoint can be used to update the value, providing a more accurate representation of campaign performance.

const updateConversionBusinessValue = async (conversionId, newValue, token) => {
const url = `https://soycap.io/conversions/${conversionId}/value`;
const response = await fetch(url, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify({
businessValue: newValue,
}),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Failed to update conversion value: ${error.message}`);
}
const updatedConversion = await response.json();
return updatedConversion; // Returns the updated conversion object
};
// Example usage based on transactionData.metadata details
const updatedConversion = await updateConversionBusinessValue(transactionData.metadata.conversionId, businessValue, authToken)