{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading"]},"type":"markdown"},"seo":{"title":"Compliance","description":"Transform your commerce with PXP's unified platform—seamless payments, real-time insights, and global growth in one powerful integration.","lang":"en-UK","siteUrl":"https://developer.pxp.io","llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"compliance","__idx":0},"children":["Compliance"]},{"$$mdtype":"Tag","name":"SubHeading","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Ensure regulatory compliance for PayPal payouts in your Android app."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When implementing PayPal payouts, you must comply with various financial regulations, data protection laws, and industry standards. This guide outlines key compliance considerations for your Android application."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"financial-regulations","__idx":2},"children":["Financial regulations"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"know-your-customer-kyc","__idx":3},"children":["Know Your Customer (KYC)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Verify customer identity before enabling payouts:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"fun enablePayouts(customerId: String): Boolean {\n    // Check KYC verification status\n    val kycStatus = checkKYCStatus(customerId)\n    \n    return when (kycStatus) {\n        KYCStatus.VERIFIED -> {\n            // Customer is verified, enable payouts\n            true\n        }\n        KYCStatus.PENDING -> {\n            showMessage(\"Identity verification in progress\")\n            false\n        }\n        KYCStatus.NOT_VERIFIED -> {\n            showMessage(\"Please complete identity verification to enable payouts\")\n            redirectToKYCFlow()\n            false\n        }\n        KYCStatus.FAILED -> {\n            showMessage(\"Identity verification failed. Please contact support\")\n            false\n        }\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"anti-money-laundering-aml","__idx":4},"children":["Anti-Money Laundering (AML)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement AML checks and monitoring:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"data class AMLCheck(\n    val transactionAmount: Double,\n    val dailyTotal: Double,\n    val monthlyTotal: Double,\n    val customerRiskScore: Int\n)\n\nfun performAMLCheck(\n    customerId: String,\n    amount: Double\n): AMLCheckResult {\n    val dailyTotal = getTodayPayoutTotal(customerId)\n    val monthlyTotal = getMonthlyPayoutTotal(customerId)\n    val riskScore = getCustomerRiskScore(customerId)\n    \n    return when {\n        // Flag large single transactions\n        amount > AML_LARGE_TRANSACTION_THRESHOLD -> {\n            AMLCheckResult.REVIEW_REQUIRED\n        }\n        // Flag unusual pattern\n        dailyTotal + amount > AML_DAILY_LIMIT -> {\n            AMLCheckResult.LIMIT_EXCEEDED\n        }\n        // Flag high-risk customers\n        riskScore > AML_HIGH_RISK_THRESHOLD -> {\n            AMLCheckResult.HIGH_RISK_REVIEW\n        }\n        else -> {\n            AMLCheckResult.APPROVED\n        }\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"transaction-limits","__idx":5},"children":["Transaction limits"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Enforce regulatory transaction limits:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"data class TransactionLimits(\n    val minAmount: Double = 1.0,\n    val maxSingleTransaction: Double = 10000.0,\n    val maxDailyAmount: Double = 25000.0,\n    val maxMonthlyAmount: Double = 100000.0\n)\n\nfun validateTransactionLimits(\n    customerId: String,\n    amount: Double\n): ValidationResult {\n    val limits = getCustomerLimits(customerId)\n    val dailyTotal = getTodayPayoutTotal(customerId)\n    val monthlyTotal = getMonthlyPayoutTotal(customerId)\n    \n    return when {\n        amount < limits.minAmount -> ValidationResult(\n            isValid = false,\n            message = \"Minimum payout amount is ${limits.minAmount}\"\n        )\n        amount > limits.maxSingleTransaction -> ValidationResult(\n            isValid = false,\n            message = \"Maximum single payout is ${limits.maxSingleTransaction}\"\n        )\n        dailyTotal + amount > limits.maxDailyAmount -> ValidationResult(\n            isValid = false,\n            message = \"Daily limit of ${limits.maxDailyAmount} would be exceeded\"\n        )\n        monthlyTotal + amount > limits.maxMonthlyAmount -> ValidationResult(\n            isValid = false,\n            message = \"Monthly limit of ${limits.maxMonthlyAmount} would be exceeded\"\n        )\n        else -> ValidationResult(isValid = true)\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"data-protection","__idx":6},"children":["Data protection"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"gdpr-compliance","__idx":7},"children":["GDPR compliance"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement proper data handling for European customers:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"// Data retention policy\ndata class DataRetentionPolicy(\n    val payoutRecordsRetentionDays: Int = 2555,  // 7 years for financial records\n    val personalDataRetentionDays: Int = 365     // 1 year after last activity\n)\n\n// Right to be forgotten\nfun handleDataDeletionRequest(customerId: String) {\n    // Verify customer identity\n    val verified = verifyCustomerIdentity(customerId)\n    if (!verified) {\n        throw SecurityException(\"Identity verification failed\")\n    }\n    \n    // Check if data must be retained for legal reasons\n    val hasActiveFinancialObligations = checkFinancialObligations(customerId)\n    if (hasActiveFinancialObligations) {\n        throw IllegalStateException(\"Cannot delete data with active financial obligations\")\n    }\n    \n    // Anonymise personal data\n    anonymizePersonalData(customerId)\n    \n    // Retain transaction records as required by law\n    retainFinancialRecords(customerId)\n    \n    Log.i(\"Compliance\", \"Data deletion request processed for customer: $customerId\")\n}\n\n// Data export (right to data portability)\nfun exportCustomerData(customerId: String): CustomerDataExport {\n    return CustomerDataExport(\n        customerId = customerId,\n        personalInfo = getPersonalInfo(customerId),\n        payoutHistory = getPayoutHistory(customerId),\n        walletDetails = getWalletDetails(customerId),\n        exportDate = System.currentTimeMillis()\n    )\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"secure-data-storage","__idx":8},"children":["Secure data storage"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Never store sensitive payment data:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"// Good: Store only necessary identifiers\ndata class StoredWalletData(\n    val customerId: String,\n    val walletType: String,           // \"PayPal\" (Venmo has limited support on Android)\n    val paypalPayerId: String?,       // PayPal payer ID (not email)\n    val lastFourDigits: String?,      // Last 4 digits for display only\n    val linkedAt: Long,\n    val lastUsedAt: Long?\n)\n\n// Bad: Never store full email addresses or sensitive data\n// ❌ Don't do this:\ndata class BadWalletData(\n    val fullEmailAddress: String,      // Don't store\n    val fullPhoneNumber: String,       // Don't store\n    val fullName: String               // Don't store unless necessary\n)\n\n// Implement encryption for stored data\nfun storeWalletData(data: StoredWalletData) {\n    val encryptedData = encrypt(data.toJson())\n    secureStorage.store(\"wallet_${data.customerId}\", encryptedData)\n}\n\nfun retrieveWalletData(customerId: String): StoredWalletData? {\n    val encryptedData = secureStorage.retrieve(\"wallet_$customerId\") ?: return null\n    val json = decrypt(encryptedData)\n    return StoredWalletData.fromJson(json)\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"security-requirements","__idx":9},"children":["Security requirements"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"secure-communication","__idx":10},"children":["Secure communication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Ensure all API communication is encrypted:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"// Enforce TLS 1.2 or higher\nval okHttpClient = OkHttpClient.Builder()\n    .connectionSpecs(listOf(\n        ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)\n            .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3)\n            .build()\n    ))\n    .build()\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"certificate-pinning","__idx":11},"children":["Certificate pinning"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement certificate pinning for enhanced security:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val certificatePinner = CertificatePinner.Builder()\n    .add(\"api.pxp.io\", \"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\")\n    .build()\n\nval okHttpClient = OkHttpClient.Builder()\n    .certificatePinner(certificatePinner)\n    .build()\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"authentication","__idx":12},"children":["Authentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement proper authentication for payout operations:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"fun authenticatePayoutRequest(\n    customerId: String,\n    amount: Double\n): AuthResult {\n    // Require authentication for payouts above threshold\n    if (amount > AUTHENTICATION_REQUIRED_THRESHOLD) {\n        return requireBiometricAuthentication()\n    }\n    \n    // Require session validation\n    if (!isSessionValid(customerId)) {\n        return AuthResult.SESSION_EXPIRED\n    }\n    \n    // Verify device fingerprint\n    if (!verifyDeviceFingerprint(customerId)) {\n        return AuthResult.DEVICE_NOT_RECOGNIZED\n    }\n    \n    return AuthResult.AUTHENTICATED\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"record-keeping","__idx":13},"children":["Record keeping"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"transaction-logging","__idx":14},"children":["Transaction logging"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Maintain comprehensive transaction logs:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"data class PayoutAuditLog(\n    val merchantTransactionId: String,\n    val systemTransactionId: String,\n    val customerId: String,\n    val amount: Double,\n    val currency: String,\n    val recipientWallet: String,\n    val status: String,\n    val initiatedAt: Long,\n    val completedAt: Long?,\n    val failureReason: String?,\n    val ipAddress: String,\n    val deviceId: String,\n    val userAgent: String\n)\n\nfun logPayoutTransaction(\n    result: PostPayoutResult?,\n    error: PayOutError?,\n    metadata: TransactionMetadata\n) {\n    val log = PayoutAuditLog(\n        merchantTransactionId = metadata.merchantTransactionId,\n        systemTransactionId = result?.systemTransactionId ?: \"N/A\",\n        customerId = metadata.customerId,\n        amount = metadata.amount,\n        currency = metadata.currency,\n        recipientWallet = metadata.recipientWallet,\n        status = if (result != null) \"SUCCESS\" else \"FAILED\",\n        initiatedAt = metadata.initiatedAt,\n        completedAt = System.currentTimeMillis(),\n        failureReason = error?.errorReason,\n        ipAddress = metadata.ipAddress,\n        deviceId = metadata.deviceId,\n        userAgent = metadata.userAgent\n    )\n    \n    // Store in secure audit log\n    auditLogRepository.save(log)\n    \n    // Send to monitoring system\n    monitoringService.recordTransaction(log)\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"audit-trail","__idx":15},"children":["Audit trail"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Maintain a complete audit trail:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"sealed class AuditEvent {\n    data class PayoutInitiated(\n        val transactionId: String,\n        val amount: Double,\n        val customerId: String\n    ) : AuditEvent()\n    \n    data class PayoutApproved(\n        val transactionId: String,\n        val approvedBy: String\n    ) : AuditEvent()\n    \n    data class PayoutCompleted(\n        val transactionId: String,\n        val systemTransactionId: String\n    ) : AuditEvent()\n    \n    data class PayoutFailed(\n        val transactionId: String,\n        val errorCode: String,\n        val errorReason: String\n    ) : AuditEvent()\n}\n\nfun recordAuditEvent(event: AuditEvent) {\n    val auditRecord = AuditRecord(\n        eventType = event::class.simpleName ?: \"Unknown\",\n        eventData = event.toJson(),\n        timestamp = System.currentTimeMillis(),\n        userId = getCurrentUserId(),\n        sessionId = getCurrentSessionId()\n    )\n    \n    auditTrailRepository.save(auditRecord)\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"user-consent","__idx":16},"children":["User consent"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"terms-of-service","__idx":17},"children":["Terms of service"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Require explicit consent before enabling payouts:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"@Composable\nfun PayoutConsentScreen(onAccept: () -> Unit, onDecline: () -> Unit) {\n    var acceptedTerms by remember { mutableStateOf(false) }\n    var acceptedPrivacy by remember { mutableStateOf(false) }\n    \n    Column(\n        modifier = Modifier\n            .fillMaxSize()\n            .padding(16.dp)\n    ) {\n        Text(\n            text = \"Payout Terms and Conditions\",\n            style = MaterialTheme.typography.headlineMedium\n        )\n        \n        // Terms content\n        ScrollableTermsContent()\n        \n        // Consent checkboxes\n        Row(verticalAlignment = Alignment.CenterVertically) {\n            Checkbox(\n                checked = acceptedTerms,\n                onCheckedChange = { acceptedTerms = it }\n            )\n            Text(\"I accept the payout terms and conditions\")\n        }\n        \n        Row(verticalAlignment = Alignment.CenterVertically) {\n            Checkbox(\n                checked = acceptedPrivacy,\n                onCheckedChange = { acceptedPrivacy = it }\n            )\n            Text(\"I consent to data processing for payouts\")\n        }\n        \n        // Action buttons\n        Row(\n            modifier = Modifier.fillMaxWidth(),\n            horizontalArrangement = Arrangement.spacedBy(8.dp)\n        ) {\n            Button(\n                onClick = onDecline,\n                modifier = Modifier.weight(1f)\n            ) {\n                Text(\"Decline\")\n            }\n            \n            Button(\n                onClick = {\n                    if (acceptedTerms && acceptedPrivacy) {\n                        recordConsent()\n                        onAccept()\n                    }\n                },\n                enabled = acceptedTerms && acceptedPrivacy,\n                modifier = Modifier.weight(1f)\n            ) {\n                Text(\"Accept\")\n            }\n        }\n    }\n}\n\nfun recordConsent() {\n    val consent = ConsentRecord(\n        customerId = getCurrentCustomerId(),\n        consentType = \"PAYOUT_TERMS\",\n        version = \"1.0\",\n        acceptedAt = System.currentTimeMillis(),\n        ipAddress = getClientIpAddress(),\n        userAgent = getUserAgent()\n    )\n    \n    consentRepository.save(consent)\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"regional-requirements","__idx":18},"children":["Regional requirements"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"country-specific-regulations","__idx":19},"children":["Country-specific regulations"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement country-specific compliance:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"fun getCountrySpecificRequirements(countryCode: String): ComplianceRequirements {\n    return when (countryCode) {\n        \"US\" -> ComplianceRequirements(\n            requiresSSN = true,\n            requiresTaxId = true,\n            maxSingleTransaction = 10000.0,\n            requiresBankVerification = true\n        )\n        \"GB\" -> ComplianceRequirements(\n            requiresSortCode = true,\n            requiresFCA_Compliance = true,\n            maxSingleTransaction = 8000.0\n        )\n        \"DE\" -> ComplianceRequirements(\n            requiresGDPR_Compliance = true,\n            requiresBaFin_Compliance = true,\n            maxSingleTransaction = 15000.0\n        )\n        else -> ComplianceRequirements.default()\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"compliance-checklist","__idx":20},"children":["Compliance checklist"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Before launching payouts:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["KYC verification implemented"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["AML checks in place"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Transaction limits enforced"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["GDPR compliance implemented (if applicable)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Data encryption enabled"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Secure communication (TLS 1.2+)"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Certificate pinning implemented"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Authentication required for payouts"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Transaction logging comprehensive"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Audit trail maintained"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["User consent obtained"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Terms of service accepted"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Privacy policy accepted"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Country-specific requirements met"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Legal review completed"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Security audit passed"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Penetration testing completed"]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"whats-next","__idx":21},"children":["What's next?"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paypal/payouts/testing"},"children":["Testing"]},": Test compliance requirements."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paypal/payouts/data-validation"},"children":["Data validation"]},": Understand validation rules."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paypal/payouts/troubleshooting"},"children":["Troubleshooting"]},": Debug compliance issues."]}]}]},"headings":[{"value":"Compliance","id":"compliance","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Financial regulations","id":"financial-regulations","depth":2},{"value":"Know Your Customer (KYC)","id":"know-your-customer-kyc","depth":3},{"value":"Anti-Money Laundering (AML)","id":"anti-money-laundering-aml","depth":3},{"value":"Transaction limits","id":"transaction-limits","depth":3},{"value":"Data protection","id":"data-protection","depth":2},{"value":"GDPR compliance","id":"gdpr-compliance","depth":3},{"value":"Secure data storage","id":"secure-data-storage","depth":3},{"value":"Security requirements","id":"security-requirements","depth":2},{"value":"Secure communication","id":"secure-communication","depth":3},{"value":"Certificate pinning","id":"certificate-pinning","depth":3},{"value":"Authentication","id":"authentication","depth":3},{"value":"Record keeping","id":"record-keeping","depth":2},{"value":"Transaction logging","id":"transaction-logging","depth":3},{"value":"Audit trail","id":"audit-trail","depth":3},{"value":"User consent","id":"user-consent","depth":2},{"value":"Terms of service","id":"terms-of-service","depth":3},{"value":"Regional requirements","id":"regional-requirements","depth":2},{"value":"Country-specific regulations","id":"country-specific-regulations","depth":3},{"value":"Compliance checklist","id":"compliance-checklist","depth":2},{"value":"What's next?","id":"whats-next","depth":2}],"frontmatter":{"seo":{"title":"Compliance"}},"lastModified":"2026-02-26T12:14:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/android/paypal/payouts/compliance","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}