Promo Code Methods

Let users enter referral codes manually in your app

Overview

Promo code methods allow users to enter influencer codes manually (not just via links). This is useful when influencers share codes verbally on podcasts, YouTube videos, or social media posts.

Available Methods

  • getPrefilledCode() - Get code if user came via link
  • validateCode(code) - Check if code is valid
  • setReferralCode(code) - Apply a code
  • applyCode(code) - Validate + apply in one step
  • checkAccess() - Server-authoritative free-access check (comp codes)

getPrefilledCode()

Get referral code if user came via attribution link

Returns

Promise<string | null>

Example

// User clicked: https://influ.to/yourapp/FITGURU30

const prefilled = await InfluTo.getPrefilledCode();

if (prefilled) {
  console.log('Code from link:', prefilled);  // "FITGURU30"
  setInputValue(prefilled);  // Pre-fill your input
} else {
  console.log('No prefilled code');
}

Use Cases

  • Pre-fill promo code input if user clicked a link
  • Show "Code detected from your link" message
  • Auto-validate prefilled codes

validateCode(code)

Validate a promo code without applying it

Parameters

code: string - The promo code to validate

Returns

Promise<CodeValidationResult>

interface CodeValidationResult {
  valid: boolean                   // Is code valid?
  code?: string                   // Normalized code (uppercase)
  campaign?: {
    id: string
    name: string
    description?: string
    commission_percentage: number
    campaign_type: string
  }
  influencer?: {
    name: string
    social_handle?: string
    follower_count?: number
  }
  message?: string                // Success message
  error?: string                  // Error message if invalid
  error_code?: 'INVALID_FORMAT' | 'CODE_NOT_FOUND' | 'NETWORK_ERROR'
}

Example - Valid Code

const result = await InfluTo.validateCode('FITGURU30');

if (result.valid) {
  console.log('Campaign:', result.campaign.name);
  // "Fitness Influencer Program"

  console.log('Commission:', result.campaign.commission_percentage + '%');
  // "30%"

  console.log('Influencer:', result.influencer.name);
  // "John Doe"

  console.log('Social:', result.influencer.social_handle);
  // "@fitguru"

  // Show custom offer based on campaign
  if (result.campaign.commission_percentage >= 30) {
    showPremiumOffer();
  } else {
    showStandardOffer();
  }
}

Example - Invalid Code

const result = await InfluTo.validateCode('INVALID99');

if (!result.valid) {
  console.log('Error:', result.error);
  // "Code not found or inactive"

  console.log('Error code:', result.error_code);
  // "CODE_NOT_FOUND"

  Alert.alert('Invalid Code', result.error);
}

Error Codes

  • INVALID_FORMAT - Code too short/long (4-20 chars required)
  • CODE_NOT_FOUND - Code doesn't exist or campaign ended
  • NETWORK_ERROR - Connection issue

setReferralCode(code, appUserId?)

Apply a referral code manually

Parameters

code: string           // Required: Referral code to set
appUserId?: string     // Optional: User ID if available

Returns

Promise<SetCodeResult>

interface SetCodeResult {
  success: boolean
  code?: string
  message: string
  campaign?: {
    id: string
    name: string
  }
}

What It Does

  1. Stores code locally (AsyncStorage)
  2. Sets in RevenueCat attributes automatically
  3. Records attribution with backend
  4. Future purchases will be attributed

Example

const result = await InfluTo.setReferralCode('FITGURU30', userId);

if (result.success) {
  console.log('Code applied:', result.code);
  // "FITGURU30"

  console.log('Campaign:', result.campaign.name);
  // "Fitness Program"

  // ✅ SDK automatically called:
  // await Purchases.setAttributes({ influto_code: 'FITGURU30' });

  showSuccessMessage('Code applied!');
} else {
  Alert.alert('Error', result.message);
}

applyCode(code, appUserId?)

Validate and apply code in one step (convenience method)

Parameters

code: string           // Required: Code to validate and apply
appUserId?: string     // Optional: User ID

Returns

Promise<CodeValidationResult & { applied?: boolean }>

Example

// One-step validation + application
const result = await InfluTo.applyCode('FITGURU30', userId);

if (result.valid && result.applied) {
  // Code validated AND applied successfully!
  console.log('Campaign:', result.campaign.name);
  console.log('Commission:', result.campaign.commission_percentage + '%');
  console.log('Influencer:', result.influencer?.name);

  // Show appropriate paywall
  navigation.navigate('Paywall', { campaign: result.campaign });
} else if (!result.valid) {
  Alert.alert('Invalid Code', result.error);
} else {
  Alert.alert('Error', 'Failed to apply code');
}

