Skip to content

Commit 5d816c7

Browse files
Merge pull request #3 from Flutterwave/v3-api
V3 api
2 parents 39fc53a + a87f5a3 commit 5d816c7

File tree

83 files changed

+5794
-3596
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+5794
-3596
lines changed

CONTRIBUTING.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ If you want to open a PR that fixes a bug or adds a feature, then we can't thank
1010

1111
## Submitting pull requests
1212

13-
### Modifying react-native-flutterwave
13+
### Modifying flutterwave-react-native
1414
1. Fork this repository
1515
2. Clone your fork
1616
3. Make a branch for your feature or bug fix (i.e. `git checkout -b what-im-adding`)
@@ -20,12 +20,12 @@ If you want to open a PR that fixes a bug or adds a feature, then we can't thank
2020
Depending on the changes you make you might want to test to see if the feature/fix works correctly.
2121
Use the following steps to test your newly added feature/fix.
2222
1. Set up your react-native example project or use one you already have.
23-
2. Create a `.env` file in the root of the library (react-native-flutterwave).
23+
2. Create a `.env` file in the root of the library (flutterwave-react-native).
2424
3. Add **RN_FLW_EXAMPLE_PROJECT** to the `.env` file it's value should be an absolute path to the install destination in your example project.
2525
**E.g.** `RN_FLW_EXAMPLE_PROJECT="/Users/your-name/projects/example-project/src"`.
2626
4. Run the following command `npm run set-example`.
2727

28-
Following these steps will result in you building and copy the built version of the library in the following directory `/Users/your-name/projects/example-project/src/react-native-flutterwave`, you can then go ahead an import the library from within your example project from the location the library has been copied to.
28+
Following these steps will result in you building and copy the built version of the library in the following directory `/Users/your-name/projects/example-project/src/flutterwave-react-native`, you can then go ahead an import the library from within your example project from the location the library has been copied to.
2929

