|
| 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 | +[](https://developer.flutterwave.com/v2.0/docs/getting-started) [](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: |
0 commit comments