Skip to content

Commit

Permalink
Changes for v0.10.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wilburx9 committed Feb 8, 2019
1 parent e25f344 commit ee9851f
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 32 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,12 @@
## 0.10.0 (Breaking change)


* Security Improvement: Removed usage of the secret key in checkout
* Removed support for bank payment (requires secret key)
* Transaction initialization and verification is no longer being handled by the checkout function (requires secret key)
* Handled Gateway timeout error
* Returning last for digits instead full card number after payment

## 0.9.3

* Fixed failure of web OTP on iOS devices
Expand Down
54 changes: 32 additions & 22 deletions README.md
Expand Up @@ -2,42 +2,45 @@

[![pub package](https://img.shields.io/pub/v/flutter_paystack.svg)](https://pub.dartlang.org/packages/flutter_paystack)

A Flutter plugin for making payments via Paystack Payment Gateway. Completely supports Android and iOS.
A Flutter plugin for making payments via Paystack Payment Gateway. Fully
supports Android and iOS.

## :rocket: Installation
To use this plugin, add `flutter_paystack` as a [dependency in your pubspec.yaml file](https://flutter.io/platform-plugins/).

Then initialize the plugin preferably in the `initState` of your widget.

``` dart
import 'package:flutter_paystack/flutter_paystack.dart'
import 'package:flutter_paystack/flutter_paystack.dart';
class _PaymentPageState extends State<PaymentPage> {
var paystackPublicKey = '[YOUR_PAYSTACK_PUBLIC_KEY]';
var paystackSecretKey = '[YOUR_PAYSTACK_SECRET_KEY]';
var publicKey = '[YOUR_PAYSTACK_PUBLIC_KEY]';
@override
void initState() {
PaystackPlugin.initialize(
publicKey: paystackPublicKey, secretKey: paystackSecretKey);
// secretKey is not needed if you're not using checkout as a payment method.
//
publicKey: publicKey);
}
}
```

No other configuration required - the plugin works out of the box.
No other configuration required&mdash;the plugin works out of the box.

## :heavy_dollar_sign: Making Payments
There are two ways of making payment with the plugin.
1. **Checkout**: This is the easy way; as the plugin handles all the processes involved in making a payment.
2. **Charge Card**: This is a longer approach; you handle all callbacks and UI states on your own.
1. **Checkout**: This is the easy way; as the plugin handles all the
processes involved in making a payment (except transaction
initialization and verification which should be done from your
backend).
2. **Charge Card**: This is a longer approach; you handle all callbacks
and UI states.

### 1. :star2: Checkout (Recommended)
You initialize a charge object with just an amount, email & accessCode or reference.
Pass an `accessCode` only when you have [initialized the transaction](https://developers.paystack.co/reference#initialize-a-transaction) from your end otherwise, pass `reference`;
You initialize a charge object with an amount, email & accessCode or
reference. Pass an `accessCode` only when you have
[initialized the transaction](https://developers.paystack.co/reference#initialize-a-transaction)
from your backend. Otherwise, pass a `reference`.

Except you want the user to use a preferred checkout method, pass a one of your choosing.

```dart
Charge charge = Charge()
Expand All @@ -46,20 +49,28 @@ There are two ways of making payment with the plugin.
// or ..accessCode = _getAccessCodeFrmInitialization()
..email = 'customer@email.com';
CheckoutResponse response = await PaystackPlugin.checkout(
context,
method: _method,
context context,
charge: charge,
);
```

`PaystackPlugin.checkout()` returns `true` for a successful payment otherwise, it returns `false`.
`PaystackPlugin.checkout()` returns the state and details of the
payment in an instance of `CheckoutResponse` .


It is recommended that when `PaystackPlugin.checkout()` returns, the
payment should be
[verified](https://developers.paystack.co/v2.0/reference#verify-transaction)
on your backend.

### 2. :star: Charge Card
You can choose to initialize the payment locally or via Paystack's backend.
You can choose to initialize the payment locally or via your backend.

#### A. Initialize Via Paystack (Recommended)
#### A. Initialize Via Your Backend (Recommended)

1.a. This starts by making a HTTP POST request to [paystack](https://developers.paystack.co/reference#initialize-a-transaction).
1.a. This starts by making a HTTP POST request to
[paystack](https://developers.paystack.co/reference#initialize-a-transaction)
on your backend.

1.b If everything goes well, the initialization request returns a response with an `access_code`.
You can then create a `Charge` object with the access code and card details. The `charge` is in turn passed to the ` PaystackPlugin.chargeCard()` function for payment:
Expand Down Expand Up @@ -96,10 +107,9 @@ You can then create a `Charge` object with the access code and card details. The
// addressLine1: '90, Nnebisi Road, Asaba, Deleta State');
}
_chargeCard(http.Response response) {
Map<String, dynamic> responseBody = json.decode(response.body);
_chargeCard(String accessCode) {
var charge = Charge()
..accessCode = responseBody['access_code']
..accessCode = accessCode
..card = _getCardFromUI();
PaystackPlugin.chargeCard(context,
Expand Down
3 changes: 2 additions & 1 deletion lib/src/common/paystack.dart
Expand Up @@ -139,7 +139,8 @@ class PaystackPlugin {
/// [onValidated] - Called when the payment completes with an unrecoverable error
///
/// [method] - The payment payment method to use(card, bank). It defaults to
/// [CheckoutMethod.selectable] to allow the user to select
/// [CheckoutMethod.selectable] to allow the user to select. Please note that this is
/// just redundant pending when bank payment returns
static Future<CheckoutResponse> checkout(
BuildContext context, {
@required Charge charge,
Expand Down
20 changes: 12 additions & 8 deletions lib/src/model/card.dart
Expand Up @@ -167,9 +167,10 @@ class PaymentCard {
if (cardCvc == null || cardCvc.trim().isEmpty) return false;

var cvcValue = cardCvc.trim();
bool validLength = ((_type == null && cvcValue.length >= 3 && cvcValue.length <= 4) ||
(CardType.americanExpress == _type && cvcValue.length == 4) ||
(CardType.americanExpress != _type && cvcValue.length == 3));
bool validLength =
((_type == null && cvcValue.length >= 3 && cvcValue.length <= 4) ||
(CardType.americanExpress == _type && cvcValue.length == 4) ||
(CardType.americanExpress != _type && cvcValue.length == 3));
return !(!CardUtils.isWholeNumberPositive(cvcValue) || !validLength);
}

Expand All @@ -182,7 +183,8 @@ class PaymentCard {
if (StringUtils.isEmpty(cardNumber)) return false;

// Remove all non digits
var formattedNumber = cardNumber.trim().replaceAll(new RegExp(r'[^0-9]'), '');
var formattedNumber =
cardNumber.trim().replaceAll(new RegExp(r'[^0-9]'), '');

// Verve card needs no other validation except it matched pattern
if (CardType.fullPatternVerve.hasMatch(formattedNumber)) {
Expand Down Expand Up @@ -265,16 +267,18 @@ abstract class CardType {
static final fullPatternDiscover = RegExp(r'^6(?:011|5[0-9]{2})[0-9]{12}$');
static final fullPatternJCB = RegExp(r'^(?:2131|1800|35[0-9]{3})'
r'[0-9]{11}$');
static final fullPatternVerve = RegExp(r'^((506(0|1))|(507(8|9))|(6500))[0-9]{12,15}$');
static final fullPatternVerve =
RegExp(r'^((506(0|1))|(507(8|9))|(6500))[0-9]{12,15}$');

// Regular expression to match starting characters (aka issuer
// identification number (IIN)) of the card
// Source https://en.wikipedia.org/wiki/Payment_card_number
static final startingPatternVisa = RegExp(r'[4]');
static final startingPatternMasterCard =
RegExp(r'((5[1-5])|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720))');
static final startingPatternMasterCard = RegExp(
r'((5[1-5])|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720))');
static final startingPatternAmericanExpress = RegExp(r'((34)|(37))');
static final startingPatternDinersClub = RegExp(r'((30[0-5])|(3[89])|(36)|(3095))');
static final startingPatternDinersClub =
RegExp(r'((30[0-5])|(3[89])|(36)|(3095))');
static final startingPatternJCB = RegExp(r'(352[89]|35[3-8][0-9])');
static final startingPatternVerve = RegExp(r'((506(0|1))|(507(8|9))|(6500))');
static final startingPatternDiscover = RegExp(r'((6[45])|(6011))');
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
@@ -1,6 +1,6 @@
name: flutter_paystack
description: A Flutter plugin for making payments via Paystack Payment Gateway. Completely supports Android and iOS.
version: 0.9.3
version: 0.10.0
author: Wilberforce Uwadiegwu <faradaywilly@gmail.com>
homepage: https://github.com/wilburt/flutter_paystack

Expand Down

0 comments on commit ee9851f

Please sign in to comment.