اذهب إلى المحتوى

السؤال

نشر

السلام عليكم ورحمة الله وبركاته

تحيه طيبه للجميع

لدي كود لدفع بواسطته الى بوابة الدفع PayPal

الكود الان شغال على وضع الاختبار Sandbox 

ارغب بتغيره الى الدفع الحقيقي كيف يمكن فعل ذلك؟

الكود المستعمل كالتالي:


import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_paypal/models/paypal_response_model.dart';
import 'package:meta/meta.dart';
import 'package:flutter/services.dart';

class FlutterPaypal {
  static const MethodChannel _channel =  const MethodChannel('flutter_paypal');

  static Future<String> initialization({
    @required bool isEnvironmentSandbox,
    @required String payPalClientId
  }) async {
    try {
      final String initResponse = await _channel.invokeMethod('initialization', {
        'isEnvironmentSandbox': isEnvironmentSandbox,
        'payPalClientId': payPalClientId,
      });
      return initResponse;
    } catch (e) {
      throw ErrorDescription(e.toString());
    }
  }

  static Future<PayPalResponse> processPayment({
    @required double amount,
    @required String currency,
    @required String description,
  }) async {
    try {
      final String paypalResponse = await _channel.invokeMethod('processPayment', {
        'amount': amount,
        'currency': currency,
        'description': description
      });
      return PayPalResponse.fromJson(jsonDecode(paypalResponse));
    } catch (e) {
      throw ErrorDescription(e.toString());
    }
  }

}

 

 

class PayPalResponse {
  Client client;
  Response response;
  String responseType;
  String paymentAmount;

  PayPalResponse(
      {this.client, this.response, this.responseType, this.paymentAmount});

  PayPalResponse.fromJson(Map<String, dynamic> json) {
    client =
        json['client'] != null ? new Client.fromJson(json['client']) : null;
    response = json['response'] != null
        ? new Response.fromJson(json['response'])
        : null;
    responseType = json['response_type'];
    paymentAmount = json['paymentAmount'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this.client != null) {
      data['client'] = this.client.toJson();
    }
    if (this.response != null) {
      data['response'] = this.response.toJson();
    }
    data['response_type'] = this.responseType;
    data['paymentAmount'] = this.paymentAmount;
    return data;
  }
}

class Client {
  String environment;
  String paypalSdkVersion;
  String platform;
  String productName;

  Client(
      {this.environment,
      this.paypalSdkVersion,
      this.platform,
      this.productName});

  Client.fromJson(Map<String, dynamic> json) {
    environment = json['environment'];
    paypalSdkVersion = json['paypal_sdk_version'];
    platform = json['platform'];
    productName = json['product_name'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['environment'] = this.environment;
    data['paypal_sdk_version'] = this.paypalSdkVersion;
    data['platform'] = this.platform;
    data['product_name'] = this.productName;
    return data;
  }
}

class Response {
  String createTime;
  String id;
  String intent;
  String state;

  Response({this.createTime, this.id, this.intent, this.state});

  Response.fromJson(Map<String, dynamic> json) {
    createTime = json['create_time'];
    id = json['id'];
    intent = json['intent'];
    state = json['state'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['create_time'] = this.createTime;
    data['id'] = this.id;
    data['intent'] = this.intent;
    data['state'] = this.state;
    return data;
  }
}

 

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_paypal/flutter_paypal.dart';
import 'package:flutter_paypal/models/paypal_response_model.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  TextEditingController _amountCtrl = TextEditingController();
  TextEditingController _descriptionCtrl = TextEditingController();

