Skip to main content

Completing KYC and enabling funds flow

When users are ready to add funds or pay for purchases using wallets, they'll need to complete KYC verification to unlock full banking features.

User Attempts Transaction → KYC Prompt → Verification → Full Access

What Triggers KYC requirements

KYC is required when users attempt:

  • Depositing money into the wallet
  • Making a purchase
  • Any actual money movement

The Verification Process

Once triggered, the verification process follows these steps:

  1. Accept required disclosures
  2. Provide identity information (DOB and mailing address)
  3. Automated approval (usually immediate)
  4. Full banking features unlocked

Implementation Guide

Step 1: Complete KYC (When Needed)

KYC is only required when users want to move money. Move is move either to pay for goods and service or to add cash value to the wallet. Here's how to handle that transition:

Detecting When KYC is Needed

async function attemptMoneyMovement(userId, operation) {
try {
// Try the operation
const result = await performOperation(userId, operation);
return result;
} catch (error) {
if (error.code === 'InvalidKycStatus') {
// User needs KYC
return {
requiresKyc: true,
message: 'Complete verification to continue',
action: 'SHOW_KYC_PROMPT'
};
}
throw error;
}
}

Starting KYC Verification

Endpoint: POST /api/v1/users/:userId/disclosures/kyc

async function startKycProcess(userId) {
// Step 1: Accept disclosures (required by regulations)
await fetch(
`${API_CONFIG.baseUrl}/api/v1/users/${userId}/disclosures/kyc`,
{
method: 'POST',
headers: API_CONFIG.headers
}
);

// Step 2: User completes KYC in wallet interface
// You'll receive webhooks about status changes

return {
status: 'KYC_INITIATED',
nextStep: 'User will complete verification in wallet'
};
}

Step 2: Monitor Status with Webhooks

Instead of polling, use webhooks for real-time updates:

// Webhook handler
app.post('/webhooks/accrue', async (req, res) => {
const signature = req.headers['x-accrue-signature'];
if (!verifySignature(req.body, signature)) {
return res.status(401).send();
}

const event = req.body;
const userId = event.included[0].id;

switch (event.attributes.topic) {
case 'ApplicationApproved':
// Enable banking features in your UI
await markUserAsVerified(userId);
await notifyUser(userId, 'Verification complete! You can now fund your wallet.');
break;

case 'ApplicationAwaitingDocuments':
// Prompt for document upload
await notifyUser(userId, 'Please upload your ID to complete verification.');
break;

case 'ApplicationDeclined':
// Handle denial
await handleKycDenial(userId);
break;
}

res.status(200).send();
});

Understanding Wallet Balances

The wallet balance structure provides detailed accounting information. See the Understanding Wallet Balances reference guide for:

  • Complete balance structure breakdown
  • Available, pending, and reserved balance explanations
  • Conversion examples for display formatting

Endpoint: GET /api/v1/users/:userId/wallet-balance

KYC Status Reference

Track where users are in the verification process. See the KYC Status Reference guide for:

  • Complete status table with descriptions
  • Status flow and transitions
  • Appropriate actions for each status
  • Webhook monitoring examples

Complete Integration Example

See an implementation combining all concepts in the Complete Integration Example page:

  • Full AccrueOnboarding class implementation
  • Two-phase onboarding strategy
  • Webhook handling and error management
  • Integration points and best practices

Best Practices

Design Principles

Progressive Disclosure Don't overwhelm users upfront. Let them explore and build value before asking for verification.

Clear Value Proposition Show users what they're building toward. Display locked features with "Verify to unlock" messaging.

Smart Prompting Only prompt for KYC when users try to move money, not during initial setup.

Error Handling

const errorHandlers = {
UserAlreadyExists: async (email) => {
// User exists - fetch and continue
return await findExistingUser(email);
},

InvalidKycStatus: () => ({
requiresKyc: true,
message: 'Verification required for this action'
}),

WalletAlreadyExists: () => ({
success: true,
message: 'Wallet ready'
})
};

Common Questions

Q: How long does KYC approval take? A: Most applications are approved in seconds through automated verification. Complex cases requiring manual review may take 1-3 business days.

Q: What happens to rewards if KYC is denied? A: Users retain their rewards but cannot convert them to spendable funds or make purchases until KYC is approved.

Q: Can KYC be retried after denial? A: Yes, users can typically reapply with corrected information, though specific policies depend on the denial reason.

Next Steps

You're now ready to: