{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","admonition","tabs","tab","br","details","required"]},"type":"markdown"},"seo":{"title":"Withdrawal flow","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":"withdrawal-flow","__idx":0},"children":["Withdrawal flow"]},{"$$mdtype":"Tag","name":"SubHeading","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Send payouts to returning customers using stored wallet details."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The withdrawal flow is designed for returning customers whose wallet details you already have stored. This provides a faster, streamlined experience — the customer simply reviews the payout details and confirms, without needing to log in again."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This flow uses the receiver and submission components together, displaying the stored wallet information and providing a \"Withdraw\" button."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"payout-flow","__idx":2},"children":["Payout flow"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The withdrawal flow consists of five key steps for returning customer payouts."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-display-payout-details","__idx":3},"children":["Step 1: Display payout details"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The customer sees their stored PayPal email displayed alongside the payout amount. The receiver component shows the wallet destination, optionally masked for privacy."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-2-submission","__idx":4},"children":["Step 2: Submission"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The customer taps the \"Withdraw with PayPal\" button. The SDK validates the payout configuration and stored wallet details before proceeding. If validation fails, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onError"]}," is triggered."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-3-payout-approval","__idx":5},"children":["Step 3: Payout approval"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPrePayoutSubmit"]}," callback is triggered, giving you the opportunity to show a confirmation dialog or perform additional validation before the payout executes."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PrePayoutSubmitResult(isApproved = true)"]}," to proceed with the payout, or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PrePayoutSubmitResult(isApproved = false)"]}," to cancel."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-4-payout-execution","__idx":6},"children":["Step 4: Payout execution"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For the SDK-initiated mode, the SDK automatically sends the payout request to the PXP Gateway. For merchant-initiated mode, your backend triggers the payout via API."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-5-payout-result","__idx":7},"children":["Step 5: Payout result"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostPayout"]}," callback receives the transaction result. You can display a success message and redirect the customer to a confirmation screen."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"implementation","__idx":8},"children":["Implementation"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"before-you-start","__idx":9},"children":["Before you start"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["To use the withdrawal flow for payouts:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Ensure your PayPal merchant account is onboarded with PXP."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Have sufficient funds in your gateway balance to cover payout amounts and fees."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-1-initialise-the-sdk","__idx":10},"children":["Step 1: Initialise the SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Set up your SDK configuration with wallet details to trigger the withdrawal flow."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"import com.pxp.checkout.PxpCheckout\nimport com.pxp.checkout.models.*\nimport java.util.UUID\n\nval pxpCheckout = PxpCheckout.builder()\n    .withConfig(\n        PxpSdkConfig(\n            environment = Environment.TEST, // or Environment.LIVE for production\n            session = sessionData,\n            ownerId = \"your-owner-id\",\n            ownerType = \"MerchantGroup\",\n            clientId = \"your-client-id\",\n            transactionData = TransactionData(\n                amount = 100.0,\n                currency = \"USD\",\n                merchant = \"your-merchant-id\",\n                entryType = EntryType.Ecom,\n                intent = TransactionIntentData(paypal = IntentType.Payout),\n                merchantTransactionId = UUID.randomUUID().toString(),\n                merchantTransactionDate = { System.currentTimeMillis() }\n            ),\n            paypalConfig = PaypalConfig(\n                payout = PayoutConfig(\n                    proceedPayoutWithSdk = true,\n                    paypalWallet = PayPalPayOutWalletConfig(\n                        email = \"customer@example.com\",  // Stored PayPal email\n                        payerId = \"PAYER_ID_XXX\"         // Required: stored payer ID\n                    )\n                )\n            )\n        )\n    )\n    .withContext(context)\n    .build()\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Admonition","attributes":{"type":"info"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Providing the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["paypalWallet"]}," property signals to the SDK that this is a returning customer with stored wallet details."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-2-create-the-components","__idx":11},"children":["Step 2: Create the components"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the amount, receiver, and submission components to build the withdrawal experience."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"import com.pxp.checkout.components.payoutamount.PayoutAmountComponentConfig\nimport com.pxp.checkout.components.paypalpayoutreceiver.PaypalPayoutReceiverComponentConfig\nimport com.pxp.checkout.components.payoutsubmission.PayoutSubmissionComponentConfig\nimport com.pxp.checkout.models.payout.PrePayoutSubmitResult\nimport com.pxp.checkout.types.ComponentType\n\n// Create the amount display component\nval amountComponent = pxpCheckout.createComponent(\n    type = ComponentType.PAYOUT_AMOUNT,\n    config = PayoutAmountComponentConfig(\n        label = \"Withdrawal Amount\"\n    )\n)\n\n// Create the PayPal receiver display component\nval receiverComponent = pxpCheckout.createComponent(\n    type = ComponentType.PAYPAL_PAYOUT_RECEIVER,\n    config = PaypalPayoutReceiverComponentConfig(\n        label = \"PayPal Account\",\n        showMaskToggle = true,  // Display a toggle to allow the customer to show or hide their full email\n        applyMask = true        // Start with masked email\n    )\n)\n\n// Create the submission button for PayPal\nval submitConfig = PayoutSubmissionComponentConfig(\n    recipientWallet = \"Paypal\",\n    \n    // OPTIONAL: Called before payout execution\n    onPrePayoutSubmit = {\n        val confirmed = showConfirmationDialog()\n        PrePayoutSubmitResult(isApproved = confirmed)\n    },\n    \n    // OPTIONAL: Called when the payout completes successfully\n    onPostPayout = { result ->\n        Log.d(\"Payout\", \"Payout successful: ${result.systemTransactionId}\")\n        showSuccessMessage(\"Your withdrawal has been processed!\")\n        navigateToSuccessScreen(result.merchantTransactionId)\n    },\n    \n    // OPTIONAL: Called on any error\n    onError = { error ->\n        Log.e(\"Payout\", \"Payout failed: ${error.errorReason}\")\n        showErrorMessage(\"Withdrawal failed. Please try again.\")\n    }\n)\n\nval submitComponent = pxpCheckout.createComponent(\n    type = ComponentType.PAYOUT_SUBMISSION,\n    config = submitConfig\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-3-render-the-components","__idx":12},"children":["Step 3: Render the components"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Compose the components in your UI using Jetpack Compose."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"import androidx.compose.foundation.layout.*\nimport androidx.compose.material3.*\nimport androidx.compose.runtime.*\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\n\n@Composable\nfun WithdrawalScreen() {\n    Surface(\n        modifier = Modifier.fillMaxSize(),\n        color = MaterialTheme.colorScheme.background\n    ) {\n        Column(\n            modifier = Modifier\n                .fillMaxSize()\n                .padding(16.dp),\n            verticalArrangement = Arrangement.spacedBy(16.dp)\n        ) {\n            Text(\n                text = \"Withdraw funds\",\n                style = MaterialTheme.typography.headlineMedium\n            )\n            \n            Text(\n                text = \"Review your withdrawal details below\",\n                style = MaterialTheme.typography.bodyMedium,\n                color = MaterialTheme.colorScheme.onSurfaceVariant\n            )\n            \n            Card(\n                modifier = Modifier.fillMaxWidth(),\n                colors = CardDefaults.cardColors(\n                    containerColor = MaterialTheme.colorScheme.surfaceVariant\n                )\n            ) {\n                Column(\n                    modifier = Modifier.padding(16.dp),\n                    verticalArrangement = Arrangement.spacedBy(12.dp)\n                ) {\n                    // Amount component\n                    pxpCheckout.buildComponentView(\n                        component = amountComponent,\n                        modifier = Modifier.fillMaxWidth()\n                    )\n                    \n                    Divider()\n                    \n                    // Receiver component\n                    pxpCheckout.buildComponentView(\n                        component = receiverComponent,\n                        modifier = Modifier.fillMaxWidth()\n                    )\n                    \n                    Divider()\n                    \n                    // Submit button\n                    pxpCheckout.buildComponentView(\n                        component = submitComponent,\n                        modifier = Modifier.fillMaxWidth()\n                    )\n                }\n            }\n            \n            TextButton(\n                onClick = { navigateToChangePayoutMethod() }\n            ) {\n                Text(\"Use a different PayPal account?\")\n            }\n        }\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-4-handle-payout-modes","__idx":13},"children":["Step 4: Handle payout modes"]},{"$$mdtype":"Tag","name":"Tabs","attributes":{"size":"medium"},"children":[{"$$mdtype":"Tag","name":"div","attributes":{"label":"SDK-initiated payout","disable":false},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proceedPayoutWithSdk = true"]},", the SDK handles the complete flow:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The customer sees their stored wallet details."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The customer taps \"Withdraw with PayPal\"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPrePayoutSubmit"]}," is called for approval."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The SDK executes the payout automatically."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostPayout"]}," is called with the result."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"paypalConfig = PaypalConfig(\n    payout = PayoutConfig(\n        proceedPayoutWithSdk = true,  // SDK handles payout execution\n        paypalWallet = PayPalPayOutWalletConfig(\n            email = \"customer@example.com\",\n            payerId = \"PAYER_ID_XXX\"\n        )\n    )\n)\n","lang":"kotlin"},"children":[]}]},{"$$mdtype":"Tag","name":"div","attributes":{"label":"Merchant-initiated","disable":false},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["proceedPayoutWithSdk = false"]},", your backend controls payout execution:"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The customer sees their stored wallet details."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The customer taps \"Withdraw with PayPal\"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The SDK validates the configuration."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Your backend calls the payout API when ready."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"paypalConfig = PaypalConfig(\n    payout = PayoutConfig(\n        proceedPayoutWithSdk = false,  // Merchant controls payout execution\n        paypalWallet = PayPalPayOutWalletConfig(\n            email = \"customer@example.com\",\n            payerId = \"PAYER_ID_XXX\"\n        )\n    )\n)\n","lang":"kotlin"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"step-5-handle-errors","__idx":14},"children":["Step 5: Handle errors"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement comprehensive error handling for the payout process."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"val submitConfig = PayoutSubmissionComponentConfig(\n    recipientWallet = \"Paypal\",\n    \n    onError = { error ->\n        Log.e(\"Payout\", \"Payout error: ${error.errorReason}\")\n        \n        // Handle specific error types\n        when (error.errorCode) {\n            \"PO04\" -> showError(\"Invalid recipient information.\")\n            \"PO02\" -> showError(\"Invalid payout amount. Please contact support.\")\n            \"PO03\" -> showError(\"Invalid currency.\")\n            \"PO07\" -> showError(\"Invalid transaction date.\")\n            else -> showError(\"An error occurred. Please try again or contact support.\")\n        }\n    }\n)\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"example","__idx":15},"children":["Example"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following example shows a complete withdrawal flow implementation for returning customers."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"import android.os.Bundle\nimport androidx.activity.ComponentActivity\nimport androidx.activity.compose.setContent\nimport androidx.compose.foundation.layout.*\nimport androidx.compose.material3.*\nimport androidx.compose.runtime.*\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.pxp.checkout.PxpCheckout\nimport com.pxp.checkout.components.payoutamount.PayoutAmountComponentConfig\nimport com.pxp.checkout.components.paypalpayoutreceiver.PaypalPayoutReceiverComponentConfig\nimport com.pxp.checkout.components.payoutsubmission.PayoutSubmissionComponentConfig\nimport com.pxp.checkout.models.*\nimport com.pxp.checkout.models.payout.PrePayoutSubmitResult\nimport com.pxp.checkout.types.ComponentType\nimport java.util.UUID\n\nclass WithdrawalActivity : ComponentActivity() {\n    \n    private lateinit var pxpCheckout: PxpCheckout\n    private val payoutAmount = 150.0\n    \n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        \n        // Get session data from your backend\n        val sessionData = getSessionDataFromBackend()\n        \n        // Get stored customer wallet details\n        val customerWallet = getStoredCustomerWallet()\n        \n        // Initialise SDK with stored wallet details (withdrawal flow)\n        pxpCheckout = PxpCheckout.builder()\n            .withConfig(\n                PxpSdkConfig(\n                    environment = Environment.TEST,\n                    session = sessionData,\n                    ownerId = \"Unity\",\n                    ownerType = \"MerchantGroup\",\n                    clientId = \"your-client-id\",\n                    transactionData = TransactionData(\n                        amount = payoutAmount,\n                        currency = \"USD\",\n                        merchant = \"your-merchant-id\",\n                        entryType = EntryType.Ecom,\n                        intent = TransactionIntentData(paypal = IntentType.Payout),\n                        merchantTransactionId = UUID.randomUUID().toString(),\n                        merchantTransactionDate = { System.currentTimeMillis() }\n                    ),\n                    paypalConfig = PaypalConfig(\n                        payout = PayoutConfig(\n                            proceedPayoutWithSdk = true,\n                            paypalWallet = PayPalPayOutWalletConfig(\n                                email = customerWallet.email,\n                                payerId = customerWallet.payerId\n                            )\n                        )\n                    )\n                )\n            )\n            .withContext(this)\n            .build()\n        \n        setContent {\n            MaterialTheme {\n                WithdrawalScreen()\n            }\n        }\n    }\n    \n    @Composable\n    fun WithdrawalScreen() {\n        var payoutStatus by remember { mutableStateOf<String?>(null) }\n        var showSuccessDialog by remember { mutableStateOf(false) }\n        \n        // Create amount display component\n        val amountComponent = remember {\n            pxpCheckout.createComponent(\n                type = ComponentType.PAYOUT_AMOUNT,\n                config = PayoutAmountComponentConfig(\n                    label = \"Withdrawal Amount\"\n                )\n            )\n        }\n        \n        // Create receiver display component\n        val receiverComponent = remember {\n            pxpCheckout.createComponent(\n                type = ComponentType.PAYPAL_PAYOUT_RECEIVER,\n                config = PaypalPayoutReceiverComponentConfig(\n                    label = \"Sending to\",\n                    showMaskToggle = true,\n                    applyMask = true\n                )\n            )\n        }\n        \n        // Create submission button\n        val submitConfig = remember {\n            PayoutSubmissionComponentConfig(\n                recipientWallet = \"Paypal\",\n                \n                onClick = {\n                    trackEvent(\"payout_button_tapped\")\n                },\n                \n                onPrePayoutSubmit = {\n                    // Perform validation\n                    val balance = checkUserBalance()\n                    if (balance < payoutAmount) {\n                        showError(\"Insufficient balance for this withdrawal.\")\n                        return@PayoutSubmissionComponentConfig PrePayoutSubmitResult(isApproved = false)\n                    }\n                    \n                    // Show confirmation dialog\n                    val confirmed = showConfirmationDialog(\n                        title = \"Confirm Withdrawal\",\n                        message = \"Withdraw $${\"%.2f\".format(payoutAmount)} to your PayPal account?\",\n                        details = listOf(\n                            \"Processing time: 1-2 business days\"\n                        )\n                    )\n                    \n                    if (!confirmed) {\n                        trackEvent(\"payout_cancelled_by_user\")\n                        PrePayoutSubmitResult(isApproved = false)\n                    } else {\n                        trackEvent(\"payout_approved\")\n                        PrePayoutSubmitResult(isApproved = true)\n                    }\n                },\n                \n                onPostPayout = { result ->\n                    Log.d(\"Payout\", \"Payout successful: $result\")\n                    \n                    trackEvent(\"payout_completed\", mapOf(\n                        \"merchantTransactionId\" to result.merchantTransactionId,\n                        \"systemTransactionId\" to result.systemTransactionId,\n                        \"amount\" to payoutAmount\n                    ))\n                    \n                    // Update local balance\n                    updateUserBalance(balance - payoutAmount)\n                    \n                    payoutStatus = \"Withdrawal completed successfully!\"\n                    showSuccessDialog = true\n                },\n                \n                onError = { error ->\n                    Log.e(\"Payout\", \"Payout error: ${error.errorReason}\")\n                    \n                    trackEvent(\"payout_failed\", mapOf(\n                        \"errorCode\" to error.errorCode,\n                        \"httpStatusCode\" to error.httpStatusCode.toString()\n                    ))\n                    \n                    payoutStatus = \"Error: ${error.errorReason}\"\n                }\n            )\n        }\n        \n        val submitComponent = remember {\n            pxpCheckout.createComponent(\n                type = ComponentType.PAYOUT_SUBMISSION,\n                config = submitConfig\n            )\n        }\n        \n        Surface(\n            modifier = Modifier.fillMaxSize(),\n            color = MaterialTheme.colorScheme.background\n        ) {\n            Column(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .padding(16.dp),\n                verticalArrangement = Arrangement.spacedBy(16.dp)\n            ) {\n                Text(\n                    text = \"Withdraw funds\",\n                    style = MaterialTheme.typography.headlineMedium\n                )\n                \n                Text(\n                    text = \"Review your withdrawal details below\",\n                    style = MaterialTheme.typography.bodyMedium,\n                    color = MaterialTheme.colorScheme.onSurfaceVariant\n                )\n                \n                Card(\n                    modifier = Modifier.fillMaxWidth(),\n                    colors = CardDefaults.cardColors(\n                        containerColor = MaterialTheme.colorScheme.surfaceVariant\n                    )\n                ) {\n                    Column(\n                        modifier = Modifier.padding(16.dp),\n                        verticalArrangement = Arrangement.spacedBy(12.dp)\n                    ) {\n                        // Amount\n                        pxpCheckout.buildComponentView(\n                            component = amountComponent,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                        \n                        Divider()\n                        \n                        // Receiver\n                        pxpCheckout.buildComponentView(\n                            component = receiverComponent,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                        \n                        Divider()\n                        \n                        // Submit button\n                        pxpCheckout.buildComponentView(\n                            component = submitComponent,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                    }\n                }\n                \n                TextButton(\n                    onClick = { navigateToChangePayoutMethod() }\n                ) {\n                    Text(\"Use a different PayPal account?\")\n                }\n                \n                // Status message\n                payoutStatus?.let { status ->\n                    Text(\n                        text = status,\n                        style = MaterialTheme.typography.bodyMedium,\n                        color = if (status.contains(\"Error\")) {\n                            MaterialTheme.colorScheme.error\n                        } else {\n                            MaterialTheme.colorScheme.primary\n                        }\n                    )\n                }\n            }\n        }\n        \n        // Success dialog\n        if (showSuccessDialog) {\n            AlertDialog(\n                onDismissRequest = { showSuccessDialog = false },\n                title = { Text(\"Withdrawal Successful\") },\n                text = { Text(payoutStatus ?: \"\") },\n                confirmButton = {\n                    Button(onClick = { \n                        showSuccessDialog = false\n                        finish()\n                    }) {\n                        Text(\"OK\")\n                    }\n                }\n            )\n        }\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"callback-data","__idx":16},"children":["Callback data"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This section describes the data received by the different callbacks as part of the withdrawal flow."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onprepayoutsubmit","__idx":17},"children":["onPrePayoutSubmit"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPrePayoutSubmit"]}," callback is called before payout execution. Return a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PrePayoutSubmitResult"]}," object indicating whether to proceed."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onPrePayoutSubmit = {\n    val approved = showConfirmationDialog()\n    PrePayoutSubmitResult(isApproved = approved)\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Return Property"},"children":["Return Property"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isApproved"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Boolean"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Whether to proceed with the payout. Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["false"]}," to cancel."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onpostpayout","__idx":18},"children":["onPostPayout"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostPayout"]}," callback receives the payout result when the transaction completes successfully."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onPostPayout = { result ->\n    Log.d(\"Payout\", \"Transaction details: ${result.merchantTransactionId}, ${result.systemTransactionId}\")\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["result"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["PostPayoutResult"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Object containing transaction identifiers."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["result.merchantTransactionId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Your unique identifier for the transaction. Use this with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["systemTransactionId"]}," to retrieve full authorisation details from the Unity backend."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["result.systemTransactionId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The system's unique identifier for the transaction. Use this with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["merchantTransactionId"]}," to retrieve full authorisation details from the Unity backend."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onerror","__idx":19},"children":["onError"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onError"]}," callback receives error information when the payout fails."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onError = { error ->\n    Log.e(\"Payout\", \"Error: ${error.errorReason}\")\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Parameter"},"children":["Parameter"]},{"$$mdtype":"Tag","name":"th","attributes":{"align":"left","data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["PayOutError"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Required","attributes":{},"children":[]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The error object containing details about what went wrong."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.correlationId"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The correlation ID for tracking the error."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.details"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["List<String?>?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["List of additional error details."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.errorCode"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The error code identifier (e.g., \"PO04\")."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.errorReason"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["Human-readable error reason (e.g., \"Invalid recipient information.\")."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.httpStatusCode"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["Int?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{"align":"left"},"children":["The HTTP status code of the response."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"whats-next","__idx":20},"children":["What's next?"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Now that you've implemented the withdrawal flow, explore these related topics:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paypal/payouts/about-configuration"},"children":["Configuration"]},": Customise component appearance and behaviour."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paypal/payouts/events"},"children":["Events"]},": Handle additional payout events and callbacks."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/guides/checkout/components/android/paypal/payouts/testing"},"children":["Testing"]},": Test your payout integration."]}]}]},"headings":[{"value":"Withdrawal flow","id":"withdrawal-flow","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"Payout flow","id":"payout-flow","depth":2},{"value":"Step 1: Display payout details","id":"step-1-display-payout-details","depth":3},{"value":"Step 2: Submission","id":"step-2-submission","depth":3},{"value":"Step 3: Payout approval","id":"step-3-payout-approval","depth":3},{"value":"Step 4: Payout execution","id":"step-4-payout-execution","depth":3},{"value":"Step 5: Payout result","id":"step-5-payout-result","depth":3},{"value":"Implementation","id":"implementation","depth":2},{"value":"Before you start","id":"before-you-start","depth":3},{"value":"Step 1: Initialise the SDK","id":"step-1-initialise-the-sdk","depth":3},{"value":"Step 2: Create the components","id":"step-2-create-the-components","depth":3},{"value":"Step 3: Render the components","id":"step-3-render-the-components","depth":3},{"value":"Step 4: Handle payout modes","id":"step-4-handle-payout-modes","depth":3},{"value":"Step 5: Handle errors","id":"step-5-handle-errors","depth":3},{"value":"Example","id":"example","depth":2},{"value":"Callback data","id":"callback-data","depth":2},{"value":"onPrePayoutSubmit","id":"onprepayoutsubmit","depth":3},{"value":"onPostPayout","id":"onpostpayout","depth":3},{"value":"onError","id":"onerror","depth":3},{"value":"What's next?","id":"whats-next","depth":2}],"frontmatter":{"seo":{"title":"Withdrawal flow"}},"lastModified":"2026-04-15T15:24:26.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/android/paypal/payouts/withdrawal-flow","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}