  PayPalResponse _payPalResponse;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.black,
          elevation: 0.0,
        ),
        body: SingleChildScrollView(
          child: Container(
            margin: EdgeInsets.all(16.0),
            child: Column(
              children: [
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('PayPal SDK example app', style: TextStyle(fontSize: 22.0, fontWeight: FontWeight.bold)),
                    SizedBox(height: 5.0),
                    Text('Complete all the information below', style: TextStyle(color: Colors.grey)),
                    SizedBox(height: 10.0),
                    TextField(
                      controller: _amountCtrl,
                      keyboardType: TextInputType.phone,
                      decoration: InputDecoration(
                        hintText: "Amount to pay"
                      ),
                    ),
                    SizedBox(height: 10.0),
                    TextField(
                      controller: _descriptionCtrl,
                      decoration: InputDecoration(
                          hintText: "Description"
                      ),
                    ),
                    SizedBox(height: 40.0),
                    Container(
                      height: 45.0,
                      width: double.infinity,
                      child: RaisedButton(
                        color: Colors.white,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10.0)
                        ),
                        onPressed: () async {
                          try {
                            final result = await FlutterPaypal.initialization(
                                isEnvironmentSandbox: false,
                                payPalClientId: "=============================="
                            );
                            print(result);
                          } catch (e) {
                            print("Error initializing PAYPAL: ${e.toString()}");
                          }
                        },
                        child: Text("Initialze PayPal", style: TextStyle(fontWeight: FontWeight.bold),),
                      ),
                    ),
                    SizedBox(height: 20.0),
                    Container(
                      height: 45.0,
                      width: double.infinity,
                      child: RaisedButton(
                        color: Colors.black,
                        shape: RoundedRectangleBorder(
                          borderRadius: BorderRadius.circular(10.0)
                        ),
                        onPressed: () async {
                          try {
                            final result = await FlutterPaypal.processPayment(
                                amount: double.parse(_amountCtrl.text),
                                currency: "USD",
                                description: _descriptionCtrl.text
                            );
                            setState(() {
                              _payPalResponse = result;
                            });
                          } catch (e) {
                            print("Error in transaction with PAYPAL: ${e.toString()}");
                          }
                        },
                        child: Text("Pay with PayPal", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),),
                      ),
                    ),
                    SizedBox(height: 40.0),
                    (_payPalResponse != null) ?
                    _buildPayPalResponse() :
                    Container()
                  ]
                ),
              ]
            ),
          ),
        ),
      ),
    );
  }

  _buildPayPalResponse() {
    return Center(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Text('RESPONSE', style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),),
          SizedBox(height: 10.0),
          Text(_payPalResponse.paymentAmount),
          Text(_payPalResponse.response.state),
          Text(_payPalResponse.response.id),
          Text(_payPalResponse.response.intent),
          Text(_payPalResponse.response.createTime),
          Text(_payPalResponse.client.productName),
          Text(_payPalResponse.client.environment),
          Text(_payPalResponse.client.paypalSdkVersion),
          Text(_payPalResponse.client.platform),
        ],
      ),
    );
  }

}

 

Recommended Posts

  • 0
نشر
بتاريخ 6 دقائق مضت قال بلال زيادة:

لو لاحظت في الكود المستخدم انه يوجد متغير باسم isEnvironmentSandbox وهذا يأخذ قيمة bool 

يعني true or false 

إذا أردت تغيير الوضع إلى live mode قم بتغيير قيمة isEnvironmentSandbox إلى false. 

 

مرحبا اخي هو الان وضع false معمول من قبل

  • 0
نشر

لا أعلم في حال كان الكود الذي قمت بكتابته هنا كاملاً لأنني لم ألاحظ مكان وجود رابط الاتصال مع paypal ولكن يجب عليك تغييره من api.sandbox إلى api.paypal وعادة يتم تقسيم الكود إلى 3 ملفات للسهولة، سأقوم بوضع مثال شامل لك لكي تستطيع الاستفادة منه بشكل كامل:
أولاً ملف PaypalServices.dart وهو الملف المسؤول عن الاتصال مع paypal:
 

import 'package:http/http.dart' as http;
import 'dart:async';
import 'dart:convert' as convert;
import 'package:http_auth/http_auth.dart';

class PaypalServices {

  String domain = "https://api.sandbox.paypal.com"; // for sandbox mode للتجربة فقط
//  String domain = "https://api.paypal.com"; // for production mode عند النشر نقوم باستخدام هذا الرابط

  // هنا يجب عليك استبدال المعلومات التالية بمعلومات حسابك
  String clientId = 'Ab4vS4vmfQFgUuQMH49F9Uy3L1FdNHtfGrASCyjNijm_EkHWCFM96ex0la-YFbwavw41R3rTKU3k_Bbm';
  String secret = 'EDjvPfYgTYqdYWR2BfOiBW4dz_jeeuadqH7Z98pZMDvY33PcViiooqYFWVPFSGbfKBfNOb3LnroSI1hv';

  // for getting the access token from Paypal
  Future<String> getAccessToken() async {
    try {
      var client = BasicAuthClient(clientId, secret);
      var response = await client.post('$domain/v1/oauth2/token?grant_type=client_credentials');
      if (response.statusCode == 200) {
        final body = convert.jsonDecode(response.body);
        return body["access_token"];
      }
      return null;
    } catch (e) {
      rethrow;
    }
  }

  // for creating the payment request with Paypal
  Future<Map<String, String>> createPaypalPayment(
      transactions, accessToken) async {
    try {
      var response = await http.post("$domain/v1/payments/payment",
          body: convert.jsonEncode(transactions),
          headers: {
            "content-type": "application/json",
            'Authorization': 'Bearer ' + accessToken
          });

      final body = convert.jsonDecode(response.body);
      if (response.statusCode == 201) {
        if (body["links"] != null && body["links"].length > 0) {
          List links = body["links"];

          String executeUrl = "";
          String approvalUrl = "";
          final item = links.firstWhere((o) => o["rel"] == "approval_url",
              orElse: () => null);
          if (item != null) {
            approvalUrl = item["href"];
          }
          final item1 = links.firstWhere((o) => o["rel"] == "execute",
              orElse: () => null);
          if (item1 != null) {
            executeUrl = item1["href"];
          }
          return {"executeUrl": executeUrl, "approvalUrl": approvalUrl};
        }
        return null;
      } else {
        throw Exception(body["message"]);
      }
    } catch (e) {
      rethrow;
    }
  }

