# Testing

Test your payout integration end-to-end before going live.

## Before you start

- Complete [PayPal payouts onboarding](/guides/checkout/components/android/paypal/payouts/onboarding) for sandbox.


- Implement the [withdrawal flow](/guides/checkout/components/android/paypal/payouts/withdrawal-flow).
- Review [How it works](/guides/checkout/components/android/paypal/payouts/how-it-works) so you understand flows and payout modes.


## Step 1: Configure sandbox environment

Use the `TEST` environment and sandbox credentials for both SDK and backend.

```kotlin
import com.pxp.checkout.PxpCheckout
import com.pxp.checkout.models.*
import java.util.UUID

val pxpCheckout = PxpCheckout.builder()
    .withConfig(
        PxpSdkConfig(
            environment = Environment.TEST,  // Use test environment
            session = sessionData,
            ownerId = "Unity",
            ownerType = "MerchantGroup",
            clientId = "your-client-id",
            transactionData = TransactionData(
                amount = 100.0,
                currency = "USD",
                merchant = "your-merchant-id",
                entryType = EntryType.Ecom,
                intent = TransactionIntentData(paypal = IntentType.Payout),
                merchantTransactionId = UUID.randomUUID().toString(),
                merchantTransactionDate = { System.currentTimeMillis() }
            ),
            paypalConfig = PaypalConfig(
                payout = PayoutConfig(
                    proceedPayoutWithSdk = true
                    // Add paypalWallet for withdrawal flow tests
                )
            )
        )
    )
    .withContext(context)
    .build()
```

## Step 2: Test core happy paths

Focus first on the main customer journeys.

### Withdrawal flow (returning customers)

- Initialise the SDK with a stored PayPal wallet (`paypalWallet.email` and `payerId`).
- Render `PayoutAmountComponent`, `PaypalPayoutReceiverComponent`, and `PayoutSubmissionComponent`.
- Verify:
  - Amount and receiver are correctly displayed (including masking behaviour).
  - Tapping **Withdraw with PayPal** triggers `onPrePayoutSubmit`.
  - Successful approval results in `onPostPayout` being called and the sandbox recipient balance increasing.


### SDK-initiated vs merchant-initiated

- With `proceedPayoutWithSdk = true`, confirm the SDK executes the payout after `onPrePayoutSubmit` approves and calls `onPostPayout` with a transaction ID.
- With `proceedPayoutWithSdk = false`, confirm:
  - SDK validates inputs and calls `onPrePayoutSubmit`.
  - Your backend receives the necessary data and successfully calls the payout API.


### Minimal test checklist

Use this as a lightweight "must-have" list before going live:

| Area | Scenario | What to verify |
|  --- | --- | --- |
| Withdrawal flow | Returning customer payout | Stored PayPal wallet is shown (including masking), `onPrePayoutSubmit` and `onPostPayout` fire, and sandbox balance increases. |
| Validation & errors | Invalid amount / email | `onError` receives the right error code, and the UI shows clear, user-friendly messages. |
| Integration | SDK- vs merchant-initiated payouts | `proceedPayoutWithSdk` modes behave as expected, and backend payout execution works when SDK is not executing the payout. |


## Step 3: Test validation and error handling

Use targeted negative tests rather than exhaustively covering every error code.

- **Amounts:** Negative or zero amount → expect amount validation error (see [Data validation](/guides/checkout/components/android/paypal/payouts/data-validation)).
- **PayPal receiver:** Invalid email format or missing payer ID → expect PayPal receiver errors (`PO04`).
- **Configuration:** Missing `recipientWallet` or wallet details → expect payout configuration errors.


In each case, verify that:

- `onError` is called with the appropriate error code and message.
- Your UI maps technical errors to clear, user-friendly messages.


```kotlin
val submitConfig = PayoutSubmissionComponentConfig(
    recipientWallet = "Paypal",
    onError = { error ->
        Log.e("Payout", "Error: ${error.errorCode} - ${error.errorReason}")
        
        // Map to user-friendly messages
        val message = when (error.errorCode) {
            "PO02" -> "Amount must be greater than zero"
            "PO03" -> "Invalid currency code"
            "PO04" -> "Invalid PayPal account details"
            "PO07" -> "Invalid transaction date"
            else -> "An error occurred. Please try again."
        }
        
        showError(message)
    }
)
```

## Step 4: Test UI and events

Verify that core components render and behave as expected:

- `PayoutAmountComponent`: correct amount, currency, and custom label/styling.
- `PaypalPayoutReceiverComponent`: masking toggle, labels, and styles.
- `PayoutSubmissionComponent`:
  - Button states (default, loading, disabled).
  - Event callbacks: `onClick`, `onPrePayoutSubmit`, `onPostPayout`, `onError`.


### Test on multiple devices

- Phone (5-6 inch screen)
- Phone (6-7 inch screen)
- Tablet (10+ inch screen)
- Different Android versions (min SDK to latest)
- Different screen orientations (portrait and landscape)


For detailed callback payloads, see [Events](/guides/checkout/components/android/paypal/payouts/events).

## Step 5: Moving to production

Once your sandbox tests pass:

1. **Switch environments**

```kotlin
val pxpCheckout = PxpCheckout.builder()
    .withConfig(
        PxpSdkConfig(
            environment = Environment.LIVE,  // Production environment
            // ... rest of config
        )
    )
    .build()
```
2. **Update backend credentials** to use live PayPal and Unity endpoints and secrets.
3. **Run a small live test** (for example, a $1 payout to your own PayPal account) and confirm funds, reporting, and reconciliation.
4. **Enable monitoring** (error tracking, alerts on payout failures, webhook monitoring) and roll out gradually if needed.


If you hit issues during testing, see [Troubleshooting](/guides/checkout/components/android/paypal/payouts/troubleshooting) and [Data validation](/guides/checkout/components/android/paypal/payouts/data-validation) for common problems and error codes.