Skip to content

Commit 773dd11

Browse files
committed
Reintroduced and improved bank payment
1 parent ee9851f commit 773dd11

21 files changed

+325
-380
lines changed

example/lib/main.dart

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class _HomePageState extends State<HomePage> {
4646
color: Colors.red,
4747
);
4848
int _radioValue = 0;
49-
CheckoutMethod _method = CheckoutMethod.card;
49+
CheckoutMethod _method;
5050
bool _inProgress = false;
5151
String _cardNumber;
5252
String _cvv;
@@ -181,14 +181,8 @@ class _HomePageState extends State<HomePage> {
181181
isDense: true,
182182
onChanged: (CheckoutMethod value) {
183183
setState(() {
184-
// _method = value;
185-
_method = CheckoutMethod.card;
184+
_method = value;
186185
});
187-
188-
if (value != CheckoutMethod.card) {
189-
_showMessage(
190-
'Currently not supported');
191-
}
192186
},
193187
items: banks.map((String value) {
194188
return new DropdownMenuItem<
@@ -236,13 +230,11 @@ class _HomePageState extends State<HomePage> {
236230
..email = '[email protected]'
237231
..card = _getCardFromUI();
238232

239-
if (_method != CheckoutMethod.bank) {
240-
if (!_isLocal()) {
241-
var accessCode = await _fetchAccessCodeFrmServer(_getReference());
242-
charge.accessCode = accessCode;
243-
} else {
244-
charge.reference = _getReference();
245-
}
233+
if (!_isLocal()) {
234+
var accessCode = await _fetchAccessCodeFrmServer(_getReference());
235+
charge.accessCode = accessCode;
236+
} else {
237+
charge.reference = _getReference();
246238
}
247239

248240
CheckoutResponse response = await PaystackPlugin.checkout(context,
@@ -401,6 +393,7 @@ class _HomePageState extends State<HomePage> {
401393
'There was a problem getting a new access code form'
402394
' the backend: $e');
403395
}
396+
404397
return accessCode;
405398
}
406399

lib/src/api/model/transaction_api_response.dart

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ class TransactionApiResponse extends ApiResponse {
1212
message = 'Unknown server response';
1313
}
1414

15-
TransactionApiResponse.fromMap(Map<String, dynamic> map, {String reference}) {
16-
// Some times the response doesn't return an otp (e.g birthday response) so instead
17-
// nullifying the reference, let's use the passed response.
18-
this.reference =
19-
map.containsKey('reference') ? map['reference'] : reference;
15+
TransactionApiResponse.fromMap(Map<String, dynamic> map) {
16+
this.reference = map['reference'];
2017
if (map.containsKey('trans')) {
2118
trans = map['trans'];
2219
} else if (map.containsKey('id')) {
@@ -26,7 +23,23 @@ class TransactionApiResponse extends ApiResponse {
2623
otpMessage = map['otpmessage'];
2724
status = map['status'];
2825
message = map['message'];
29-
displayText = map['display_text'];
26+
displayText =
27+
!map.containsKey('display_text') ? message : map['display_text'];
28+
29+
if (status != null) {
30+
status = status.toLowerCase();
31+
}
32+
33+
if (auth != null) {
34+
auth = auth.toLowerCase();
35+
}
36+
}
37+
38+
TransactionApiResponse.fromAccessCodeVerification(Map<String, dynamic> map) {
39+
var data = map['data'];
40+
trans = data['id'].toString();
41+
status = data['transaction_status'];
42+
message = map['message'];
3043
}
3144

3245
bool hasValidReferenceAndTrans() {
@@ -51,6 +64,8 @@ class TransactionApiResponse extends ApiResponse {
5164

5265
@override
5366
String toString() {
54-
return 'TransactionApiResponse{reference: $reference, trans: $trans, auth: $auth, otpMessage: $otpMessage, displayText: $displayText}';
67+
return 'TransactionApiResponse{reference: $reference, trans: $trans, auth: $auth, '
68+
'otpMessage: $otpMessage, displayText: $displayText, message: $message, '
69+
'status: $status}';
5570
}
5671
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import 'package:flutter_paystack/src/api/request/base_request_body.dart';
2+
import 'package:flutter_paystack/src/model/charge.dart';
3+
import 'package:flutter_paystack/src/widgets/checkout/bank_checkout.dart';
4+
5+
class BankChargeRequestBody extends BaseRequestBody {
6+
String _accessCode;
7+
BankAccount _account;
8+
String _birthday;
9+
String _token;
10+
String transactionId;
11+
12+
BankChargeRequestBody(Charge charge)
13+
: this._accessCode = charge.accessCode,
14+
this._account = charge.account;
15+
16+
Map<String, String> tokenParams() => {fieldDevice: device, 'token': _token};
17+
18+
@override
19+
Map<String, String> paramsMap() {
20+
var map = {fieldDevice: device, 'account_number': account.number};
21+
if (_birthday != null) {
22+
map['birthday'] = _birthday;
23+
}
24+
return map;
25+
}
26+
27+
set token(String value) => _token = value;
28+
29+
set birthday(String value) => _birthday = value;
30+
31+
BankAccount get account => _account;
32+
33+
String get accessCode => _accessCode;
34+
}

lib/src/api/request/base_request_body.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ abstract class BaseRequestBody {
44
final fieldDevice = 'device';
55
String _device;
66

7+
BaseRequestBody() {
8+
_setDeviceId();
9+
}
10+
711
Map<String, String> paramsMap();
812

913
String get device => _device;
1014

11-
setDeviceId() {
12-
String deviceId = PlatformInfo().deviceId;
15+
_setDeviceId() {
16+
String deviceId = PlatformInfo().deviceId ?? '';
1317
this._device = deviceId;
1418
}
1519
}

lib/src/api/request/mobile_request_body.dart renamed to lib/src/api/request/card_request_body.dart

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'package:flutter_paystack/flutter_paystack.dart';
66
import 'package:flutter_paystack/src/common/card_utils.dart';
77
import 'package:flutter_paystack/src/common/crypto.dart';
88

9-
class ChargeRequestBody extends BaseRequestBody {
9+
class CardRequestBody extends BaseRequestBody {
1010
static const String fieldClientData = "clientdata";
1111
static const String fieldLast4 = "last4";
1212
static const String fieldAccessCode = "access_code";
@@ -38,7 +38,7 @@ class ChargeRequestBody extends BaseRequestBody {
3838
String _plan;
3939
Map<String, String> _additionalParameters;
4040

41-
ChargeRequestBody._(Charge charge, String clientData)
41+
CardRequestBody._(Charge charge, String clientData)
4242
: this._clientData = clientData,
4343
this._last4 = charge.card.last4Digits,
4444
this._publicKey = PaystackPlugin.publicKey,
@@ -55,13 +55,11 @@ class ChargeRequestBody extends BaseRequestBody {
5555
this._plan = charge.plan,
5656
this._currency = charge.currency,
5757
this._accessCode = charge.accessCode,
58-
this._additionalParameters = charge.additionalParameters {
59-
this.setDeviceId();
60-
}
58+
this._additionalParameters = charge.additionalParameters;
6159

62-
static Future<ChargeRequestBody> getChargeRequestBody(Charge charge) async {
60+
static Future<CardRequestBody> getChargeRequestBody(Charge charge) async {
6361
return Crypto.encrypt(CardUtils.concatenateCardFields(charge.card))
64-
.then((clientData) => ChargeRequestBody._(charge, clientData));
62+
.then((clientData) => CardRequestBody._(charge, clientData));
6563
}
6664

6765
addPin(String pin) async {

lib/src/api/request/validate_request_body.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ class ValidateRequestBody extends BaseRequestBody {
66
String trans;
77
String token;
88

9-
ValidateRequestBody() {
10-
this.setDeviceId();
11-
}
12-
139
@override
1410
Map<String, String> paramsMap() {
1511
Map<String, String> params = {_fieldTrans: trans, _fieldToken: token};

lib/src/api/request/web_charge_request_body.dart

Lines changed: 0 additions & 46 deletions
This file was deleted.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import 'dart:async';
2+
import 'dart:convert';
3+
import 'dart:io';
4+
5+
import 'package:flutter_paystack/src/api/model/transaction_api_response.dart';
6+
import 'package:flutter_paystack/src/api/request/bank_charge_request_body.dart';
7+
import 'package:flutter_paystack/src/api/service/base_service.dart';
8+
import 'package:flutter_paystack/src/common/exceptions.dart';
9+
import 'package:flutter_paystack/src/common/my_strings.dart';
10+
import 'package:http/http.dart' as http;
11+
12+
class BankService extends BaseApiService {
13+
Future<String> getTransactionId(String accessCode) async {
14+
var url =
15+
'https://api.paystack.co/transaction/verify_access_code/$accessCode';
16+
try {
17+
http.Response response = await http.get(url);
18+
Map responseBody = jsonDecode(response.body);
19+
bool status = responseBody['status'];
20+
if (response.statusCode == HttpStatus.ok && status) {
21+
return responseBody['data']['id'].toString();
22+
}
23+
} catch (e) {}
24+
return null;
25+
}
26+
27+
Future<TransactionApiResponse> chargeBank(
28+
BankChargeRequestBody requestBody) async {
29+
var url =
30+
'$baseUrl/bank/charge_account/${requestBody.account.bank.id}/${requestBody.transactionId}';
31+
return _getChargeFuture(url, fields: requestBody.paramsMap());
32+
}
33+
34+
Future<TransactionApiResponse> validateToken(
35+
BankChargeRequestBody requestBody, Map<String, String> fields) async {
36+
var url =
37+
'$baseUrl/bank/validate_token/${requestBody.account.bank.id}/${requestBody.transactionId}';
38+
return _getChargeFuture(url, fields: fields);
39+
}
40+
41+
Future<TransactionApiResponse> _getChargeFuture(String url,
42+
{var fields}) async {
43+
http.Response response =
44+
await http.post(url, body: fields, headers: headers);
45+
return _getResponseFuture(response);
46+
}
47+
48+
TransactionApiResponse _getResponseFuture(http.Response response) {
49+
var body = response.body;
50+
51+
Map<String, dynamic> responseBody = json.decode(body);
52+
53+
var statusCode = response.statusCode;
54+
55+
if (statusCode == HttpStatus.ok) {
56+
return TransactionApiResponse.fromMap(responseBody);
57+
} else {
58+
throw new ChargeException(Strings.unKnownResponse);
59+
}
60+
}
61+
}
Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
1-
import 'package:meta/meta.dart';
1+
import 'dart:convert';
2+
import 'dart:io';
23

3-
class BaseApiService {
4-
final Map<String, String> headers;
5-
final String baseUrl;
4+
import 'package:flutter_paystack/src/common/platform_info.dart';
65

7-
BaseApiService({@required this.headers, @required this.baseUrl});
6+
class BaseApiService {
7+
final Map<String, String> headers = {
8+
HttpHeaders.contentTypeHeader: 'application/x-www-form-urlencoded',
9+
HttpHeaders.userAgentHeader: PlatformInfo().userAgent,
10+
HttpHeaders.acceptHeader: 'application/json',
11+
'X-Paystack-Build': PlatformInfo().paystackBuild,
12+
'X-PAYSTACK-USER-AGENT':
13+
jsonEncode({'lang': Platform.isIOS ? 'objective-c' : 'kotlin'}),
14+
'bindings_version': Platform.isIOS
15+
? '3.0.5' // Latest version of Paystack official iOS SDK
16+
: '3.0.10', // Latest version of Paystack official Android SDK
17+
'X-FLUTTER-USER-AGENT': jsonEncode({'version': '0.10.0'})
18+
};
19+
final String baseUrl = 'https://standard.paystack.co';
820
}

0 commit comments

Comments
 (0)