ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • paypal 결제 시스템 연동 (1)
    flutter 2025. 1. 2. 16:17
    반응형

    https://developer.paypal.com/home/

     

    PayPal Developer

    Learn how to create and integrate scalable PayPal checkout solutions for web and mobile applications.

    developer.paypal.com

    접속후 계정만들기

    먼저 디폴트로 API 키가 만들어진다

    해당 키를 이용해서

    import 'dart:convert';
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    import 'package:flutter_inappwebview/flutter_inappwebview.dart';
    
    class PayPalService {
      // 테스트
      final String clientId = "AZSJ......"; // PayPal 클라이언트 ID
      final String clientSecret = "EMNs....."; // PayPal 클라이언트 Secret
      final String sandboxBaseUrl = "https://api-m.sandbox.paypal.com";
    
      // 실제
      // final String clientId = "ATTr...."; // PayPal 클라이언트 ID
      // final String clientSecret = "ECDTK..."; // PayPal 클라이언트 Secret
      // final String sandboxBaseUrl = "https://api-m.paypal.com";
    
      // **1. PayPal Access Token 생성**
      Future<String?> getAccessToken() async {
        final String url = "$sandboxBaseUrl/v1/oauth2/token";
        try {
          final response = await http.post(
            Uri.parse(url),
            headers: {
              "Authorization": "Basic ${base64Encode(utf8.encode('$clientId:$clientSecret'))}",
              "Content-Type": "application/x-www-form-urlencoded",
            },
            body: "grant_type=client_credentials",
          );
    
          if (response.statusCode == 200) {
            final data = jsonDecode(response.body);
            return data['access_token'];
          } else {
            print("Error getting access token: ${response.statusCode} - ${response.body}");
          }
        } catch (e) {
          print("Error: $e");
        }
        return null;
      }
    
      // **2. PayPal Checkout 생성**
      Future<String?> createOrder(String accessToken, double amount, String currency) async {
        final String url = "$sandboxBaseUrl/v2/checkout/orders";
        final Map<String, dynamic> orderData = {
          "intent": "CAPTURE",
          "application_context": {
            "return_url": "https://your-domain.com/success",
            "cancel_url": "https://your-domain.com/cancel",
            "shipping_preference": "NO_SHIPPING",
          },
          "purchase_units": [
            {
              "amount": {
                "currency_code": currency,
                "value": amount.toString(),
              }
            }
          ]
        };
    
    
        try {
          final response = await http.post(
            Uri.parse(url),
            headers: {
              "Authorization": "Bearer $accessToken",
              "Content-Type": "application/json",
            },
            body: jsonEncode(orderData),
          );
    
          if (response.statusCode == 201) {
            final data = jsonDecode(response.body);
            final approvalUrl = data['links']
                .firstWhere((link) => link['rel'] == 'approve')['href'];
            return approvalUrl;
          } else {
            print("Error creating order: ${response.statusCode} - ${response.body}");
          }
        } catch (e) {
          print("Error: $e");
        }
        return null;
      }
    }
    
    class PayPalPaymentPage extends StatefulWidget {
      @override
      _PayPalPaymentPageState createState() => _PayPalPaymentPageState();
    }
    
    class _PayPalPaymentPageState extends State<PayPalPaymentPage> {
      final PayPalService _payPalService = PayPalService();
      late InAppWebViewController webViewController;
      String approvalUrl = "";
      bool _isLoading = true;
    
      Future<void> initiatePayment() async {
        final accessToken = await _payPalService.getAccessToken();
        if (accessToken != null) {
          final url =
          await _payPalService.createOrder(accessToken, 1.00, "USD");
          if (url != null) {
            setState(() {
              approvalUrl = url;
              _isLoading = false;
            });
          } else {
            print("Failed to create order.");
          }
        } else {
          print("Failed to get access token.");
        }
      }
    
      @override
      void initState() {
        super.initState();
        initiatePayment();
      }
    
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('PayPal 결제'),
          ),
          body: Stack(
            children: [
              if (!_isLoading)
                InAppWebView(
                  initialUrlRequest: URLRequest(url: WebUri(approvalUrl)),
                  onWebViewCreated: (controller) {
                    webViewController = controller;
                  },
    
                  onLoadStop: (controller, url) async {
                    final currentUrl = url.toString();
    
                    if (currentUrl.contains("https://your-domain.com/success")) {
                      // 결제 성공 처리
                      print("결제 성공: $currentUrl");
                      Navigator.pop(context, "success");
                    } else if (currentUrl.contains("https://your-domain.com/cancel")) {
                      // 결제 취소 처리
                      print("결제 취소: $currentUrl");
                      Navigator.pop(context, "cancel");
                    }
                  },
                ),
              if (_isLoading)
                Center(child: CircularProgressIndicator()),
            ],
          ),
        );
      }
    }
    
    void main() {
      runApp(MaterialApp(
        debugShowCheckedModeBanner: false,
        home: PayPalPaymentPage(),
      ));
    }

     

     

    참고로 

    국내 거래(예: 구매자와 판매자 모두 한국인)는 불가합니다.

    또한, 지원하는 통화 종류에 제약이 있으니 반드시 숙지

    반응형

    댓글

Designed by Tistory.