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:
- Accept required disclosures
- Provide identity information (DOB and mailing address)
- Automated approval (usually immediate)
- 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
AccrueOnboardingclass 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:
- Complete Integration Example - See an implementation
- Understanding Wallet Balances - Reference for balance structure
- KYC Status Reference - Status codes and meanings
- Integrate the Wallet UI - Add the visual interface
- Implement Payments - Enable transactions
- Configure Webhooks - Set up real-time updates
- Explore Full API - View all available endpoints