شرح استخدام paymob مع Flutter بسهوله تامه
في هذا المقال سوف نقوم بالتعامل مع خدمة paymob مع Flutter حيث في الدروس السابقة شرحنا لكم كيف تقوم بالتعامل معها مع post man وماهي الاشياء التي تحتاجها في انشاء التطبيق الخاص بك ,وفي هذه المقالة سوف نكمل معكم السلسلة وسوف نقوم بربط paymob مع تطبيقات فلاتر الخاصه بنا بكل سهوله الامر بسيط جدا وغير معقد كل ما سوف نحتاجه هو تركيب المكتبات التاليه والتي بوسعها مساعدتنا في التعامل مع api وايضا عمل state management للتطبيق الخاص بنا .
add packages :
flutter_bloc: ^8.0.1
dio: ^4.0.6
How to handle dio file
في البداية سوف نقوم بعمل تهيئة لملف dio والذي يكون الملف الذي سوف يساعدنا في التعامل مع الملفات من الانترنت من apis وغيره .
dio.dart
import 'package:dio/dio.dart';
import 'constants.dart';
class DioHelper {
static late Dio dio;
//initial state
static init() {
BaseOptions options = BaseOptions(
baseUrl: baseurl,
validateStatus: (_) => true,
receiveDataWhenStatusError: true,
connectTimeout: 20 * 1000,
receiveTimeout: 20 * 1000,
);
dio = Dio(options);
}
//getdata from api
static Future<Response?> getData({
required String url,
Map<String, dynamic>? query,
}) async {
dio.options.headers = {
"Content-Type": "application/json",
};
try {
Response response = await dio.get(
url,
queryParameters: query,
);
return response;
} catch (e) {
print(e);
return null;
}
}
//post data to api
static Future<Response?> postData({
required String url,
required Map<String, dynamic>? data,
Map<String, dynamic>? query,
}) async {
dio.options.headers = {
"Content-Type": "application/json",
};
try {
Response response = await dio.post(
url,
data: data,
queryParameters: query,
);
return response;
} catch (e) {
print(e);
return null;
}
}
}
Strings file
نقوم هنا بعمل class جديد يمكننا من عمل المحتويات النصية التي سوف نحتاجها في العمل وهيا base url وايضا ال end point وهيا العناصر التي تكون في نهايه الرابط , وايضا قم بوضع token الخاص بك وال id الخاص بال card و kiosk الذين تحصل عليهم من paymob والذي شرحنا طرق الحصول عليهم في الدروس السابقة .
constants.dart
const String baseurl = 'https://accept.paymob.com/api/';
//first token url
const String authenticationrequesturl = 'auth/tokens';
const String orderidurl = 'ecommerce/orders';
const String paymentkeytokenurl = 'acceptance/payment_keys';
const String paymentReferencecodeurl = 'acceptance/payments/pay';
const String paymentApiKey ='YOUR_TOKEN';
//card
const String integrationIDCard = '---';
//kiosk
const String integrationIDKiosk = '---';
String finalToken = '';
String refcode = '';
create ui in Flutter payment
في هذا الجزء سوف نقوم بعمل التصميم الذي سوف نعمل عليهم وهو بسيط جدا عباره عن buttons سوف نتعامل معهم وكل زر منهم يقوم بامر معين والكود الخاص بهم موجود في ال cubit .
ui.dart
myButton(
elevation: 0.0,
textOnly: false,
iconWidget: svgImage(
path: Assets.images.svg.login,
color: Colors.white,
),
height: context.heightScreenWithOutBottom * 0.09,
text: AppString.login,
onPressed: () {
cubit.paymentWithCard(integrationMethod: integrationIDKiosk);
}),
myButton(
elevation: 0.0,
textOnly: false,
iconWidget: svgImage(
path: Assets.images.svg.login,
color: Colors.white,
),
height: context.heightScreenWithOutBottom * 0.09,
text: AppString.login,
onPressed: () {
cubit.paymentWithCard(integrationMethod: integrationIDCard);
// navigateTo(context, PinPage());
}),
How to create methods to handle with bloc
الجزء الاخير وهو الكود الذي يوجد بال cubit والمسؤول عن عمل استدعاء لل dio والحصول على البيانات من ال api وعرضها .
cubit.dart
/// ----------------- payment Application
// payment
String firstToken = '';
String finalToken = '';
String orderId = '';
Future paymentWithCard({
String firstname = 'ahmed',
String lastname = 'mohamed',
String email = 'test',
String phone = '01000000000',
String integrationMethod = '',
int price = 100,
bool isCard = true,
}) async {
// 1 - first token
DioHelper.postData(
url: authenticationrequesturl,
data: {"api_key": paymentApiKey}).then((value) async {
firstToken = value!.data['token'];
print('firstToken --------------- $firstToken');
// 2 - order id
getOrderId().then((value) {
print('orderId --------------- $orderId');
// 3 - final token
getFinalToken(
firstname: firstname,
lastname: lastname,
email: email,
price: price,
phone: phone,
firstToken: firstToken,
integrationmethod: integrationMethod);
});
emit(PaymentSuccess());
});
}
// OrdeId
Future getOrderId() async {
await DioHelper.postData(url: orderidurl, data: {
'auth_token': firstToken,
'delivery_needed': false,
'amount_cents': '20000',
"currency": "EGP",
'items': [],
}).then((value) {
orderId = value!.data['id'].toString();
emit(PaymentGetOrderIdSuccess());
}).catchError((error) {
print(error.toString());
emit(PaymentGetOrderIdError(error.toString()));
});
}
// Payment key Token (final)
Future getFinalToken({
required String firstname,
required String lastname,
required String email,
required String phone,
required int price,
required String integrationmethod,
required String firstToken,
}) async {
await DioHelper.postData(url: paymentkeytokenurl, data: {
"auth_token": firstToken,
"amount_cents": "${price * 100}",
"expiration": 3600,
"order_id": orderId,
"billing_data": {
"apartment": "NA",
"email": email,
"floor": "NA",
"first_name": firstname,
"street": "NA",
"building": "NA",
"phone_number": phone,
"shipping_method": "NA",
"postal_code": "NA",
"city": "NA",
"country": "NA",
"last_name": lastname,
"state": "NA"
},
"currency": "EGP",
"integration_id": integrationmethod,
"lock_order_when_paid": "false"
}).then((value) {
finalToken = value!.data['token'];
print('final token is :$finalToken');
if (integrationmethod == integrationIDKiosk)
getRefererencCodeKiosk();
emit(PaymentkeyTokenSuccess());
}).catchError((error) {
print(error.toString());
emit(PaymentkeyTokenError(error.toString()));
});
}
//get ref code
Future getRefererencCodeKiosk() async {
await DioHelper.postData(url:
paymentReferencecodeurl, data: {
"source": {"identifier":
"AGGREGATOR", "subtype":
"AGGREGATOR"},
"payment_token": finalToken
}).then((value) {
refcode = value!.data['id'].toString();
print('referance code is ---- :$refcode');
emit(PaymentkReferencecodeSuccess());
}).catchError((error) {
emit(PaymentReferencecodeError(error.toString()));
});
}