Repository: razorpay/razorpay-python

Issue:
Missing function to fetch payment details made to a Virtual Account if payment is UPI Transfer
The docs says for UPI transaction there is a separate api call ([here](https://razorpay.com/docs/smart-collect/api/fetch/#upi)) to fetch payment details given an id. 

I see something similar is already done for `bank_account` payments. ([here](https://github.com/razorpay/razorpay-python/blob/5bc63fd8452165a4b54556888492e555222c8afe/razorpay/resources/payment.py#L94)) so please provide another function to fetch particular `upi_transfer` payment details.

Happy to give a PR sometime over the weekend if need be.


Discussion:
Vibhu-Agarwal: @captn3m0 

Patch:
diff --git a/.travis.yml b/.travis.yml
index e27cf0d..37b69e0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,8 +1,6 @@
 language: python
 python:
-  - "2.7.6"
   - "2.7"
-  - "3.3"
   - "3.4"
   - "3.5"
   - "3.6"
diff --git a/razorpay/resources/payment.py b/razorpay/resources/payment.py
index a7546b8..fc9d6b6 100644
--- a/razorpay/resources/payment.py
+++ b/razorpay/resources/payment.py
@@ -40,7 +40,7 @@ class Payment(Resource):
 
         Args:
             payment_id : Id for which payment object has to be retrieved
-            Amount : Amount for which the payment has to be retrieved
+            amount : Amount for which the payment has to be retrieved
 
         Returns:
             Payment dict after getting captured
@@ -55,7 +55,7 @@ class Payment(Resource):
 
         Args:
             payment_id : Id for which payment object has to be refunded
-            Amount : Amount for which the payment has to be refunded
+            amount : Amount for which the payment has to be refunded
 
         Returns:
             Payment dict after getting refunded
@@ -69,10 +69,10 @@ class Payment(Resource):
         Create Transfer for given Payment Id
 
         Args:
-            payment_id : Id for which payment object has to be transfered
+            payment_id : Id for which payment object has to be transferred
 
         Returns:
-            Payment dict after getting transfered
+            Payment dict after getting transferred
         """
         url = "{}/{}/transfers".format(self.base_url, payment_id)
         return self.post_url(url, data, **kwargs)
@@ -82,11 +82,11 @@ class Payment(Resource):
         Fetches all transfer for given Payment Id
 
         Args:
-            payment_id : Id for which payment object has to be refunded
-            Amount : Amount for which the payment has to be refunded
+            payment_id : Id for which all the transfers has to be fetched
 
         Returns:
-            Payment dict after getting refunded
+            A collection (dict) of transfers
+            items : The key containing a list of 'transfer' entities
         """
         url = "{}/{}/transfers".format(self.base_url, payment_id)
         return self.get_url(url, data, **kwargs)
@@ -103,3 +103,16 @@ class Payment(Resource):
         """
         url = "{}/{}/bank_transfer".format(self.base_url, payment_id)
         return self.get_url(url, data, **kwargs)
+
+    def upi_transfer(self, payment_id, data={}, **kwargs):
+        """"
+        UPI Transfer Entity for given Payment
+
+        Args:
+            payment_id : Id for which upi transfer entity has to be fetched
+
+        Returns:
+            UPI Transfer dict
+        """
+        url = "{}/{}/upi_transfer".format(self.base_url, payment_id)
+        return self.get_url(url, data, **kwargs)
diff --git a/setup.py b/setup.py
index b36593c..e1c06bc 100644
--- a/setup.py
+++ b/setup.py
@@ -1,9 +1,14 @@
 from setuptools import setup
 
+with open('README.md') as readme:
+    readme_content = readme.read()
+
 setup(
     name="razorpay",
     version="1.2.0",
     description="Razorpay Python Client",
+    long_description=readme_content,
+    long_description_content_type='text/markdown',
     url="https://github.com/razorpay/razorpay-python",
     author="Team Razorpay",
     license="MIT",
@@ -23,7 +28,6 @@ setup(
         'Programming Language :: Python :: 2',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.3',
         'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',


Test patch:
diff --git a/tests/helpers.py b/tests/helpers.py
index 96c706e..ed051a9 100644
--- a/tests/helpers.py
+++ b/tests/helpers.py
@@ -8,7 +8,9 @@ def mock_file(filename):
         return ''
     file_dir = os.path.dirname(__file__)
     file_path = "{}/mocks/{}.json".format(file_dir, filename)
-    return open(file_path).read()
+    with open(file_path) as f:
+        mock_file_data = f.read()
+    return mock_file_data
 
 
 class ClientTestCase(unittest.TestCase):
diff --git a/tests/mocks/fake_upi_transfer.json b/tests/mocks/fake_upi_transfer.json
new file mode 100644
index 0000000..bf1d891
--- /dev/null
+++ b/tests/mocks/fake_upi_transfer.json
@@ -0,0 +1,8 @@
+{
+    "amount": 10000,
+    "payer_vpa": null,
+    "payer_account": null,
+    "payer_bank": "Razorpay",
+    "payment_id": "fake_payment_id",
+    "virtual_account_id": "va_8J2ny4Naokqbpf"
+}
diff --git a/tests/test_client_payment.py b/tests/test_client_payment.py
index 1a01b28..926d949 100644
--- a/tests/test_client_payment.py
+++ b/tests/test_client_payment.py
@@ -92,3 +92,17 @@ class TestClientPayment(ClientTestCase):
         response = self.client.payment.bank_transfer(self.payment_id)
         self.assertEqual(response['virtual_account_id'], 'va_8J2ny4Naokqbpe')
         self.assertEqual(response['payment_id'], self.payment_id)
+
+    @responses.activate
+    def test_upi_transfer_fetch(self):
+        result = mock_file('fake_upi_transfer')
+        url = '{}/{}/upi_transfer'.format(self.base_url, self.payment_id)
+        responses.add(responses.GET,
+                      url,
+                      status=200,
+                      body=result,
+                      match_querystring=True)
+
+        response = self.client.payment.upi_transfer(self.payment_id)
+        self.assertEqual(response['virtual_account_id'], 'va_8J2ny4Naokqbpf')
+        self.assertEqual(response['payment_id'], self.payment_id)