paypal_native_flutter 0.1.0 copy "paypal_native_flutter: ^0.1.0" to clipboard
paypal_native_flutter: ^0.1.0 copied to clipboard

Native PayPal card payments and PayPal web checkout for Flutter, wrapping the official paypal-android and paypal-ios SDKs. Server-created Orders v2; your client secret never touches the app.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:paypal_native_flutter/paypal_native_flutter.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: CheckoutDemo());
  }
}

class CheckoutDemo extends StatefulWidget {
  const CheckoutDemo({super.key});

  @override
  State<CheckoutDemo> createState() => _CheckoutDemoState();
}

class _CheckoutDemoState extends State<CheckoutDemo> {
  String _status = 'Not initialized';
  bool _ready = false;

  // Card entry controllers — this is YOUR native UI, style it however you want.
  final _number = TextEditingController(text: '4111111111111111'); // sandbox test card
  final _expMonth = TextEditingController(text: '01');
  final _expYear = TextEditingController(text: '2030');
  final _cvv = TextEditingController(text: '123');

  @override
  void initState() {
    super.initState();
    _init();
  }

  Future<void> _init() async {
    try {
      await PaypalNativeFlutter.init(
        // TODO: replace with your sandbox client ID from developer.paypal.com
        clientId: 'YOUR_SANDBOX_CLIENT_ID',
        environment: PayPalEnvironment.sandbox,
        returnUrl: 'dev.yourorg.paypalnativeflutterexample://paypal-return',
      );
      // Check for a payment orphaned by process death (Android):
      final pending = await PaypalNativeFlutter.recoverPendingPayment();
      setState(() {
        _ready = true;
        _status = pending == null
            ? 'Initialized. Ready.'
            : 'Recovered pending order ${pending.orderId} — '
              'check its status with your backend.';
      });
    } catch (e) {
      setState(() => _status = 'Init failed: $e');
    }
  }

  Future<void> _payWithCard() async {
    // In a real app this orderId comes from YOUR BACKEND (Orders v2).
    // For a quick sandbox smoke test you can create one manually with curl
    // and paste it here — see the README.
    const orderId = 'PASTE_A_SANDBOX_ORDER_ID';
    setState(() => _status = 'Approving with card…');
    try {
      final approval = await PaypalNativeFlutter.approveOrderWithCard(
        orderId: orderId,
        card: PayPalCard(
          number: _number.text,
          expirationMonth: _expMonth.text,
          expirationYear: _expYear.text,
          securityCode: _cvv.text,
        ),
      );
      setState(() => _status =
          'APPROVED order ${approval.orderId} (3DS: ${approval.didAttemptThreeDSecure}). '
          'Now your backend must CAPTURE it — approval is not payment.');
    } on PayPalCanceledException {
      setState(() => _status = 'Buyer canceled.');
    } on PayPalException catch (e) {
      setState(() => _status = 'Error ${e.code}: ${e.message}');
    }
  }

  Future<void> _payWithPayPal() async {
    const orderId = 'PASTE_A_SANDBOX_ORDER_ID';
    setState(() => _status = 'Launching PayPal…');
    try {
      final approval = await PaypalNativeFlutter.approveOrderWithPayPal(
        orderId: orderId,
      );
      setState(() => _status =
          'APPROVED order ${approval.orderId}, payer ${approval.payerId}. '
          'Now your backend must CAPTURE it.');
    } on PayPalCanceledException {
      setState(() => _status = 'Buyer canceled.');
    } on PayPalException catch (e) {
      setState(() => _status = 'Error ${e.code}: ${e.message}');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('paypal_native_flutter demo')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(_status),
            const SizedBox(height: 24),
            TextField(
              controller: _number,
              decoration: const InputDecoration(labelText: 'Card number'),
              keyboardType: TextInputType.number,
            ),
            Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _expMonth,
                    decoration: const InputDecoration(labelText: 'MM'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: TextField(
                    controller: _expYear,
                    decoration: const InputDecoration(labelText: 'YYYY'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: TextField(
                    controller: _cvv,
                    decoration: const InputDecoration(labelText: 'CVV'),
                    obscureText: true,
                  ),
                ),
              ],
            ),
            const SizedBox(height: 24),
            FilledButton(
              onPressed: _ready ? _payWithCard : null,
              child: const Text('Pay with card (native)'),
            ),
            const SizedBox(height: 8),
            OutlinedButton(
              onPressed: _ready ? _payWithPayPal : null,
              child: const Text('Pay with PayPal'),
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
140
points
8
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Native PayPal card payments and PayPal web checkout for Flutter, wrapping the official paypal-android and paypal-ios SDKs. Server-created Orders v2; your client secret never touches the app.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter

More

Packages that depend on paypal_native_flutter

Packages that implement paypal_native_flutter