Metadata-Version: 2.1
Name: rave-python
Version: 1.2.2
Summary: Official Rave Python Wrapper By Flutterwave
Home-page: https://github.com/Flutterwave/rave-python
Author: Flutterwave
Author-email: developers@flutterwavego.com
License: MIT
Description: # Rave_Python
        
        ## Introduction
        This is a Python wrapper around the [API](https://flutterwavedevelopers.readme.io/v2.0/reference) for [Rave by Flutterwave](https://rave.flutterwave.com).
        
        #### Payment types implemented:
        * Card Payments
        * Bank Account Payments
        * Ghana Mobile Money Payments
        * Mpesa Payments
        * Rwanda Mobile Money Payments
        * Uganda Mobile Money Payments
        * Zambia Mobile Money Payments
        * Mobile Money Payments for Francophone countries
        * Subaccounts
        * Transfer
        * Subscription (Recurring Payments)
        * Bills payment
        * Payment Plan
        * USSD Payments (Still in Beta Mode)
        
        #### Other features include:
        * Preauthorization charges
        * Refunds
        * Transaction Verification
        * Transfer Recipients
        * Virtual Cards
        * Virtual Accounts
        
        ## Installation
        To install, run
        
        ```sh
        pip install rave_python
        ```
        
        Note: This is currently under active development
        ## Import Package
        The base class for this package is 'Rave'. To use this class, add:
        
        ```py
        from rave_python import Rave
        ```
        
        ## Initialization
        
        #### To instantiate in sandbox:
        To use Rave, instantiate the Rave class with your public key. We recommend that you store your secret key in an environment variable named, ```RAVE_SECRET_KEY```. Instantiating your rave object is therefore as simple as:
        
        ```py
        rave = Rave("YOUR_PUBLIC_KEY")
        ```
        
        ####  To instantiate without environment variables (Sandbox):
        If you choose not to store your secret key in an environment variable, we do provide a ```usingEnv``` flag which can be set to ```False```, but please be warned, do not use this package without environment variables in production
        
        ```py
        rave = Rave("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY", usingEnv = False)
        ```
        
        
        #### To instantiate in production:
        To initialize in production, simply set the ```production``` flag to ```True```. It is highly discouraged but if you choose to not use environment variables, you can do so in the same way mentioned above.
        
        ```py
        rave = Rave("YOUR_PUBLIC_KEY", production=True)
        ```
        
        # Rave Objects
        This is the documentation for all of the components of rave_python
        
        ## ```rave.Card```
        This is used to facilitate card transactions.
        
        **Functions included:**
        
        * ```.charge```
        
        * ```.validate```
        
        * ```.verify```
        
        * ```.getTypeOfArgsRequired```
        
        * ```.updatePayload```
        
        <br>
        
        ### ```.charge(payload)```
        This is called to start a card transaction. The payload should be a dictionary containing card information. It should have the parameters:
        
        * ```cardno```,
        
        * ```cvv```, 
        
        * ```currency```, 
        
        * ```country```, 
        
        * ```expirymonth```, 
        
        * ```expiryyear```, 
        
        * ```amount```, 
        
        * ```email```, 
        
        * ```phonenumber```,
        
        * ```firstname```, 
        
        * ```lastname```, 
        
        * ```IP```
        
        Optionally, you can add a custom transaction reference using the ```txRef``` parameter. Note that if you do not specify one, it would be automatically generated. We do provide a function for generating transaction references in the [Misc library](https://github.com/Flutterwave/rave-python/blob/master/rave_python/rave_misc.py).
        
        
        A sample call is:
        
        ```py
        res = rave.Card.charge(payload)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
         {'validationRequired': True, 'suggestedAuth': u'PIN', 'flwRef': None, 'authUrl': None, 'error': False, 'txRef': 'MC-1538095398058'}
         ```
        
        This call raises a ```CardChargeError``` if there was a problem processing your transaction. The ```CardChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.CardChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': 'MC-1530897824739', 'flwRef': None, 'errMsg': 'Sorry, that card number is invalid, please check and try again'}
        ```
        
        
        <br>
        
        ### ```rave.Misc.updatePayload(authMethod, payload, arg)```
        
        Depending on the suggestedAuth from the charge call, you may need to update the payload with a pin or address. To know which type of authentication you would require, simply call ```rave.Card.getTypeOfArgsRequired(suggestedAuth)```. This returns either ```pin``` or ```address```. 
        
        In the case of ```pin```, you are required to call ```rave.Card.updatePayload(suggestedAuth, payload, pin="THE_CUSTOMER_PIN")```. 
        
        In the case of ```address```, you are required to call ```rave.Card.updatePayload(suggestedAuth, payload, address={ THE_ADDRESS_DICTIONARY })```
        
        A typical address dictionary includes the following parameters:
        
        ```billingzip```, 
        
        ```billingcity```,
        
        ```billingaddress```, 
         
        ```billingstate```,
         
        ```billingcountry```
        
        **Note:**
        ```suggestedAuth``` is the suggestedAuth returned from the initial charge call and ```payload``` is the original payload
        
        <br>
        
        ### ```.validate(txRef)```
        
        After a successful charge, most times you will be asked to verify with OTP. To check if this is required, check the ```validationRequired``` key in the ```res``` of the charge call.
        
        To validate, you need to pass the ```flwRef``` from the ```res``` of the charge call as well as the OTP.
        
        A sample validate call is: 
        
        ```py
        res2 = rave.Card.validate(res["flwRef"], "12345")
        ```
        
        #### Returns
        
        This call returns a dictionary containing the ```txRef```, ```flwRef``` among others if successful. 
        
        This call raises a ```TransactionValidationError``` if the OTP is not correct or there was a problem processing your request. 
        
        To handle this, write:
        
        ```py
        try:
            # Your charge call
        except RaveExceptions.TransactionValidationError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': None, 'flwRef': 'FLW-MOCK-a7911408bd7f55f89f0211819d6fd370', 'errMsg': 'otp is required'}
        ```
        
        <br>
        
        ### ```.verify(txRef)```
        
        You can call this to check if your transaction was completed successfully. You have to pass the transaction reference generated at the point of charging. This is the ```txRef``` in the ```res``` parameter returned any of the calls (```charge``` or ```validate```). 
        
        A sample verify call is:
        
        ```py
        res = rave.Card.verify(data["txRef"])
        ```
        
        #### Returns
        
        This call returns a dict with ```txRef```, ```flwRef``` and ```transactionComplete``` which indicates whether the transaction was completed successfully. 
        
        Sample
        ```py
        {'flwRef': None, 'cardToken': u'flw-t1nf-5b0f12d565cd961f73c51370b1340f1f-m03k', 'chargedAmount': 100, 'amount': 100, 'transactionComplete': True, 'error': False, 'txRef': u'MC-1538095718251'}
        ```
        
        #### Please note that after charging a card successfully on rave, if you wish to save the card for further charges, in your verify payment response you will find an object: "cardtoken": "flw-t0-f6f915f53a094671d98560272572993e-m03k".  This is the token you will use for card tokenization. Details are provided below.
        
        If your call could not be completed successfully, a ```TransactionVerificationError``` is raised.
        
        <br>
        
        ### ```.charge(payload_for_saved_card, chargeWithToken=True)```
        This is called to start a card transaction with a card that has been saved. The payload should be a dictionary containing card information. It should have the parameters:
        
        * ```token```,
        
        * ```country```, 
        
        * ```amount```, 
        
        * ```email```, 
        
        * ```firstname```, 
        
        * ```lastname```, 
        
        * ```IP```,
        
        * ```txRef```, 
        
        * ```currency```
        
        #### NB: email must be the same as before the card was saved
        Optionally, you can add a custom transaction reference using the ```txRef``` parameter. Note that if you do not specify one, it would be automatically generated. We do provide a function for generating transaction references in the [Misc library](https://github.com/Flutterwave/rave-python/blob/master/rave_python/rave_misc.py).
        
        A sample call is:
        
        ```py
        res = rave.Card.charge(payload_for_saved_card, chargeWithToken=True)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
         ```py
         {'status': u'success', 'validationRequired': False, 'suggestedAuth': None, 'flwRef': u'FLW-M03K-cdb24d740fb18c242dd277fb1f74d399', 'authUrl': None, 'error': False, 'txRef': 'MC-7666-YU'}
         ```
        
         This call raises a ```CardChargeError``` if a wrong token or email is passed or if there was a problem processing your transaction. The ```CardChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.CardChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        This call also raises an ```IncompletePaymentDetailsError``` if any of the required parameters are missing. The ```IncompletePaymentDetailsError``` contains information about which parameter was not included in the payload. You can handle this such as:
        
        ```py
        try:
            #Your charge call
        except RaveExceptions.IncompletePaymentDetailsError as e:
            print(e.err["errMsg"])
        ```
        
        Once this is done, call ```rave.Card.verify``` passing in the ```txRef``` returned in the response to verify the payment. Sample response:
        
        ```py
        {'flwRef': None, 'cardToken': u'flw-t1nf-5b0f12d565cd961f73c51370b1340f1f-m03k', 'chargedAmount': 1000, 'amount': 1000, 'transactionComplete': True, 'error': False, 'txRef': 'MC-7666-YU'}
        ```
        
        ```rave.Card.verify``` raises a ```TransactionVerificationError``` if an invalid ```txRef``` is supplied. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.CardChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        #### NB: when charging saved cards, you do not need to call rave.card.Validate()
        
        ### Complete card charge flow
        
        ```py
        from rave_python import Rave
        rave = Rave("YOUR_PUBLIC_KEY", "YOUR_SECRET_KEY", usingEnv = False)
        
        # Payload with pin
        payload = {
          "cardno": "5438898014560229",
          "cvv": "890",
          "expirymonth": "09",
          "expiryyear": "19",
          "amount": "10",
          "email": "user@gmail.com",
          "phonenumber": "0902620185",
          "firstname": "temi",
          "lastname": "desola",
          "IP": "355426087298442",
        }
        
        try:
            res = rave.Card.charge(payload)
        
            if res["suggestedAuth"]:
                arg = Misc.getTypeOfArgsRequired(res["suggestedAuth"])
        
                if arg == "pin":
                    Misc.updatePayload(res["suggestedAuth"], payload, pin="3310")
                if arg == "address":
                    Misc.updatePayload(res["suggestedAuth"], payload, address= {"billingzip": "07205", "billingcity": "Hillside", "billingaddress": "470 Mundet PI", "billingstate": "NJ", "billingcountry": "US"})
                
                res = rave.Card.charge(payload)
        
            if res["validationRequired"]:
                rave.Card.validate(res["flwRef"], "")
        
            res = rave.Card.verify(res["txRef"])
            print(res["transactionComplete"])
        
        except RaveExceptions.CardChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        
        except RaveExceptions.TransactionValidationError as e:
            print(e.err)
            print(e.err["flwRef"])
        
        except RaveExceptions.TransactionVerificationError as e:
            print(e.err["errMsg"])
            print(e.err["txRef"])
        ```
        
        <br><br>
        ## ```rave.Account```
        This is used to facilitate account transactions.
        
        **Functions included:**
        
        * ```.charge```
        
        * ```.validate```
        
        * ```.verify```
        
        <br>
        
        ### ```.charge(payload)```
        This is called to start an account transaction. The payload should be a dictionary containing card information. It should have the parameters:
        
        * ```accountbank```, 
        
        * ```accountnumber```, 
        
        * ```amount```, 
        
        * ```email```, 
        
        * ```phonenumber```, 
        
        * ```IP```
        
        Optionally, you can add a custom transaction reference using the ```txRef``` parameter. Note that if you do not specify one, it would be automatically generated. We do provide a function for generating transaction references in the [Misc library](https://github.com/Flutterwave/rave-python/blob/master/rave_python/rave_misc.py).
        
        
        A sample call is:
        
        ```py
        res = rave.Account.charge(payload)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
         {'error': False, 'validationRequired': True, 'txRef': 'MC-1530899106006', 'flwRef': 'ACHG-1530899109682', 'authUrl': None}
        ```
        
         This call raises an ```AccountChargeError``` if there was a problem processing your transaction. The ```AccountChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.AccountChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': 'MC-1530897824739', 'flwRef': None, 'errMsg': 'Sorry, that account number is invalid, please check and try again'}
        ```
        
        <br>
        
        ### ```.validate(txRef)```
        
        After a successful charge, most times you will be asked to verify with OTP. To check if this is required, check the ```validationRequired``` key in the ```res``` of the charge call.
        
        In the case that an ```authUrl``` is returned from your charge call, you may skip the validation step and simply pass your authUrl to the end-user. 
        
        ```py
        authUrl = res['authUrl']
        ```
        
        To validate, you need to pass the ```flwRef``` from the ```res``` of the charge call as well as the OTP.
        
        A sample validate call is: 
        
        ```py
        res2 = rave.Account.validate(res["flwRef"], "12345")
        ```
        
        
        #### Returns
        
        This call returns a dictionary containing the ```txRef```, ```flwRef``` among others if successful.
        
        This call raises a ```TransactionValidationError``` if the OTP is not correct or there was a problem processing your request. 
        
        To handle this, write:
        
        ```py
        try:
            # Your charge call
        except RaveExceptions.TransactionValidationError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': 'MC-1530899869968', 'flwRef': 'ACHG-1530899873118', 'errMsg': 'Pending OTP validation'}
        ```
        
        
        
        <br>
        
        ### ```.verify(txRef)```
        
        You can call this to check if your transaction was completed successfully. You have to pass the transaction reference generated at the point of charging. This is the ```txRef``` in the ```res``` parameter returned any of the calls (```charge``` or ```validate```). 
        
        A sample verify call is:
        
        ```py
        res = rave.Account.verify(data["txRef"])
        ```
        
        #### Returns
        
        This call returns a dict with ```txRef```, ```flwRef``` and ```transactionComplete``` which indicates whether the transaction was completed successfully. 
        
        Sample
        
        ```py
        {'status': u'success', 'vbvcode': u'N/A', 'chargedamount': 500, 'vbvmessage': u'N/A', 'error': False, 'flwRef': u'ACHG-1538093023787', 'currency': u'NGN', 'amount': 500, 'transactionComplete': True, 'acctmessage': u'Approved Or Completed Successfully', 'chargecode': u'00', 'txRef': u'MC-1538093008498'}
        ```
        
        If your call could not be completed successfully or if a wrong ```txRef``` is passed, a ```TransactionVerificationError``` is raised. You can handle that as such
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransactionVerificationError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        
        
        <br>
        
        ### Complete account flow
        
        ```py
        from rave_python import Rave, RaveExceptions, Misc
        rave = Rave("ENTER_YOUR_PUBLIC_KEY", "ENTER_YOUR_SECRET_KEY", usingEnv = False)
        # account payload
        payload = {
          "accountbank": "044",  # get the bank code from the bank list endpoint.
          "accountnumber": "0690000031",
          "currency": "NGN",
          "country": "NG",
          "amount": "100",
          "email": "test@test.com",
          "phonenumber": "0902620185",
          "IP": "355426087298442",
        }
        
        try:
            res = rave.Account.charge(payload)
            if res["authUrl"]:
                print(res["authUrl"])
        
            elif res["validationRequired"]:
                rave.Account.validate(res["flwRef"], "12345")
        
            res = rave.Account.verify(res["txRef"])
            print(res)
        
        except RaveExceptions.AccountChargeError as e:
            print(e.err)
            print(e.err["flwRef"])
        
        except RaveExceptions.TransactionValidationError as e:
            print(e.err)
            print(e.err["flwRef"])
        
        except RaveExceptions.TransactionVerificationError as e:
            print(e.err["errMsg"])
            print(e.err["txRef"])
        ```
        <br><br>
        
        ## ```rave.GhMobile```
        This is used to facilitate Ghanaian mobile money transactions.
        
        **Functions included:**
        
        * ```.charge```
        
        
        * ```.verify```
        
        <br>
        
        ### ```.charge(payload)```
        This is called to start a Ghana mobile money transaction. The payload should be a dictionary containing account information. It should have the parameters:
        
        * ```amount```,
        
        * ```email```, 
        
        * ```phonenumber```,
        
        * ```network```,
        
        * ```IP```,
        
        * ```redirect_url```
        
        Optionally, you can add a custom transaction reference using the ```txRef``` parameter. Note that if you do not specify one, it would be automatically generated. We do provide a function for generating transaction references in the [Misc library](https://github.com/Flutterwave/rave-python/blob/master/rave_python/rave_misc.py).
        
        
        A sample call is:
        
        ```py
        res = rave.GhMobile.charge(payload)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'validationRequired': True, 'txRef': 'MC-1530910216380', 'flwRef': 'N/A'}
        ```
        
         This call raises a ```TransactionChargeError``` if there was a problem processing your transaction. The ```TransactionChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransactionChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': 'MC-1530911537060', 'flwRef': None, 'errMsg': None}
        ```
        
        
        <br>
        
        ### ```.verify(txRef)```
        
        You can call this to check if your transaction was completed successfully. You have to pass the transaction reference generated at the point of charging. This is the ```txRef``` in the ```res``` parameter returned any of the calls (```charge``` or ```validate```). 
        
        A sample verify call is:
        
        ```py
        res = rave.GhMobile.verify(data["txRef"])
        ```
        
        #### Returns
        
        This call returns a dict with ```txRef```, ```flwRef``` and ```transactionComplete``` which indicates whether the transaction was completed successfully. 
        
        If your call could not be completed successfully, a ```TransactionVerificationError``` is raised.
        
        <br>
        
        ### Complete GhMobile charge flow
        
        ```py
        from rave_python import Rave, RaveExceptions, Misc
        rave = Rave("ENTER_YOUR_PUBLIC_KEY", "ENTER_YOUR_SECRET_KEY", usingEnv = False)
        
        # mobile payload
        payload = {
          "amount": "50",
          "email": "",
          "phonenumber": "054709929220",
          "network": "MTN",
          "redirect_url": "https://rave-webhook.herokuapp.com/receivepayment",
          "IP":""
        }
        
        try:
          res = rave.GhMobile.charge(payload)
          res = rave.GhMobile.verify(res["txRef"])
          print(res)
        
        except RaveExceptions.TransactionChargeError as e:
          print(e.err)
          print(e.err["flwRef"])
        
        except RaveExceptions.TransactionVerificationError as e:
          print(e.err["errMsg"])
          print(e.err["txRef"])
        ```
        
        <br><br>
        
        ## ```rave.Mpesa```
        This is used to facilitate Mpesa transactions.
        
        **Functions included:**
        
        * ```.charge```
        
        
        * ```.verify```
        
        <br>
        
        ### ```.charge(payload)```
        This is called to start an Mpesa transaction. The payload should be a dictionary containing account information. It should have the parameters:
        
        * ```account```, 
        
        * ```email```, 
        
        * ```phonenumber```, 
        
        * ```IP```
        
        Optionally, you can add a custom transaction reference using the ```txRef``` parameter. Note that if you do not specify one, it would be automatically generated. We do provide a function for generating transaction references in the [Misc library](https://github.com/Flutterwave/rave-python/blob/master/rave_python/rave_misc.py).
        
        
        A sample call is:
        
        ```py
        res = rave.Mpesa.charge(payload)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'validationRequired': True, 'txRef': 'MC-1530910216380', 'flwRef': 'N/A'}
        ```
        
         This call raises a ```TransactionChargeError``` if there was a problem processing your transaction. The ```TransactionChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransactionChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': 'MC-1530910109929', 'flwRef': None, 'errMsg': 'email is required'}
        ```
        
        
        <br>
        
        ### ```.verify(txRef)```
        
        You can call this to check if your transaction was completed successfully. You have to pass the transaction reference generated at the point of charging. This is the ```txRef``` in the ```res``` parameter returned any of the calls (```charge``` or ```validate```). 
        
        A sample verify call is:
        
        ```py
        res = rave.Mpesa.verify(data["txRef"])
        ```
        
        #### Returns
        
        This call returns a dict with ```txRef```, ```flwRef``` and ```transactionComplete``` which indicates whether the transaction was completed successfully. 
        
        If your call could not be completed successfully, a ```TransactionVerificationError``` is raised.
        
        <br>
        
        ### Complete Mpesa charge flow
        
        ```py
        from rave_python import Rave, RaveExceptions, Misc
        rave = Rave("ENTER_YOUR_PUBLIC_KEY", "ENTER_YOUR_SECRET_KEY", usingEnv = False)
        
        # mobile payload
        payload = {
            "amount": "100",
            "phonenumber": "0926420185",
            "email": "user@exampe.com",
            "IP": "40.14.290",
            "narration": "funds payment",
        }
        
        try:
            res = rave.Mpesa.charge(payload)
            res = rave.Mpesa.verify(res["txRef"])
            print(res)
        
        except RaveExceptions.TransactionChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        
        except RaveExceptions.TransactionVerificationError as e:
            print(e.err["errMsg"])
            print(e.err["txRef"])
        ```
        
        <br><br>
        
        ## ```rave.UGMobile```
        This is used to facilitate Uganda mobile money transactions.
        
        **Functions included:**
        
        * ```.charge```
        
        
        * ```.verify```
        
        <br>
        
        ### ```.charge(payload)```
        This is called to start a Ugandan mobile money transaction. The payload should be a dictionary containing account information. It should have the parameters:
        
        * ```amount```,
        
        * ```email```, 
        
        * ```phonenumber```,
        
        * ```IP```,
        
        * ```redirect_url```
        
        Optionally, you can add a custom transaction reference using the ```txRef``` parameter. Note that if you do not specify one, it would be automatically generated. We do provide a function for generating transaction references in the [Misc library](https://github.com/Flutterwave/rave-python/blob/master/rave_python/rave_misc.py).
        
        
        A sample call is:
        
        ```py
        res = rave.UGMobile.charge(payload)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'status': 'success', 'validationRequired': True, 'txRef': 'MC-1544013787279', 'flwRef': 'flwm3s4m0c1544013788481'}
        ```
        
         This call raises a ```TransactionChargeError``` if there was a problem processing your transaction. The ```TransactionChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransactionChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': 'MC-1530911537060', 'flwRef': None, 'errMsg': None}
        ```
        
        
        <br>
        
        ### ```.verify(txRef)```
        
        You can call this to check if your transaction was completed successfully. You have to pass the transaction reference generated at the point of charging. This is the ```txRef``` in the ```res``` parameter returned any of the calls (```charge``` or ```validate```). 
        
        A sample verify call is:
        
        ```py
        res = rave.UGMobile.verify(data["txRef"])
        ```
        
        #### Returns
        
        This call returns a dict with ```txRef```, ```flwRef``` and ```transactionComplete``` which indicates whether the transaction was completed successfully. 
        
        If your call could not be completed successfully, a ```TransactionVerificationError``` is raised.
        
        <br>
        
        ### Complete UGMobile charge flow
        
        ```py
        from rave_python import Rave, RaveExceptions, Misc
        rave = Rave("ENTER_YOUR_PUBLIC_KEY", "ENTER_YOUR_SECRET_KEY", usingEnv = False)
        
        # mobile payload
        payload = {
          "amount": "50",
          "email": "",
          "phonenumber": "xxxxxxxx",
          "redirect_url": "https://rave-webhook.herokuapp.com/receivepayment",
          "IP":""
        }
        
        try:
          res = rave.UGMobile.charge(payload)
          res = rave.UGMobile.verify(res["txRef"])
          print(res)
        
        except RaveExceptions.TransactionChargeError as e:
          print(e.err)
          print(e.err["flwRef"])
        
        except RaveExceptions.TransactionVerificationError as e:
          print(e.err["errMsg"])
          print(e.err["txRef"])
        ```
        
        <br><br>
        
        ## ```rave.ZBMobile```
        This is used to facilitate Zambian mobile money transactions.
        
        **Functions included:**
        
        * ```.charge```
        
        
        * ```.verify```
        
        <br>
        
        ### ```.charge(payload)```
        This is called to start a Zambian mobile money transaction. The payload should be a dictionary containing account information. It should have the parameters:
        
        * ```amount```,
        
        * ```email```, 
        
        * ```phonenumber```,
        
        * ```IP```,
        
        * ```redirect_url```
        
        Optionally, you can add a custom transaction reference using the ```txRef``` parameter. Note that if you do not specify one, it would be automatically generated. We do provide a function for generating transaction references in the [Misc library](https://github.com/Flutterwave/rave-python/blob/master/rave_python/rave_misc.py).
        
        
        A sample call is:
        
        ```py
        res = rave.ZBMobile.charge(payload)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'status': 'success', 'validationRequired': True, 'txRef': 'MC-1544013787279', 'flwRef': 'flwm3s4m0c1544013788481'}
        ```
        
         This call raises a ```TransactionChargeError``` if there was a problem processing your transaction. The ```TransactionChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransactionChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': 'MC-1530911537060', 'flwRef': None, 'errMsg': None}
        ```
        
        
        <br>
        
        ### ```.verify(txRef)```
        
        You can call this to check if your transaction was completed successfully. You have to pass the transaction reference generated at the point of charging. This is the ```txRef``` in the ```res``` parameter returned any of the calls (```charge``` or ```validate```). 
        
        A sample verify call is:
        
        ```py
        res = rave.ZBMobile.verify(data["txRef"])
        ```
        
        #### Returns
        
        This call returns a dict with ```txRef```, ```flwRef``` and ```transactionComplete``` which indicates whether the transaction was completed successfully. 
        
        If your call could not be completed successfully, a ```TransactionVerificationError``` is raised.
        
        <br>
        
        ### Complete ZBMobile charge flow
        
        ```py
        from rave_python import Rave, RaveExceptions, Misc
        rave = Rave("ENTER_YOUR_PUBLIC_KEY", "ENTER_YOUR_SECRET_KEY", usingEnv = False)
        
        # mobile payload
        payload = {
          "amount": "50",
          "email": "",
          "phonenumber": "xxxxxxxx",
          "redirect_url": "https://rave-webhook.herokuapp.com/receivepayment",
          "IP":""
        }
        
        try:
          res = rave.ZBMobile.charge(payload)
          res = rave.ZBMobile.verify(res["txRef"])
          print(res)
        
        except RaveExceptions.TransactionChargeError as e:
          print(e.err)
          print(e.err["flwRef"])
        
        except RaveExceptions.TransactionVerificationError as e:
          print(e.err["errMsg"])
          print(e.err["txRef"])
        ```
        
        <br><br>
        
        ## ```rave.Francophone```
        This is used to facilitate mobile money transactions in Ivory Coast, Senegal and Mali.
        
        **Functions included:**
        
        * ```.charge```
        
        
        * ```.verify```
        
        <br>
        
        ### ```.charge(payload)```
        This is called to start a francophone mobile money transaction. The payload should be a dictionary containing account information. It should have the parameters:
        
        * ```amount```,
        
        * ```email```, 
        
        * ```phonenumber```,
        
        * ```IP```,
        
        * ```redirect_url```
        
        Optionally, you can add a custom transaction reference using the ```txRef``` parameter. Note that if you do not specify one, it would be automatically generated. We do provide a function for generating transaction references in the [Misc library](https://github.com/Flutterwave/rave-python/blob/master/rave_python/rave_misc.py).
        
        
        A sample call is:
        
        ```py
        res = rave.Francophone.charge(payload)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'validationRequired': True, 'txRef': 'MC-1566482674756', 'flwRef': None, 'suggestedAuth': None, 'redirectUrl': 'https://flutterwaveprodv2.com/flwcinetpay/paymentServlet?reference=FLW186321566482674310'}
        ```
         
         The call returns redirect Url ```'redirectUrl':'https://redirecturl.com'``` for the authentication of the transaction. It raises a ```TransactionChargeError``` if there was a problem processing your transaction. The ```TransactionChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransactionChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        A sample ``` e.err ``` contains:
        
        ```py
        {'error': True, 'txRef': 'MC-1530911537060', 'flwRef': None, 'errMsg': None}
        ```
        
        
        <br>
        
        ### ```.verify(txRef)```
        
        You can call this to check if your transaction was completed successfully. You have to pass the transaction reference generated at the point of charging. This is the ```txRef``` in the ```res``` parameter returned any of the calls (```charge``` or ```validate```). 
        
        A sample verify call is:
        
        ```py
        res = rave.Francophone.verify(data["txRef"])
        ```
        
        #### Returns
        
        This call returns a dict with ```txRef```, ```flwRef``` and ```transactionComplete``` which indicates whether the transaction was completed successfully. 
        
        If your call could not be completed successfully, a ```TransactionVerificationError``` is raised.
        
        <br>
        
        ### Complete Francophone mobile money charge flow
        
        ```py
        from rave_python import Rave, RaveExceptions, Misc
        rave = Rave("ENTER_YOUR_PUBLIC_KEY", "ENTER_YOUR_SECRET_KEY", usingEnv = False)
        
        # mobile payload
        payload = {
          "amount": "50",
          "email": "",
          "phonenumber": "054709929220",
          "redirect_url": "https://rave-webhook.herokuapp.com/receivepayment",
          "IP":""
        }
        
        try:
          res = rave.Francophone.charge(payload)
          print(res)
          res = rave.Francophone.verify(res["txRef"])
          print(res)
        
        except RaveExceptions.TransactionChargeError as e:
          print(e.err)
          print(e.err["flwRef"])
        
        except RaveExceptions.TransactionVerificationError as e:
          print(e.err["errMsg"])
          print(e.err["txRef"])
        ```
        
        <br><br>
        
        ## ```rave.Preauth```
        This is used to facilitate preauthorized card transactions. This inherits the Card class so any task you can do on Card, you can do with preauth.
        
        **Functions included:**
        
        * ```.charge```
        
        * ```.capture```
        
        * ```.validate```
        
        * ```.verify```
        
        * ```.refund```
        
        * ```.void```
        
        
        <br>
        
        **
        In order to ```preauthorize``` a card, you must have:
            1. charged the card initially using ```rave.Card.charge(payload)```
            2. saved the ```token``` returned to you for that card. A ```token``` looks like this ```flw-t1nf-5b0f12d565cd961f73c51370b1340f1f-m03k```
        **
        
        ### ```.charge(cardDetails, chargeWithToken=True, hasFailed=False)```
        
        This is used to preauthorize a specific amount to be paid by a customer.
        
        **Note:** > it takes the same parameters as Card charge. However, the cardDetails object differs. See below for an example
        
        Once preauthorized successfully, you can then ```capture``` that ```held``` amount at a later time or date
        
        A sample charge call is:
        
        ```py
        payload = {
            "token":"flw-t1nf-5b0f12d565cd961f73c51370b1340f1f-m03k",
            "country":"NG",
            "amount":1000,
            "email":"user@gmail.com",
            "firstname":"temi",
            "lastname":"Oyekole",
            "IP":"190.233.222.1",
            "txRef":"MC-7666-YU",
            "currency":"NGN"
        rave.Preauth.charge(payload)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'status': 'success', 'validationRequired': False, 'txRef': 'MC-7666-YU', 'flwRef': 'FLW-PREAUTH-M03K-7d01799093ee2db9d8136cf042dc8c37', 'suggestedAuth': None, 'authUrl': None}
        ```
        
         This call raises a ```TransactionChargeError``` if there was a problem processing your transaction. The ```TransactionChargeError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransactionChargeError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        
        <br>
        
        
        ### ```.capture(flwRef)```
        
        This is used to capture the funds held in the account. Similar to the validate call, it requires you to pass the ```flwRef``` of the transaction.
        
        >Please **NOTE** that the ```flwRef``` must be gotten from the response of the initial charge i.e after calling ```rave.Preauth.charge(payload)```
        
        
        A sample capture call is:
        
        ```py
        rave.Preauth.capture(data["flwRef"])
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'status': 'success', 'message': 'Capture complete', 'validationRequired': False, 'txRef': 'MC-7666-YU', 'flwRef': 'FLW-PREAUTH-M03K-0bce8fe1c3561e17e026ddfbbea37fdb'}
        ```
        
         This call raises a ```PreauthCaptureError``` if there was a problem processing your transaction. The ```PreauthCaptureError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PreauthCaptureError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        <br>
        
        ### ```.void(flwRef)```
        
        This is used to void a preauth transaction. Similar to the validate call, it requires you to pass the ```flwRef```. 
        
        >Please **NOTE** that the ```flwRef``` must be gotten from the response of the initial charge i.e after calling ```rave.Preauth.charge(payload)```
        
        
        
        A sample void call is:
        
        ```py
        rave.Preauth.void(data["flwRef"])
        ```
        
        <br>
        
        ### ```.refund(flwRef)```
        
        This is used to refund a preauth transaction. Similar to the validate call, it requires you to pass the ```flwRef```. 
        
        >Please **NOTE** that the ```flwRef``` must be gotten from the response of the initial charge i.e after calling ```rave.Preauth.charge(payload)```
        
        
        
        A sample void call is:
        
        ```py
        rave.Preauth.refund(data["flwRef"])
        ```
        
        
        ### ```.verify(txRef)```
        
        **See rave.Card.verify above**
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'transactionComplete': True, 'txRef': 'MC-7666-YU', 'flwRef': None, 'amount': 1000, 'chargedAmount': 1000, 'cardToken': 'flw-t1nf-5b0f12d565cd961f73c51370b1340f1f-m03k'}
        ```
        
         This call raises a ```TransactionVerificationError``` if there was a problem processing your transaction. The ```TransactionVerificationError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransactionVerificationError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        <br>
        
        
        ### Complete preauth charge flow
        
        ```py
        from rave_python import Rave, Misc, RaveExceptions
        rave = Rave("ENTER_YOUR_PUBLIC_KEY", "ENTER_YOUR_SECRET_KEY", usingEnv = False)
        
        # Payload with pin
        payload = {
            "token":"flw-t1nf-5b0f12d565cd961f73c51370b1340f1f-m03k",
            "country":"NG",
            "amount":1000,
            "email":"user@gmail.com",
            "firstname":"temi",
            "lastname":"Oyekole",
            "IP":"190.233.222.1",
            "txRef":"MC-7666-YU",
            "currency":"NGN",
        }
        
        try:
            res = rave.Preauth.charge(payload)
            res = rave.Preauth.capture(res["flwRef"])
            res = rave.Preauth.verify(res["txRef"])
            print(res)
        
        except RaveExceptions.TransactionChargeError as e:
            print(e)
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        
        except RaveExceptions.PreauthCaptureError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        
        except RaveExceptions.TransactionVerificationError as e:
            print(e.err["errMsg"])
            print(e.err["txRef"])
        ```
        
        <br>
        
        ## ```rave.SubAccount```
        
        This is used to initiate and manage payouts
        
        
        **Functions included:**
        
        * ```.create```
        
        * ```.all```
        
        * ```.fetch```
        
        * ```.edit```
        
        * ```.cancel```
        
        <br>
        
        ### ```.create(accountDetails)```
        
        This allows you to create a subaccount plan. It requires a dict ```accountDetails``` containing ```account_bank```, ```account_number```, ```business_name```, ```business_email```, ```business_contact```, ```business_contact_mobile```, ```business_mobile```.
         
        >account_bank: This is the sub-accounts bank ISO code, use the [List of Banks for Transfer](https://developer.flutterwave.com/reference#list-of-banks-for-transfer) endpoint to retrieve a list of bank codes.
        
        >account_number: This is the customer's account number
        
        >business_name: This is the sub-account business name.
        
        >business_email: This is the sub-account business email.
        
        >business_contact: This is the contact person for the sub-account e.g. Richard Hendrix
        
        >business_contact_mobile: Business contact number.
        
        >business_mobile: Primary business contact number.
        
        >split_type: This can be set as   ```percentage``` or ```flat``` when set as percentage it means you want to take a percentage fee on all transactions, and vice versa for flat this means you want to take a flat fee on every transaction.
        
        >split_value: This can be a ```percentage``` value or ```flat``` value depending on what was set on ```split_type```
        
        More information can be found [here](https://developer.flutterwave.com/v2.0/reference#create-subaccount)
        
        
        A sample create call is:
        
        ```py
         res = rave.SubAccount.create({
        	"account_bank": "044",
        	"account_number": "0690000031",
        	"business_name": "Jake Stores",
        	"business_email": "kwakj@services.com",
        	"business_contact": "Amy Parkers",
        	"business_contact_mobile": "09083772",
        	"business_mobile": "0188883882",
            "split_type": "flat",
            "split_value": 3000
        	"meta": [{"metaname": "MarketplaceID", "metavalue": "ggs-920900"}]
        })
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'id': 114, 'data': {'id': 114, 'account_number': '0690000032', 'account_bank': '044', 'business_name': 'Jake Stores', 'fullname': 'Pastor Bright', 'date_created': '2018-10-09T10:43:02.000Z', 'meta': [{'metaname': 'MarketplaceID', 'metavalue': 'ggs-920900'}], 'split_ratio': 1, 'split_type': 'flat', 'split_value': 3000, 'subaccount_id': 'RS_8279B1518A139DD3238328747F322418', 'bank_name': 'ACCESS BANK NIGERIA'}}
        ```
        
         This call raises a ```.SubaccountCreationError``` if there was a problem processing your transaction. The ```.SubaccountCreationError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions..SubaccountCreationError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.all()```
        
        This allows you retrieve all subaccounts 
        
        A sample all Subaccounts call is:
        
        ```py
        res2 = rave.SubAccount.all()
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'SUBACCOUNTS', 'data': {'page_info': {'total': 3, 'current_page': 1, 'total_pages': 1}, 'subaccounts': [{'id': 114, 'account_number': '0690000032', 'account_bank': '044', 'business_name': 'Jake Stores', 'fullname': 'Pastor Bright', 'date_created': '2018-10-09T10:43:02.000Z', 'meta': [{'metaname': 'MarketplaceID', 'metavalue': 'ggs-920900'}], 'split_ratio': 1, 'split_type': 'flat', 'split_value': 3000, 'subaccount_id': 'RS_8279B1518A139DD3238328747F322418', 'bank_name': 'ACCESS BANK NIGERIA'}, {'id': 107, 'account_number': '0690000031', 'account_bank': '044', 'business_name': 'Jake Stores', 'fullname': 'Forrest Green', 'date_created': '2018-10-05T18:30:09.000Z', 'meta': [{'metaname': 'MarketplaceID', 'metavalue': 'ggs-920900'}], 'split_ratio': 1, 'split_type': 'flat', 'split_value': 100, 'subaccount_id': 'RS_41FFE616A1FA7EA56C85E57F593056F7', 'bank_name': 'ACCESS BANK NIGERIA'}]}}}
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.fetch(subaccount_id)```
        
        This allows you fetch a subaccount. You may or may not pass in a ```subaccount_id```. If you do not pass in a ```subaccount_id``` all subacocunts will be returned.
        
        >subaccount_id: This is the payment plan ID. It can be gotten from the response returned from creating a plan or from the Rave Dashboard
        
        
        A sample fetch Subaccount call is:
        
        ```py
        res2 = rave.SubAccount.fetch(900)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'SUBACCOUNT', 'data': {'id': 106, 'account_number': '0690000035', 'account_bank': '044', 'business_name': 'JK Services', 'fullname': 'Peter Crouch', 'date_created': '2018-10-05T18:24:21.000Z', 'meta': [{'metaname': 'MarketplaceID', 'metavalue': 'ggs-920900'}], 'split_ratio': 1, 'split_type': 'flat', 'split_value': 100, 'subaccount_id': 'RS_0A6C260E1A70934DE6EF2F8CEE46BBB3', 'bank_name': 'ACCESS BANK NIGERIA'}}}
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### Complete SubAccount flow
        
        ```py
        from rave_python import Rave, Misc, RaveExceptions
        rave = Rave("YOUR_PUBLIC_KEY", "YOUR_PRIVATE_KEY", usingEnv = False)
        try:
           
            res = rave.SubAccount.create({
        	"account_bank": "044",
        	"account_number": "0690000032",
        	"business_name": "Jake Stores",
        	"business_email": "jdhhd@services.com",
        	"business_contact": "Amy Parkers",
        	"business_contact_mobile": "09083772",
        	"business_mobile": "0188883882",
            "split_type": "flat",
            "split_value": 3000,
        	"meta": [{"metaname": "MarketplaceID", "metavalue": "ggs-920900"}]
            })
            res = rave.SubAccount.fetch('RS_0A6C260E1A70934DE6EF2F8CEE46BBB3')
            print(res)
        
        except RaveExceptions.IncompletePaymentDetailsError as e:
            print(e)
        
        except RaveExceptions.PlanStatusError as e:
            print(e.err)
        
        except RaveExceptions.ServerError as e:
            print(e.err)
        ```
        
        <br>
        
        ## ```rave.Transfer```
        
        This is used to initiate and manage payouts
        
        
        **Functions included:**
        
        * ```.initiate```
        
        * ```.bulk```
        
        * ```.fetch```
        
        * ```.all```
        
        * ```.getFee```
        
        * ```.getBalance```
        
        <br>
        
        ### ```.initiate(transferDetails)```
        
        This initiates a transfer to a customer's account. When a transfer is initiated, it comes with a status NEW this means the transfer has been queued for processing.
        
        **Please note that you must pass ```beneficiary_name``` as part of the initiate call. Else an error will be thrown.**
        >Also, if you are doing international transfers, you must pass a meta parameter as part of your payload as shown below:
        
        ```py
        "meta": [
            {
              "AccountNumber": "09182972BH",
              "RoutingNumber": "0000000002993",
              "SwiftCode": "ABJG190",
              "BankName": "BANK OF AMERICA, N.A., SAN FRANCISCO, CA",
              "BeneficiaryName": "Mark Cuban",
              "BeneficiaryAddress": "San Francisco, 4 Newton",
              "BeneficiaryCountry": "US"
            }
        ]
        ```
        
        A sample initiate call is:
        
        ```py
        res = rave.Transfer.initiate({
            "account_bank": "044",
            "account_number": "0690000044",
            "amount": 500,
            "narration": "New transfer",
            "currency": "NGN",
            "beneficiary_name": "Kwame Adew"
            })
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'id': 2671, 'data': {'id': 2671, 'account_number': '0690000044', 'bank_code': '044', 'fullname': 'Mercedes Daniel', 'date_created': '2018-10-09T08:37:20.000Z', 'currency': 'NGN', 'amount': 500, 'fee': 45, 'status': 'NEW', 'reference': 'MC-1539074239367', 'meta': None, 'narration': 'New transfer', 'complete_message': '', 'requires_approval': 0, 'is_approved': 1, 'bank_name': 'ACCESS BANK NIGERIA'}}
        ```
        
         This call raises an ```IncompletePaymentDetailsError``` if there was a problem processing your transaction. The ```IncompletePaymentDetailsError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.IncompletePaymentDetailsError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.bulk(bulkDetails)```
        
        This initiates a bulk transfer to the customers specified in the ```bulkDetails``` object. When a transfer is initiated, it comes with a status NEW this means the transfer has been queued for processing.
        
        A sample bulk call is:
        
        ```py
        res2 = rave.Transfer.bulk({
            "title":"May Staff Salary",
            "bulk_data":[
                {
                    "Ban":"044",
                    "Account Number": "0690000032",
                    "Amount":500,
                    "Currency":"NGN",
                    "Narration":"Bulk transfer 1",
                    "reference": "mk-82973029"
                },
                {
                    "Bank":"044",
                    "Account Number": "0690000034",
                    "Amount":500,
                    "Currency":"NGN",
                    "Narration":"Bulk transfer 2",
                    "reference": "mk-283874750"
                }
            ]
        })
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'status': 'success', 'message': 'BULK-TRANSFER-CREATED', 'id': 499, 'data': {'id': 499, 'date_created': '2018-10-09T09:13:54.000Z', 'approver': 'N/A'}}
        ```
        
         This call raises an ```InitiateTransferError``` if there was a problem processing your transaction. The ```InitiateTransferError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.InitiateTransferError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.fetch(reference=None)```
        
        This allows you retrieve a single transfer. You may or may not pass in a ```reference```. If you do not pass in a reference, all transfers that have been processed will be returned.
        
        A sample fetch call is:
        
        ```py
        res2 = rave.Transfer.fetch("mk-82973029")
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'QUERIED-TRANSFERS', 'data': {'page_info': {'total': 0, 'current_page': 0, 'total_pages': 0}, 'transfers': []}}}
        ```
        
         This call raises a ```TransferFetchError``` if there was a problem processing your transaction. The ```TransferFetchError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransferFetchError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.all()```
        
        This allows you retrieve all transfers. 
        
        A sample all Transfers call is:
        
        ```py
        res2 = rave.Transfer.all("")
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'QUERIED-TRANSFERS', 'data': {'page_info': {'total': 19, 'current_page': 1, 'total_pages': 2}, 'transfers': [{'id': 2676, 'account_number': '0690000044', 'bank_code': '044', 'fullname': 'Mercedes Daniel', 'date_created': '2018-10-09T09:37:12.000Z', 'currency': 'NGN', 'debit_currency': None, 'amount': 500, 'fee': 45, 'status': 'PENDING', 'reference': 'MC-1539077832148', 'meta': None, 'narration': 'New transfer', 'approver': None, 'complete_message': '', 'requires_approval': 0, 'is_approved': 1, 'bank_name': 'ACCESS BANK NIGERIA'}, {'id': 2673, 'account_number': '0690000044', 'bank_code': '044', 'fullname': 'Mercedes Daniel', 'date_created': '2018-10-09T09:31:37.000Z', 'currency': 'NGN', 'debit_currency': None, 'amount': 500, 'fee': 45, 'status': 'FAILED', 'reference': 'MC-1539077498173', 'meta': None, 'narration': 'New transfer', 'approver': None, 'complete_message': 'DISBURSE FAILED: Insufficient funds', 'requires_approval': 0, 'is_approved': 1, 'bank_name': 'ACCESS BANK NIGERIA'}, {'id': 2672, 'account_number': '0690000034', 'bank_code': '044', 'fullname': 'Ade Bond', 'date_created': '2018-10-09T09:13:56.000Z', 'currency': 'NGN', 'debit_currency': None, 'amount': 500, 'fee': 45, 'status': 'FAILED', 'reference': None, 'meta': None, 'narration': 'Bulk transfer 2', 'approver': None, 'complete_message': 'DISBURSE FAILED: Insufficient funds', 'requires_approval': 0, 'is_approved': 1, 'bank_name': 'ACCESS BANK NIGERIA'}]}}}
        ```
        
         This call raises a ```TransferFetchError``` if there was a problem processing your transaction. The ```TransferFetchError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.TransferFetchError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.getFee(currency)```
        
        This allows you get transfer rates for all Rave supported currencies. You may or may not pass in a ```currency```. If you do not pass in a ```currency```, all Rave supported currencies transfer rates will be returned.
        
        A sample getFee call is:
        
        ```py
        res2 = rave.Transfer.getFee("EUR")
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'TRANSFER-FEES', 'data': [{'id': 6, 'fee_type': 'value', 'currency': 'EUR', 'fee': 35, 'createdAt': None, 'updatedAt': None, 'deletedAt': None, 'AccountId': 1}]}}
        ```
        
         ### ```.getBalance(currency)```
        
        This allows you get your balance in a specified. You may or may not pass in a ```currency```. If you do not pass in a ```currency```, your balance will be returned in the currency specified in your rave account
        
        A sample fetch call is:
        
        ```py
        res2 = rave.Transfer.Balance("EUR")
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'WALLET-BALANCE', 'data': {'Id': 27122, 'ShortName': 'EUR', 'WalletNumber': '3855000502677', 'AvailableBalance': 0, 'LedgerBalance': 0}}}
        ```
        
        
        <br>
        
        ### Complete transfer flow
        
        ```py
        from rave_python import Rave, RaveExceptions
        try:
            rave = Rave("ENTER_YOUR_PUBLIC_KEY", "ENTER_YOUR_SECRET_KEY", usingEnv = False)
        
            res = rave.Transfer.initiate({
            "account_bank": "044",
            "account_number": "0690000044",
            "amount": 500,
            "narration": "New transfer",
            "currency": "NGN",
            "beneficiary_name": "Kwame Adew"
            })
        
            res2 = rave.Transfer.bulk({
                "title": "test",
                "bulk_data":[
                ]
            })
            print(res)
        
            balanceres = rave.Transfer.getBalance("NGN")
            print(balanceres)
        
        except RaveExceptions.IncompletePaymentDetailsError as e:
            print(e)
        
        except RaveExceptions.InitiateTransferError as e:
            print(e.err)
        
        except RaveExceptions.TransferFetchError as e:
            print(e.err)
        
        except RaveExceptions.ServerError as e:
            print(e.err)
        ```
        
        <br>
        
        ## ```rave.Subscriptions```
        
        This is used to initiate and manage Subscriptions
        
        
        **Functions included:**
        
        * ```.all```
        
        * ```.fetch```
        
        * ```.cancel```
        
        * ```.activate```
        
        
        ### ```.all()```
        
        This allows you retrieve all subscriptions 
        
        A sample all subscriptions call is:
        
        ```py
        res2 = rave.Subscriptions.all()
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'SUBSCRIPTIONS-FETCHED', 'data': {'page_info': {'total': 0, 'current_page': 0, 'total_pages': 0}, 'plansubscriptions': []}}}
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.fetch(subscription_id, subscription_email)```
        
        This allows you fetch a subscription. You may or may not pass in a ```subscription_id``` or ```subscription_email```. If you do not pass in a ```subscription_id``` or ```subscription_email``` all subscriptions will be returned.
        
        >subscription_id: This is the subscription ID.
        
        >subscription_email: This is the subscription email.
        
        
        A sample fetch subscription call is:
        
        ```py
        res2 = rave.Subscriptions.fetchSubscription(900)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'SUBSCRIPTIONS-FETCHED', 'data': {'page_info': {'total': 0, 'current_page': 0, 'total_pages': 0}, 'plansubscriptions': []}}}
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.cancelSubscription(subscription_id)```
        
        This allows you cancel a subscription.
        
        >subscription_id: This is the subscription ID. It can be gotten from the Rave Dashboard
        
        
        A sample cancel subscription call is:
        
        ```py
        res2 = rave.Subscriptions.cancel(900)
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        
        ### ```.activate(subscription_id)```
        
        This allows you activate a subscription.
        
        >subscription_id: This is the subscription ID. It can be gotten from the Rave Dashboard
        
        
        A sample activate subscription call is:
        
        ```py
        res2 = rave.Subscriptions.activate(900)
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### Complete Subscriptions flow
        
        ```py
        from rave_python import Rave, Misc, RaveExceptions
        rave = Rave("YOUR_PUBLIC_KEY", "YOUR_PRIVATE_KEY", usingEnv = False)
        try:
           
            res = rave.Subscriptions.all()
            res = rave.Subscriptions.fetch(880)
            res = rave.Subscriptions.cancel(880)
            print(res)
        
        except RaveExceptions.PlanStatusError as e:
            print(e.err)
        
        except RaveExceptions.ServerError as e:
            print(e.err)
        ```
        
        <br>
        
        ## ```rave.PaymentPlan```
        
        This is used to initiate and manage payment plans
        
        
        **Functions included:**
        
        * ```.create```
        
        * ```.all```
        
        * ```.fetch```
        
        * ```.cancelPlan```
        
        * ```.edit```
        
        <br>
        
        ### ```.create(planDetails)```
        
        This allows a customer to create a payment plan. It requires a dict ```planDetails``` containing ```amount```, ```name```, ```interval```, ```duration```. 
        >amount: this is the amount for the plan
        
        >name: This is what would appear on the subscription reminder email
        
        >interval: This are the charge intervals possible values are:
        ```
        daily;
        weekly;
        monthly;
        yearly;
        quarterly;
        bi-anually;
        every 2 days;
        every 90 days;
        every 5 weeks;
        every 12 months;
        every 6 years;
        every x y (where x is a number and y is the period e.g. every 5 months)
        ```
        
        >duration: This is the frequency, it is numeric, e.g. if set to 5 and intervals is set to monthly you would be charged 5 months, and then the subscription stops.
        
        More information can be found [here](https://developer.flutterwave.com/v2.0/reference#create-payment-plan)
        
        
        **If duration is not passed, any subscribed customer will be charged indefinitely**
        
        
        A sample create call is:
        
        ```py
         res = rave.PaymentPlan.create({
            "amount": 1,
            "duration": 5,
            "name": "Ultimate Play",
            "interval": "5"
         })
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'id': 890, 'data': {'id': 890, 'name': 'Ultimate Play', 'amount': 1, 'interval': 'dai', 'duration': 5, 'status': 'active', 'currency': 'NGN', 'plan_token': 'rpp_af8ea4d5d785d08f47d8', 'date_created': '2018-10-09T10:03:00.000Z'}}
        ```
        
         This call raises an ```IncompletePaymentDetailsError``` if there was a problem processing your transaction. The ```IncompletePaymentDetailsError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.IncompletePaymentDetailsError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.all()```
        
        This allows you retrieve all payment plans. 
        
        A sample all plans call is:
        
        ```py
        res2 = rave.Transfer.all()
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'QUERIED-PAYMENTPLANS', 'data': {'page_info': {'total': 12, 'current_page': 1, 'total_pages': 2}, 'paymentplans': [{'id': 890, 'name': 'Ultimate Play', 'amount': 1, 'interval': 'dai', 'duration': 5, 'status': 'active', 'currency': 'NGN', 'plan_token': 'rpp_af8ea4d5d785d08f47d8', 'date_created': '2018-10-09T10:03:00.000Z'}, {'id': 885, 'name': 'N/A', 'amount': 0, 'interval': 'daily', 'duration': 0, 'status': 'cancelled', 'currency': 'NGN', 'plan_token': 'rpp_19c8a7af7a06351fd78b', 'date_created': '2018-10-05T17:16:15.000Z'}]}}}
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.fetch(plan_id, plan_name)```
        
        This allows you fetch a payment plan. You may or may not pass in a ```plan_id``` or ```plan_name```. If you do not pass in a ```plan_id``` or ```plan_name```, all payment plans will be returned.
        
        >plan_id: This is the payment plan ID. It can be gotten from the response returned from creating a plan or from the Rave Dashboard
        
        >plan_name: This is the payment plan name. It can be gotten from the response returned from creating a plan or from the Rave Dashboard
        
        A sample fetch plan call is:
        
        ```py
        res2 = rave.Transfer.fetch(900)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'QUERIED-PAYMENTPLANS', 'data': {'page_info': {'total': 1, 'current_page': 1, 'total_pages': 1}, 'paymentplans': [{'id': 890, 'name': 'Ultimate Play', 'amount': 1, 'interval': 'dai', 'duration': 5, 'status': 'active', 'currency': 'NGN', 'plan_token': 'rpp_af8ea4d5d785d08f47d8', 'date_created': '2018-10-09T10:03:00.000Z'}]}}}
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.cancelPlan(plan_id)```
        
        This allows you cancel a payment plan. It requires that you pass in an ```plan_id```.
        
        >plan_id: This is the payment plan ID. It can be gotten from the response returned from creating a plan or from the Rave Dashboard
        
        A sample cancelPlan call is:
        
        ```py
        res2 = rave.Transfer.cancelPlan(900)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'PLAN-CANCELED', 'data': {'id': 890, 'name': 'Ultimate Play', 'uuid': 'rpp_af8ea4d5d785d08f47d8', 'status': 'cancelled', 'start': None, 'stop': None, 'initial_charge_amount': None, 'currency': 'NGN', 'amount': 1, 'duration': 5, 'interval': 'dai', 'createdAt': '2018-10-09T10:03:00.000Z', 'updatedAt': '2018-10-09T10:17:14.000Z', 'deletedAt': None, 'AccountId': 5949, 'paymentpageId': None}}}
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        
        ### ```.edit(plan_id, newData={})```
        
        This allows you edit a payment plan. It requires that you pass in an ```plan_id```. If you do not pass in the ```newData``` dict containing the change you want to make to your plan, the plan stays the same.
        
        >plan_id: This is the payment plan ID. It can be gotten from the response returned from creating a plan or from the Rave Dashboard
        
        >newData: A ```dict``` that must contain one or both of: ```name```, ```status``` as properties. 
        >```name``` specifies the new name for your payment plan.
        >```status``` : possible values are ```active``` and ```cancelled```
        
        A sample cancel plan call is:
        
        ```py
        res = rave.PaymentPlan.editPlan(880, {
                "name": "Jack's Plan",
                "status": "active"
        })
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {'error': False, 'returnedData': {'status': 'success', 'message': 'PLAN-EDITED', 'data': {'id': 880, 'name': "Jack's Plan", 'uuid': 'rpp_237e94690d8e7089c07b', 'status': 'active', 'start': None, 'stop': None, 'initial_charge_amount': None, 'currency': 'NGN', 'amount': 1, 'duration': 5, 'interval': 'dai', 'createdAt': '2018-10-05T17:13:16.000Z', 'updatedAt': '2018-10-09T10:25:25.000Z', 'deletedAt': None, 'AccountId': 5949, 'paymentpageId': None}}}
        ```
        
         This call raises a ```PlanStatusError``` if there was a problem processing your transaction. The ```PlanStatusError``` contains some information about your transaction. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.PlanStatusError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        <br>
        
        ### Complete PaymentPlan flow
        
        ```py
        from rave_python import Rave, Misc, RaveExceptions
        rave = Rave("YOUR_PUBLIC_KEY", "YOUR_PRIVATE_KEY", usingEnv = False)
        try:
        
            res = rave.PaymentPlan.create({
                "amount": 1,
                "duration": 5,
                "name": "Ultimate Plan",
                "interval": "dai"
            })
            
            res = rave.PaymentPlan.edit(880, {
                "name": "Jack's Plan",
                "status": "active"
            })
            print(res)
        
        except RaveExceptions.IncompletePaymentDetailsError as e:
            print(e)
        
        except RaveExceptions.TransferFetchError as e:
            print(e.err)
        
        except RaveExceptions.ServerError as e:
            print(e.err)
        ```
        
        <br>
        
        ## ```rave.Ussd```
        
        >**NOTE:** This payment option is still in beta mode.
        
        <br>
        
        ## ```rave.VirtualAccount```
        
        This is used to create virtual account for transfers.
        
        
        **Functions included:**
        
        * ```.create```
        
        <br>
        
        ### ```.create(accountDetails)```
        
        This allows a customer to create a virtual card. It requires a dict ```vcardDetails``` containing ```email```, ```seckey```, ```is_permanant```, ```frequency```, ```duration``` and  ```narration```.
        
        A sample Create call is:
        
        ```py
         res = rave.VirtualAccount.create({
        	"email": "user@example.com",
        	"seckey": "FLWSECK-****************************-X",
        	"is_permanent": true
        })
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {
            "status": "success",
            "message": "BANKTRANSFERS-ACCOUNTNUMBER-CREATED",
            "data": {
                "response_code": "02",
                "response_message": "Transaction in progress",
                "flw_reference": "FLW-89298329b9794587807aa775cda5db9f",
                "accountnumber": "1357960669",
                "accountstatus": "ACTIVE",
                "frequency": "N/A",
                "bankname": "Highstreet MFB",
                "created_on": "2019-08-20 12:18:46",
                "expiry_date": "N/A",
                "note": "Please make a bank transfer to Raver",
                "amount": null
            }
        }
        ```
        
         This call raises an ```IncompleteAccountDetailsError``` if there was a problem creating your virtual account. The ```IncompleteCardDetailsError``` contains some information about your virtual account. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.IncompleteAccountDetailsError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        <br>
        
        ## ```rave.VirtualCard```
        
        This is used to create virtual cards and carry out other virtual card operations.
        
        
        **Functions included:**
        
        * ```.create```
        
        * ```.all```
        
        * ```.get```
        
        * ```.cancel```
        
        * ```.freeze```
        
        * ```.unfreeze```
        
        * ```.fund```
        
        * ```.withdraw```
        <br>
        
        ### ```.create(vcardDetails)```
        
        This allows a customer to create a virtual card. It requires a dict ```vcardDetails``` containing ```currency```, ```amount```, ```billing name```, ```billing address```, ```billing city```, ```billing state```, ```billing postal code```, ```billing country```
        
        A sample Create call is:
        
        ```py
         res = rave.VirtualCard.create({
            "currency": "NGN",
            "amount": "100",
            "billing_name": "Corvus james",
            "billing_address": "8, Providence Street",
            "billing_city": "Lekki",
            "billing_state": "Lagos",
            "billing_postal_code": "100001",
            "billing_country": "NG",
         })
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {"status": "success", "message": "Card created successfully", "data": {"id": "c3ff3ac4-784b-4d07-9fc7-b5b9cde75752", "AccountId": 507, "amount": "100.00", "currency": "NGN", "card_hash": "c3ff3ac4-784b-4d07-9fc7-b5b9cde75752", "cardpan": "5563389915692128", "maskedpan": "556338*******2128", "city": "Lekki", "state": "Lagos", "address_1": "8, Providence Street", "address_2": null, "zip_code": "100001", "cvv": "408", "expiration": "2022-01", "send_to": null, "bin_check_name": null, "card_type": "mastercard", "name_on_card": "Corvus james", "date_created": "2019-01-30T16:45:45.550663+00:00", "is_active": true}}
        ```
        
         This call raises an ```IncompleteCardDetailsError``` if there was a problem creating your card. The ```IncompleteCardDetailsError``` contains some information about the error encountered in creating your card. You can handle this as such:
        
        ```py
        try: 
            #Your charge call
        except RaveExceptions.IncompleteCardDetailsError as e:
            print(e.err["errMsg"])
            print(e.err["flwRef"])
        ```
        
        ### ```.all()```
        
        This allows a the user to query all cards 
        
        A sample Create call is:
        
        ```py
        res = rave.VirtualCard.all()
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {
            "status": "success",
            "message": "SUCCESSFUL",
            "data": [
                {
                    "id": "660bae3b-333c-410f-b283-2d181587247f",
                    "AccountId": 507,
                    "amount": "1.00",
                    "currency": "USD",
                    "card_hash": "660bae3b-333c-410f-b283-2d181587247f",
                    "cardpan": "5563384241646062",
                    "maskedpan": "556338*******6062",
                    "city": "Hillside",
                    "state": "New jersey",
                    "address_1": "471 mundet pl",
                    "address_2": null,
                    "zip_code": "07205",
                    "cvv": "480",
                    "expiration": "2022-01",
                    "send_to": null,
                    "bin_check_name": null,
                    "card_type": "mastercard",
                    "name_on_card": "ruby cupp",
                    "date_created": "2019-01-26T04:00:10.263Z",
                    "is_active": true
                },
                {
                    "id": "6b7daf10-ade2-4633-a2ab-ea5495bb0ce2",
                    "AccountId": 507,
                    "amount": "10.00",
                    "currency": "USD",
                    "card_hash": "6b7daf10-ade2-4633-a2ab-ea5495bb0ce2",
                    "cardpan": "5563387512530188",
                    "maskedpan": "556338*******0188",
                    "city": "Hillside",
                    "state": "New jersey",
                    "address_1": "471 mundet pl",
                    "address_2": null,
                    "zip_code": "07205",
                    "cvv": "248",
                    "expiration": "2022-01",
                    "send_to": null,
                    "bin_check_name": null,
                    "card_type": "mastercard",
                    "name_on_card": "Paige graffunder",
                    "date_created": "2019-01-27T10:52:31.65Z",
                    "is_active": true
                },
                {
                    "id": "f32a2067-1b5e-419f-ae5c-69f968ee85db",
                    "AccountId": 507,
                    "amount": "1.00",
                    "currency": "USD",
                    "card_hash": "f32a2067-1b5e-419f-ae5c-69f968ee85db",
                    "cardpan": "5563387304903023",
                    "maskedpan": "556338*******3023",
                    "city": "Hillside",
                    "state": "New jersey",
                    "address_1": "471 mundet pl",
                    "address_2": null,
                    "zip_code": "07205",
                    "cvv": "994",
                    "expiration": "2022-01",
                    "send_to": null,
                    "bin_check_name": null,
                    "card_type": "mastercard",
                    "name_on_card": "Donna Gaydosh",
                    "date_created": "2019-01-27T11:10:29.333Z",
                    "is_active": true
                },
                {
                    "id": "3ff39cd4-4451-403d-874a-f90fa67fd1b8",
                    "AccountId": 507,
                    "amount": "1.00",
                    "currency": "USD",
                    "card_hash": "3ff39cd4-4451-403d-874a-f90fa67fd1b8",
                    "cardpan": "5563380574586529",
                    "maskedpan": "556338*******6529",
                    "city": "Hillside",
                    "state": "New jersey",
                    "address_1": "471 mundet pl",
                    "address_2": null,
                    "zip_code": "07205",
                    "cvv": "950",
                    "expiration": "2022-01",
                    "send_to": null,
                    "bin_check_name": null,
                    "card_type": "mastercard",
                    "name_on_card": "Stephanie elmer",
                    "date_created": "2019-01-27T11:12:26.68Z",
                    "is_active": true
                },
                {
                    "id": "cabbea77-9040-47b4-ac05-b7d1d804173b",
                    "AccountId": 507,
                    "amount": "1.00",
                    "currency": "USD",
                    "card_hash": "cabbea77-9040-47b4-ac05-b7d1d804173b",
                    "cardpan": "5563388312887679",
                    "maskedpan": "556338*******7679",
                    "city": "Hillside",
                    "state": "New jersey",
                    "address_1": "471 mundet pl",
                    "address_2": null,
                    "zip_code": "07205",
                    "cvv": "147",
                    "expiration": "2022-01",
                    "send_to": null,
                    "bin_check_name": null,
                    "card_type": "mastercard",
                    "name_on_card": "Jack Ma",
                    "date_created": "2019-01-27T15:20:20.52Z",
                    "is_active": true
                },
                {
                    "id": "c3ff3ac4-784b-4d07-9fc7-b5b9cde75752",
                    "AccountId": 507,
                    "amount": "12.00",
                    "currency": "USD",
                    "card_hash": "c3ff3ac4-784b-4d07-9fc7-b5b9cde75752",
                    "cardpan": "5563389915692128",
                    "maskedpan": "556338*******2128",
                    "city": "Hillside",
                    "state": "New jersey",
                    "address_1": "471 mundet pl",
                    "address_2": null,
                    "zip_code": "07205",
                    "cvv": "408",
                    "expiration": "2022-01",
                    "send_to": null,
                    "bin_check_name": null,
                    "card_type": "mastercard",
                    "name_on_card": "Jamiu Ganiu",
                    "date_created": "2019-01-30T16:45:47.233Z",
                    "is_active": true
                }
            ]
        }
        ```
        
        ### ```.get()```
        
        This allows a the user to query the details of a card with a given id. 
        
        A sample Create call is:
        
        ```py
        card_id = "660bae3b-333c-410f-b283-2d181587247f"
        res = rave.VirtualCard.getCard(card_id)
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {
            "status": "success",
            "message": "SUCCESSFUL",
            "data": {
                "id": "660bae3b-333c-410f-b283-2d181587247f",
                "AccountId": 507,
                "amount": "21.00",
                "currency": "USD",
                "card_hash": "660bae3b-333c-410f-b283-2d181587247f",
                "cardpan": "5563384241646062",
                "maskedpan": "556338*******6062",
                "city": "Hillside",
                "state": null,
                "address_1": "471 mundet pl",
                "address_2": null,
                "zip_code": "07205",
                "cvv": "480",
                "expiration": "2022-01",
                "send_to": null,
                "bin_check_name": null,
                "card_type": "mastercard",
                "name_on_card": null,
                "date_created": "2019-01-30T17:01:47.0972087+00:00",
                "is_active": true
            }
        }
        ```
        
        ### ```.cancel()```
        
        This allows a the user to terminate the use of a card with a given id permanently. This cancellation results in the permanent deletion of the card. 
        
        A sample Create call is:
        
        ```py
        card_id = "660bae3b-333c-410f-b283-2d181587247f"
        res = rave.VirtualCard.cancelCard(card_id)
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {
          "Status": "success",
          "Message": "Card terminated successfully",
          "Reference": null
        }
        ```
        
        ### ```.freeze()```
        
        This allows a the user to terminate the use of a card with a given id temporarily. This cancellation results in the temporary suspension of the card 
        
        A sample Create call is:
        
        ```py
        card_id = "660bae3b-333c-410f-b283-2d181587247f"
        res = rave.VirtualCard.freezeCard(card_id)
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {
          "Status": "success",
          "Message": "Card freeze successful",
          "Reference": null
        }
        ```
        
        ### ```.unfreeze()```
        
        This allows a the user to resume the use of a temporarily suspended or frozen card with a given id. 
        
        A sample Create call is:
        
        ```py
        card_id = "660bae3b-333c-410f-b283-2d181587247f"
        res = rave.VirtualCard.getCard(card_id)
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {
          "Status": "success",
          "Message": "Card unfreeze successful",
          "Reference": null
        }
        ```
        
        ### ```.fund()```
        
        This allows a the user to add funds to a card with a given id. the `card_id`, `currency` and `amount` are passed into the `.fundCard()` method.
        
        A sample Create call is:
        
        ```py
        card_id = "660bae3b-333c-410f-b283-2d181587247f"
        res = rave.VirtualCard.fundCard(card_id, "NGN", 2000)
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {
            "Status": "success",
            "Message": "Card was funded successfully",
            "Reference": null
        }
        ```
        
        ### ```.Withdraw()```
        
        This allows a the user to withdraw funds from a card with a given id. the `card id` and `amount` are passed into the `.Withdraw()` method.
        
        A sample Create call is:
        
        ```py
        card_id = "660bae3b-333c-410f-b283-2d181587247f"
        res = rave.VirtualCard.Withdraw(card_id, 1000)
        print(res)
        ```
        
        #### Returns
        
        This call returns a dictionary. A sample response is:
        
        ```py
        {
            "Status": "success",
            "Message": "Withdrawal successful",
            "Reference": null
        }
        ```
        <br>
        
        ## Run Tests
        
        All of the SDK's tests are written with Python's ```unittest``` module. The tests currently test:
        ```rave.Account```
        ```rave.Card```
        ```rave.Transfer```
        ```rave.Preauth```
        ```rave.Subaccount```
        ```rave.Subscriptions```
        ```rave.Paymentplan```
        
        They can be run like so:
        
        ```sh
        python test.py
        ```
        
        >**NOTE:** If the test fails for creating a subaccount, just change the ```account_number``` ```account_bank```  and ```businesss_email``` to something different
        
        >**NOTE:** The test may fail for account validation - ``` Pending OTP validation``` depending on whether the service is down or not
        <br>
        
        ## Support
        For further assistance in using the SDK, you can contact the Developers on [Slack](https://join.slack.com/t/flutterwavedevelopers/shared_invite/enQtNTk3MjgxMjU3ODI5LWFkMjBkYTc0ZGJhM2Q5MTY3YjFkYzAyYmM1ZDZjZjUwMjE4YTc2NjQ1ZGM5ZWE4NDUxMzc4MmExYmI1Yjg5ZWU) and [Email](mailto:developers@flutterwavego.com). You can get more information about the amazing features here [here](https://developer.flutterwave.com/reference#introduction).
        
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
Description-Content-Type: text/markdown
