PayPal Payment Gateway Integration in Mobile Application
PayPal provides several mobile SDKs — current for new integrations is PayPal Mobile Checkout SDK (iOS and Android). Old Braintree SDK also supported and used for card payments without PayPal redirect. Choice between them depends on task: if only PayPal Wallet needed — use PayPal Checkout SDK, if cards + PayPal + Venmo needed — Braintree.
PayPal Checkout SDK: Basic Integration
PayPal Checkout works via browser flow: application opens PayPal WebView (or browser), user logs in to PayPal and confirms payment, PayPal redirects back with orderId.
Server Side: Order Creation
POST https://api-m.paypal.com/v2/checkout/orders
Authorization: Bearer access_token
{
"intent": "CAPTURE",
"purchase_units": [{
"amount": {
"currency_code": "USD",
"value": "15.00"
},
"description": "Order #1234"
}]
}
Response contains order id — passed to mobile SDK.
Android: PayPal Checkout SDK
// build.gradle
implementation("com.paypal.checkout:android-sdk:1.x.x")
// Application.onCreate()
PayPalCheckout.setConfig(
CheckoutConfig(
application = this,
clientId = "your_client_id",
environment = Environment.LIVE,
returnUrl = "yourapp://x-callback-url/paypal-sdk/paypal-checkout",
currencyCode = CurrencyCode.USD,
userAction = UserAction.PAY_NOW
)
)
// Launch payment
PayPalCheckout.start(
createOrder = CreateOrder { createOrderActions ->
createOrderActions.set(orderId) // ID from server
},
onApprove = OnApprove { approval ->
// approval.data.orderId — confirm on server
capturePaymentOnServer(approval.data.orderId)
},
onCancel = OnCancel {
// user closed
},
onError = OnError { errorInfo ->
Log.e("PayPal", errorInfo.reason)
}
)
iOS: PayPalCheckout SDK
// SPM: PayPalCheckout
import PayPalCheckout
PayPalCheckout.set(config: CheckoutConfig(
clientID: "your_client_id",
createOrder: nil,
onApprove: nil,
onCancel: nil,
onError: nil,
environment: .live
))
Checkout.start(
createOrder: { action in
action.set(orderId: "order_id_from_server")
},
onApprove: { approval in
// Capture payment on server
self.capturePayment(orderId: approval.data.ecToken)
},
onCancel: { },
onError: { error in
print("PayPal error: \(error.reason)")
}
)
Payment Capture on Server
After onApprove order must be captured:
POST https://api-m.paypal.com/v2/checkout/orders/{order_id}/capture
Authorization: Bearer access_token
Response with status COMPLETED means successful charge. Do not consider payment complete only on onApprove on client — without capture money is not charged.
Braintree: Cards + PayPal without Redirect
If native card input without PayPal.com redirect needed:
// Android Braintree SDK
implementation("com.braintreepayments.api:braintree-android:4.x.x")
implementation("com.braintreepayments.api:paypal:4.x.x")
implementation("com.braintreepayments.api:card:4.x.x")
val braintreeClient = BraintreeClient(context, "client_token_from_server")
val payPalClient = PayPalClient(activity, braintreeClient)
// PayPal Checkout via Braintree
val request = PayPalCheckoutRequest(amount = "15.00", currencyCode = "USD")
payPalClient.tokenizePayPalAccount(activity, request)
Braintree returns nonce — one-time token which server uses to charge via Braintree API.
Limitations for Russian Market
PayPal limited work with Russian legal entities and cards in 2022. Integration is relevant for international applications with foreign registration or accepting payments from foreign users.
Work Scope
- PayPal Checkout SDK or Braintree integration (iOS / Android)
- Server endpoints for order creation and capture
- Deeplink-return handling and error processing
- Sandbox testing with test PayPal accounts
Timeline
2–3 days. Cost calculated individually.