  // for executing the payment transaction
  Future<String> executePayment(url, payerId, accessToken) async {
    try {
      var response = await http.post(url,
          body: convert.jsonEncode({"payer_id": payerId}),
          headers: {
            "content-type": "application/json",
            'Authorization': 'Bearer ' + accessToken
          });

      final body = convert.jsonDecode(response.body);
      if (response.statusCode == 200) {
        return body["id"];
      }
      return null;
    } catch (e) {
      rethrow;
    }
  }
}

الملف الثاني وهو PaypalPayment.dart المسؤول عن عرض webview التي ستقوم بدورها بعرض واجهة الدفع، وفي المثال التالي تم عرض شراء منتج موبايل على سبيل المثال كالتالي:

import 'dart:core';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'PaypalServices.dart';

class PaypalPayment extends StatefulWidget {
  final Function onFinish;

  PaypalPayment({this.onFinish});

  @override
  State<StatefulWidget> createState() {
    return PaypalPaymentState();
  }
}

class PaypalPaymentState extends State<PaypalPayment> {
  GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
  String checkoutUrl;
  String executeUrl;
  String accessToken;
  PaypalServices services = PaypalServices();

  // you can change default currency according to your need
  Map<dynamic,dynamic> defaultCurrency = {"symbol": "USD ", "decimalDigits": 2, "symbolBeforeTheNumber": true, "currency": "USD"};

  bool isEnableShipping = false;
  bool isEnableAddress = false;

  String returnURL = 'return.example.com';
  String cancelURL= 'cancel.example.com';


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

    Future.delayed(Duration.zero, () async {
      try {
        accessToken = await services.getAccessToken();

        final transactions = getOrderParams();
        final res =
            await services.createPaypalPayment(transactions, accessToken);
        if (res != null) {
          setState(() {
            checkoutUrl = res["approvalUrl"];
            executeUrl = res["executeUrl"];
          });
        }
      } catch (e) {
        print('exception: '+e.toString());
        final snackBar = SnackBar(
          content: Text(e.toString()),
          duration: Duration(seconds: 10),
          action: SnackBarAction(
            label: 'Close',
            onPressed: () {
              // Some code to undo the change.
            },
          ),
        );
        _scaffoldKey.currentState.showSnackBar(snackBar);
      }
    });
  }

  // item name, price and quantity
  String itemName = 'iPhone X';
  String itemPrice = '1.99';
  int quantity = 1;

  Map<String, dynamic> getOrderParams() {
    List items = [
      {
        "name": itemName,
        "quantity": quantity,
        "price": itemPrice,
        "currency": defaultCurrency["currency"]
      }
    ];


    // checkout invoice details
    String totalAmount = '1.99';
    String subTotalAmount = '1.99';
    String shippingCost = '0';
    int shippingDiscountCost = 0;
    String userFirstName = 'Gulshan';
    String userLastName = 'Yadav';
    String addressCity = 'Delhi';
    String addressStreet = 'Mathura Road';
    String addressZipCode = '110014';
    String addressCountry = 'India';
    String addressState = 'Delhi';
    String addressPhoneNumber = '+919990119091';

    Map<String, dynamic> temp = {
      "intent": "sale",
      "payer": {"payment_method": "paypal"},
      "transactions": [
        {
          "amount": {
            "total": totalAmount,
            "currency": defaultCurrency["currency"],
            "details": {
              "subtotal": subTotalAmount,
              "shipping": shippingCost,
              "shipping_discount":
                  ((-1.0) * shippingDiscountCost).toString()
            }
          },
          "description": "The payment transaction description.",
          "payment_options": {
            "allowed_payment_method": "INSTANT_FUNDING_SOURCE"
          },
          "item_list": {
            "items": items,
            if (isEnableShipping &&
                isEnableAddress)
              "shipping_address": {
                "recipient_name": userFirstName +
                    " " +
                    userLastName,
                "line1": addressStreet,
                "line2": "",
                "city": addressCity,
                "country_code": addressCountry,
                "postal_code": addressZipCode,
                "phone": addressPhoneNumber,
                "state": addressState
              },
          }
        }
      ],
      "note_to_payer": "Contact us for any questions on your order.",
      "redirect_urls": {
        "return_url": returnURL,
        "cancel_url": cancelURL
      }
    };
    return temp;
  }

  @override
  Widget build(BuildContext context) {
    print(checkoutUrl);

    if (checkoutUrl != null) {
      return Scaffold(
        appBar: AppBar(
          backgroundColor: Theme.of(context).backgroundColor,
          leading: GestureDetector(
            child: Icon(Icons.arrow_back_ios),
            onTap: () => Navigator.pop(context),
          ),
        ),
        body: WebView(
          initialUrl: checkoutUrl,
          javascriptMode: JavascriptMode.unrestricted,
          navigationDelegate: (NavigationRequest request) {
            if (request.url.contains(returnURL)) {
              final uri = Uri.parse(request.url);
              final payerID = uri.queryParameters['PayerID'];
              if (payerID != null) {
                services
                    .executePayment(executeUrl, payerID, accessToken)
                    .then((id) {
                  widget.onFinish(id);
                  Navigator.of(context).pop();
                });
              } else {
                Navigator.of(context).pop();
              }
              Navigator.of(context).pop();
            }
            if (request.url.contains(cancelURL)) {
              Navigator.of(context).pop();
            }
            return NavigationDecision.navigate;
          },
        ),
      );
    } else {
      return Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          leading: IconButton(
              icon: Icon(Icons.arrow_back),
              onPressed: () {
                Navigator.of(context).pop();
              }),
          backgroundColor: Colors.black12,
          elevation: 0.0,
        ),
        body: Center(child: Container(child: CircularProgressIndicator())),
      );
    }
  }
}