3030
### Writting Tests
3131
We currently don't have strict rules for writting tests but when writting one be sure to make your tests and their captions clear and coincise, test only what you added, and then follow up with the dependencies if need be.
@@ -43,3 +43,5 @@ To start a commit simply run the following cli command from within the project `
4343
4. Have your branch get merged in! :white_check_mark:
4444

4545
If you experience a problem at any point, please don't hesitate to file an issue to get some assistance!
46+
47+
With love from Flutterwave. :yellow_heart:

README.md

+135-137
Large diffs are not rendered by default.

README.v2.md

+317
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
# React Native Flutterwave
2+
Easily implement Flutterwave for payments in your React Native appliction. This library supports both Android and iOS, and use the Flutterwave's V2 API.
3+
4+
[![V2 API](https://img.shields.io/badge/API-V2-brightgreen)](https://developer.flutterwave.com/v2.0/docs/getting-started) [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
5+
6+
<p align="center">
7+
<img src=".github/images/github-preview-ios.gif" alt="ios-preview"/>
8+
<img src=".github/images/github-preview-android.gif" alt="android-preview"/>
9+
</p>
10+
11+
## Table Of Content
12+
- Getting Started
13+
- [V3 API](#warning-if-using-version-3-api-warning)
14+
- [Installation](#installation)
15+
- [Dependencies](#dependencies)
16+
- [Activity Indicator (Android)](#activity-indicator-only-needed-for-android)
17+
- [Important Information](#fire-important-information-fire)
18+
- Usage
19+
- [PayWithFlutterwaveV2 ](#paywithflutterwavev2)
20+
- [PayWithFlutterwaveV2 (with custom render)](#paywithflutterwavev2-with-custom-render)
21+
- [FlutterwaveButton (Flutterwave styled button)](#flutterwavebutton-flutterwave-styled-button)
22+
- [FlutterwaveInitV2](#flutterwaveinitv2)
23+
- [Aborting Payment Initialization](#aborting-payment-initialization)
24+
- Props
25+
- [FlutterwaveInitV2Options](#flutterwaveinitv2options)
26+
- [PayWithFlutterwaveV2Props](#paywithflutterwavev2props)
27+
- [FlutterwaveButton Props](#flutterwavebutton-props)
28+
- Types
29+
- [PayWithFlutterwaveV2Props](#paywithflutterwavev2props-interface)
30+
- [FlutterwaveButtonProps](#flutterwavebuttonprops-interface)
31+
- [FlutterwaveInitV2Options](#flutterwaveinitv2options-interface)
32+
- [FlutterwaveInitError](#flutterwaveiniterror)
33+
- [FlutterwavePaymentMetaV2](#flutterwavepaymentmetav2)
34+
- [RedirectParamsV2](#redirectparamsv2)
35+
- [CustomButtonProps](#custombuttonprops)
36+
- [Contributing](./CONTRIBUTING.md)
37+
38+
## What's Inside?
39+
- Pay with Flutterwave button and checkout dialog.
40+
- Standard payment initialization function.
41+
- Flutterwave designed button.
42+
43+
## :warning: If Using Version 3 API :warning:
44+
This version of the library's docs focuses on use cases with the Version 2 of Flutterwaves API, if you are using the Version 3 API please use [this documentation](./README.md) instead.
45+
46+
## Installation
47+
This library is available on npm, you can install it by running `npm install --save flutterwave-react-native` or `yarn add flutterwave-react-native`
48+
49+
### Dependencies
50+
In order to render the Flutterwave checkout screen this library depends on [react-native-webview](https://github.com/react-native-community/react-native-webview) ensure you properly install this library before continuing.
51+
52+
### Activity Indicator (only needed for android)
53+
To display the Flutterwave styled activity indicator when the checkout screen is being loaded on Android you will need to add some modules in `android/app/build.gradle`.
54+
***Skip this if you already have setup your app to support gif images.***
55+
````javascript
56+
dependencies {
57+
// If your app supports Android versions before Ice Cream Sandwich (API level 14)
58+
implementation 'com.facebook.fresco:animated-base-support:1.3.0'
59+
60+
// For animated GIF support
61+
implementation 'com.facebook.fresco:animated-gif:2.0.0'
62+
}
63+
````
64+
65+
### :fire: IMPORTANT INFORMATION :fire:
66+
If the `options` property on the [PayWithFlutterwaveV2](flutterwavebuttonprops-interface) changes, when next the user taps on the button a new payment will be initialized whether the last one was successful or not.
67+
68+
Remember you cannot use the same transaction reference for two different payments, remember to recreate the transaction reference before allowing the user initiate a new payment.
69+
70+
71+
## Usage
72+
Below are a few examples showcasing how you can use the library to implement payment in your React Native app.
73+
74+
### PayWithFlutterwaveV2
75+
<img src=".github/images/pay-with-flutterwave.png" alt="preview" width="350"/>
76+
77+
[View All Props](#flutterwavebuttonprops)
78+
79+
Import `PayWithFlutterwaveV2` from `flutterwave-react-native` and use it like so.
80+
````jsx
81+
import {PayWithFlutterwaveV2} from 'flutterwave-react-native';
82+
// or import PayWithFlutterwaveV2 from 'flutterwave-react-native/PayWithFlutterwaveV2';
83+
84+
<PayWithFlutterwaveV2
85+
...
86+
onComplete={handleOnComplete}
87+
options={{
88+
txref: txref,
89+
PBFPubKey: '[Your Flutterwave Public Key]',
90+
customer_email: '[email protected]',
91+
amount: 2000,
92+
currency: 'NGN',
93+
}}
94+
/>
95+
````
96+
97+
### PayWithFlutterwaveV2 (with custom render)
98+
<img src=".github/images/pay-with-flutterwave-custom.png" alt="preview" width="350"/>
99+
100+
[View All Props](#flutterwavebuttonprops)
101+
102+
Import `PayWithFlutterwaveV2` from `flutterwave-react-native` and use it like so.
103+
````jsx
104+
import {PayWithFlutterwaveV2} from 'flutterwave-react-native';
105+
// or import PayWithFlutterwaveV2 from 'flutterwave-react-native/PayWithFlutterwaveV2';
106+
107+
<PayWithFlutterwaveV2
108+
...
109+
onComplete={handleOnComplete}
110+
options={{...}}
111+
customButton={(props) => (
112+
<TouchableOpacity
113+
style={styles.paymentButton}
114+
onPress={props.onPress}
115+
isBusy={props.isInitializing}
116+
disabled={props.disabled}>
117+
<Text style={styles.paymentButtonText}>Pay $500</Text>
118+
</TouchableOpacity>
119+
)}
120+
/>
121+
````
122+
123+
### FlutterwaveButton (Flutterwave styled button)
124+
<img src=".github/images/flutterwave-styled-button.png" alt="preview" width="350"/>
125+
126+
[View All Props](#flutterwavebuttonprops)
127+
128+
Import `FlutterwaveButton` from `flutterwave-react-native` and use it like so.
129+
````jsx
130+
import {FlutterwaveButton} from 'flutterwave-react-native';
131+
132+
<FlutterwaveButton
133+
style={styles.paymentButton}
134+
onPress={onPress}
135+
disabled={disabled}>
136+
<Text style={styles.paymentButtonText}>Pay $500</Text>
137+
</FlutterwaveButton>
138+
````
139+
140+
### FlutterwaveInitV2
141+
When called, this function returns a Promise which resolves to a string on success and rejects if an error occurs. [See all config options](#flutterwaveinitv2options)
142+
143+
Import `FlutterwaveInitV2` from `flutterwave-react-native` and use it like so.
144+
````javascript
145+
import {FlutterwaveInitV2} from 'flutterwave-react-native';;
146+
// or import FlutterwaveInitV2 from 'flutterwave-react-native/FlutterwaveInitV2';
147+
148+
// initialize a new payment
149+
const payment = await FlutterwaveInitV2({
150+
txref: generateTransactionRef(),
151+
PBFPubKey: '[Your Flutterwave Public Key]',
152+
amount: 100,
153+
currency: 'USD',
154+
});
155+
156+
// link is available if payment initialized successfully
157+
if (payment.link) {
158+
// use payment link
159+
return usePaymentLink(payment.link);
160+
}
161+
162+
// handle payment error
163+
handlePaymentError(
164+
payment.error
165+
? paymet.error.message
166+
: 'Kai, an unknown error occurred!'
167+
);
168+
````
169+
### Aborting Payment Initialization
170+
Hi :wave:, so there are cases where you have already initialized a payment with `FlutterwaveInitV2` but might also want to be able to cancel the payment initialization should in case your component is being unmounted or you want to allow users cancel the action before the payment is initialized, we have provided a way for you to do this... [continue reading](./docs/v2/AbortingPaymentInitialization.md)
171+
172+
## Props
173+
174+
### FlutterwaveInitV2Options
175+
[See Interface](#flutterwaveinitv2options-interface)
176+
| Name | Required | Type | Default | Description |
177+
| --------- | --------- | ---- | ------- | ----------- |
178+
| PBFPubKey | Yes | string | **REQUIRED** | Your merchant public key, see how to get your [API Keys](https://developer.flutterwave.com/v2.0/docs/api-keys)|
179+
| txref | Yes | string | **REQUIRED** | Your Unique transaction reference.|
180+
| customer_email | Yes | string | **REQUIRED** | The customer's email address. |
181+
| customer_phone | No | string | undefined | The customer's phone number. |
182+
| customer_firstname | No | string | undefined | The customer's first name. |
183+
| customer_lastname | No | string | undefined | The customer's last name. |
184+
| amount | Yes | number | undefined | Amount to charge the customer.|
185+
| currency | No | string | NGN | Currency to charge in. Defaults to NGN. Check our [International Payments](https://developer.flutterwave.com/v2.0/docs/multicurrency-payments) section for more on international currencies.|
186+
| redirect_url | No | string | undefined | URL to redirect to when a transaction is completed. This is useful for 3DSecure payments so we can redirect your customer back to a custom page you want to show them. |
187+
| payment_options | No | string | undefined | This allows you to select the payment option you want for your users, see [Choose Payment Methods](https://developer.flutterwave.com/v2.0/docs/splitting-payment-methods) for more info. |
188+
| payment_plan | No | number | undefined | This is the payment plan ID used for [Recurring billing](https://developer.flutterwave.com/v2.0/docs/recurring-billing). |
189+
| subaccounts | No | array of [FlutterwaveInitSubAccount](#flutterwaveinitsubaccount) | undefined | This is an array of objects containing the subaccount IDs to [split the payment](https://developer.flutterwave.com/v2.0/docs/split-payment) into. |
190+
| country | No | string | NG | Route country. Defaults to NG |
191+
| pay_button_text | No | string | undefined | Text to be displayed on the Rave Checkout Button. |
192+
| custom_title | No | string | undefined | Text to be displayed as the title of the payment modal. |
193+
| custom_description | No | string | undefined | Text to be displayed as a short modal description. |
194+
| custom_logo | No | string | undefined | Link to the Logo image. |
195+
| meta | No | array of [FlutterwavePaymentMetaV2](#flutterwavepaymentmetav2) | undefined | Any other custom data you wish to pass. |
196+
197+
### PayWithFlutterwaveV2Props
198+
[See Interface](#paywithflutterwavev2props-interface)
199+
| Name | Required | Type | Default | Description |
200+
| --------- | --------- | ---- | ------- | ----------- |
201+
| style | No | object | undefined | Used to apply styling to the button.|
202+
| onComplete | Yes | function | **REQUIRED** | Called when a payment is completed successfully or is canceled. The function will receive [on complete data](#oncompletedata)|
203+
| onWillInitialize | No | function | undefined | This will be called before a payment link is generated.|
204+
| onDidInitialize | No | function | undefined | This is called when a new payment link has been successfully initialized.|
205+
| onInitializeError | No | function | undefined | This is called if an error occurred while initializing a new pyment link. The function will receive [FlutterwaveInitError](#flutterwaveiniterror) |
206+
| onAbort | No | function | undefined | This is called if a user aborts a transaction, a user can abort a transaction when they click on the dialog's backdrop and choose cancel when prompted to cancel transaction. |
207+
| options | Yes | **[FlutterwaveInitOptions](#flutterwaveinitv2options)** | **REQUIRED** | The option passed here is used to initialize a payment. |
208+
| customButton | No | function | undefined | This is used to render a custom button. The function a prop argument structured like [CustomButtonProps](#custombuttonprops), this function should return a valid React node. |
209+
| alignLeft | No | boolean | undefined | This aligns the content of the button to the left. |
210+
211+
### FlutterwaveButton Props
212+
[See Interface](#flutterwavebuttonprops-interface)
213+
| Name | Required | Type | Default | Description |
214+
| --------- | --------- | ---- | ------- | ----------- |
215+
| style | No | ViewStyle | undefined | This component uses the same style properties that are applicable to react-native's View component style.|
216+
| onPress | Yes | function | undefined | This property receive a function that is called on button press. |
217+
| disabled | No | boolean | undefined | This disables button, and causes onPress not to be fired.|
218+
| alignLeft | No | boolean | undefined | This aligns the content of the button to the left. |
219+
220+
## Types
221+
#### CustomButtonProps
222+
````typescript
223+
interface CustomButtonProps {
224+
disabled: boolean;
225+
isInitializing: boolean;
226+
onPress: () => void;
227+
}
228+
````
229+
230+
#### RedirectParamsV2
231+
````typescript
232+
interface RedirectParamsV2 {
233+
canceled?: 'true' | 'false';
234+
flwref?: string;
235+
txref: string;
236+
}
237+
````
238+
239+
#### FlutterwaveInitError
240+
````typescript
241+
interface FlutterwaveInitError {
242+
code: string;
243+
message: string;
244+
}
245+
````
246+
247+
### FlutterwaveInitSubAccount
248+
```typescript
249+
interface FlutterwaveInitSubAccount {
250+
id: string;
251+
transaction_split_ratio?: number;
252+
transaction_charge_type?: string;
253+
transaction_charge?: number;
254+
}
255+
```
256+
257+
#### FlutterwavePaymentMetaV2
258+
````typescript
259+
interface FlutterwavePaymentMetaV2 {
260+
metaname: string;
261+
metavalue: string;
262+
}
263+
````
264+
265+
#### FlutterwaveInitV2Options Interface
266+
````typescript
267+
export interface FlutterwaveInitV2Options {
268+
txref: string;
269+
PBFPubKey: string;
270+
customer_firstname?: string;
271+
customer_lastname?: string;
272+
customer_phone?: string;
273+
customer_email: string;
274+
amount: number;
275+
currency?: string;
276+
redirect_url?: string;
277+
payment_options?: string;
278+
payment_plan?: number;
279+
subaccounts?: Array<FlutterwaveInitSubAccount>;
280+
country?: string;
281+
pay_button_text?: string;
282+
custom_title?: string;
283+
custom_description?: string;
284+
custom_logo?: string;
285+
meta?: Array<FlutterwavePaymentMetaV2>;
286+
}
287+
````
288+
289+
#### PayWithFlutterwaveV2Props Interface
290+
````typescript
291+
interface PayWithFlutterwaveV2Props {
292+
style?: ViewStyle;
293+
onComplete: (data: RedirectParamsV2) => void;
294+
onWillInitialize?: () => void;
295+
onDidInitialize?: () => void;
296+
onInitializeError?: (error: FlutterwaveInitError) => void;
297+
onAbort?: () => void;
298+
options: Omit<FlutterwaveInitOptions, 'redirect_url'>;
299+
customButton?: (props: CustomButtonProps) => React.ReactNode;
300+
alignLeft?: 'alignLeft' | boolean;
301+
}
302+
````
303+
304+
#### FlutterwaveButtonProps Interface
305+
````typescript
306+
interface FlutterwaveButton {
307+
style?: ViewStyle;
308+
onPress?: () => void;
309+
disabled?: boolean;
310+
alignLeft?: 'alignLeft' | boolean,
311+
}
312+
````
313+
314+
## Contributing
315+
For information on how you can contribute to this repo, simply [go here](./CONTRIBUTING.md), all contributions are greatly appreciated.
316+
317+
With love from Flutterwave. :yellow_heart:
+5-4
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
import 'react-native';
22
import {PaymentOptionsPropRule} from '../src/utils/CustomPropTypesRules';
33
const PropName = 'payment_options';
4+
const PAYMENT_OPTIONS = ['barter', 'card', 'banktransfer']
45

56
describe('CustomPropTypes.PaymentOptionsPropRule', () => {
67
it ('returns null if prop is not defined in props', () => {
7-
const result = PaymentOptionsPropRule({}, PropName);
8+
const result = PaymentOptionsPropRule(PAYMENT_OPTIONS)({}, PropName);
89
expect(result).toBe(null);
910
});
1011

1112
it ('returns error if prop is not a string', () => {
12-
const result = PaymentOptionsPropRule({[PropName]: []}, PropName);
13+
const result = PaymentOptionsPropRule(PAYMENT_OPTIONS)({[PropName]: []}, PropName);
1314
expect(result !== null).toBe(true);
1415
expect(result.message).toContain('should be a string.');
1516
});
1617

1718
it ('returns error if prop includes invalid payment option', () => {
18-
const result = PaymentOptionsPropRule({[PropName]: 'barter, foo'}, PropName);
19+
const result = PaymentOptionsPropRule(PAYMENT_OPTIONS)({[PropName]: 'barter, foo'}, PropName);
1920
expect(result !== null).toBe(true);
2021
expect(result.message).toContain('must be any of the following values.');
2122
});
2223

2324
it ('returns null if payment options are valid', () => {
24-
const result = PaymentOptionsPropRule({[PropName]: 'barter'}, PropName);
25+
const result = PaymentOptionsPropRule(PAYMENT_OPTIONS)({[PropName]: 'barter'}, PropName);
2526
expect(result).toBe(null);
2627
});
2728
})

0 commit comments

Comments
 (0)