flutter_paypal_payment_checkout_v2 2.0.7 copy "flutter_paypal_payment_checkout_v2: ^2.0.7" to clipboard
flutter_paypal_payment_checkout_v2: ^2.0.7 copied to clipboard

retracted

A powerful, secure PayPal checkout wrapper for Flutter.

example/main.dart

import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/paypal_checkout_view.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v1/enums/pay_pal_order_intent_v1.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v1/models/pay_pal_order_request_v1.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v1/models/pay_pal_shipping_address_v1.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v1/models/paypal_transaction_v1.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v1/models/paypal_transaction_v1_amount.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v1/models/paypal_transaction_v1_item.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v2/enums/pay_pal_item_category_v2.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v2/enums/pay_pal_order_intent_v2.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v2/enums/pay_pal_payment_method_preference_v2.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v2/enums/pay_pal_shipping_preference_v2.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v2/models/pay_pal_experience_context_v2.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v2/models/pay_pal_order_request_v2.dart';
import 'package:flutter_paypal_payment_checkout_v2/src/v2/models/pay_pal_purchase_unit_v2.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'PayPal Payment Demo',
      debugShowCheckedModeBanner: false,
      home: PaypalDemoHome(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('PayPal Payment Demo'),
        centerTitle: true,
      ),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            const _HelpCard(),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: () => _startV2Flow(context),
              child: const Text('Pay with PayPal (V2 – Checkout Orders API)'),
            ),
            const SizedBox(height: 12),
            ElevatedButton(
              onPressed: () => _startV1Flow(context),
              child: const Text('Pay with PayPal (V1 – Payments API, legacy)'),
            ),
          ],
        ),
      ),
    );
  }

  // ---------------- V2 EXAMPLE ----------------
  void _startV2Flow(BuildContext context) {
    // Build a simple V2 order with 1 purchase unit
    final order = PayPalOrderRequestV2(
      intent: PayPalOrderIntentV2.capture,
      paymentSource: PayPalPaymentSourceV2(
        paymentMethodPreference:
            PayPalPaymentMethodPreferenceV2.immediatePaymentRequired,
        shippingPreference: PayPalShippingPreferenceV2.noShipping,
        // Where PayPal should redirect the user after they approve or cancel
        // returnUrl: "https://example.com/paypal/return",
        // cancelUrl: "https://example.com/paypal/cancel",
        // Optional:
        // landingPage: PayPalLandingPageV2.noPreference,
        // userAction: PayPalUserActionV2.payNow,
      ),
      purchaseUnits: [
        PayPalPurchaseUnitV2(
          // invoiceId: 'INV-123456',
          amount: PayPalAmountV2(
            currency: 'USD',
            value: 100.0, // total amount
            itemTotal: 100.0, // sum of items
            taxTotal: 0.0, // total tax
          ),
          items: [
            PaypalTransactionV2Item(
              name: 'Apple',
              description: 'Fresh red apples',
              quantity: 2,
              unitAmount: 50.0,
              // 2 * 50 = 100
              currency: 'USD',
              category: PayPalItemCategoryV2.physicalGoods,
              sku: 'SKU_APPLE',
              imageUrl: 'https://example.com/images/apple.png',
              url: 'https://example.com/products/apple',
              upcCode: '123456789012',
              upcType: 'UPC_A',
            ),
          ],
          shippingAddress: PayPalShippingAddressV2(
            name: 'John Doe',
            addressLine1: '123 Demo Street',
            addressLine2: 'Suite 100',
            city: 'San Francisco',
            state: 'CA',
            postalCode: '94105',
            countryCode: 'US',
          ),
        ),
      ],
    );

    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => PaypalCheckoutView(
          version: PayPalApiVersion.v2,
          // 👇 In production, prefer getting approvalUrl / accessToken from backend
          getAccessToken: null,
          // using clientId/secret (sandbox ONLY)
          approvalUrl: null,

          sandboxMode: true,
          clientId: 'ONLY FOR SANDBOX (TESTING PURPOSES ONLY)',
          secretKey: 'ONLY FOR SANDBOX (TESTING PURPOSES ONLY)',

          payPalOrder: order,
          onUserPayment: (success, payment) {
            log('V2 onSuccess payment: ${payment.toJson()}');
            log('V2 onSuccess capture data: ${success?.data}');
            Navigator.pop(context);
          },
          onError: (error) {
            log('V2 onError: ${error.message} (${error.key})');
            Navigator.pop(context);
          },
          onCancel: () {
            log('V2 cancelled by user');
            Navigator.pop(context);
          },
        ),
      ),
    );
  }

  // ---------------- V1 EXAMPLE ----------------
  void _startV1Flow(BuildContext context) {
    // Build a V1-style order with transactions/items
    final transaction = PaypalTransactionV1(
      amount: PaypalTransactionV1Amount(
        subTotal: 100.0,
        tax: 0.0,
        total: 100.0,
        // total = subtotal + tax + shipping + handlingFee - shippingDiscount + insurance
        shipping: 0.0,
        handlingFee: 0.0,
        shippingDiscount: 0.0,
        insurance: 0.0,
        currency: 'USD',
      ),
      description: "V1 demo – apples & pineapples",
      custom: "EXAMPLE-USER-ID",
      items: [
        PaypalTransactionV1Item(
          name: "Apple",
          description: "Fresh apples",
          quantity: 4,
          price: 10.0,
          tax: 0.0,
          sku: "SKU_APPLE",
          currency: "USD",
        ),
        PaypalTransactionV1Item(
          name: "Pineapple",
          description: "Fresh pineapples",
          quantity: 5,
          price: 12.0,
          tax: 0.0,
          sku: "SKU_PINEAPPLE",
          currency: "USD",
        ),
      ],
      shippingAddress: PayPalShippingAddressV1(
        recipientName: "John Doe",
        line1: "123 Demo Street",
        line2: "Suite 100",
        city: "San Francisco",
        postalCode: '94105',
        countryCode: 'US',
        phone: '+201111111111',
        state: 'CA',
      ),
      // optional
      // invoiceNumber: "123456789",
      // payPalAllowedPaymentMethod: PayPalAllowedPaymentMethodV1.immediatePay,
      // softDescriptor: "123456789",
    );

    final order = PayPalOrderRequestV1(
      intent: PayPalOrderIntentV1.sale,
      // paymentMethod: "paypal",
      transactions: [transaction],
      // Where PayPal should redirect the user after they approve or cancel
      // returnUrl: "https://example.com/paypal/return",
      // cancelUrl: "https://example.com/paypal/cancel",
      noteToPayer: "Contact us for any questions on your order.",
    );

    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => PaypalCheckoutView(
          version: PayPalApiVersion.v1,
          // 👇 In production, prefer backend access token / approvalUrl
          getAccessToken: null,
          // using clientId/secret (sandbox ONLY)
          approvalUrl: null,

          sandboxMode: true,
          clientId: 'ONLY FOR SANDBOX (TESTING PURPOSES ONLY)',
          secretKey: 'ONLY FOR SANDBOX (TESTING PURPOSES ONLY)',

          payPalOrder: order,
          onUserPayment: (success, payment) {
            log('V1 onSuccess payment: ${payment.toJson()}');
            log('V1 onSuccess execute data: ${success?.data}');
            Navigator.pop(context);
          },
          onError: (error) {
            log('V1 onError: ${error.message} (${error.key})');
            Navigator.pop(context);
          },
          onCancel: () {
            log('V1 cancelled by user');
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

// ---------------- HELP WIDGET ----------------

class _HelpCard extends StatelessWidget {
  const _HelpCard();

  @override
  Widget build(BuildContext context) {
    return const Card(
      elevation: 2,
      child: Padding(
        padding: EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              "How this demo works",
              style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 8),
            Text(
              "• V2 button uses the modern Checkout Orders API (v2). "
              "This is the recommended integration for new apps.\n\n"
              "• V1 button uses the legacy Payments API (v1). "
              "PayPal still supports it for older integrations but it is not recommended for new projects.\n\n"
              "Security notes:\n"
              "- In production, NEVER ship clientId/secret inside the app.\n"
              "- Your backend should call PayPal (create order/payment, capture/execute) "
              "and send only the approval URL to the client.\n"
              "- `getAccessToken` and `approvalUrl` callbacks are designed for that secure flow.",
            ),
          ],
        ),
      ),
    );
  }
}
3
likes
0
points
46
downloads

Publisher

unverified uploader

Weekly Downloads

A powerful, secure PayPal checkout wrapper for Flutter.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

dartz, dio, flutter, flutter_inappwebview

More

Packages that depend on flutter_paypal_payment_checkout_v2