وأخيراً، الملف الرئيسي الذي سيحوي زر عند الضغط عليه سيقوم بتحويلك إلى واجهة paypal السابقة، makePayment.dart:
 

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'PaypalPayment.dart';

class makePayment extends StatefulWidget {
  
  @override
  _makePaymentState createState() => _makePaymentState();
}

class _makePaymentState extends State<makePayment> {

  TextStyle style = TextStyle(fontFamily: 'Open Sans', fontSize: 15.0);
  final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: new Scaffold(
          backgroundColor: Colors.transparent,
          key: _scaffoldKey,
          appBar: PreferredSize(
            preferredSize: Size.fromHeight(45.0),
            child: new AppBar(
              backgroundColor: Colors.white,
              title: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(
                    'Paypal Payment Example',
                    style: TextStyle(
                        fontSize: 16.0,
                        color: Colors.red[900],
                        fontWeight: FontWeight.bold,
                        fontFamily: 'Open Sans'),
                  ),
                ],
              ),
            ),
          ),
          body:Container(
              width: MediaQuery.of(context).size.width,
              child: Container(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    RaisedButton(
                      onPressed: (){

                        // make PayPal payment

                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (BuildContext context) => PaypalPayment(
                              onFinish: (number) async {

                                // payment done
                                print('order id: '+number);

                              },
                            ),
                          ),
                        );

                        
                      },
                      child: Text('Pay with Paypal', textAlign: TextAlign.center,),
                    ),

                  ],
                ),
              )
          ),
        )
    );
  }

}

بالتوفيق،

  • 0
نشر
بتاريخ On 2/10/2021 at 22:18 قال Sam Ahw:

لا أعلم في حال كان الكود الذي قمت بكتابته هنا كاملاً لأنني لم ألاحظ مكان وجود رابط الاتصال مع paypal ولكن يجب عليك تغييره من api.sandbox إلى api.paypal وعادة يتم تقسيم الكود إلى 3 ملفات للسهولة، سأقوم بوضع مثال شامل لك لكي تستطيع الاستفادة منه بشكل كامل:
أولاً ملف PaypalServices.dart وهو الملف المسؤول عن الاتصال مع paypal:
 


 

الملف الثاني وهو PaypalPayment.dart المسؤول عن عرض webview التي ستقوم بدورها بعرض واجهة الدفع، وفي المثال التالي تم عرض شراء منتج موبايل على سبيل المثال كالتالي:


 

وأخيراً، الملف الرئيسي الذي سيحوي زر عند الضغط عليه سيقوم بتحويلك إلى واجهة paypal السابقة، makePayment.dart:
 


 

بالتوفيق،

مرحبا اخي 

شكرا على ردك والكود الذي ارسلته

اخي هذا الكود يعمل نعم لقد قمت بتجربته من قبل ولكن توجد مشكله وحيده لا اعلم اذا كنت تعلم طريقة حلها

المشكله هذا الكود يعرض للمستخدم طريقة الدفع القديمة من الباي يبال وليس النوع الجديد الذي يحتوي على خيار الدفع بواسطة الفيزا 

هل تملك فكره عن سبب حدوث ذلك؟

 

انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أجب على هذا السؤال...

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.

  • إعلانات

  • تابعنا على



×
×
  • أضف...