pixelpay_sdk 2.0.6 pixelpay_sdk: ^2.0.6 copied to clipboard
PixelPay's tool that simplifies integrations with APIs from the PixelPay platform.
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'dart:math';
import 'package:flutter/services.dart';
import 'package:pixelpay_sdk/models/billing.dart' as pixelpay;
import 'package:pixelpay_sdk/models/item.dart' as pixelpay;
import 'package:pixelpay_sdk/models/order.dart' as pixelpay;
import 'package:pixelpay_sdk/models/card.dart' as pixelpay;
import 'package:pixelpay_sdk/models/settings.dart' as pixelpay;
import 'package:pixelpay_sdk/requests/sale_transaction.dart' as pixelpay;
import 'package:pixelpay_sdk/services/transaction.dart' as pixelpay;
import 'package:pixelpay_sdk/resources/locations.dart' as pixelpay;
final _rnd = Random();
const _chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz1234567890';
String getRandomString(int length) => String.fromCharCodes(Iterable.generate(
length, (_) => _chars.codeUnitAt(_rnd.nextInt(_chars.length))));
pixelpay.Card _card = pixelpay.Card();
pixelpay.Billing _billing = pixelpay.Billing();
pixelpay.Item _item = pixelpay.Item();
pixelpay.Order _order = pixelpay.Order();
Map<String, dynamic> _countries = Map();
Map<String, dynamic> _states = Map();
Map<String, dynamic> _formats = Map();
pixelpay.Card setCardModel() {
final card = pixelpay.Card();
card.number = _testRepository[_selectedUseCase]["card"]["number"];
card.cvv2 = _testRepository[_selectedUseCase]["card"]["cvv2"];
card.expire_month = _testRepository[_selectedUseCase]["card"]["expire_month"];
card.expire_year = DateTime.now().year + 1;
card.cardholder = _testRepository[_selectedUseCase]["card"]["cardholder"];
return card;
}
pixelpay.Billing setBillingModel() {
final billing = pixelpay.Billing();
billing.address = _testRepository[_selectedUseCase]["billing"]["address"];
billing.country = _testRepository[_selectedUseCase]["billing"]["country"];
billing.state = _testRepository[_selectedUseCase]["billing"]["state"];
billing.city = _testRepository[_selectedUseCase]["billing"]["city"];
billing.phone = _testRepository[_selectedUseCase]["billing"]["phone"];
return billing;
}
pixelpay.Item setItemModel() {
final item = pixelpay.Item();
item.code = _testRepository[_selectedUseCase]["item"]["address"];
item.title = _testRepository[_selectedUseCase]["item"]["title"];
item.price = _testRepository[_selectedUseCase]["item"]["price"];
item.qty = _testRepository[_selectedUseCase]["item"]["qty"];
return item;
}
pixelpay.Order setOrderModel(pixelpay.Item item) {
final order = pixelpay.Order();
order.id = getRandomString(8);
order.currency = _testRepository[_selectedUseCase]["order"]["currency"];
order.customer_email = _testRepository[_selectedUseCase]["order"]["customer_email"];
order.customer_name = _testRepository[_selectedUseCase]["order"]["customer_name"];
order.addItem(item);
order.addExtra("test", "lorem ipsum");
order.totalize();
return order;
}
/// Test data repository
Map<String, dynamic> _testRepository = Map();
/// Selected use case
String? _selectedUseCase = '0';
/// General style for buttons
final ButtonStyle buttonStyle = ElevatedButton.styleFrom(
backgroundColor: Colors.teal,
textStyle: const TextStyle(fontSize: 20),
);
/// General style for inputs
InputDecoration inputStyle(String labelText) {
return InputDecoration(
labelText: labelText,
labelStyle: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.w800,
),
border: const OutlineInputBorder(),
);
}
void main() async {
runApp(const MyApp());
if (_testRepository.isEmpty) {
String testingData = await rootBundle.loadString('assets/test.json', cache: true);
_testRepository = jsonDecode(testingData);
_card = setCardModel();
_billing = setBillingModel();
_item = setItemModel();
_order = setOrderModel(_item);
_countries = await pixelpay.Locations.countriesList();
_states = await pixelpay.Locations.statesList("HN");
_formats = await pixelpay.Locations.formatsList("HN");
}
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: const Padding(
padding: EdgeInsets.all(8.0),
child: MyStatefulWidget(),
),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
String _status_code = '---';
String _message = '---';
String _response = 'Empty';
// TODO: cambios para controlar Currency y 3DS interactivo
// String? _selectedCurrency = 'L';
// bool _isChecked = false;
Future<void> sendTransaction() async {
if (!mounted) return;
setState(() {
_message = 'Start transaction ...';
_status_code = '---';
_response = 'Empty';
});
try {
final settings = pixelpay.Settings();
settings.setupSandbox();
_order = setOrderModel(_item);
final sale = pixelpay.SaleTransaction();
sale.setCard(_card);
sale.setBilling(_billing);
sale.setOrder(_order);
// TODO: mejora para cuotas interactivo
sale.setInstallment(12, "extra");
sale.withPointsRedeemAmount(1);
if (_card.number != '4111 1111 1111 1111') {
sale.withAuthenticationRequest();
}
final service = pixelpay.Transaction(settings);
setState(() {
_message = 'Sending transaction ...';
});
final response = await service.doSale(sale);
if (response != null) {
setState(() {
_message = response.message ?? 'Empty message';
_status_code = response.getStatus().toString();
_response = response.toJson();
});
}
} on PlatformException {
setState(() {
_message = 'Failed to get request data.';
});
} on Exception {
setState(() {
_message = 'Exception on code.';
});
}
}
Future<void> resetOutput() async {
if (!mounted) return;
setState(() {
_status_code = '---';
_message = '---';
_response = 'Empty';
});
}
Future<void> showAssets() async {
if (!mounted) return;
setState(() {
_status_code = 'Showing';
_message = 'Assets';
_response = 'FORMATS: ' + jsonEncode(_formats)
+'\n\nSTATES: ' + jsonEncode(_states)
+'\n\nCOUNTRIES: ' + jsonEncode(_countries);
});
}
/// Custom button
Widget customButton(String text, IconData icon, VoidCallback onPressedCallback) {
return ElevatedButton(
key: Key(text),
style: buttonStyle,
onPressed: onPressedCallback,
child: textIconRow(text, icon),
);
}
/// Text and icon in a row
Widget textIconRow(String text, IconData icon) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(text),
Padding(
padding: const EdgeInsets.only(left: 5),
child: Icon(icon),
),
],
);
}
/// Custom text field with focus
Widget customTextField(String? textEditing, String labelText, void Function(String?) onBlurCallback) {
final TextEditingController controller = TextEditingController(text: textEditing);
return Focus(
onFocusChange: (hasFocus) {
if (!hasFocus) {
onBlurCallback(controller.text);
}
},
child: TextField(
decoration: inputStyle(labelText),
controller: controller,
),
);
}
/// Custom read only text field
Widget customReadOnlyTextField(String textEditing, String labelText) {
return TextField(
maxLines: null,
readOnly: true,
controller: TextEditingController(text: textEditing),
decoration: inputStyle(labelText),
);
}
/// Custom Dropdown Button
Widget customDropdownButton(String? textEditing, Map<String, dynamic> dataList, String labelText, void Function(String?) onChangedCallback) {
return DropdownButtonFormField(
key: Key(labelText),
value: textEditing,
decoration: inputStyle(labelText),
isExpanded: true,
icon: const Icon(Icons.expand_more),
elevation: 16,
items: dataList.keys.map<DropdownMenuItem<String>>((String key) {
return DropdownMenuItem<String>(
value: key,
child: Text(dataList[key]["title"]),
);
}).toList(),
onChanged: onChangedCallback,
);
}
/// X Axis Separator
Widget xAxisSeparator(double? width) {
return SizedBox(width: width,);
}
/// Y Axis Separator
Widget yAxisSeparator() {
return const SizedBox(height: 14,);
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
yAxisSeparator(),
customDropdownButton(
_selectedUseCase,
_testRepository,
'Select card',
(value) { setState(() {
_selectedUseCase = value;
_card = setCardModel();
_billing = setBillingModel();
_item = setItemModel();
_order = setOrderModel(_item);
}); }
),
yAxisSeparator(),
Row(
children: [
// TODO: mejora para Currency interactivo
// customDropdownButton(_selectedCurrency, 'Currency'),
// xAxisSeparator(10),
Expanded(
child: customTextField(_order.amount.toString(), 'Amount', (value) { setState(() {
_item.price = double.parse(value!);
_order = setOrderModel(_item);
}); }
),
),
],
),
yAxisSeparator(),
customTextField(_card.number, 'Card Number', (value) { setState(() {_card.number = value;}); }),
yAxisSeparator(),
customTextField(_card.cardholder, 'Card Holder', (value) { setState(() {_card.cardholder = value;}); }),
yAxisSeparator(),
Row(
children: <Widget>[
Expanded(child: customTextField(_card.expire_month.toString(), 'Expire Month', (value) { setState(() {_card.expire_month = int.tryParse(value!);}); }),),
xAxisSeparator(10),
Expanded(child: customTextField((DateTime.now().year + 1).toString(), 'Expire Year', (value) { setState(() {_card.expire_year = int.tryParse(value!);}); }),),
xAxisSeparator(10),
Expanded(child: customTextField(_card.cvv2, 'CVC', (value) { setState(() {_card.cvv2 = value;}); }),),
],
),
yAxisSeparator(),
// TODO: mejorar para 3DS interactivo
// InkWell(
// onTap:() { setState(() { _isChecked = !_isChecked; }); },
// child: Row(
// children: <Widget>[
// Checkbox(
// value: _isChecked,
// onChanged: (value) { setState(() { _isChecked = value!; }); },
// ),
// const Text('Enable 3DS/EMV transaction'),
// ],
// ),
// ),
// yAxisSeparator(),
Row(
children: <Widget>[
Expanded(child: customButton('SALE', Icons.attach_money, sendTransaction),),
xAxisSeparator(10),
Expanded(child: customButton('RESET', Icons.settings_backup_restore, resetOutput),),
],
),
Row(children: <Widget>[
Expanded(child: customButton('SHOW ASSETS', Icons.source, showAssets),),
],),
yAxisSeparator(),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_status_code, key: const Key('status_code')),
xAxisSeparator(10),
Text(_message, key: const Key('main_message'),),
],
),
yAxisSeparator(),
customReadOnlyTextField(_response, 'Response'),
],
),
);
}
}