When to Use

  • Use applyCode(): When you want simple one-step application
  • Use validateCode() + setReferralCode(): When you need separate validation (e.g., show campaign info before applying)

Creator Access Codes & Comp (Free Access)

The same input that accepts influencer referral codes also redeems free-access (comp) codes: platform-issued creator codes (INFLU-…) and comp codes you mint yourself. No separate flow —applyCode() / setReferralCode() handle both, and the response tells you when a code grants free access.

Redemption Response (comp codes)

const result = await InfluTo.applyCode('INFLU-48291', userId);

if (result.applied && result.free_access) {
  console.log('Grants access:', result.grants_access);  // true
  console.log('Entitlement:', result.entitlement);      // e.g. "pro"
  console.log('Expires:', result.expires_at);           // ISO date or null

  unlockPremium();  // Unlock immediately — no purchase needed
}

// result.rc_grant — additive diagnostic for the OPTIONAL RevenueCat mirror:
// { attempted: boolean, ok: boolean, error?: string }
// Native access is granted regardless of rc_grant.ok.

Gating Premium: the OR-Gate with checkAccess()

Comp access is server-authoritative: checkAccess() answers from InfluTo's database (GET /sdk/access), so it works for RevenueCat AND store-direct apps with zero extra config. The recommended premium gate:

const access = await InfluTo.checkAccess(userId);

const isPremium = hasStoreEntitlement || access.hasAccess;
//                ^ RevenueCat entitlement or store receipt
//                                       ^ InfluTo comp access
  • Positive results are cached ~5 minutes client-side; negative results are never cached
  • Comp access survives logout (the cache is not cleared by clearAttribution())
  • Seat caps and expiry are server-enforced — a blocked/expired code revokes access on the next checkAccess()

Gating Only on the RevenueCat Entitlement?

If comp grants are mirrored into your RevenueCat project as promotional entitlements and you gate only on the RC entitlement, note that Purchases.getCustomerInfo() may serve a cached result right after a successful grant. Call Purchases.invalidateCustomerInfoCache() (or your SDK's equivalent) after a comp redemption — or use the OR-gate above, which sidesteps the staleness entirely.

Platform-side setup (auto-issued INFLU- codes, the RC mirror config, troubleshooting): Creator Access Codes.

Complete Integration Examples

Example 1: Simple Integration

import InfluTo from '@influto/react-native-sdk';

function PromoCodeScreen() {
  const [code, setCode] = useState('');

  const handleSubmit = async () => {
    const result = await InfluTo.applyCode(code, userId);

    if (result.valid && result.applied) {
      navigation.navigate('Paywall');
    } else {
      Alert.alert('Invalid', result.error);
    }
  };

  return (
    <TextInput value={code} onChangeText={setCode} />
    <Button title="Apply" onPress={handleSubmit} />
  );
}

Example 2: With Pre-fill

function SmartPromoInput() {
  const [code, setCode] = useState('');
  const [isPrefilled, setIsPrefilled] = useState(false);

  useEffect(() => {
    async function loadPrefill() {
      const prefilled = await InfluTo.getPrefilledCode();

      if (prefilled) {
        setCode(prefilled);
        setIsPrefilled(true);
        // Optionally auto-validate
        await handleValidate(prefilled);
      }
    }

    loadPrefill();
  }, []);

  return (
    <>
      <TextInput value={code} onChangeText={setCode} />
      {isPrefilled && (
        <Text style={{color: 'green'}}>
          ✓ Code detected from your link
        </Text>
      )}
      <Button title="Apply" onPress={() => handleApply(code)} />
    </>
  );
}

Example 3: Conditional Offers

async function handleCodeEntry(code: string) {
  // Validate first
  const validation = await InfluTo.validateCode(code);

  if (validation.valid) {
    const commission = validation.campaign.commission_percentage;

    // Different offers based on campaign tier
    if (commission >= 40) {
      showVIPOffer(30);  // 30-day trial
    } else if (commission >= 30) {
      showPremiumOffer(14);  // 14-day trial
    } else {
      showStandardOffer(7);  // 7-day trial
    }

    // Apply the code
    await InfluTo.setReferralCode(code, userId);
  }
}

Testing Promo Codes

Get Test Codes

  1. Create a campaign in dashboard
  2. Add a test influencer
  3. Copy their referral code
  4. Use in your app

Verify Code is Set

// After applying code
const customerInfo = await Purchases.getCustomerInfo();
const attributes = customerInfo.entitlements.all;

console.log('Referral code in RC:', attributes.influto_code);
// Should match the code you entered

Next Steps

  1. Use pre-built ReferralCodeInput component
  2. View all TypeScript interfaces