Test your payout integration end-to-end before going live.
- Complete PayPal payouts onboarding for sandbox.
- Implement the withdrawal flow.
- Review How it works so you understand flows and payout modes.
Use the TEST environment and sandbox credentials for both SDK and backend.
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()Focus first on the main customer journeys.
- Initialise the SDK with a stored PayPal wallet (
paypalWallet.emailandpayerId). - Render
PayoutAmountComponent,PaypalPayoutReceiverComponent, andPayoutSubmissionComponent. - Verify:
- Amount and receiver are correctly displayed (including masking behaviour).
- Tapping Withdraw with PayPal triggers
onPrePayoutSubmit. - Successful approval results in
onPostPayoutbeing called and the sandbox recipient balance increasing.
- With
proceedPayoutWithSdk = true, confirm the SDK executes the payout afteronPrePayoutSubmitapproves and callsonPostPayoutwith 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.
- SDK validates inputs and calls
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. |
Use targeted negative tests rather than exhaustively covering every error code.
- Amounts: Negative or zero amount → expect amount validation error (see Data validation).
- PayPal receiver: Invalid email format or missing payer ID → expect PayPal receiver errors (
PO04). - Configuration: Missing
recipientWalletor wallet details → expect payout configuration errors.
In each case, verify that:
onErroris called with the appropriate error code and message.- Your UI maps technical errors to clear, user-friendly messages.
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)
}
)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.
- 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.
Once your sandbox tests pass:
Switch environments
val pxpCheckout = PxpCheckout.builder() .withConfig( PxpSdkConfig( environment = Environment.LIVE, // Production environment // ... rest of config ) ) .build()Update backend credentials to use live PayPal and Unity endpoints and secrets.
Run a small live test (for example, a $1 payout to your own PayPal account) and confirm funds, reporting, and reconciliation.
Enable monitoring (error tracking, alerts on payout failures, webhook monitoring) and roll out gradually if needed.
If you hit issues during testing, see Troubleshooting and Data validation for common problems and error codes.