{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-guides/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["sub-heading","br","details"]},"type":"markdown"},"seo":{"title":"Submission component","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":"submission-component","__idx":0},"children":["Submission component"]},{"$$mdtype":"Tag","name":"SubHeading","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Add a withdrawal button for returning customers in your Android app."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"overview","__idx":1},"children":["Overview"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The payout submission component provides a \"Withdraw with PayPal\" button that executes payouts for returning customers. It's designed for the withdrawal flow when you already have the customer's wallet details stored."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"when-to-use","__idx":2},"children":["When to use"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the submission component when:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You're implementing the withdrawal flow for returning customers."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You have the customer's PayPal email and payer ID stored."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You want to provide a streamlined payout experience without requiring login."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["You need full control over the payout approval process."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"component-creation","__idx":3},"children":["Component creation"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create the submission component using the SDK's factory method:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"import com.pxp.checkout.components.payoutsubmission.PayoutSubmissionComponentConfig\nimport com.pxp.checkout.models.payout.PrePayoutSubmitResult\nimport com.pxp.checkout.types.ComponentType\n\nval submitConfig = PayoutSubmissionComponentConfig(\n    recipientWallet = \"Paypal\",\n    onPrePayoutSubmit = {\n        val confirmed = showConfirmationDialog()\n        PrePayoutSubmitResult(isApproved = confirmed)\n    },\n    onPostPayout = { result ->\n        navigateToSuccessScreen(result.merchantTransactionId)\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":2,"id":"configuration-options","__idx":4},"children":["Configuration options"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"payoutsubmissioncomponentconfig","__idx":5},"children":["PayoutSubmissionComponentConfig"]},{"$$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":{"data-label":"Property"},"children":["Property"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recipientWallet"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The recipient wallet type. Only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Paypal\""]}," is currently supported. Empty or blank values default to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Paypal\""]},". Component validation will throw an error for other non-empty values. Receiver email is obtained from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sdkConfig.paypalConfig.payout.paypalWallet.email"]},". Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Paypal\""]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["buttonText"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["String"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The submit button text. Customise it to match your app's terminology. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"Withdraw with\""]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["style"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["PayoutSubmissionStyle?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["The submit button styling. Customise colours, typography, and spacing. Uses default PayPal styling if not provided. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onClick"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["(() -> Unit)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Called when the submit button is tapped. Use for analytics tracking, show loading indicators, or perform pre-validation checks. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPrePayoutSubmit"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["(suspend () -> PrePayoutSubmitResult)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Called before payout submission. Show confirmation dialog and perform validation checks. This is a suspend function where the component waits for approval. Return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PrePayoutSubmitResult"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isApproved"]}," status. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onPostPayout"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["((PostPayoutResult) -> Unit)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Called when payout succeeds. Receives transaction identifiers. Update your records, show success message, and navigate to confirmation screen. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},"."]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["onError"]},{"$$mdtype":"Tag","name":"Break","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Details","attributes":{},"children":["((PayOutError) -> Unit)?"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Called when payout fails. Receives error details with code and reason. May include transaction IDs if transaction was created. Display error messages and implement retry logic. Defaults to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},"."]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"event-callbacks","__idx":6},"children":["Event callbacks"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onclick","__idx":7},"children":["onClick"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Triggered when the customer taps the withdrawal button."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onClick = {\n    Log.d(\"Payout\", \"Withdrawal button tapped\")\n    trackEvent(\"payout_button_tapped\")\n    showLoadingIndicator()\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onprepayoutsubmit","__idx":8},"children":["onPrePayoutSubmit"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Triggered after tap and validation, before payout execution. The component suspends and waits for approval."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Return value:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["isApproved"]}," (Boolean, required): Whether to proceed with the payout."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onPrePayoutSubmit = {\n    // Show confirmation dialog\n    val confirmed = showConfirmationDialog(\n        title = \"Confirm Withdrawal\",\n        message = \"Withdraw $$amount to your PayPal account?\"\n    )\n    \n    if (!confirmed) {\n        return@PayoutSubmissionComponentConfig PrePayoutSubmitResult(isApproved = false)\n    }\n    \n    // Perform validation\n    val balanceCheck = verifyBalance()\n    if (!balanceCheck.sufficient) {\n        showError(\"Insufficient balance\")\n        return@PayoutSubmissionComponentConfig PrePayoutSubmitResult(isApproved = false)\n    }\n    \n    // Approve the payout\n    PrePayoutSubmitResult(isApproved = true)\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onpostpayout","__idx":9},"children":["onPostPayout"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Triggered when payout completes successfully."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameters:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data.merchantTransactionId"]}," (String?): Your transaction identifier (optional)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data.systemTransactionId"]}," (String): The system transaction identifier."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onPostPayout = { result ->\n    Log.d(\"Payout\", \"Payout successful: ${result.systemTransactionId}\")\n    \n    // Update records\n    storeTransaction(\n        merchantTransactionId = result.merchantTransactionId,\n        systemTransactionId = result.systemTransactionId\n    )\n    \n    // Show success\n    showSuccessMessage(\"$amount has been sent to your PayPal account!\")\n    \n    // Navigate\n    navigateToSuccessScreen(result.merchantTransactionId)\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"onerror","__idx":10},"children":["onError"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Triggered when payout fails."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Parameters:"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.errorCode"]}," (String?): Error code identifier."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.errorReason"]}," (String?): Human-readable error message."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.httpStatusCode"]}," (Int?): HTTP status code."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.correlationId"]}," (String?, optional): Correlation ID for tracking."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error.details"]}," (List<String?>?, optional): Additional error details."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onError = { error ->\n    Log.e(\"Payout\", \"Payout failed: ${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        else -> showError(\"An error occurred. Please try again.\")\n    }\n    \n    // Log for debugging\n    logError(\"payout_error\", mapOf(\n        \"errorCode\" to error.errorCode,\n        \"correlationId\" to error.correlationId\n    ))\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"rendering-the-component","__idx":11},"children":["Rendering the component"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Render the component using Jetpack Compose:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"@Composable\nfun WithdrawalScreen() {\n    val submitComponent = remember {\n        pxpCheckout.createComponent(\n            type = ComponentType.PAYOUT_SUBMISSION,\n            config = submitConfig\n        )\n    }\n    \n    pxpCheckout.buildComponentView(\n        component = submitComponent,\n        modifier = Modifier.fillMaxWidth()\n    )\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"complete-example","__idx":12},"children":["Complete example"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Here's a complete example showing the submission component in a withdrawal flow:"]},{"$$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 PayoutSubmissionActivity : 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 stored customer wallet\n        val customerWallet = getStoredCustomerWallet()\n        \n        // Initialise SDK with stored wallet details\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 components\n        val amountComponent = remember {\n            pxpCheckout.createComponent(\n                type = ComponentType.PAYOUT_AMOUNT,\n                config = PayoutAmountComponentConfig(\n                    label = \"Withdrawal Amount\"\n                )\n            )\n        }\n        \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        val submitConfig = remember {\n            PayoutSubmissionComponentConfig(\n                recipientWallet = \"Paypal\",\n                buttonText = \"Withdraw to PayPal\",\n                \n                onClick = {\n                    Log.d(\"Payout\", \"Button tapped\")\n                    trackEvent(\"payout_button_tapped\")\n                },\n                \n                onPrePayoutSubmit = {\n                    Log.d(\"Payout\", \"Pre-payout validation\")\n                    \n                    // Check balance\n                    val balance = checkUserBalance()\n                    if (balance < payoutAmount) {\n                        showError(\"Insufficient balance\")\n                        return@PayoutSubmissionComponentConfig PrePayoutSubmitResult(isApproved = false)\n                    }\n                    \n                    // Show confirmation\n                    val confirmed = showConfirmationDialog(\n                        title = \"Confirm Withdrawal\",\n                        message = \"Withdraw $${\"%.2f\".format(payoutAmount)} to your PayPal account?\",\n                        details = listOf(\"Processing time: 1-2 business days\")\n                    )\n                    \n                    if (!confirmed) {\n                        trackEvent(\"payout_cancelled\")\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.systemTransactionId}\")\n                    \n                    trackEvent(\"payout_completed\", mapOf(\n                        \"merchantTransactionId\" to result.merchantTransactionId,\n                        \"systemTransactionId\" to result.systemTransactionId,\n                        \"amount\" to payoutAmount\n                    ))\n                    \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                Card(modifier = Modifier.fillMaxWidth()) {\n                    Column(\n                        modifier = Modifier.padding(16.dp),\n                        verticalArrangement = Arrangement.spacedBy(12.dp)\n                    ) {\n                        pxpCheckout.buildComponentView(\n                            component = amountComponent,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                        \n                        Divider()\n                        \n                        pxpCheckout.buildComponentView(\n                            component = receiverComponent,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                        \n                        Divider()\n                        \n                        pxpCheckout.buildComponentView(\n                            component = submitComponent,\n                            modifier = Modifier.fillMaxWidth()\n                        )\n                    }\n                }\n                \n                TextButton(onClick = { navigateToChangePayoutMethod() }) {\n                    Text(\"Use a different PayPal account?\")\n                }\n                \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        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":"best-practices","__idx":13},"children":["Best practices"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"always-implement-onprepayoutsubmit","__idx":14},"children":["Always implement onPrePayoutSubmit"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use this callback to confirm the payout with the customer:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"// Good: Confirm before payout\nonPrePayoutSubmit = {\n    val confirmed = showConfirmationDialog()\n    PrePayoutSubmitResult(isApproved = confirmed)\n}\n\n// Less ideal: No confirmation\nonPrePayoutSubmit = {\n    PrePayoutSubmitResult(isApproved = true)  // Risky without user confirmation\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"proper-error-handling","__idx":15},"children":["Proper error handling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Handle all error types gracefully:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onError = { error ->\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.\")\n    }\n}\n","lang":"kotlin"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"track-analytics","__idx":16},"children":["Track analytics"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement comprehensive tracking:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"kotlin","header":{"controls":{"copy":{}}},"source":"onClick = { trackEvent(\"payout_button_tapped\") }\nonPrePayoutSubmit = {\n    if (approved) trackEvent(\"payout_approved\")\n    else trackEvent(\"payout_cancelled\")\n    //...\n}\nonPostPayout = { trackEvent(\"payout_completed\") }\nonError = { trackEvent(\"payout_failed\") }\n","lang":"kotlin"},"children":[]}]},"headings":[{"value":"Submission component","id":"submission-component","depth":1},{"value":"Overview","id":"overview","depth":2},{"value":"When to use","id":"when-to-use","depth":2},{"value":"Component creation","id":"component-creation","depth":2},{"value":"Configuration options","id":"configuration-options","depth":2},{"value":"PayoutSubmissionComponentConfig","id":"payoutsubmissioncomponentconfig","depth":3},{"value":"Event callbacks","id":"event-callbacks","depth":2},{"value":"onClick","id":"onclick","depth":3},{"value":"onPrePayoutSubmit","id":"onprepayoutsubmit","depth":3},{"value":"onPostPayout","id":"onpostpayout","depth":3},{"value":"onError","id":"onerror","depth":3},{"value":"Rendering the component","id":"rendering-the-component","depth":2},{"value":"Complete example","id":"complete-example","depth":2},{"value":"Best practices","id":"best-practices","depth":2},{"value":"Always implement onPrePayoutSubmit","id":"always-implement-onprepayoutsubmit","depth":3},{"value":"Proper error handling","id":"proper-error-handling","depth":3},{"value":"Track analytics","id":"track-analytics","depth":3}],"frontmatter":{"seo":{"title":"Submission component"}},"lastModified":"2026-02-26T12:14:32.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/guides/checkout/components/android/paypal/payouts/submission-component","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}