From 05e39d82cc921b7fde4706551614455846689aa9 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Thu, 23 Dec 2021 16:52:22 +0530 Subject: [PATCH 01/25] add gitaction --- .github/workflows/python.yml | 34 ++++++++++++++++++++++++++++++++++ .travis.yml | 9 --------- README.md | 2 +- setup.py | 2 +- 4 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/python.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml new file mode 100644 index 00000000..014cb9de --- /dev/null +++ b/.github/workflows/python.yml @@ -0,0 +1,34 @@ +# This workflow will upload a Python Package using Twine when a release is created +# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries + +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Python Package + +on: + release: + types: [published] + +jobs: + deploy: + + runs-on: ubuntu-latest + strategy: + max-parallel: 4 + matrix: + python-version: [3, 3.5, 3.6] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python + uses: actions/setup-python@v2 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install responses + python3 setup.py install + - name: Run Tests + run: python3 -m unittest diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 37b69e08..00000000 --- a/.travis.yml +++ /dev/null @@ -1,9 +0,0 @@ -language: python -python: - - "2.7" - - "3.4" - - "3.5" - - "3.6" -install: pip install requests responses coveralls -script: nosetests -v --with-coverage --cover-package=razorpay -after_success: coveralls diff --git a/README.md b/README.md index 66cc4b35..e5e565c7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Razorpay Python Client -[![PyPI Version](https://img.shields.io/pypi/v/razorpay.svg)](https://pypi.python.org/pypi/razorpay) [![Build Status](https://travis-ci.org/razorpay/razorpay-python.svg?branch=master)](https://travis-ci.org/razorpay/razorpay-python) [![Coverage Status](https://coveralls.io/repos/github/razorpay/razorpay-python/badge.svg?branch=master)](https://coveralls.io/github/razorpay/razorpay-python?branch=master) [![PyPI](https://img.shields.io/pypi/pyversions/razorpay.svg)]() [![License](https://img.shields.io/:license-mit-blue.svg)](https://opensource.org/licenses/MIT) +[![PyPI Version](https://img.shields.io/pypi/v/razorpay.svg)](https://pypi.python.org/pypi/razorpay) [![Coverage Status](https://coveralls.io/repos/github/razorpay/razorpay-python/badge.svg?branch=master)](https://coveralls.io/github/razorpay/razorpay-python?branch=master) [![PyPI](https://img.shields.io/pypi/pyversions/razorpay.svg)]() [![License](https://img.shields.io/:license-mit-blue.svg)](https://opensource.org/licenses/MIT) Python bindings for interacting with the Razorpay API diff --git a/setup.py b/setup.py index e1c06bc0..cccc6709 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ "License :: OSI Approved :: MIT License", # List of supported Python versions - # Make sure that this is reflected in .travis.yml as well + # Make sure that this is reflected in .github/workflows/python.yml as well "Programming Language :: Python", 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', From 855616c13d135eb0af69031033274eb0bf648bb8 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Thu, 23 Dec 2021 16:55:43 +0530 Subject: [PATCH 02/25] command fixed --- .github/workflows/python.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 014cb9de..b543080b 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -1,7 +1,3 @@ -# This workflow will upload a Python Package using Twine when a release is created -# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries - -# This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. @@ -9,8 +5,11 @@ name: Python Package on: - release: - types: [published] + push: + branches: [ master ] + pull_request: + branches: [ master ] + jobs: deploy: @@ -31,4 +30,4 @@ jobs: pip install responses python3 setup.py install - name: Run Tests - run: python3 -m unittest + run: python3 -m unittest \ No newline at end of file From 2c5cbb3e74387de476e977a28d6547950be1f91a Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Thu, 23 Dec 2021 17:42:36 +0530 Subject: [PATCH 03/25] updated addon fundaccount module --- razorpay/__init__.py | 2 + razorpay/constants/url.py | 1 + razorpay/resources/__init__.py | 2 + razorpay/resources/addon.py | 9 ++++ razorpay/resources/fund_account.py | 33 +++++++++++++ razorpay/resources/payment.py | 9 ++++ tests/mocks/addon_collection.json | 60 ++++++++++++++++++++++++ tests/mocks/fake_create_recurring.json | 9 ++++ tests/mocks/fund_account_collection.json | 38 +++++++++++++++ tests/mocks/init_create_recurring.json | 15 ++++++ tests/test_client_addon.py | 9 ++++ tests/test_client_fund_account.py | 41 ++++++++++++++++ tests/test_client_payment.py | 13 +++++ 13 files changed, 241 insertions(+) create mode 100644 razorpay/resources/fund_account.py create mode 100644 tests/mocks/addon_collection.json create mode 100644 tests/mocks/fake_create_recurring.json create mode 100644 tests/mocks/fund_account_collection.json create mode 100644 tests/mocks/init_create_recurring.json create mode 100644 tests/test_client_fund_account.py diff --git a/razorpay/__init__.py b/razorpay/__init__.py index ab11dc3f..25b619a6 100644 --- a/razorpay/__init__.py +++ b/razorpay/__init__.py @@ -13,6 +13,7 @@ from .resources import Subscription from .resources import Plan from .resources import Settlement +from .resources import FundAccount from .utility import Utility from .constants import ERROR_CODE from .constants import HTTP_STATUS_CODE @@ -33,6 +34,7 @@ 'Addon', 'Subscription', 'Plan', + 'FundAccount', 'Settlement', 'HTTP_STATUS_CODE', 'ERROR_CODE', diff --git a/razorpay/constants/url.py b/razorpay/constants/url.py index 3d2cb40d..156fa5a6 100644 --- a/razorpay/constants/url.py +++ b/razorpay/constants/url.py @@ -13,3 +13,4 @@ class URL(object): ADDON_URL = "/addons" PLAN_URL = "/plans" SETTLEMENT_URL = "/settlements" + FUND_ACCOUNT_URL = "/fund_accounts" diff --git a/razorpay/resources/__init__.py b/razorpay/resources/__init__.py index f8af63d4..f8f87878 100644 --- a/razorpay/resources/__init__.py +++ b/razorpay/resources/__init__.py @@ -12,6 +12,7 @@ from .plan import Plan from .subscription import Subscription from .settlement import Settlement +from .fund_account import FundAccount __all__ = [ 'Payment', @@ -28,4 +29,5 @@ 'Plan', 'Subscription', 'Settlement', + 'FundAccount' ] diff --git a/razorpay/resources/addon.py b/razorpay/resources/addon.py index 62c1a8ae..5e8a867c 100644 --- a/razorpay/resources/addon.py +++ b/razorpay/resources/addon.py @@ -27,3 +27,12 @@ def delete(self, addon_id, data={}, **kwargs): addon_id : Id for which addon object has to be deleted """ return super(Addon, self).delete(addon_id, data, **kwargs) + + def all(self, data={}, **kwargs): + """" + Fetch all Add-ons + Returns: + Dictionary of Add-ons + """ + print(data) + return super(Addon, self).all(data, **kwargs) diff --git a/razorpay/resources/fund_account.py b/razorpay/resources/fund_account.py new file mode 100644 index 00000000..98b02203 --- /dev/null +++ b/razorpay/resources/fund_account.py @@ -0,0 +1,33 @@ +from .base import Resource +from ..constants.url import URL + + +class FundAccount(Resource): + def __init__(self, client=None): + super(FundAccount, self).__init__(client) + self.base_url = URL.FUND_ACCOUNT_URL + + def all(self, data={}, **kwargs): + """" + Fetch all Fund Account entities + + Returns: + Dictionary of Fund Account + """ + return super(FundAccount, self).all(data, **kwargs) + + def create(self, data={}, **kwargs): + """" + Create a fund account + + Args: + data : Dictionary having keys using which order have to be created + 'customerId' : Customer Id for the customer + 'account_type' : The bank_account to be linked to the customer ID + 'bank_account' : key value pair + + Returns: + fund account Dict which was created + """ + url = self.base_url + return self.post_url(url, data, **kwargs) \ No newline at end of file diff --git a/razorpay/resources/payment.py b/razorpay/resources/payment.py index fc9d6b6e..7759b065 100644 --- a/razorpay/resources/payment.py +++ b/razorpay/resources/payment.py @@ -116,3 +116,12 @@ def upi_transfer(self, payment_id, data={}, **kwargs): """ url = "{}/{}/upi_transfer".format(self.base_url, payment_id) return self.get_url(url, data, **kwargs) + + def createRecurring(self, data={}, **kwargs): + """" + Create Recurring Payments + Return: + Recurring Payments dict + """ + url = "{}/{}/recurring".format(self.base_url,'create') + return self.post_url(url, data, **kwargs) diff --git a/tests/mocks/addon_collection.json b/tests/mocks/addon_collection.json new file mode 100644 index 00000000..3bc6b70e --- /dev/null +++ b/tests/mocks/addon_collection.json @@ -0,0 +1,60 @@ +{ + "entity": "collection", + "count": 2, + "items": [ + { + "id": "ao_IZfz8DsvzEu2w4", + "entity": "addon", + "item": { + "id": "item_IZfz8DdzVw4Sda", + "active": true, + "name": "Shipping charges", + "description": "Shipping charges", + "amount": 500, + "unit_amount": 500, + "currency": "INR", + "type": "addon", + "unit": null, + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "tax_id": null, + "tax_group_id": null, + "created_at": 1639991720, + "updated_at": 1639991720 + }, + "quantity": 1, + "created_at": 1639991720, + "subscription_id": "sub_IZfz84gerEXmVG", + "invoice_id": "inv_IZfz8cWWBAjU12" + }, + { + "id": "ao_IZe1vykIM4hmFv", + "entity": "addon", + "item": { + "id": "item_IZe1vyVGweG3ya", + "active": true, + "name": "Shipping charges", + "description": "Shipping charges", + "amount": 500, + "unit_amount": 500, + "currency": "INR", + "type": "addon", + "unit": null, + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "tax_id": null, + "tax_group_id": null, + "created_at": 1639984836, + "updated_at": 1639984836 + }, + "quantity": 1, + "created_at": 1639984836, + "subscription_id": "sub_IZe1vrmbHpvgCh", + "invoice_id": "inv_IZe1wNpGVcDHZD" + } + ] +} \ No newline at end of file diff --git a/tests/mocks/fake_create_recurring.json b/tests/mocks/fake_create_recurring.json new file mode 100644 index 00000000..70798f3b --- /dev/null +++ b/tests/mocks/fake_create_recurring.json @@ -0,0 +1,9 @@ +{ + "razorpay_payment_id": "pay_Ia5nRCnwjqXGxv", + "razorpay_order_id": "order_Ia5nABHSOWXg0Q", + "razorpay_signature": "1aa6e8472135fad2925071d547c6682a95a42d8b773e8346ddffec1c67ef3edf", + "org_logo": "", + "org_name": "Razorpay Software Private Ltd", + "checkout_logo": "https://cdn.razorpay.com/logo.png", + "custom_branding": false +} \ No newline at end of file diff --git a/tests/mocks/fund_account_collection.json b/tests/mocks/fund_account_collection.json new file mode 100644 index 00000000..f971b7ce --- /dev/null +++ b/tests/mocks/fund_account_collection.json @@ -0,0 +1,38 @@ +{ + "entity":"collection", + "count":1, + "items":[ + { + "id": "fa_IJXLAImwGqjlkS", + "entity": "fund_account", + "customer_id": "cust_IEfAt3ruD4OEzo", + "account_type": "bank_account", + "bank_account": { + "ifsc": "HDFC0000053", + "bank_name": "HDFC Bank", + "name": "Gaurav Kumar", + "notes": [], + "account_number": "11214311215411" + }, + "batch_id": null, + "active": true, + "created_at": 1636467835 + }, + { + "id": "fa_IJXI5ppTQAc3YB", + "entity": "fund_account", + "customer_id": "cust_IEfAt3ruD4OEzo", + "account_type": "bank_account", + "bank_account": { + "ifsc": "HDFC0000053", + "bank_name": "HDFC Bank", + "name": "Gaurav Kumar", + "notes": [], + "account_number": "11214311215411" + }, + "batch_id": null, + "active": true, + "created_at": 1636467660 + } + ] + } \ No newline at end of file diff --git a/tests/mocks/init_create_recurring.json b/tests/mocks/init_create_recurring.json new file mode 100644 index 00000000..6275ec37 --- /dev/null +++ b/tests/mocks/init_create_recurring.json @@ -0,0 +1,15 @@ +{ + "email": "gaurav.kumar@example.com", + "contact": "9876543567", + "amount": 10000, + "currency": "INR", + "order_id": "order_Ia5nABHSOWXg0Q", + "customer_id": "cust_DzYEzfJLV03rkp", + "token": "token_Ia5ip8Ix07JDRm", + "recurring": "1", + "notes": { + "note_key_1": "Tea. Earl grey. Hot.", + "note_key_2": "Tea. Earl grey. Decaf." + }, + "description": "Creating recurring payment for Gaurav Kumar" + } \ No newline at end of file diff --git a/tests/test_client_addon.py b/tests/test_client_addon.py index 5a0739ea..9a4d9588 100644 --- a/tests/test_client_addon.py +++ b/tests/test_client_addon.py @@ -29,3 +29,12 @@ def test_addon_delete(self): body=json.dumps(result), match_querystring=True) self.assertEqual(self.client.addon.delete(self.addon_id), result) + + + @responses.activate + def test_addon_fetch_all(self): + result = mock_file('addon_collection') + url = self.base_url + responses.add(responses.GET, url, status=200, + body=json.dumps(result), match_querystring=True) + self.assertEqual(self.client.addon.all(), result) diff --git a/tests/test_client_fund_account.py b/tests/test_client_fund_account.py new file mode 100644 index 00000000..4f1946a0 --- /dev/null +++ b/tests/test_client_fund_account.py @@ -0,0 +1,41 @@ +import responses +import json + +from .helpers import mock_file, ClientTestCase + + +class TestClientFundAccount(ClientTestCase): + + def setUp(self): + super(TestClientFundAccount, self).setUp() + self.base_url = '{}/fund_accounts'.format(self.base_url) + + @responses.activate + def test_all(self): + result = mock_file('fund_account_collection') + url = self.base_url + responses.add(responses.GET, url, status=200, + body=json.dumps(result), match_querystring=True) + self.assertEqual(self.client.fund_account.all(), result) + + @responses.activate + def test_create(self): + param = { + "customer_id": "cust_IEfAt3ruD4OEzo", + "account_type":"bank_account", + "bank_account":{ + "name":"Gaurav Kumar", + "account_number":"11214311215411", + "ifsc":"HDFC0000053" + } + } + result = mock_file('fund_account_collection') + url = self.base_url + responses.add(responses.POST, + url, + status=200, + body=json.dumps(result), + match_querystring=True) + + self.assertEqual(self.client.fund_account.create(param), result) + \ No newline at end of file diff --git a/tests/test_client_payment.py b/tests/test_client_payment.py index 926d949d..af902b14 100644 --- a/tests/test_client_payment.py +++ b/tests/test_client_payment.py @@ -106,3 +106,16 @@ def test_upi_transfer_fetch(self): 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) + + @responses.activate + def createRecurring(self): + init = mock_file('init_create_recurring') + result = mock_file('fake_create_recurring') + url = "{}/{}/recurring".format(self.base_url,'create') + responses.add(responses.POST, + url, + status=200, + body=json.dumps(result), + match_querystring=True) + + self.assertEqual(self.client.payment.createRecurring(init), result) From 82c991f8e0c41abd376bdef378eb468db2520563 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Mon, 27 Dec 2021 14:30:18 +0530 Subject: [PATCH 04/25] added registation link and edit order --- razorpay/__init__.py | 2 + razorpay/constants/url.py | 1 + razorpay/resources/__init__.py | 2 + razorpay/resources/order.py | 16 +++++++ razorpay/resources/registration_link.py | 26 ++++++++++++ tests/mocks/edit_order.json | 17 ++++++++ tests/mocks/fake_registration_link.json | 55 +++++++++++++++++++++++++ tests/mocks/init_registration_link.json | 31 ++++++++++++++ tests/test_client_order.py | 15 +++++++ tests/test_client_registration_link.py | 24 +++++++++++ 10 files changed, 189 insertions(+) create mode 100644 razorpay/resources/registration_link.py create mode 100644 tests/mocks/edit_order.json create mode 100644 tests/mocks/fake_registration_link.json create mode 100644 tests/mocks/init_registration_link.json create mode 100644 tests/test_client_registration_link.py diff --git a/razorpay/__init__.py b/razorpay/__init__.py index ab11dc3f..2ca70a61 100644 --- a/razorpay/__init__.py +++ b/razorpay/__init__.py @@ -11,6 +11,7 @@ from .resources import VirtualAccount from .resources import Addon from .resources import Subscription +from .resources import RegistrationLink from .resources import Plan from .resources import Settlement from .utility import Utility @@ -32,6 +33,7 @@ 'VirtualAccount', 'Addon', 'Subscription', + 'RegistrationLink', 'Plan', 'Settlement', 'HTTP_STATUS_CODE', diff --git a/razorpay/constants/url.py b/razorpay/constants/url.py index 3d2cb40d..b3905bb8 100644 --- a/razorpay/constants/url.py +++ b/razorpay/constants/url.py @@ -13,3 +13,4 @@ class URL(object): ADDON_URL = "/addons" PLAN_URL = "/plans" SETTLEMENT_URL = "/settlements" + REGISTRATION_LINK_URL = "/subscription_registration" diff --git a/razorpay/resources/__init__.py b/razorpay/resources/__init__.py index f8af63d4..cda643f7 100644 --- a/razorpay/resources/__init__.py +++ b/razorpay/resources/__init__.py @@ -11,6 +11,7 @@ from .addon import Addon from .plan import Plan from .subscription import Subscription +from .registration_link import RegistrationLink from .settlement import Settlement __all__ = [ @@ -27,5 +28,6 @@ 'Addon', 'Plan', 'Subscription', + 'RegistrationLink', 'Settlement', ] diff --git a/razorpay/resources/order.py b/razorpay/resources/order.py index dbb5ec4c..fa323b50 100644 --- a/razorpay/resources/order.py +++ b/razorpay/resources/order.py @@ -69,3 +69,19 @@ def create(self, data={}, **kwargs): """ url = self.base_url return self.post_url(url, data, **kwargs) + + def edit(self, order_id, data={}, **kwargs): + """" + Update order + + Args: + data : Dictionary having keys using which order have to be edited + 'notes' : key value pair as notes + + Returns: + Order Dict which was edited + + """ + url = '{}/{}'.format(self.base_url, order_id) + + return self.patch_url(url, data, **kwargs) \ No newline at end of file diff --git a/razorpay/resources/registration_link.py b/razorpay/resources/registration_link.py new file mode 100644 index 00000000..9dc17166 --- /dev/null +++ b/razorpay/resources/registration_link.py @@ -0,0 +1,26 @@ +from .base import Resource +from ..constants.url import URL + + +class RegistrationLink(Resource): + def __init__(self, client=None): + super(RegistrationLink, self).__init__(client) + self.base_url = URL.REGISTRATION_LINK_URL + + def create(self, data={}, **kwargs): + """" + Create a Registration Link + Args: + customer : Details of the customer to whom the registration link will be sent. + type* : In this case the value is link. + currency* : Currency used in Order + amount* : Amount of Order + description : The count may not be greater than 100. + subscription_registration : Details of the authorization payment. + notes : A key-value pair + + Returns: + {"success": true} + """ + url = "{}/{}".format(self.base_url, 'auth_links') + return self.post_url(url, data, **kwargs) \ No newline at end of file diff --git a/tests/mocks/edit_order.json b/tests/mocks/edit_order.json new file mode 100644 index 00000000..b2cd0808 --- /dev/null +++ b/tests/mocks/edit_order.json @@ -0,0 +1,17 @@ +{ + "id":"order_DaaS6LOUAASb7Y", + "entity":"order", + "amount":2200, + "amount_paid":0, + "amount_due":2200, + "currency":"INR", + "receipt":"Receipt #211", + "offer_id":null, + "status":"attempted", + "attempts":1, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1572505143 + } \ No newline at end of file diff --git a/tests/mocks/fake_registration_link.json b/tests/mocks/fake_registration_link.json new file mode 100644 index 00000000..f304320e --- /dev/null +++ b/tests/mocks/fake_registration_link.json @@ -0,0 +1,55 @@ +{ + "id": "inv_FHrZAOeCuB9HtK", + "entity": "invoice", + "receipt": "Receipt no. 26", + "invoice_number": "Receipt no. 26", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrZAPOStKd4xS", + "line_items": [], + "payment_id": null, + "status": "issued", + "expire_by": 1880480689, + "issued_at": 1595491123, + "paid_at": null, + "cancelled_at": null, + "expired_at": null, + "sms_status": "pending", + "email_status": "pending", + "date": 1595491123, + "terms": null, + "partial_payment": false, + "gross_amount": 0, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 0, + "amount_paid": 0, + "amount_due": 0, + "currency": "INR", + "currency_symbol": "₹", + "description": "test registration link", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/RllVOmA", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491123, + "idempotency_key": null + } \ No newline at end of file diff --git a/tests/mocks/init_registration_link.json b/tests/mocks/init_registration_link.json new file mode 100644 index 00000000..dc1a2bb2 --- /dev/null +++ b/tests/mocks/init_registration_link.json @@ -0,0 +1,31 @@ +{ + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": 9123456780 + }, + "type": "link", + "amount": 0, + "currency": "INR", + "description": "12 p.m. Meals", + "subscription_registration": { + "method": "emandate", + "auth_type": "netbanking", + "expire_at": 1580480689, + "max_amount": 50000, + "bank_account": { + "beneficiary_name" : "Gaurav Kumar", + "account_number" : 11214311215411, + "account_type" : "savings", + "ifsc_code" : "HDFC0001233" + } + }, + "receipt": "Receipt no. 1", + "expire_by" : 1880480689, + "sms_notify": 1, + "email_notify": 1, + "notes" : { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } + } \ No newline at end of file diff --git a/tests/test_client_order.py b/tests/test_client_order.py index 47af7b38..a8e747a4 100644 --- a/tests/test_client_order.py +++ b/tests/test_client_order.py @@ -67,3 +67,18 @@ def test_order_create(self): responses.add(responses.POST, url, status=200, body=json.dumps(result), match_querystring=True) self.assertEqual(self.client.order.create(init), result) + + @responses.activate + def test_order_edit(self): + param = { + "notes": { + "key1": "value3", + "key2": "value2" + } + } + + result = mock_file('edit_order') + url = '{}/{}'.format(self.base_url, 'dummy_id') + responses.add(responses.PATCH, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.order.edit('dummy_id', param), result) diff --git a/tests/test_client_registration_link.py b/tests/test_client_registration_link.py new file mode 100644 index 00000000..93356811 --- /dev/null +++ b/tests/test_client_registration_link.py @@ -0,0 +1,24 @@ +import responses +import json + +from .helpers import mock_file, ClientTestCase + + +class TestClientRegistrationLink(ClientTestCase): + + def setUp(self): + super(TestClientRegistrationLink, self).setUp() + self.base_url = '{}/subscription_registration/{}'.format(self.base_url, 'auth_links') + + @responses.activate + def test_create(self): + param = mock_file('init_registration_link') + result = mock_file('fake_registration_link') + url = self.base_url + responses.add(responses.POST, + url, + status=200, + body=json.dumps(result), + match_querystring=True) + + self.assertEqual(self.client.registration_link.create(param), result) From b663555ea72b74cccb0ebeb493f3d9e1ac97c37a Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Mon, 3 Jan 2022 15:30:09 +0530 Subject: [PATCH 05/25] updated payment module --- razorpay/resources/payment.py | 68 +++++++++++++++++++++++ tests/mocks/edit_payment.json | 35 ++++++++++++ tests/mocks/fake_card_detail_payment.json | 12 ++++ tests/mocks/fake_payment_json.json | 41 ++++++++++++++ tests/test_client_payment.py | 63 +++++++++++++++++++++ 5 files changed, 219 insertions(+) create mode 100644 tests/mocks/edit_payment.json create mode 100644 tests/mocks/fake_card_detail_payment.json create mode 100644 tests/mocks/fake_payment_json.json diff --git a/razorpay/resources/payment.py b/razorpay/resources/payment.py index fc9d6b6e..b7bb0751 100644 --- a/razorpay/resources/payment.py +++ b/razorpay/resources/payment.py @@ -116,3 +116,71 @@ def upi_transfer(self, payment_id, data={}, **kwargs): """ url = "{}/{}/upi_transfer".format(self.base_url, payment_id) return self.get_url(url, data, **kwargs) + + def edit(self, payment_id, data={}, **kwargs): + """" + Update the Payment + Args: + data : Dictionary having keys using which order have to be edited + 'notes' : key value pair as notes + + Returns: + Payment Dict which was edited + """ + url = '{}/{}'.format(self.base_url, payment_id) + + return self.patch_url(url, data, **kwargs) + + def fetchCardDetails(self, payment_id, **kwargs): + """" + Fetch Card Details of a Payment + + Args: + payment_id : Id for which payment objects has to be retrieved + + Returns: + Payment dict for given Order Id + """ + url = "{}/{}/card".format(self.base_url, payment_id) + return self.get_url(url, {}, **kwargs) + + def fetchDownTime(self, **kwargs): + """" + Fetch Card Details of a Payment + + Args: + payment_id : Id for which payment objects has to be retrieved + + Returns: + Payment dict for given Order Id + """ + url = "{}/{}".format(self.base_url,'downtimes') + return self.get_url(url, {}, **kwargs) + + def fetchDownTimeById(self, downtime_id, **kwargs): + """" + Fetch Payment Downtime Details by ID + + Args: + payment_id : Id for which payment objects has to be retrieved + + Returns: + Payment dict for given Order Id + """ + url = "{}/downtimes/{}".format(self.base_url, downtime_id) + return self.get_url(url, {}, **kwargs) + + def createPaymentJson(self ,data={}, **kwargs): + """" + Create a Payment + + Args: + payment_id : Id for which payment object has to be refunded + amount : Amount for which the payment has to be refunded + + Returns: + Payment Dict which was created + """ + url = "{}/create/{}".format(self.base_url, 'json') + + return self.post_url(url, data, **kwargs) \ No newline at end of file diff --git a/tests/mocks/edit_payment.json b/tests/mocks/edit_payment.json new file mode 100644 index 00000000..677908b9 --- /dev/null +++ b/tests/mocks/edit_payment.json @@ -0,0 +1,35 @@ +{ + "id": "pay_CBYy6tLmJTzn3Q", + "entity": "payment", + "amount": 1000, + "currency": "INR", + "status": "authorized", + "order_id": null, + "invoice_id": null, + "international": false, + "method": "netbanking", + "amount_refunded": 0, + "refund_status": null, + "captured": false, + "description": null, + "card_id": null, + "bank": "UTIB", + "wallet": null, + "vpa": null, + "email": "testme@acme.com", + "notes": { + "key1": "value1", + "key2": "value2" + }, + "fee": null, + "tax": null, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "bank_transaction_id": "0125836177" + }, + "created_at": 1553504328 + } \ No newline at end of file diff --git a/tests/mocks/fake_card_detail_payment.json b/tests/mocks/fake_card_detail_payment.json new file mode 100644 index 00000000..cbf2a547 --- /dev/null +++ b/tests/mocks/fake_card_detail_payment.json @@ -0,0 +1,12 @@ +{ + "id": "card_6krZ6bcjoeqyV9", + "entity": "card", + "name": "Gaurav", + "last4": "3335", + "network": "Visa", + "type": "debit", + "issuer": "SBIN", + "international": false, + "emi": null, + "sub_type": "business" + } \ No newline at end of file diff --git a/tests/mocks/fake_payment_json.json b/tests/mocks/fake_payment_json.json new file mode 100644 index 00000000..65a0a9ac --- /dev/null +++ b/tests/mocks/fake_payment_json.json @@ -0,0 +1,41 @@ +{ + "type": "respawn", + "request": { + "url": "https://api.razorpay.com/v1/payments?key_id=rzp_test_pNL6H0AmbBEyjD", + "method": "POST", + "content": { + "amount": "500", + "currency": "INR", + "email": "gaurav.kumar@example.com", + "contact": "9123456789", + "order_id": "order_IfCiyxcRYv1bbf", + "method": "upi", + "card": { + "number": "4854980604708430", + "cvv": "123", + "expiry_month": "12", + "expiry_year": "21", + "name": "Gaurav Kumar" + }, + "_": { + "library": "s2s" + }, + "upi": { + "flow": "collect", + "type": "default" + } + } + }, + "image": null, + "theme": "#3594E2", + "method": "upi", + "version": "1", + "missing": [ + "vpa" + ], + "base": "api.razorpay.com", + "org_logo": "", + "org_name": "Razorpay Software Private Ltd", + "checkout_logo": "https://cdn.razorpay.com/logo.png", + "custom_branding": false +} \ No newline at end of file diff --git a/tests/test_client_payment.py b/tests/test_client_payment.py index 926d949d..73384df4 100644 --- a/tests/test_client_payment.py +++ b/tests/test_client_payment.py @@ -106,3 +106,66 @@ def test_upi_transfer_fetch(self): 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) + + @responses.activate + def test_payment_edit(self): + param = { + "notes": { + "key1": "value3", + "key2": "value2" + } + } + + result = mock_file('edit_payment') + url = '{}/{}'.format(self.base_url, 'dummy_id') + responses.add(responses.PATCH, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment.edit('dummy_id', param), result) + + + @responses.activate + def test_fetch_card_detail(self): + result = mock_file('fake_card_detail_payment') + url = '{}/{}/card'.format(self.base_url, 'dummy_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment.fetchCardDetails('dummy_id'), result) + + @responses.activate + def test_fetch_downtimes(self): + result = mock_file('fake_card_detail_payment') + url = '{}/{}'.format(self.base_url, 'downtimes') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment.fetchDownTime(), result) + + @responses.activate + def test_fetch_downtime_by_id(self): + result = mock_file('fake_card_detail_payment') + url = '{}/downtimes/{}'.format(self.base_url, 'dummy_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment.fetchDownTimeById('dummy_id'), result) + + @responses.activate + def test_payment_json(self): + param = { + "amount": "500", + "currency": "INR", + "email": "gaurav.kumar@example.com", + "contact": "9123456789", + "order_id": "order_IfCjbAb066hM9i", + "method": "upi", + "card": { + "number": "4854980604708430", + "cvv": "123", + "expiry_month": "12", + "expiry_year": "21", + "name": "Gaurav Kumar" + } + } + result = mock_file('fake_payment_json') + url = "{}/create/{}".format(self.base_url, 'json') + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment.createPaymentJson(param), result) \ No newline at end of file From d00de877c959655ff65868d9b2ce6fab267a209d Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Tue, 4 Jan 2022 11:31:33 +0530 Subject: [PATCH 06/25] remove print from addon --- razorpay/resources/addon.py | 1 - 1 file changed, 1 deletion(-) diff --git a/razorpay/resources/addon.py b/razorpay/resources/addon.py index 5e8a867c..85a995e1 100644 --- a/razorpay/resources/addon.py +++ b/razorpay/resources/addon.py @@ -34,5 +34,4 @@ def all(self, data={}, **kwargs): Returns: Dictionary of Add-ons """ - print(data) return super(Addon, self).all(data, **kwargs) From 29e69eff0d7599b44052e2fc4e0a273fa7ee7818 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Wed, 5 Jan 2022 12:38:56 +0530 Subject: [PATCH 07/25] updated paymentlink & verfication --- razorpay/resources/payment_link.py | 28 +++++++++ razorpay/utility/utility.py | 26 +++++++- tests/mocks/cancel_payment_link.json | 32 ++++++++++ tests/mocks/edit_payment_link.json | 42 +++++++++++++ tests/mocks/fake_payment_link.json | 43 ++++++++++++++ tests/mocks/init_payment_link.json | 24 ++++++++ tests/mocks/payment_link_collection.json | 72 +++++++++++++++++++++++ tests/test_client_payment_link.py | 75 ++++++++++++++++++++++++ tests/test_client_utility.py | 29 +++++++++ 9 files changed, 368 insertions(+), 3 deletions(-) create mode 100644 tests/mocks/cancel_payment_link.json create mode 100644 tests/mocks/edit_payment_link.json create mode 100644 tests/mocks/fake_payment_link.json create mode 100644 tests/mocks/init_payment_link.json create mode 100644 tests/mocks/payment_link_collection.json create mode 100644 tests/test_client_payment_link.py diff --git a/razorpay/resources/payment_link.py b/razorpay/resources/payment_link.py index b313e072..98d687fe 100644 --- a/razorpay/resources/payment_link.py +++ b/razorpay/resources/payment_link.py @@ -58,4 +58,32 @@ def cancel(self, payment_link_id, **kwargs): """ url = "{}/{}/cancel".format(self.base_url, payment_link_id) return self.post_url(url, {}, **kwargs) + + def edit(self, payment_link_id, data={}, **kwargs): + """" + Edit the Payment link + Args: + data : Dictionary having keys using which order have to be edited + reference_id : Adds a unique reference number to an existing link. + + expire_by : Timestamp, in Unix format, when the payment links should expire. + + notes : key value pair as notes + + Returns: + Payment Link Dict which was edited + """ + url = '{}/{}'.format(self.base_url, payment_link_id) + return self.patch_url(url, data, **kwargs) + def notifyBy(self, payment_link_id, medium, **kwargs): + """" + Send notification + + Args: + payment_link_id : Unique identifier of the Payment Link that should be resent. + + medium : sms/email + """ + url = "{}/{}/notify_by/{}".format(self.base_url, payment_link_id, medium) + return self.post_url(url, {}, **kwargs) diff --git a/razorpay/utility/utility.py b/razorpay/utility/utility.py index a7c05a2b..0bcddd5e 100644 --- a/razorpay/utility/utility.py +++ b/razorpay/utility/utility.py @@ -14,12 +14,28 @@ def verify_payment_signature(self, parameters): order_id = str(parameters['razorpay_order_id']) payment_id = str(parameters['razorpay_payment_id']) razorpay_signature = str(parameters['razorpay_signature']) - + msg = "{}|{}".format(order_id, payment_id) - + secret = str(self.client.auth[1]) return self.verify_signature(msg, razorpay_signature, secret) + + def verify_payment_link_signature(self, parameters): + payment_id = str(parameters['razorpay_payment_id']) + payment_link_id = str(parameters['payment_link_id']) + payment_link_reference_id = str(parameters['payment_link_reference_id']) + payment_link_status = str(parameters['payment_link_status']) + razorpay_signature = str(parameters['razorpay_signature']) + + msg = "{}|{}|{}|{}".format(payment_link_id, payment_link_reference_id, payment_link_status, payment_id) + + if 'secret' in parameters.keys() : + secret = str(parameters['secret']) + else: + secret = str(self.client.auth[1]) + + return self.verify_signature(msg, razorpay_signature, secret) def verify_subscription_payment_signature(self, parameters): """ @@ -31,7 +47,11 @@ def verify_subscription_payment_signature(self, parameters): razorpay_signature = str(parameters['razorpay_signature']) msg = "{}|{}".format(payment_id, subscription_id) - secret = str(self.client.auth[1]) + + if 'secret' in parameters.keys() : + secret = str(parameters['secret']) + else: + secret = str(self.client.auth[1]) return self.verify_signature(msg, razorpay_signature, secret) diff --git a/tests/mocks/cancel_payment_link.json b/tests/mocks/cancel_payment_link.json new file mode 100644 index 00000000..66db39d6 --- /dev/null +++ b/tests/mocks/cancel_payment_link.json @@ -0,0 +1,32 @@ +{ + "accept_partial": false, + "amount": 100, + "amount_paid": 0, + "cancelled_at": 1602524667, + "created_at": 1602524646, + "currency": "INR", + "customer": { + "contact": "9999999999", + "email": "gaurav.kumar@razorpay.com" + }, + "description": "Payment for Acme Inc", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 0, + "id": "plink_Fo4oI0cXjpQIz3", + "notes": null, + "notify": { + "email": true, + "sms": true + }, + "order_id": "order_Fo4oOGcvR4srav", + "payments": [], + "reference_id": "", + "reminder_enable": false, + "reminders": [], + "short_url": "https://rzp.io/i/foDnrXbBD", + "status": "cancelled", + "updated_at": 1602524667, + "upi_link": true, + "user_id": "FmjfFPCOUOAcSH" + } \ No newline at end of file diff --git a/tests/mocks/edit_payment_link.json b/tests/mocks/edit_payment_link.json new file mode 100644 index 00000000..b4073ed9 --- /dev/null +++ b/tests/mocks/edit_payment_link.json @@ -0,0 +1,42 @@ +{ + "accept_partial": false, + "amount": 100, + "amount_paid": 100, + "cancelled_at": 0, + "created_at": 1602522293, + "currency": "INR", + "customer": { + "contact": "9999999999", + "email": "gaurav.kumar@razorpay.com" + }, + "description": "Payment for Acme Inc", + "expire_by": 1653347540, + "expired_at": 0, + "first_min_partial_amount": 0, + "id": "plink_Fo48rl281ENAg9", + "notes": { + "policy_name": "Jeevan Saral" + }, + "notify": { + "email": true, + "sms": true + }, + "order_id": "order_Fo491cL6NGAjkI", + "payments": [ + { + "amount": 100, + "created_at": 1602522351, + "method": "upi", + "payment_id": "pay_Fo49sHbQ78PCMI", + "status": "captured" + } + ], + "reference_id": "TS35", + "reminder_enable": false, + "reminders": [], + "short_url": "https://rzp.io/i/XQiMe4w", + "status": "paid", + "updated_at": 1602523645, + "upi_link": true, + "user_id": "FmjfFPCOUOAcSH" + } \ No newline at end of file diff --git a/tests/mocks/fake_payment_link.json b/tests/mocks/fake_payment_link.json new file mode 100644 index 00000000..ea06d5c2 --- /dev/null +++ b/tests/mocks/fake_payment_link.json @@ -0,0 +1,43 @@ +{ + "accept_partial": false, + "amount": 100, + "amount_paid": 100, + "cancelled_at": 0, + "created_at": 1602522293, + "currency": "INR", + "customer": { + "contact": "9999999999", + "email": "gaurav.kumar@razorpay.com" + }, + "description": "Payment for Acme Inc", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 0, + "id": "plink_Fo48rl281ENAg9", + "notes": { + "policy_name": "Jivan Asha" + }, + "notify": { + "email": true, + "sms": true + }, + "order_id": "order_Fo491cL6NGAjkI", + "payments": [ + { + "amount": 100, + "created_at": 1602522351, + "method": "upi", + "payment_id": "pay_Fo49sHbQ78PCMI", + "status": "captured" + } + ], + "reference_id": "", + "reminder_enable": false, + "reminders": [], + "short_url": "https://rzp.io/i/XQiMe4w", + "status": "paid", + "updated_at": 1602522351, + "upi_link": true, + "user_id": "FmjfFPCOUOAcSH" + } + \ No newline at end of file diff --git a/tests/mocks/init_payment_link.json b/tests/mocks/init_payment_link.json new file mode 100644 index 00000000..e06bdeb2 --- /dev/null +++ b/tests/mocks/init_payment_link.json @@ -0,0 +1,24 @@ +{ + "amount": 1000, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "expire_by": 1691097057, + "reference_id": "TS1989", + "description": "Payment for policy no #23456", + "customer": { + "name": "Gaurav Kumar", + "contact": "+919999999999", + "email": "gaurav.kumar@example.com" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "notes": { + "policy_name": "Jeevan Bima" + }, + "callback_url": "https://example-callback-url.com/", + "callback_method": "get" + } \ No newline at end of file diff --git a/tests/mocks/payment_link_collection.json b/tests/mocks/payment_link_collection.json new file mode 100644 index 00000000..d9b23776 --- /dev/null +++ b/tests/mocks/payment_link_collection.json @@ -0,0 +1,72 @@ +{ + "payment_links": [ + { + "accept_partial": false, + "amount": 100, + "amount_paid": 0, + "cancelled_at": 0, + "created_at": 1602523443, + "currency": "INR", + "customer": { + "contact": "9999999999", + "email": "gaurav.kumar@razorpay.com", + "name": "Gaurav Kumar" + }, + "description": "Payment for policy no #23456", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 0, + "id": "plink_Fo4T7Ht271epg3", + "notes": { + "policy_name": "Jeevan Bima" + }, + "notify": { + "email": false, + "sms": true + }, + "payments": [], + "reference_id": "#41956", + "reminder_enable": true, + "reminders": { + "status": "in_progress" + }, + "short_url": "https://rzp.io/i/LXnmFr3a", + "status": "created", + "updated_at": 1602523443, + "upi_link": true, + "user_id": "" + }, + { + "accept_partial": false, + "amount": 100, + "amount_paid": 0, + "cancelled_at": 1602522621, + "created_at": 1602522615, + "currency": "INR", + "customer": { + "contact": "9999999999", + "email": "gaurav.kumar@razorpay.com" + }, + "description": "Payment for Acme Inc", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 0, + "id": "plink_Fo4EWsg3KmfWGW", + "notes": [], + "notify": { + "email": true, + "sms": true + }, + "order_id": "order_Fo4EayQh1zSGxn", + "payments": [], + "reference_id": "", + "reminder_enable": false, + "reminders": [], + "short_url": "https://rzp.io/i/2agF8tv", + "status": "cancelled", + "updated_at": 1602522621, + "upi_link": true, + "user_id": "FmjfFPCOUOAcSH" + } + ] + } \ No newline at end of file diff --git a/tests/test_client_payment_link.py b/tests/test_client_payment_link.py new file mode 100644 index 00000000..891e8b49 --- /dev/null +++ b/tests/test_client_payment_link.py @@ -0,0 +1,75 @@ +import responses +import json + +from .helpers import mock_file, ClientTestCase + + +class TestClientPaymentLink(ClientTestCase): + + def setUp(self): + super(TestClientPaymentLink, self).setUp() + self.base_url = '{}/payment_links'.format(self.base_url) + + @responses.activate + def test_payment_link_create(self): + init = mock_file('init_payment_link') + + result = mock_file('fake_payment_link') + url = '{}/{}'.format(self.base_url, 'fake_payment_link_id') + responses.add(responses.PATCH, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment_link.edit('fake_payment_link_id', init), result) + + + @responses.activate + def test_payment_link_edit(self): + init = { + "reference_id": "TS35", + "expire_by": 1653347540, + "reminder_enable":0, + "notes":{ + "policy_name": "Jeevan Saral" + } + } + + result = mock_file('edit_payment_link') + url = '{}/{}'.format(self.base_url, 'fake_payment_link_id') + responses.add(responses.PATCH, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment_link.edit('fake_payment_link_id', init), result) + + @responses.activate + def test_payment_link_notifyBy(self): + result = {"success": 1} + + url = "{}/{}/notify_by/{}".format(self.base_url, 'fake_payment_link_id', 'email') + + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment_link.notifyBy('fake_payment_link_id',medium='email'), result) + + @responses.activate + def test_payment_link_all(self): + result = mock_file('payment_link_collection') + url = self.base_url + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment_link.all(), result) + + @responses.activate + def test_payment_all_fetch(self): + result = mock_file('fake_payment_link') + url = '{}/{}'.format(self.base_url, 'fake_payment_link_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment_link.fetch('fake_payment_link_id'),result) + + @responses.activate + def test_payment_link_cancel(self): + result = mock_file('cancel_payment_link') + + url = "{}/{}/cancel".format(self.base_url, 'fake_payment_link_id') + + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment_link.cancel('fake_payment_link_id'), result) diff --git a/tests/test_client_utility.py b/tests/test_client_utility.py index 62b5ede1..2d424658 100644 --- a/tests/test_client_utility.py +++ b/tests/test_client_utility.py @@ -21,6 +21,35 @@ def test_verify_payment_signature(self): self.client.utility.verify_payment_signature(parameters), True) + @responses.activate + def test_subscription_payment_signature(self): + sig = '601f383334975c714c91a7d97dd723eb56520318355863dcf3821c0d07a17693' + parameters = {} + parameters['razorpay_subscription_id'] = 'sub_ID6MOhgkcoHj9I' + parameters['razorpay_payment_id'] = 'pay_IDZNwZZFtnjyym' + parameters['razorpay_signature'] = sig + parameters['secret'] = 'EnLs21M47BllR3X8PSFtjtbd' + + self.assertEqual( + self.client.utility.verify_subscription_payment_signature(parameters), + True) + + @responses.activate + def test_verify_payment_link_signature(self): + sig = '07ae18789e35093e51d0a491eb9922646f3f82773547e5b0f67ee3f2d3bf7d5b' + parameters = {} + parameters['razorpay_payment_id'] = 'pay_IH3d0ara9bSsjQ' + parameters['payment_link_id'] = 'plink_IH3cNucfVEgV68' + parameters['payment_link_reference_id'] = 'TSsd1989' + parameters['payment_link_status'] = 'paid' + parameters['razorpay_signature'] = sig + parameters['secret'] = 'EnLs21M47BllR3X8PSFtjtbd' + # x = self.client.utility.verify_payment_link_signature(parameters) + + self.assertEqual( + self.client.utility.verify_payment_link_signature(parameters), + True) + @responses.activate def test_verify_payment_signature_with_exception(self): parameters = {} From 457765e723e83fe91f851cf0b497bdf5416548c1 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Thu, 6 Jan 2022 13:08:28 +0530 Subject: [PATCH 08/25] implement qrcode --- razorpay/__init__.py | 2 + razorpay/constants/url.py | 1 + razorpay/resources/__init__.py | 2 + razorpay/resources/qrcode.py | 60 +++++++++++++++++ tests/mocks/fake_qrcode.json | 22 ++++++ tests/mocks/qrcode_collection.json | 50 ++++++++++++++ tests/mocks/qrcode_payments_collection.json | 74 +++++++++++++++++++++ tests/test_client_qrcode.py | 65 ++++++++++++++++++ 8 files changed, 276 insertions(+) create mode 100644 razorpay/resources/qrcode.py create mode 100644 tests/mocks/fake_qrcode.json create mode 100644 tests/mocks/qrcode_collection.json create mode 100644 tests/mocks/qrcode_payments_collection.json create mode 100644 tests/test_client_qrcode.py diff --git a/razorpay/__init__.py b/razorpay/__init__.py index ab11dc3f..b773670a 100644 --- a/razorpay/__init__.py +++ b/razorpay/__init__.py @@ -13,6 +13,7 @@ from .resources import Subscription from .resources import Plan from .resources import Settlement +from .resources import Qrcode from .utility import Utility from .constants import ERROR_CODE from .constants import HTTP_STATUS_CODE @@ -34,6 +35,7 @@ 'Subscription', 'Plan', 'Settlement', + 'Qrcode', 'HTTP_STATUS_CODE', 'ERROR_CODE', ] diff --git a/razorpay/constants/url.py b/razorpay/constants/url.py index 3d2cb40d..99091c63 100644 --- a/razorpay/constants/url.py +++ b/razorpay/constants/url.py @@ -13,3 +13,4 @@ class URL(object): ADDON_URL = "/addons" PLAN_URL = "/plans" SETTLEMENT_URL = "/settlements" + QRCODE_URL = "/payments/qr_codes" diff --git a/razorpay/resources/__init__.py b/razorpay/resources/__init__.py index f8af63d4..1b7d6e3a 100644 --- a/razorpay/resources/__init__.py +++ b/razorpay/resources/__init__.py @@ -11,6 +11,7 @@ from .addon import Addon from .plan import Plan from .subscription import Subscription +from .qrcode import Qrcode from .settlement import Settlement __all__ = [ @@ -28,4 +29,5 @@ 'Plan', 'Subscription', 'Settlement', + 'QrCode' ] diff --git a/razorpay/resources/qrcode.py b/razorpay/resources/qrcode.py new file mode 100644 index 00000000..a9353869 --- /dev/null +++ b/razorpay/resources/qrcode.py @@ -0,0 +1,60 @@ +from .base import Resource +from ..constants.url import URL + + +class Qrcode(Resource): + def __init__(self, client=None): + super(Qrcode, self).__init__(client) + self.base_url = URL.QRCODE_URL + + def fetch(self, qrcode_id, data={}, **kwargs): + """" + Fetch a Qr code + + Args: + customer_id : Id for which customer object has to be retrieved + + Returns: + Qrcode dict for given qrcode id + """ + return super(Qrcode, self).fetch(qrcode_id, data, **kwargs) + + def create(self, data={}, **kwargs): + """" + Create a QR Code + + Returns: + QrCode Dict which was created + """ + url = self.base_url + return self.post_url(url, data, **kwargs) + + def all(self, data={}, **kwargs): + """" + Fetch All Refund + + Returns: + Qrcode dict + """ + return super(Qrcode, self).all(data, **kwargs) + + def fetch_all_payments(self, qrcode_id, data={}, **kwargs): + """" + Fetch Payments for a QR Code + + Returns: + Qrcode payment dict + """ + url = "{}/{}/payments".format(self.base_url, qrcode_id) + return self.get_url(url, data, **kwargs) + + def close(self, qrcode_id, **kwargs): + """" + Close a QR Code + + Returns: + Qrcode Dict which was closed + """ + url = '{}/{}/close'.format(self.base_url, qrcode_id) + + return self.post_url(url, {}, **kwargs) diff --git a/tests/mocks/fake_qrcode.json b/tests/mocks/fake_qrcode.json new file mode 100644 index 00000000..58cffbb3 --- /dev/null +++ b/tests/mocks/fake_qrcode.json @@ -0,0 +1,22 @@ +{ + "id": "qr_HO2r1MDprYtWRT", + "entity": "qr_code", + "created_at": 1623915088, + "name": "Store_1", + "usage": "single_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/oCswTOcCo", + "payment_amount": 300, + "status": "active", + "description": "For Store 1", + "fixed_amount": true, + "payments_amount_received": 0, + "payments_count_received": 0, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "closed_at": null, + "close_reason": null + } \ No newline at end of file diff --git a/tests/mocks/qrcode_collection.json b/tests/mocks/qrcode_collection.json new file mode 100644 index 00000000..f5c3a632 --- /dev/null +++ b/tests/mocks/qrcode_collection.json @@ -0,0 +1,50 @@ +{ + "entity": "collection", + "count": 2, + "items": [ + { + "id": "qr_HO2jGkWReVBMNu", + "entity": "qr_code", + "created_at": 1623914648, + "name": "Store_1", + "usage": "single_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/w2CEwYmkAu", + "payment_amount": 300, + "status": "active", + "description": "For Store 1", + "fixed_amount": true, + "payments_amount_received": 0, + "payments_count_received": 0, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "closed_at": null, + "close_reason": null + }, + { + "id": "qr_HO2e0813YlchUn", + "entity": "qr_code", + "created_at": 1623914349, + "name": "Acme Groceries", + "usage": "multiple_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/X6QM7LL", + "payment_amount": null, + "status": "closed", + "description": "Buy fresh groceries", + "fixed_amount": false, + "payments_amount_received": 200, + "payments_count_received": 1, + "notes": { + "Branch": "Bangalore - Rajaji Nagar" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1625077799, + "closed_at": 1623914515, + "close_reason": "on_demand" + } + ] + } \ No newline at end of file diff --git a/tests/mocks/qrcode_payments_collection.json b/tests/mocks/qrcode_payments_collection.json new file mode 100644 index 00000000..c9dcdf49 --- /dev/null +++ b/tests/mocks/qrcode_payments_collection.json @@ -0,0 +1,74 @@ +{ + "entity": "collection", + "count": 2, + "items": [ + { + "id": "pay_HMtDKn3TnF4D8x", + "entity": "payment", + "amount": 500, + "currency": "INR", + "status": "captured", + "order_id": null, + "invoice_id": null, + "international": false, + "method": "upi", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "QRv2 Payment", + "card_id": null, + "bank": null, + "wallet": null, + "vpa": "gauri.kumari@okhdfcbank", + "email": "gauri.kumari@example.com", + "contact": "+919999999999", + "customer_id": "cust_HKsR5se84c5LTO", + "notes": [], + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "rrn": "116514257019" + }, + "created_at": 1623662800 + }, + { + "id": "pay_HMsr242ZnaLumA", + "entity": "payment", + "amount": 1000, + "currency": "INR", + "status": "refunded", + "order_id": null, + "invoice_id": null, + "international": false, + "method": "upi", + "amount_refunded": 1000, + "refund_status": "full", + "captured": true, + "description": "QRv2 Payment", + "card_id": null, + "bank": null, + "wallet": null, + "vpa": "gauri.kumari@okhdfcbank", + "email": "gauri.kumari@example.com", + "contact": "+919999999999", + "customer_id": "cust_HKsR5se84c5LTO", + "notes": [], + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "rrn": "116514090501" + }, + "created_at": 1623661533 + } + ] + } \ No newline at end of file diff --git a/tests/test_client_qrcode.py b/tests/test_client_qrcode.py new file mode 100644 index 00000000..b0c62475 --- /dev/null +++ b/tests/test_client_qrcode.py @@ -0,0 +1,65 @@ +import responses +import json + +from .helpers import mock_file, ClientTestCase + + +class TestClientQrcode(ClientTestCase): + + def setUp(self): + super(TestClientQrcode, self).setUp() + self.base_url = '{}/payments/qr_codes'.format(self.base_url) + self.plan_id = 'qr_IAgePI1GuSMTFN' + + @responses.activate + def test_qrcode_all(self): + result = mock_file('qrcode_collection') + url = self.base_url + responses.add(responses.GET, url, status=200, + body=json.dumps(result), match_querystring=True) + self.assertEqual(self.client.qrcode.all(), result) + + @responses.activate + def test_qrcode_fetch(self): + result = mock_file('fake_qrcode') + url = '{}/{}'.format(self.base_url, 'fake_qrcode_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.qrcode.fetch('fake_qrcode_id'), result) + + @responses.activate + def test_qrcode_create(self): + init = { + "type": "upi_qr", + "name": "Store_1", + "usage": "single_use", + "fixed_amount": 1, + "payment_amount": 300, + "description": "For Store 1", + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "notes": { + "purpose": "Test UPI QR code notes" + } + } + result = mock_file('fake_qrcode') + url = self.base_url + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.qrcode.create(init), result) + + @responses.activate + def test_qrcode_fetch_all_payment(self): + result = mock_file('qrcode_payments_collection') + url = '{}/{}/payments'.format(self.base_url, 'fake_qrcode_id') + responses.add(responses.GET, url, status=200, + body=json.dumps(result), match_querystring=True) + self.assertEqual(self.client.qrcode.fetch_all_payments('fake_qrcode_id'), result) + + @responses.activate + def test_qrcode_close(self): + result = mock_file('fake_qrcode') + url = '{}/{}/close'.format(self.base_url, 'fake_qrcode_id') + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.qrcode.close('fake_qrcode_id'), result) \ No newline at end of file From 97f44f7af0cf0c121d722e98b2307ee778a731d8 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Fri, 7 Jan 2022 13:30:18 +0530 Subject: [PATCH 09/25] updated refund api --- razorpay/resources/payment.py | 31 +++++++++++++++++++++++++++++++ razorpay/resources/refund.py | 10 ++++++++++ tests/mocks/fake_refund.json | 21 ++++++++++++++++----- tests/test_client_payment.py | 27 +++++++++++++++++++++++++++ tests/test_client_refund.py | 14 ++++++++++++++ 5 files changed, 98 insertions(+), 5 deletions(-) diff --git a/razorpay/resources/payment.py b/razorpay/resources/payment.py index fc9d6b6e..46135eb6 100644 --- a/razorpay/resources/payment.py +++ b/razorpay/resources/payment.py @@ -116,3 +116,34 @@ def upi_transfer(self, payment_id, data={}, **kwargs): """ url = "{}/{}/upi_transfer".format(self.base_url, payment_id) return self.get_url(url, data, **kwargs) + + def refund(self, payment_id, data={}, **kwargs): + """" + Create a normal refund + + Returns: + Payment dict after getting refund + """ + url = "{}/{}/refund".format(self.base_url, payment_id) + return self.post_url(url, data, **kwargs) + + def fetch_multiple_refund(self, payment_id, data={}, **kwargs): + """" + Fetch multiple refunds for a payment + + Returns: + refunds dict + """ + url = "{}/{}/refunds".format(self.base_url, payment_id) + return self.get_url(url, data, **kwargs) + + def fetch_refund_id(self, payment_id, refund_id, **kwargs): + """" + Fetch multiple refunds for a payment + + Returns: + Refund dict + """ + url = "{}/{}/refunds/{}".format(self.base_url, payment_id, refund_id) + return self.get_url(url, {}, **kwargs) + \ No newline at end of file diff --git a/razorpay/resources/refund.py b/razorpay/resources/refund.py index 92504124..5b2ba1f1 100644 --- a/razorpay/resources/refund.py +++ b/razorpay/resources/refund.py @@ -40,3 +40,13 @@ def fetch(self, refund_id, data={}, **kwargs): Refund dict for given refund Id """ return super(Refund, self).fetch(refund_id, data, **kwargs) + + def edit(self, refund_id, data={}, **kwargs): + """" + Update Refund + + Returns: + Refund Dict which was edited + """ + url = "{}/{}".format(self.base_url, refund_id) + return self.patch_url(url, data, **kwargs) diff --git a/tests/mocks/fake_refund.json b/tests/mocks/fake_refund.json index 36a7983f..47760266 100644 --- a/tests/mocks/fake_refund.json +++ b/tests/mocks/fake_refund.json @@ -1,8 +1,19 @@ { - "id": "fake_refund_id", + "id": "rfnd_FP8DDKxqJif6ca", "entity": "refund", - "amount": 2000, + "amount": 300100, "currency": "INR", - "payment_id": "fake_payment_id", - "created_at": 1500826750 -} + "payment_id": "pay_FIKOnlyii5QGNx", + "notes": { + "notes_key_1": "Beam me up Scotty.", + "notes_key_2": "Engage" + }, + "receipt": "#126", + "acquirer_data": { + "arn": "10000000000000" + }, + "created_at": 1597078124, + "status": "processed", + "speed_processed": "normal", + "speed_requested": "optimum" +} \ No newline at end of file diff --git a/tests/test_client_payment.py b/tests/test_client_payment.py index 926d949d..57d195d0 100644 --- a/tests/test_client_payment.py +++ b/tests/test_client_payment.py @@ -106,3 +106,30 @@ def test_upi_transfer_fetch(self): 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) + + @responses.activate + def test_payment_refund(self): + init = { + "amount": "100" + } + result = mock_file('fake_refund') + url = '{}/{}/refund'.format(self.base_url, 'fake_refund_id') + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment.refund('fake_refund_id',init), result) + + @responses.activate + def test_payment_fetch_multiple_refund(self): + result = mock_file('refund_collection') + url = "{}/{}/refunds".format(self.base_url, 'fake_payment_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment.fetch_multiple_refund(self.payment_id), result) + + @responses.activate + def test_payment_fetch_refund_id(self): + result = mock_file('refund_collection') + url = "{}/{}/refunds/{}".format(self.base_url, 'fake_payment_id', 'fake_refund_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.payment.fetch_refund_id('fake_payment_id', 'fake_refund_id'), result) \ No newline at end of file diff --git a/tests/test_client_refund.py b/tests/test_client_refund.py index f45fab6d..990f4ff1 100644 --- a/tests/test_client_refund.py +++ b/tests/test_client_refund.py @@ -34,3 +34,17 @@ def test_refund_create(self): responses.add(responses.POST, url, status=200, body=json.dumps(result), match_querystring=True) self.assertEqual(self.client.refund.create(init), result) + + @responses.activate + def test_refund_edit(self): + param = { + "notes": { + "notes_key_1":"Beam me up Scotty.", + "notes_key_2":"Engage" + } + } + result = mock_file('fake_refund') + url = "{}/{}".format(self.base_url,'rfnd_DfjjhJC6eDvUAi') + responses.add(responses.PATCH, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.refund.edit('rfnd_DfjjhJC6eDvUAi', param), result) From 66f412820e54516e729e265f943a587255179e9b Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Mon, 10 Jan 2022 12:05:45 +0530 Subject: [PATCH 10/25] updated settlement module --- razorpay/resources/settlement.py | 40 +++++++++++++++++++++++++++++++ tests/mocks/init_settlement.json | 39 ++++++++++++++++++++++++++++++ tests/test_client_settlement.py | 41 ++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 tests/mocks/init_settlement.json diff --git a/razorpay/resources/settlement.py b/razorpay/resources/settlement.py index 12124025..9b7f3ea1 100644 --- a/razorpay/resources/settlement.py +++ b/razorpay/resources/settlement.py @@ -27,3 +27,43 @@ def fetch(self, settlement_id, data={}, **kwargs): settlement dict for given settlement id """ return super(Settlement, self).fetch(settlement_id, data, **kwargs) + + def report(self, data={}, **kwargs): + """" + Settlement report for a month + + Returns: + settlement dict + """ + url = "{}/recon/{}".format(self.base_url, 'combined') + return self.get_url(url, data, **kwargs) + + def create_ondemand_settlement(self, data={}, **kwargs): + """ + create Ondemand Settlemententity + + Returns: + settlement dict which was created + """ + url = "{}/{}".format(self.base_url,"ondemand") + return self.post_url(url, data, **kwargs) + + def fetch_all_ondemand_settlement(self, data={}, **kwargs): + """ + create Ondemand Settlemententity + + Returns: + settlement dict which was created + """ + url = "{}/{}".format(self.base_url,"ondemand") + return self.get_url(url, data, **kwargs) + + def fetch_ondemand_settlement_id(self, settlement_id, data={}, **kwargs): + """ + fetch Ondemand Settlement by Id + + Returns: + settlement dict for given settlement id + """ + url = "{}/ondemand/{}".format(self.base_url, settlement_id) + return self.get_url(url, data, **kwargs) diff --git a/tests/mocks/init_settlement.json b/tests/mocks/init_settlement.json new file mode 100644 index 00000000..f3fe66c5 --- /dev/null +++ b/tests/mocks/init_settlement.json @@ -0,0 +1,39 @@ +{ + "id": "setlod_FNj7g2YS5J67Rz", + "entity": "settlement.ondemand", + "amount_requested": 200000, + "amount_settled": 0, + "amount_pending": 199410, + "amount_reversed": 0, + "fees": 590, + "tax": 90, + "currency": "INR", + "settle_full_balance": 0, + "status": "initiated", + "description": "Need this to make vendor payments.", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1596771429, + "ondemand_payouts": { + "entity": "collection", + "count": 1, + "items": [ + { + "id": "setlodp_FNj7g2cbvw8ueO", + "entity": "settlement.ondemand_payout", + "initiated_at": null, + "processed_at": null, + "reversed_at": null, + "amount": 200000, + "amount_settled": null, + "fees": 590, + "tax": 90, + "utr": null, + "status": "created", + "created_at": 1596771429 + } + ] + } +} \ No newline at end of file diff --git a/tests/test_client_settlement.py b/tests/test_client_settlement.py index d4bee1b8..590517de 100644 --- a/tests/test_client_settlement.py +++ b/tests/test_client_settlement.py @@ -34,3 +34,44 @@ def test_settlement_fetch(self): responses.add(responses.GET, url, status=200, body=json.dumps(result), match_querystring=True) self.assertEqual(self.client.settlement.fetch(self.settlement_id), result) + + @responses.activate + def test_settlement_report(self): + init = {"year":2020,"month":9} + result = mock_file('settlement_collection') + url = "{}/recon/{}".format(self.base_url, 'combined') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.settlement.report(self.settlement_id), result) + + @responses.activate + def test_settlement_create_ondemand_settlement(self): + init = { + "amount": 1221, + "description": "Need this to make vendor", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } + } + result = mock_file('init_settlement') + url = "{}/{}".format(self.base_url,"ondemand") + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.settlement.create_ondemand_settlement(init), result) + + @responses.activate + def test_settlement_fetch_all_ondemand_settlement(self): + result = mock_file('settlement_collection') + url = "{}/{}".format(self.base_url,"ondemand") + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.settlement.fetch_all_ondemand_settlement(), result) + + @responses.activate + def test_settlement_fetch_ondemand_settlement_id(self): + result = mock_file('init_settlement') + url = "{}/ondemand/{}".format(self.base_url, 'fake_settlement_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.settlement.fetch_ondemand_settlement_id('fake_settlement_id'), result) \ No newline at end of file From b8ce493733c052e33a12d23a218c23b79120a443 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Tue, 11 Jan 2022 12:42:46 +0530 Subject: [PATCH 11/25] updated subscription module --- razorpay/resources/subscription.py | 51 ++++++++++++++++++++++ tests/mocks/fake_subscription_paused.json | 31 +++++++++++++ tests/mocks/fake_subscription_resumed.json | 31 +++++++++++++ tests/test_client_subscription.py | 47 ++++++++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 tests/mocks/fake_subscription_paused.json create mode 100644 tests/mocks/fake_subscription_resumed.json diff --git a/razorpay/resources/subscription.py b/razorpay/resources/subscription.py index 88b6a10e..d35c2ff2 100644 --- a/razorpay/resources/subscription.py +++ b/razorpay/resources/subscription.py @@ -65,4 +65,55 @@ def createAddon(self, subscription_id, data={}, **kwargs): Subscription dict for given subscription id """ url = "{}/{}/addons".format(self.base_url, subscription_id) + return self.post_url(url, data, **kwargs) + + def edit(self, subscription_id, data={}, **kwargs): + """" + Update particular subscription + + Args: + subscription_id : Id for which subscription has to be edited + Returns: + Subscription dict for given subscription id + """ + url = '{}/{}'.format(self.base_url, subscription_id) + return self.patch_url(url, data, **kwargs) + + def pending_update(self, subscription_id, **kwargs): + """" + Fetch Subscription for given Id + + Args: + subscription_id : Id for which subscription object is retrieved + + Returns: + Subscription dict for given subscription Id + """ + url = '{}/{}/retrieve_scheduled_changes'.format(self.base_url, subscription_id) + return self.get_url(url, {}, **kwargs) + + def pause(self, subscription_id, data={}, **kwargs): + """ + Cancel subscription given by subscription_id + + Args: + subscription_id : Id for which subscription has to be paused + + Returns: + Subscription Dict for given subscription id + """ + url = "{}/{}/pause".format(self.base_url, subscription_id) return self.post_url(url, data, **kwargs) + + def resume(self, subscription_id, data={}, **kwargs): + """ + Cancel subscription given by subscription_id + + Args: + subscription_id : Id for which subscription has to be resume + + Returns: + Subscription Dict for given subscription id + """ + url = "{}/{}/resume".format(self.base_url, subscription_id) + return self.post_url(url, data, **kwargs) diff --git a/tests/mocks/fake_subscription_paused.json b/tests/mocks/fake_subscription_paused.json new file mode 100644 index 00000000..4d37d62c --- /dev/null +++ b/tests/mocks/fake_subscription_paused.json @@ -0,0 +1,31 @@ +{ + "id": "sub_8RlLljfA4AnDVx", + "entity": "subscription", + "plan_id": "plan_IdJJ47TH0TdW9R", + "customer_id": "cust_IOyIY3JvbVny9o", + "status": "paused", + "current_start": 1640854635, + "current_end": 1643481000, + "ended_at": null, + "quantity": 1, + "notes": { + "source": "magento-subscription", + "magento_quote_id": "25" + }, + "charge_at": null, + "start_at": 1640854635, + "end_at": 1653849000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 1, + "customer_notify": false, + "created_at": 1640854612, + "expire_by": null, + "short_url": "https://rzp.io/i/TfApecvk", + "has_scheduled_changes": true, + "change_scheduled_at": 1643481000, + "source": "magento-subscription", + "payment_method": "card", + "offer_id": null, + "remaining_count": 5 +} \ No newline at end of file diff --git a/tests/mocks/fake_subscription_resumed.json b/tests/mocks/fake_subscription_resumed.json new file mode 100644 index 00000000..47930c8f --- /dev/null +++ b/tests/mocks/fake_subscription_resumed.json @@ -0,0 +1,31 @@ +{ + "id": "sub_Idd0qIOzcw01qH", + "entity": "subscription", + "plan_id": "plan_IdJJ47TH0TdW9R", + "customer_id": "cust_IOyIY3JvbVny9o", + "status": "active", + "current_start": 1640854635, + "current_end": 1643481000, + "ended_at": null, + "quantity": 1, + "notes": { + "source": "magento-subscription", + "magento_quote_id": "25" + }, + "charge_at": 1643481000, + "start_at": 1640854635, + "end_at": 1653849000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 1, + "customer_notify": false, + "created_at": 1640854612, + "expire_by": null, + "short_url": "https://rzp.io/i/TfApecvk", + "has_scheduled_changes": true, + "change_scheduled_at": 1643481000, + "source": "magento-subscription", + "payment_method": "card", + "offer_id": null, + "remaining_count": 5 +} \ No newline at end of file diff --git a/tests/test_client_subscription.py b/tests/test_client_subscription.py index 58c13f1e..550f2e5b 100644 --- a/tests/test_client_subscription.py +++ b/tests/test_client_subscription.py @@ -68,3 +68,50 @@ def test_subscription_create_addon(self): self.assertEqual(response['entity'], 'addon') self.assertEqual(response['item']['name'], 'Extra Chair') self.assertEqual(response['item']['amount'], 30000) + + @responses.activate + def test_subscription_edit(self): + param = { + "quantity":2, + "schedule_change_at":"cycle_end", + } + + result = mock_file('fake_subscription') + url = '{}/{}'.format(self.base_url, 'subscription_id') + responses.add(responses.PATCH, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.subscription.edit('subscription_id', param), result) + + @responses.activate + def test_subscription_pending_update(self): + result = mock_file('fake_subscription') + url = '{}/{}/retrieve_scheduled_changes'.format(self.base_url, 'fake_subscription_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual( + self.client.subscription.pending_update('fake_subscription_id'), + result) + + @responses.activate + def test_subscription_pause(self): + result = mock_file('fake_subscription_paused') + url = '{}/{}/pause'.format(self.base_url, self.subscription_id) + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + response = json.loads( + self.client.subscription.cancel(self.subscription_id)) + self.assertEqual(response['id'], self.subscription_id) + self.assertEqual(response['entity'], 'subscription') + self.assertEqual(response['status'], 'paused') + + @responses.activate + def test_subscription_resume(self): + result = mock_file('fake_subscription_resumed') + url = '{}/{}/resume'.format(self.base_url, self.subscription_id) + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + response = json.loads( + self.client.subscription.cancel(self.subscription_id)) + self.assertEqual(response['id'], self.subscription_id) + self.assertEqual(response['entity'], 'subscription') + self.assertEqual(response['status'], 'resumed') \ No newline at end of file From f1fa8a6dc3ea664a610970f86c224ea45af01e16 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Wed, 12 Jan 2022 13:17:45 +0530 Subject: [PATCH 12/25] add case handle --- razorpay/utility/utility.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/razorpay/utility/utility.py b/razorpay/utility/utility.py index 0bcddd5e..2601d479 100644 --- a/razorpay/utility/utility.py +++ b/razorpay/utility/utility.py @@ -22,18 +22,19 @@ def verify_payment_signature(self, parameters): return self.verify_signature(msg, razorpay_signature, secret) def verify_payment_link_signature(self, parameters): - payment_id = str(parameters['razorpay_payment_id']) - payment_link_id = str(parameters['payment_link_id']) - payment_link_reference_id = str(parameters['payment_link_reference_id']) - payment_link_status = str(parameters['payment_link_status']) - razorpay_signature = str(parameters['razorpay_signature']) - - msg = "{}|{}|{}|{}".format(payment_link_id, payment_link_reference_id, payment_link_status, payment_id) - if 'secret' in parameters.keys() : - secret = str(parameters['secret']) + if 'razorpay_payment_id' in parameters.keys() and 'payment_link_reference_id' in parameters.keys() and 'payment_link_status' in parameters.keys(): + payment_id = str(parameters['razorpay_payment_id']) + payment_link_id = str(parameters['payment_link_id']) + payment_link_reference_id = str(parameters['payment_link_reference_id']) + payment_link_status = str(parameters['payment_link_status']) + razorpay_signature = str(parameters['razorpay_signature']) else: - secret = str(self.client.auth[1]) + return False + + msg = "{}|{}|{}|{}".format(payment_link_id, payment_link_reference_id, payment_link_status, payment_id) + + secret = str(parameters['secret']) if 'secret' in parameters.keys() else str(self.client.auth[1]) return self.verify_signature(msg, razorpay_signature, secret) @@ -48,10 +49,7 @@ def verify_subscription_payment_signature(self, parameters): msg = "{}|{}".format(payment_id, subscription_id) - if 'secret' in parameters.keys() : - secret = str(parameters['secret']) - else: - secret = str(self.client.auth[1]) + secret = str(parameters['secret']) if 'secret' in parameters.keys() else str(self.client.auth[1]) return self.verify_signature(msg, razorpay_signature, secret) From b6135a74b9eb5d856dd8b083aa678957fd675c86 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Thu, 13 Jan 2022 13:49:17 +0530 Subject: [PATCH 13/25] updated virtual account module --- razorpay/client.py | 3 +- razorpay/resources/virtual_account.py | 37 ++++++++++++ .../mocks/fake_virtual_accounts_receiver.json | 32 ++++++++++ tests/test_client_virtual_account.py | 60 ++++++++++++++++++- 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 tests/mocks/fake_virtual_accounts_receiver.json diff --git a/razorpay/client.py b/razorpay/client.py index 7c74eb87..e91d0cc1 100644 --- a/razorpay/client.py +++ b/razorpay/client.py @@ -6,6 +6,7 @@ from pkg_resources import DistributionNotFound from types import ModuleType + from .constants import HTTP_STATUS_CODE, ERROR_CODE, URL from . import resources, utility @@ -121,7 +122,7 @@ def request(self, method, path, **options): **options) if ((response.status_code >= HTTP_STATUS_CODE.OK) and (response.status_code < HTTP_STATUS_CODE.REDIRECT)): - return response.json() + return response.json() if(len(response.text) > 0) else response.status_code else: msg = "" code = "" diff --git a/razorpay/resources/virtual_account.py b/razorpay/resources/virtual_account.py index c7435fd6..4a4ad921 100644 --- a/razorpay/resources/virtual_account.py +++ b/razorpay/resources/virtual_account.py @@ -1,5 +1,6 @@ from .base import Resource from ..constants.url import URL +import json class VirtualAccount(Resource): @@ -69,3 +70,39 @@ def payments(self, virtual_account_id, data={}, **kwargs): """ url = "{}/{}/payments".format(self.base_url, virtual_account_id) return self.get_url(url, data, **kwargs) + + def add_receiver(self, virtual_account_id, data={}, **kwargs): + """" + Add receiver to an existing virtual account + + Args: + virtual_account_id : + Id for which Virtual Account objects has to be Closed + """ + url = "{}/{}/receivers".format(self.base_url, virtual_account_id) + return self.post_url(url, data, **kwargs) + + def add_allowed_player(self, virtual_account_id, data={}, **kwargs): + """" + Add an Allowed Payer Account + + Args: + virtual_account_id : + Id for which Virtual Account objects has to be Closed + """ + url = "{}/{}/allowed_payers".format(self.base_url, virtual_account_id) + return self.post_url(url, data, **kwargs) + + def delete_allowed_player(self, virtual_account_id, allowed_player_id, data={}, **kwargs): + """" + Delete an Allowed Payer Account + + Args: + virtual_account_id : + Id for which Virtual Account objects has to be Closed + Returns: + 204 + """ + url = "{}/{}/allowed_payers/{}".format(self.base_url, virtual_account_id, allowed_player_id) + self.delete_url(url, data, **kwargs) + return json.dumps({ "success" : True }) diff --git a/tests/mocks/fake_virtual_accounts_receiver.json b/tests/mocks/fake_virtual_accounts_receiver.json new file mode 100644 index 00000000..99362515 --- /dev/null +++ b/tests/mocks/fake_virtual_accounts_receiver.json @@ -0,0 +1,32 @@ +{ + "id": "va_4xbQrmEoA5WJ0G", + "name": "Acme Corp", + "entity": "virtual_account", + "status": "active", + "description": "", + "amount_expected": null, + "notes": [], + "amount_paid": 0, + "customer_id": "cust_DzbSeP2RJD1ZHg", + "receivers": [ + { + "id": "ba_DzcFjVqAMSCEIW", + "entity": "bank_account", + "ifsc":"RATN0VAAPIS", + "bank_name": "RBL Bank", + "name": "Acme Corp", + "notes": [], + "account_number": "2223333232194699" + }, + { + "id": "vpa_DzcZR5ofjCUKAx", + "entity": "vpa", + "username": "rpy.payto00000gaurikumar", + "handle": "icici", + "address": "rpy.payto00000gaurikumar@icici" + } + ], + "close_by": null, + "closed_at": null, + "created_at": 1577969986 + } \ No newline at end of file diff --git a/tests/test_client_virtual_account.py b/tests/test_client_virtual_account.py index 35a63d73..49f82086 100644 --- a/tests/test_client_virtual_account.py +++ b/tests/test_client_virtual_account.py @@ -1,5 +1,5 @@ import responses - +import json from .helpers import mock_file, ClientTestCase @@ -104,3 +104,61 @@ def test_virtual_accounts_payments(self): self.assertEqual(response['count'], 2) self.assertEqual(len(response['items']), 2) self.assertEqual(response['items'][0]['entity'], 'payment') + + @responses.activate + def test_virtual_add_receiver(self): + init = { + "types": ["vpa"], + "vpa": { + "descriptor": "gaurikumar" + } + } + result = mock_file('fake_virtual_accounts_closed') + url = "{}/{}/receivers".format(self.base_url, self.fake_virtual_account_id) + responses.add(responses.POST, + url, + status=200, + body=result, + match_querystring=True) + + response = self.client.virtual_account.add_receiver( + self.fake_virtual_account_id, init) + self.assertEqual(response['id'], self.fake_virtual_account_id) + self.assertEqual(response['entity'], 'virtual_account') + + @responses.activate + def test_virtual_add_allowed_player(self): + init = { + "type": "bank_account", + "bank_account": { + "ifsc": "UTIB0000013", + "account_number": "914010012345679" + } + } + result = mock_file('fake_virtual_accounts_closed') + url = "{}/{}/allowed_payers".format(self.base_url, self.fake_virtual_account_id) + responses.add(responses.POST, + url, + status=200, + body=result, + match_querystring=True) + + response = self.client.virtual_account.add_allowed_player( + self.fake_virtual_account_id, init) + self.assertEqual(response['id'], self.fake_virtual_account_id) + self.assertEqual(response['entity'], 'virtual_account') + + + @responses.activate + def test_virtual_delete_allowed_player(self): + result = json.dumps({ "success" : True }) + url = "{}/{}/allowed_payers/{}".format(self.base_url, self.fake_virtual_account_id, 'fake_allowed_player_id') + responses.add(responses.DELETE, + url, + status=200, + body=result, + match_querystring=True) + self.assertEqual(self.client.virtual_account.delete_allowed_player( + self.fake_virtual_account_id, 'fake_allowed_player_id'), result) + + \ No newline at end of file From 165451949261c008eaf28a55dd6ee52b0e612e93 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Thu, 13 Jan 2022 14:21:16 +0530 Subject: [PATCH 14/25] fixed issues --- razorpay/resources/subscription.py | 16 ++++++++++- test.py | 31 ++++++++++++++++++++++ tests/mocks/fake_subscription_resumed.json | 2 +- tests/test_client_subscription.py | 17 +++++++++--- 4 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 test.py diff --git a/razorpay/resources/subscription.py b/razorpay/resources/subscription.py index d35c2ff2..2310456c 100644 --- a/razorpay/resources/subscription.py +++ b/razorpay/resources/subscription.py @@ -116,4 +116,18 @@ def resume(self, subscription_id, data={}, **kwargs): Subscription Dict for given subscription id """ url = "{}/{}/resume".format(self.base_url, subscription_id) - return self.post_url(url, data, **kwargs) + return self.post_url(url, data, **kwargs) + + def delete_offer(self, subscription_id, offer_id, data={}, **kwargs): + """ + Delete offer linked to a subscription + + Args: + subscription_id : The id of the subscription to offer need to be deleted + offer_id : The id of the offer linked to subscription + + Returns: + Subscription Dict for given subscription id + """ + url = "{}/{}/{}".format(self.base_url, subscription_id, offer_id) + return self.delete_url(url, data, **kwargs) diff --git a/test.py b/test.py new file mode 100644 index 00000000..44fc3081 --- /dev/null +++ b/test.py @@ -0,0 +1,31 @@ +import razorpay +import requests +from pprint import pprint +import json + +client = razorpay.Client(auth=("rzp_test_k6uL897VPBz20q", "EnLs21M47BllR3X8PSFtjtbd")) + + +DATA = { + "type": "bank_account", + "bank_account": { + "ifsc": "UTIB0000013", + "account_number": "914010012345679" + } +} + +# sig = '07ae18789e35093e51d0a491eb9922646f3f82773547e5b0f67ee3f2d3bf7d5b' +# parameters = {} +# parameters['razorpay_payment_id'] = 'pay_IH3d0ara9bSsjQ' +# parameters['payment_link_id'] = 'plink_IH3cNucfVEgV68' +# parameters['payment_link_reference_id'] = 'TSsd1989' +# parameters['payment_link_status'] = 'paid' +# parameters['razorpay_signature'] = sig + +#x = client.subscription.delete_offer('sub_IjA0wMVJdFnyzx','offer_IjA06IHSz33cw2') +#response = json.load(x) +#print(x) +# if(x==''): +# return True +# else: +# return False diff --git a/tests/mocks/fake_subscription_resumed.json b/tests/mocks/fake_subscription_resumed.json index 47930c8f..4638e6a1 100644 --- a/tests/mocks/fake_subscription_resumed.json +++ b/tests/mocks/fake_subscription_resumed.json @@ -1,5 +1,5 @@ { - "id": "sub_Idd0qIOzcw01qH", + "id": "sub_8RlLljfA4AnDVx", "entity": "subscription", "plan_id": "plan_IdJJ47TH0TdW9R", "customer_id": "cust_IOyIY3JvbVny9o", diff --git a/tests/test_client_subscription.py b/tests/test_client_subscription.py index 550f2e5b..2980b20f 100644 --- a/tests/test_client_subscription.py +++ b/tests/test_client_subscription.py @@ -99,7 +99,7 @@ def test_subscription_pause(self): responses.add(responses.POST, url, status=200, body=json.dumps(result), match_querystring=True) response = json.loads( - self.client.subscription.cancel(self.subscription_id)) + self.client.subscription.pause(self.subscription_id)) self.assertEqual(response['id'], self.subscription_id) self.assertEqual(response['entity'], 'subscription') self.assertEqual(response['status'], 'paused') @@ -111,7 +111,18 @@ def test_subscription_resume(self): responses.add(responses.POST, url, status=200, body=json.dumps(result), match_querystring=True) response = json.loads( - self.client.subscription.cancel(self.subscription_id)) + self.client.subscription.resume(self.subscription_id)) self.assertEqual(response['id'], self.subscription_id) self.assertEqual(response['entity'], 'subscription') - self.assertEqual(response['status'], 'resumed') \ No newline at end of file + self.assertEqual(response['status'], 'active') + + @responses.activate + def test_subscription_delete_offer(self): + result = mock_file('fake_subscription') + url = '{}/{}/{}'.format(self.base_url, 'sub_8kip7ybbcOyc9J','offer_IjA06IHSz33cw2') + responses.add(responses.DELETE, url, status=200, body=json.dumps(result), + match_querystring=True) + response = json.loads( + self.client.subscription.delete_offer('sub_8kip7ybbcOyc9J','offer_IjA06IHSz33cw2')) + self.assertEqual(response['id'], 'sub_8kip7ybbcOyc9J') + self.assertEqual(response['entity'], 'subscription') \ No newline at end of file From 683158e0fdf4fa757726e234083015dc463e715e Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Thu, 13 Jan 2022 14:34:22 +0530 Subject: [PATCH 15/25] fix comment --- razorpay/resources/qrcode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/razorpay/resources/qrcode.py b/razorpay/resources/qrcode.py index a9353869..71150cf4 100644 --- a/razorpay/resources/qrcode.py +++ b/razorpay/resources/qrcode.py @@ -31,7 +31,7 @@ def create(self, data={}, **kwargs): def all(self, data={}, **kwargs): """" - Fetch All Refund + Fetch All Qr Code Returns: Qrcode dict From 78852cebc1b2284715650b3ffed8c7ec55ed2207 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Thu, 13 Jan 2022 17:07:05 +0530 Subject: [PATCH 16/25] implement items module --- razorpay/__init__.py | 2 + razorpay/constants/url.py | 1 + razorpay/resources/__init__.py | 2 + razorpay/resources/customer.py | 9 ++++ razorpay/resources/item.py | 63 ++++++++++++++++++++++++++++ tests/mocks/customer_collection.json | 19 +++++++++ tests/mocks/fake_item.json | 8 ++++ tests/mocks/item_collection.json | 30 +++++++++++++ tests/test_client_customer.py | 8 ++++ tests/test_client_item.py | 45 ++++++++++++++++++++ 10 files changed, 187 insertions(+) create mode 100644 razorpay/resources/item.py create mode 100644 tests/mocks/customer_collection.json create mode 100644 tests/mocks/fake_item.json create mode 100644 tests/mocks/item_collection.json create mode 100644 tests/test_client_item.py diff --git a/razorpay/__init__.py b/razorpay/__init__.py index ab11dc3f..1f8d9b1e 100644 --- a/razorpay/__init__.py +++ b/razorpay/__init__.py @@ -13,6 +13,7 @@ from .resources import Subscription from .resources import Plan from .resources import Settlement +from .resources import Item from .utility import Utility from .constants import ERROR_CODE from .constants import HTTP_STATUS_CODE @@ -34,6 +35,7 @@ 'Subscription', 'Plan', 'Settlement', + 'Item', 'HTTP_STATUS_CODE', 'ERROR_CODE', ] diff --git a/razorpay/constants/url.py b/razorpay/constants/url.py index 3d2cb40d..f75834d0 100644 --- a/razorpay/constants/url.py +++ b/razorpay/constants/url.py @@ -13,3 +13,4 @@ class URL(object): ADDON_URL = "/addons" PLAN_URL = "/plans" SETTLEMENT_URL = "/settlements" + ITEM_URL = "/items" diff --git a/razorpay/resources/__init__.py b/razorpay/resources/__init__.py index f8af63d4..d255c411 100644 --- a/razorpay/resources/__init__.py +++ b/razorpay/resources/__init__.py @@ -12,6 +12,7 @@ from .plan import Plan from .subscription import Subscription from .settlement import Settlement +from .item import Item __all__ = [ 'Payment', @@ -28,4 +29,5 @@ 'Plan', 'Subscription', 'Settlement', + 'Item' ] diff --git a/razorpay/resources/customer.py b/razorpay/resources/customer.py index 2c79c717..d5ce5054 100644 --- a/razorpay/resources/customer.py +++ b/razorpay/resources/customer.py @@ -39,3 +39,12 @@ def edit(self, customer_id, data={}, **kwargs): url = '{}/{}'.format(self.base_url, customer_id) return self.put_url(url, data, **kwargs) + + def all(self, data={}, **kwargs): + """" + Fetch all customer + + Returns: + Dictionary of Customers data + """ + return super(Customer, self).all(data, **kwargs) \ No newline at end of file diff --git a/razorpay/resources/item.py b/razorpay/resources/item.py new file mode 100644 index 00000000..2965f327 --- /dev/null +++ b/razorpay/resources/item.py @@ -0,0 +1,63 @@ +from .base import Resource +from ..constants.url import URL + + +class Item(Resource): + def __init__(self, client=None): + super(Item, self).__init__(client) + self.base_url = URL.ITEM_URL + + def create(self, data={}, **kwargs): + """" + Create item + + Returns: + Item Dict which was created + """ + url = self.base_url + return self.post_url(url, data, **kwargs) + + def fetch(self, item_id, data={}, **kwargs): + """" + Fetch an Item + + Args: + item_id : The id of the item to be fetched + + Returns: + Item dict for given card Id + """ + return super(Item, self).fetch(item_id, data, **kwargs) + + def all(self, data={}, **kwargs): + """" + Fetch all items + + Returns: + Dictionary of Items data + """ + return super(Item, self).all(data, **kwargs) + + def edit(self, item_id, data={}, **kwargs): + """" + Update an Item + + Returns: + Item Dict which was edited + """ + url = '{}/{}'.format(self.base_url, item_id) + + return self.patch_url(url, data, **kwargs) + + def delete(self, item_id, **kwargs): + """" + Delete an Item + + Args: + item_id : The id of the item to be deleted + + Returns: + The response is always be an empty array like this - [] + """ + url = "{}/{}".format(self.base_url, item_id) + return self.delete_url(url, {}, **kwargs) \ No newline at end of file diff --git a/tests/mocks/customer_collection.json b/tests/mocks/customer_collection.json new file mode 100644 index 00000000..aa0d93cb --- /dev/null +++ b/tests/mocks/customer_collection.json @@ -0,0 +1,19 @@ +{ + "entity":"collection", + "count":1, + "items":[ + { + "id":"cust_1Aa00000000001", + "entity":"customer", + "name":"Gaurav Kumar", + "email":"gaurav.kumar@example.com", + "contact":"9876543210", + "gstin":"29XAbbA4369J1PA", + "notes":{ + "note_key_1":"September", + "note_key_2":"Make it so." + }, + "created_at ":1234567890 + } + ] + } \ No newline at end of file diff --git a/tests/mocks/fake_item.json b/tests/mocks/fake_item.json new file mode 100644 index 00000000..99dbc4d8 --- /dev/null +++ b/tests/mocks/fake_item.json @@ -0,0 +1,8 @@ +{ + "id": "item_7Oxp4hmm6T4SCn", + "active": true, + "name": "Book / English August", + "description": "An indian story, Booker prize winner.", + "amount": 20000, + "currency": "INR" + } \ No newline at end of file diff --git a/tests/mocks/item_collection.json b/tests/mocks/item_collection.json new file mode 100644 index 00000000..a618ecec --- /dev/null +++ b/tests/mocks/item_collection.json @@ -0,0 +1,30 @@ +{ + "entity": "collection", + "count": 3, + "items": [ + { + "id": "item_7Oy8OMV6BdEAac", + "active": true, + "name": "Book / Ignited Minds", + "description": null, + "amount": 15000, + "currency": "INR" + }, + { + "id": "item_7Oxp4hmm6T4SCn", + "active": true, + "name": "Book / English August", + "description": "An indian story, Booker prize winner.", + "amount": 20000, + "currency": "INR" + }, + { + "id": "item_7OxoGnoxCuUKbo", + "active": true, + "name": "Book / English August", + "description": null, + "amount": 20000, + "currency": "INR" + } + ] + } \ No newline at end of file diff --git a/tests/test_client_customer.py b/tests/test_client_customer.py index ab6c3669..384c29cc 100644 --- a/tests/test_client_customer.py +++ b/tests/test_client_customer.py @@ -48,3 +48,11 @@ def test_customer_edit(self): match_querystring=True) self.assertEqual(self.client.customer.edit(self.customer_id, email), result) + + @responses.activate + def test_item_all(self): + result = mock_file('customer_collection') + url = self.base_url + responses.add(responses.GET, url, status=200, + body=json.dumps(result), match_querystring=True) + self.assertEqual(self.client.customer.all(), result) \ No newline at end of file diff --git a/tests/test_client_item.py b/tests/test_client_item.py new file mode 100644 index 00000000..7fc55010 --- /dev/null +++ b/tests/test_client_item.py @@ -0,0 +1,45 @@ +import responses +import json + +from .helpers import mock_file, ClientTestCase + + +class TestClientItem(ClientTestCase): + + def setUp(self): + super(TestClientItem, self).setUp() + self.base_url = '{}/items'.format(self.base_url) + + @responses.activate + def test_item_all(self): + result = mock_file('item_collection') + url = self.base_url + responses.add(responses.GET, url, status=200, + body=json.dumps(result), match_querystring=True) + self.assertEqual(self.client.item.all(), result) + + @responses.activate + def test_item_fetch(self): + result = mock_file('item_collection') + url = self.base_url + responses.add(responses.GET, url, status=200, + body=json.dumps(result), match_querystring=True) + self.assertEqual(self.client.item.all(), result) + + @responses.activate + def test_item_create(self): + result = mock_file('item_collection') + url = '{}/{}'.format(self.base_url, 'fake_item_id') + responses.add(responses.GET, url, status=200, body=json.dumps(result), + match_querystring=True) + self.assertEqual(self.client.item.fetch('fake_item_id'), result) + + @responses.activate + def test_item_delete(self): + result = [] + url = '{}/{}'.format(self.base_url, 'fake_item_id') + responses.add(responses.DELETE, url, status=200, + body=json.dumps(result), match_querystring=True) + self.assertEqual(self.client.item.delete('fake_item_id'), result) + + \ No newline at end of file From d07f2810ec425c85453a73660c3946ff97ba6891 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Mon, 17 Jan 2022 17:09:40 +0530 Subject: [PATCH 17/25] add cancel scheduled changes --- razorpay/resources/subscription.py | 13 +++++++++++++ tests/test_client_subscription.py | 11 +++++++++++ 2 files changed, 24 insertions(+) diff --git a/razorpay/resources/subscription.py b/razorpay/resources/subscription.py index 2310456c..037640f1 100644 --- a/razorpay/resources/subscription.py +++ b/razorpay/resources/subscription.py @@ -54,6 +54,19 @@ def cancel(self, subscription_id, data={}, **kwargs): url = "{}/{}/cancel".format(self.base_url, subscription_id) return self.post_url(url, data, **kwargs) + def cancel_scheduled_changes(self, subscription_id, data={}, **kwargs): + """ + Cancel a update + + Args: + subscription_id : Id for which subscription has to be cancelled + + Returns: + Subscription Dict for given subscription id + """ + url = "{}/{}/cancel_scheduled_changes".format(self.base_url, subscription_id) + return self.post_url(url, data, **kwargs) + def createAddon(self, subscription_id, data={}, **kwargs): """ Create addon for given subscription diff --git a/tests/test_client_subscription.py b/tests/test_client_subscription.py index 2980b20f..2883f004 100644 --- a/tests/test_client_subscription.py +++ b/tests/test_client_subscription.py @@ -50,6 +50,17 @@ def test_subscription_cancel(self): self.assertEqual(response['entity'], 'subscription') self.assertEqual(response['status'], 'cancelled') + @responses.activate + def test_subscription_cancel_scheduled_changes(self): + result = mock_file('fake_subscription_resumed') + url = '{}/{}/cancel_scheduled_changes'.format(self.base_url, self.subscription_id) + responses.add(responses.POST, url, status=200, body=json.dumps(result), + match_querystring=True) + response = json.loads( + self.client.subscription.cancel_scheduled_changes(self.subscription_id)) + self.assertEqual(response['id'], self.subscription_id) + self.assertEqual(response['entity'], 'subscription') + @responses.activate def test_subscription_create_addon(self): result = mock_file('fake_subscription_addon') From 1938e5c1d32d7d12d5adb3a9faae5577a83afba4 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Mon, 17 Jan 2022 18:38:51 +0530 Subject: [PATCH 18/25] fix indendation --- razorpay/utility/utility.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/razorpay/utility/utility.py b/razorpay/utility/utility.py index 2601d479..1272372d 100644 --- a/razorpay/utility/utility.py +++ b/razorpay/utility/utility.py @@ -24,13 +24,13 @@ def verify_payment_signature(self, parameters): def verify_payment_link_signature(self, parameters): if 'razorpay_payment_id' in parameters.keys() and 'payment_link_reference_id' in parameters.keys() and 'payment_link_status' in parameters.keys(): - payment_id = str(parameters['razorpay_payment_id']) - payment_link_id = str(parameters['payment_link_id']) - payment_link_reference_id = str(parameters['payment_link_reference_id']) - payment_link_status = str(parameters['payment_link_status']) - razorpay_signature = str(parameters['razorpay_signature']) + payment_id = str(parameters['razorpay_payment_id']) + payment_link_id = str(parameters['payment_link_id']) + payment_link_reference_id = str(parameters['payment_link_reference_id']) + payment_link_status = str(parameters['payment_link_status']) + razorpay_signature = str(parameters['razorpay_signature']) else: - return False + return False msg = "{}|{}|{}|{}".format(payment_link_id, payment_link_reference_id, payment_link_status, payment_id) From e91d63fc204e8316c2421333b72557480386898c Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Mon, 17 Jan 2022 19:04:46 +0530 Subject: [PATCH 19/25] update_readme --- CHANGELOG.md | 21 + README.md | 438 +------------- documents/addon.md | 175 ++++++ documents/card.md | 545 ++++++++++++++++++ documents/customer.md | 149 +++++ documents/emandate.md | 459 +++++++++++++++ documents/fund.md | 77 +++ documents/invoice.md | 523 +++++++++++++++++ documents/items.md | 169 ++++++ documents/order.md | 212 +++++++ documents/papernach.md | 679 ++++++++++++++++++++++ documents/payment.md | 444 +++++++++++++++ documents/paymentLink.md | 971 ++++++++++++++++++++++++++++++++ documents/paymentVerfication.md | 71 +++ documents/plans.md | 172 ++++++ documents/qrcode.md | 413 ++++++++++++++ documents/refund.md | 295 ++++++++++ documents/registerEmandate.md | 420 ++++++++++++++ documents/registerNach.md | 632 +++++++++++++++++++++ documents/settlement.md | 454 +++++++++++++++ documents/subscription.md | 726 ++++++++++++++++++++++++ documents/token.md | 190 +++++++ documents/transfer.md | 641 +++++++++++++++++++++ documents/upi.md | 517 +++++++++++++++++ documents/virtualAccount.md | 551 ++++++++++++++++++ setup.py | 2 +- 26 files changed, 9530 insertions(+), 416 deletions(-) create mode 100644 documents/addon.md create mode 100644 documents/card.md create mode 100644 documents/customer.md create mode 100644 documents/emandate.md create mode 100644 documents/fund.md create mode 100644 documents/invoice.md create mode 100644 documents/items.md create mode 100644 documents/order.md create mode 100644 documents/papernach.md create mode 100644 documents/payment.md create mode 100644 documents/paymentLink.md create mode 100644 documents/paymentVerfication.md create mode 100644 documents/plans.md create mode 100644 documents/qrcode.md create mode 100644 documents/refund.md create mode 100644 documents/registerEmandate.md create mode 100644 documents/registerNach.md create mode 100644 documents/settlement.md create mode 100644 documents/subscription.md create mode 100644 documents/token.md create mode 100644 documents/transfer.md create mode 100644 documents/upi.md create mode 100644 documents/virtualAccount.md diff --git a/CHANGELOG.md b/CHANGELOG.md index c3d61bd0..e4ef6fb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file. The format ## Unreleased +## [1.3.0][1.3.0] - 2022-01-17 + +### Added +- Added Item Api +- Added RegistrationLink Api +- QR code end point API +- Update, cancel update ,fetch details of a Pending Update, pause, resume subscription & delete offer API +- Add create ondemand , fetch all demand, fetch demand by id & report for settlement +- Add/Delete TPV Bank Account +- Register emandate and charge first payment together +- PaperNACH/Register NACH and charge first payment together +- Added create recurring payment, fetch card details, card downtime & card downtime by Id , create payment json API's for payment +- Added edit and notify API's for payment links +- Added edit, refund, fetch multiple refund, fetch multiple refund by id API's for refunds +- Added edit order API +- Fund API's end point +- UPI +- Added Verfiy payment link ,payment & subscription verification +- Update Testcases +- Update readme file + ## [1.2.0][1.2.0] - 2019-03-11 ### Added diff --git a/README.md b/README.md index e5e565c7..2cc9c783 100644 --- a/README.md +++ b/README.md @@ -34,441 +34,49 @@ client.set_app_details({"title" : "", "version" : "") - ``` +- [Order](documents/order.md) -- Capture a payment +- [Payments](documents/payment.md) - ```py - client.payment.capture("", "") - Note: should be same as the original amount while creating the payment - ``` +- [Settlements](documents/settlement.md) -- Refund a payment +- [Refunds](documents/refund.md) - ```py - client.payment.refund("", "") - # for full refund +- [Invoice](documents/invoice.md) - client.payment.refund("", "") - # for particular amount +- [Subscriptions](documents/subscription.md) - Note: should be equal/less than the original amount - ``` +- [Payment Links](documents/paymentLink.md) -- Get Bank Transfer Entity for given payment +- [Smart Collect](documents/virtualAccount.md) - ```py - client.payment.bank_transfer("") - ``` +- [Route](documents/transfer.md) -- Create transfer for given payment id +- [QR Code](documents/qrcode.md) - ```py - client.payment.transfer("") - ``` - For List of params refer to the API guide : - https://razorpay.com/docs/route/api-reference/#creating-payments +- [Emandate](documents/emandate.md) -- Fetch all transfers associated with the payment +- [Cards](documents/card.md) - ```py - client.payment.transfers("") - ``` +- [Paper NACH](documents/papernach.md) -### Refunds +- [UPI](documents/upi.md) -- Fetch a particular refund +- [Register Emandate and Charge First Payment Together](documents/registerEmandate.md) - ```py - client.refund.fetch("") - ``` +- [Register NACH and Charge First Payment Together](documents/registerNach.md) -- Fetch all refunds - - ```py - client.refund.all() - ``` - -### Orders - -- Create a new order - - ```py - client.order.create(data=DATA) - DATA should contain these keys - amount : amount of order - currency : currency of order - receipt : receipt id of order - payment_capture : 1 if capture should be done automatically or else 0 - notes(optional) : optional notes for order - ``` - -- fetch a particular order - - ```py - client.order.fetch("") - ``` - -- fetch all orders - - ```py - client.order.all() - ``` - -- fetch Payments of order - - ```py - client.order.payments("") - ``` - - -### Payment Link - -- Create payment link - - Refer [api docs](https://razorpay.com/docs/payment-links/api/#creating-payment-links) for allowed request parameters. - ```py - DATA = { - "customer": { - "name": "Test Customer", - "email": "test@example.com", - "contact": "+919999888877" - }, - "type": "link", - "amount": 100, - "currency": "INR", - "description": "Payment link for this purpose - xyz" - } - client.invoice.create(data=DATA) - ``` - -- Fetch payment link's details by id - - ```py - client.invoice.fetch("") - ``` - -- Fetch all payment link - - Refer [api docs](https://razorpay.com/docs/payment-links/api/#fetching-get-multiple-payment-links) for allowed query parameters. - ```py - client.invoice.all() - ``` - -- Cancel a payment link by id - - ```py - client.invoice.cancel("") - ``` - -- Send/resend notifications for a payment link by id - - ```py - client.invoice.notify_by("", "") - # MEDIUM - sms/email - ``` - -### Invoices - -- Create a new invoice - - Refer [api docs](https://razorpay.com/docs/invoices/api/#creating-an-invoice) for allowed request parameters in detail. - ```py - client.invoice.create(data=DATA) - ``` - -- Fetch a invoice by id - - ```py - client.invoice.fetch("") - ``` - -- Fetch all invoices - - Refer [api docs](https://razorpay.com/docs/invoices/api/#fetching-multiple-invoices) for allowed query parameters. - ```py - client.invoice.all() - ``` - -- Cancel an invoice by id - - ```py - client.invoice.cancel("") - ``` - -- Send/resend notifications for an invoice by id - - ```py - client.invoice.notify_by("", "") - # MEDIUM - sms/email - ``` - -- Issue an invoice in draft status by id - - ```py - client.invoice.issue("") - ``` - -- Delete an invoice by id - - ```py - client.invoice.delete("") - ``` - -- Edit an invoice by id - - Refer [api docs](https://razorpay.com/docs/invoices/api/#updating-an-invoice) for allowed request parameters in detail. - ```py - client.invoice.edit(invoice_id=invoice_id,data=DATA) - ``` - - -### Settlements - -- fetch a particular settlement detail - - ```py - client.settlement.fetch("") - ``` - -- fetch all settlement detail - - ```py - client.settlement.all() - ``` - -### Card - -- fetch a particular card data - - ```py - client.card.fetch(card_id=card_id) - ``` - -### Customer - -- fetch a particular customer Info - - ```py - client.customer.fetch(customer_id=customer_id) - ``` - -- Create a customer - - ```py - client.customer.create(data=data) - ``` - -- Edit a customer info - - ```py - client.customer.edit(customer_id=customer_id, data=data) - ``` - -### Token - -- fetch a token associated with a customer - - ```py - client.token.fetch(customer_id=customer_id, token_id=token_id) - ``` - -- fetch all tokens associated with customer - - ```py - client.token.all(customer_id=customer_id) - ``` - -- Delete a given token assicated with a customer - - ```py - client.token.delete(customer_id=customer_id, token_id=token_id) - ``` - -### Virtual Account - -- fetch all virtual account entities - - ```py - client.virtual_account.all() - ``` - -- fetch single virtual account details - - ```py - client.virtual_account.fetch(virtual_account_id=virtual_account_id) - ``` - -- create virtual account - - ```py - client.virtual_account.create(data=DATA) - DATA should contain these keys - receiver_types : ['bank_account'] - description : 'Random Description' - customer_id(optional) : - ``` - -- close virtual account - - ```py - client.virtual_account.close(virtual_account_id=virtual_account_id) - ``` - -- fetch all payments for virtual account id - - ```py - client.virtual_account.payments(virtual_account_id=virtual_account_id) - ``` - -### Utility - -- Verify Payment Signature - - `params_dict` should have `razorpay_order_id`, `razorpay_payment_id`, `razorpay_signature` which are received in the callback - - ```py - client.utility.verify_payment_signature(params_dict) - ``` - -- Verify Webhook Signature - - `webhook_signature` is the signature you receive under `X-Razorpay-Signature` in the webhook, while `webhook_secret` is the secret you used when creating the webhook on dashboard. - - ```py - client.utility.verify_webhook_signature(webhook_body, webhook_signature, webhook_secret) - ``` - -### Subscriptions - -- Create a new subscription - - ```py - client.subscription.create(data=DATA) - DATA should contain these keys - plan_id : plan_id of subscription - customer_id : id of customer - total_count : number of subscriptions - ``` - -- Fetch a particular subscription - - ```py - client.subscription.fetch("") - ``` - -- Fetch all subscriptions - - ```py - client.subscription.all() - ``` - -- Cancel subscription - - ```py - client.subscription.cancel("") - ``` - -- Create an addon for subscription - ``` - client.subscription.createAddon("", data=DATA) - DATA should have these keys - item : dict with keys amount, name and currency - quantity : number of items - ``` - -- Fetch a particular addon Info - - ```py - client.addon.fetch(addon_id=addon_id) - ``` - -- Delete an addon - - ```py - client.addon.delete(addon_id=addon_id) - ``` - -### Plans - -- Create a new plan - - ```py - client.plan.create(data=DATA) - DATA should contain these keys - item_id : corresponding item_id - ``` - -- Fetch a particular plan - - ```py - client.plan.fetch("") - ``` - -- Fetch all plans - - ```py - client.plan.all() - ``` - -### Transfers - -- Fetch all Transfers - - ```py - client.transfer.all() - ``` - -- Fetch transfer by ID - - ```py - client.transfer.fetch("") - ``` - -- Create Transfer from given data - - ```py - client.transfer.create(data=DATA) - DATA should contain these keys - amount : 100 - currency : INR - account : acc_865rdfghu7632 - ``` - -- Edit Transfer from given data - - ```py - client.transfer.edit(transfer_id=transfer_id, data=DATA) - DATA may contain these keys - on_hold : True/False - on_hold_until : 15678903127 - ``` - For details on Transfer edit, please refer to the API guide: - https://razorpay.com/docs/route/api-reference/#examples - -- Reverse a given Transfer - - ```py - client.transfer.reverse(transfer_id=transfer_id) - ``` - -- Fetch all reversals for a given Transfer - - ```py - client.transfer.reversals(transfer_id=transfer_id) - ``` +- [Payment Verification](documents/paymentVerfication.md) +--- ## Bugs? Feature requests? Pull requests? diff --git a/documents/addon.md b/documents/addon.md new file mode 100644 index 00000000..74b8f3be --- /dev/null +++ b/documents/addon.md @@ -0,0 +1,175 @@ +## Addons + +### Create an addon + +```py +client.subscription.createAddon('sub_I55auG9GnbsR8u',{ + "item":{ + "name":"Extra appala (papadum)", + "amount":30000, + "currency":"INR", + "description":"1 extra oil fried appala with meals" + }, + "quantity":2 +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | boolean | The subscription ID to which the add-on is being added. | +| items* | object | Details of the add-on you want to create. | +| quantity* | integer | This specifies the number of units of the add-on to be charged to the customer. | + +**Response:** +```json +{ + "id":"ao_00000000000001", + "entity":"addon", + "item":{ + "id":"item_00000000000001", + "active":true, + "name":"Extra appala (papadum)", + "description":"1 extra oil fried appala with meals", + "amount":30000, + "unit_amount":30000, + "currency":"INR", + "type":"addon", + "unit":null, + "tax_inclusive":false, + "hsn_code":null, + "sac_code":null, + "tax_rate":null, + "tax_id":null, + "tax_group_id":null, + "created_at":1581597318, + "updated_at":1581597318 + }, + "quantity":2, + "created_at":1581597318, + "subscription_id":"sub_00000000000001", + "invoice_id":null +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all addons + +```py +client.addon.all(options) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "ao_00000000000002", + "entity": "addon", + "item": { + "id": "item_00000000000002", + "active": true, + "name": "Extra sweet", + "description": "1 extra sweet of the day with meals", + "amount": 90000, + "unit_amount": 90000, + "currency": "INR", + "type": "addon", + "unit": null, + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "tax_id": null, + "tax_group_id": null, + "created_at": 1581597318, + "updated_at": 1581597318 + }, + "quantity": 1, + "created_at": 1581597318, + "subscription_id": "sub_00000000000001", + "invoice_id": "inv_00000000000001" + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch an addon + +```py +client.addon.fetch(addonId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------| +| addonId* | string | addon id to be fetched | + +**Response:** +```json +{ + "id":"ao_00000000000001", + "entity":"addon", + "item":{ + "id":"item_00000000000001", + "active":true, + "name":"Extra appala (papadum)", + "description":"1 extra oil fried appala with meals", + "amount":30000, + "unit_amount":30000, + "currency":"INR", + "type":"addon", + "unit":null, + "tax_inclusive":false, + "hsn_code":null, + "sac_code":null, + "tax_rate":null, + "tax_id":null, + "tax_group_id":null, + "created_at":1581597318, + "updated_at":1581597318 + }, + "quantity":2, + "created_at":1581597318, + "subscription_id":"sub_00000000000001", + "invoice_id":null +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete an addon + +```py +client.addon.delete(addonId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| addonId* | string | addon id to be deleted | + +**Response:** +```json +[] +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/subscriptions/#add-ons)** \ No newline at end of file diff --git a/documents/card.md b/documents/card.md new file mode 100644 index 00000000..c1b79da8 --- /dev/null +++ b/documents/card.md @@ -0,0 +1,545 @@ +## Cards + +### Create customer +```py +client.customer.create({ + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "fail_existing": "0", + "notes":{ + "note_key_1": "September", + "note_key_2": "Make it so." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| name* | string | Name of the customer | +| email | string | Email of the customer | +| contact | string | Contact number of the customer | +| fail_existing | string | If a customer with the same details already exists, the request throws an exception by default. Possible value is `0` or `1`| +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "cust_1Aa00000000003", + "entity": "customer", + "name": "Gaurav Kumar", + "email": "Gaurav.Kumar@example.com", + "contact": "9000000000", + "gstin": null, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1582033731 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create Order + +```py +client.order.create({ + "amount": 50000, + "currency": "INR", + "receipt": "receipt#1", + "notes": { + "key1": "value3", + "key2": "value2" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "order_EKwxwAgItmmXdp", + "entity": "order", + "amount": 50000, + "amount_paid": 0, + "amount_due": 50000, + "currency": "INR", + "receipt": "receipt#1", + "offer_id": null, + "status": "created", + "attempts": 0, + "notes": [], + "created_at": 1582628071 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create registration link + +```py +client.registration_link.create({ + "customer":{ + "name":"Gaurav Kumar", + "email":"gaurav.kumar@example.com", + "contact":"9123456780" + }, + "type":"link", + "amount":"100", + "currency":"INR", + "description":"Registration Link for Gaurav", + "subscription_registration":{ + "method":"card", + "max_amount":"500", + "expire_at":1644737663 + }, + "receipt":"Receipt No. #11", + "email_notify":1, + "sms_notify":1, + "expire_by":1644737663, + "notes":{ + "note_key 1":"Beam me up Scotty", + "note_key 2":"Tea. Earl Gray. Hot." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customer | object | Details of the customer to whom the registration link will be sent. | +| type* | string | the value is `link`. | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| description* | string | A brief description of the payment. | +| subscription_registration | object | All keys listed [here](https://razorpay.com/docs/api/recurring-payments/cards/authorization-transaction/#121-create-a-registration-link) are supported | +| receipt | string | Your system order reference id. | +| sms_notify | boolean | SMS notifications are to be sent by Razorpay (default : 1) | +| email_notify | boolean | Email notifications are to be sent by Razorpay (default : 1) | +| expire_by | integer | The timestamp, in Unix format, till when the customer can make the authorization payment. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "inv_FHrXGIpd3N17DX", + "entity": "invoice", + "receipt": "Receipt No. 24", + "invoice_number": "Receipt No. 24", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrXGJNngJyEAe", + "line_items": [], + "payment_id": null, + "status": "issued", + "expire_by": 4102444799, + "issued_at": 1595491014, + "paid_at": null, + "cancelled_at": null, + "expired_at": null, + "sms_status": "pending", + "email_status": "pending", + "date": 1595491014, + "terms": null, + "partial_payment": false, + "gross_amount": 100, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 100, + "amount_paid": 0, + "amount_due": 100, + "currency": "INR", + "currency_symbol": "₹", + "description": "Registration Link for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/VSriCfn", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491014, + "idempotency_key": null +} +``` +------------------------------------------------------------------------------------------------------- + +## Create an order to charge the customer + +```py +client.order.create({ + "amount": 100, + "currency": "INR", + "customer_id": "cust_IOyIY3JvbVny9o", + "method": "card", + "token": { + "max_amount": 5000, + "expire_at": 2709971120, + "frequency": "monthly" + }, + "receipt": "Receipt No. 1", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey... decaf." + } +}) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| customerId* | string | The id of the customer to be fetched | +| method* | string | Payment method used to make the registration transaction. Possible value is `card`. | +| receipt | string | Your system order reference id. | +| token | array | All keys listed [here](https://razorpay.com/docs/api/recurring-payments/cards/subsequent-payments/#31-create-an-order-to-charge-the-customer) are supported | +| notes | array | A key-value pair | + +**Response:** +```json +{ + "id":"order_1Aa00000000002", + "entity":"order", + "amount":100, + "amount_paid":0, + "amount_due":100, + "currency":"INR", + "receipt":"Receipt No. 1", + "method":"card", + "description":null, + "customer_id":"cust_4xbQrmEoA5WJ01", + "token":{ + "max_amount":5000, + "expire_at":2709971120, + "frequency":"monthly" + }, + "offer_id":null, + "status":"created", + "attempts":0, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1565172642 +} +``` +------------------------------------------------------------------------------------------------------- + +## Create a recurring payment + +```py +client.payment.createRecurring({ + "email": "gaurav.kumar@example.com", + "contact": 9123456789, + "amount": 1000, + "currency": "INR", + "order_id": "order_IDts8IQBJT40aQ", + "customer_id": "cust_Hwq7Ba6TDXl1ga", + "token": "token_1Aa00000000001", + "recurring": 1, + "description": "Creating recurring payment for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } +}) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| email* | string | The customer's email address | +| contact* | string | The customer's phone number | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| orderId* | string | The id of the order to be fetched | +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | +| recurring* | boolean | Possible values is `0` or `1` | +| description | string | A brief description of the payment. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "razorpay_payment_id" : "pay_1Aa00000000001", + "razorpay_order_id" : "order_1Aa00000000001", + "razorpay_signature" : "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d" +} +``` +------------------------------------------------------------------------------------------------------- + +### Create an Authorization Payment + +Please refer this [doc](https://razorpay.com/docs/api/recurring-payments/cards/authorization-transaction/#113-create-an-authorization-payment) for authorization payment + +------------------------------------------------------------------------------------------------------- + +## Send/Resend notifications + +```py +client.invoice.notify_by(invoiceId,medium) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be fetched | +| medium* | string | Possible values are `sms` or `email` | + +**Response:** +```json +{ + "success": true +} +``` +------------------------------------------------------------------------------------------------------- + +## Cancel registration link + +```py +client.invoice.cancel(invoiceId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be fetched | + +**Response:** +```json +{ + "id": "inv_FHrfRupD2ouKIt", + "entity": "invoice", + "receipt": "Receipt No. 1", + "invoice_number": "Receipt No. 1", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrfRw4TZU5Q2L", + "line_items": [], + "payment_id": null, + "status": "cancelled", + "expire_by": 4102444799, + "issued_at": 1595491479, + "paid_at": null, + "cancelled_at": 1595491488, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1595491479, + "terms": null, + "partial_payment": false, + "gross_amount": 100, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 100, + "amount_paid": 0, + "amount_due": 100, + "currency": "INR", + "currency_symbol": "₹", + "description": "Registration Link for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/QlfexTj", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491480, + "idempotency_key": null +} +``` +------------------------------------------------------------------------------------------------------- + +## Fetch token by payment id + +```py +client.token.fetch(paymentId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | + +**Response:** +```json +{ + "id": "pay_FHfqtkRzWvxky4", + "entity": "payment", + "amount": 100, + "currency": "INR", + "status": "captured", + "order_id": "order_FHfnswDdfu96HQ", + "invoice_id": null, + "international": false, + "method": "card", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": null, + "card_id": "card_F0zoXUp4IPPGoI", + "bank": null, + "wallet": null, + "vpa": null, + "email": "gaurav.kumar@example.com", + "contact": "+919876543210", + "customer_id": "cust_DtHaBuooGHTuyZ", + "token_id": "token_FHfn3rIiM1Z8nr", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "auth_code": "541898" + }, + "created_at": 1595449871 +} +``` +------------------------------------------------------------------------------------------------------- + +## Fetch tokens by customer id + +```py +client.token.all(customerId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "entity":"collection", + "count":1, + "items":[ + { + "id":"token_HouA2OQR5Z2jTL", + "entity":"token", + "token":"2JPRk664pZHUWG", + "bank":null, + "wallet":null, + "method":"card", + "card":{ + "entity":"card", + "name":"Gaurav Kumar", + "last4":"8950", + "network":"Visa", + "type":"credit", + "issuer":"STCB", + "international":false, + "emi":false, + "sub_type":"consumer", + "expiry_month":12, + "expiry_year":2021, + "flows":{ + "otp":true, + "recurring":true + } + }, + "recurring":true, + "recurring_details":{ + "status":"confirmed", + "failure_reason":null + }, + "auth_type":null, + "mrn":null, + "used_at":1629779657, + "created_at":1629779657, + "expired_at":1640975399, + "dcc_enabled":false, + "billing_address":null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch card + +```py +client.card.fetch(cardId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| cardId* | string | card id to be fetched | + +------------------------------------------------------------------------------------------------------- + +## Delete tokens + +```py +client.token.delete(customerId,tokenId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | + +**Response:** +```json +{ + "deleted": true +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/recurring-payments/cards/authorization-transaction/)** \ No newline at end of file diff --git a/documents/customer.md b/documents/customer.md new file mode 100644 index 00000000..e4952cc8 --- /dev/null +++ b/documents/customer.md @@ -0,0 +1,149 @@ +## Customer + +### Create customer +```py +client.customer.create({ + "name": "Gaurav Kumar", + "contact": 9123456780, + "email": "gaurav.kumar@example.com", + "fail_existing": 0, + "gstin": "29XAbbA4369J1PA", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| name* | string | Name of the customer | +| email | string | Email of the customer | +| contact | string | Contact number of the customer | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id" : "cust_1Aa00000000004", + "entity": "customer", + "name" : "Gaurav Kumar", + "email" : "gaurav.kumar@example.com", + "contact" : "9123456780", + "gstin": "29XAbbA4369J1PA", + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at ": 1234567890 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Edit customer +```py +client.customer.edit(customerId,{ + "name": "Gaurav Kumar", + "email": "Gaurav.Kumar@example.com", + "contact": 9000000000 +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be updated | +| email | string | Email of the customer | +| name | string | Name of the customer | +| contact | string | Contact number of the customer | + +**Response:** +```json +{ + "id": "cust_1Aa00000000003", + "entity": "customer", + "name": "Gaurav Kumar", + "email": "Gaurav.Kumar@example.com", + "contact": "9000000000", + "gstin": null, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1582033731 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all customer +```py +client.customer.all(options) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity":"collection", + "count":1, + "items":[ + { + "id":"cust_1Aa00000000001", + "entity":"customer", + "name":"Gaurav Kumar", + "email":"gaurav.kumar@example.com", + "contact":"9876543210", + "gstin":"29XAbbA4369J1PA", + "notes":{ + "note_key_1":"September", + "note_key_2":"Make it so." + }, + "created_at ":1234567890 + } + ] +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch a customer +```py +client.customer.fetch(customerId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "id" : "cust_1Aa00000000001", + "entity": "customer", + "name" : "Saurav Kumar", + "email" : "Saurav.kumar@example.com", + "contact" : "+919000000000", + "gstin":"29XAbbA4369J1PA", + "notes" : [], + "created_at ": 1234567890 +} +``` + +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/customers/)** \ No newline at end of file diff --git a/documents/emandate.md b/documents/emandate.md new file mode 100644 index 00000000..69251e3f --- /dev/null +++ b/documents/emandate.md @@ -0,0 +1,459 @@ +## Emandates + +### Create customer +```py +client.customer.create({ + "name": "Gaurav Kumar", + "contact": 9123456780, + "email": "gaurav.kumar@example.com", + "fail_existing": 0, + "gstin": "29XAbbA4369J1PA", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| name* | string | Name of the customer | +| email | string | Email of the customer | +| contact | string | Contact number of the customer | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "cust_1Aa00000000003", + "entity": "customer", + "name": "Gaurav Kumar", + "email": "Gaurav.Kumar@example.com", + "contact": "9000000000", + "gstin": null, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1582033731 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create order + +```py +client.order.create({ + "amount": 0, + "currency": "INR", + "method": "emandate", + "customer_id": "cust_1Aa00000000001", + "receipt": "Receipt No. 1", + "notes": { + "notes_key_1": "Beam me up Scotty", + "notes_key_2": "Engage" + }, + "token": { + "auth_type": "netbanking", + "max_amount": 9999900, + "expire_at": 4102444799, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "bank_account": { + "beneficiary_name": "Gaurav Kumar", + "account_number": 1121431121541121, + "account_type": "savings", + "ifsc_code": "HDFC0000001" + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | Amount of the order to be paid | +| currency* | string | Currency of the order. Currently only `INR` is supported. | +| method* | string | The authorization method. In this case the value will be `emandate` | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | +| token | object | A key-value pair | + +**Response:** +Create order response please click [here](https://razorpay.com/docs/api/recurring-payments/emandate/authorization-transaction/#112-create-an-order) +------------------------------------------------------------------------------------------------------- + +### Create an Authorization Payment + +Please refer this [doc](https://razorpay.com/docs/api/recurring-payments/emandate/authorization-transaction/#113-create-an-authorization-payment) for authorization payment + +------------------------------------------------------------------------------------------------------- + +### Create registration link + +```py +client.registration_link.create({ + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": 9123456780 + }, + "type": "link", + "amount": 0, + "currency": "INR", + "description": "12 p.m. Meals", + "subscription_registration": { + "method": "emandate", + "auth_type": "netbanking", + "expire_at": 1580480689, + "max_amount": 50000, + "bank_account": { + "beneficiary_name": "Gaurav Kumar", + "account_number": 11214311215411, + "account_type": "savings", + "ifsc_code": "HDFC0001233" + } + }, + "receipt": "Receipt no. 1", + "expire_by": 1880480689, + "sms_notify": 1, + "email_notify": 1, + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customer | object | Details of the customer to whom the registration link will be sent. | +| type* | string | In this case, the value is `link`. | +| currency* | string | The 3-letter ISO currency code for the payment. Currently, only `INR` is supported. | +| amount* | integer | The payment amount in the smallest currency sub-unit. | +| description* | string | A description that appears on the hosted page. For example, `12:30 p.m. Thali meals (Gaurav Kumar`). | +| subscription_registration | object | Details of the authorization payment. | +| notes | object | A key-value pair | + +**Response:** +Create registration link response please click [here](https://razorpay.com/docs/api/recurring-payments/emandate/authorization-transaction/#121-create-a-registration-link) +------------------------------------------------------------------------------------------------------- + +### Send/Resend notifications + +```py +client.invoice.notify_by(invoiceId, medium) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be notified | +| medium* | string | `sms`/`email`, Medium through which notification should be sent. | + +**Response:** +```json +{ + "success": true +} +``` +------------------------------------------------------------------------------------------------------- + +### Cancel a registration link + +```py +client.invoice.cancel(invoiceId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be cancelled | + +**Response:** +```json +{ + "id": "inv_FHrfRupD2ouKIt", + "entity": "invoice", + "receipt": "Receipt No. 1", + "invoice_number": "Receipt No. 1", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrfRw4TZU5Q2L", + "line_items": [], + "payment_id": null, + "status": "cancelled", + "expire_by": 4102444799, + "issued_at": 1595491479, + "paid_at": null, + "cancelled_at": 1595491488, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1595491479, + "terms": null, + "partial_payment": false, + "gross_amount": 100, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 100, + "amount_paid": 0, + "amount_due": 100, + "currency": "INR", + "currency_symbol": "₹", + "description": "Registration Link for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/QlfexTj", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491480, + "idempotency_key": null +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch token by payment ID + +```py +client.payment.fetch(paymentId) +``` + +**Parameters:** + +| Name | Type | Description | +|------------|--------|-----------------------------------| +| paymentId* | string | Id of the payment to be retrieved | + +**Response:** +```json +{ + "id": "pay_FHf9a7AO0iXM9I", + "entity": "payment", + "amount": 0, + "currency": "INR", + "status": "captured", + "order_id": "order_FHf9OwSeyetnKC", + "invoice_id": "inv_FHf9P2hhXEti7i", + "international": false, + "method": "emandate", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": null, + "card_id": null, + "bank": "HDFC", + "wallet": null, + "vpa": null, + "email": "gaurav.kumar@example.com", + "contact": "+919876543210", + "customer_id": "cust_DtHaBuooGHTuyZ", + "token_id": "token_FHf9aAZR9hWJkq", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": {}, + "created_at": 1595447410 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch tokens by customer ID + +```py +client.token.all(customerId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "token_FHf94Uym9tdYFJ", + "entity": "token", + "token": "2wDPM7VAlXtjAR", + "bank": "HDFC", + "wallet": null, + "method": "emandate", + "vpa": null, + "recurring": true, + "recurring_details": { + "status": "confirmed", + "failure_reason": null + }, + "auth_type": "netbanking", + "mrn": null, + "used_at": 1595447381, + "created_at": 1595447381, + "bank_details": { + "beneficiary_name": "Gaurav Kumar", + "account_number": "1121431121541121", + "ifsc": "HDFC0000001", + "account_type": "savings" + }, + "max_amount": 9999900, + "expired_at": 1689971140, + "dcc_enabled": false + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete token + +```py +client.token.delete(customerId,tokenId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | + +**Response:** +```json +{ + "deleted": true +} +``` +------------------------------------------------------------------------------------------------------- + +### Create an order to charge the customer + +```py +client.order.create({ + "amount":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "notes": { + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | Amount of the order to be paid | +| currency* | string | Currency of the order. Currently only `INR` is supported. | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id":"order_1Aa00000000002", + "entity":"order", + "amount":1000, + "amount_paid":0, + "amount_due":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "offer_id":null, + "status":"created", + "attempts":0, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1579782776 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create a Recurring Payment + +```py +client.payment.createRecurring({ + "email": "gaurav.kumar@example.com", + "contact": "9123456789", + "amount": 1000, + "currency": "INR", + "order_id": "order_1Aa00000000002", + "customer_id": "cust_1Aa00000000001", + "token": "token_1Aa00000000001", + "recurring": "1", + "description": "Creating recurring payment for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| email* | string | The customer's email address. | +| contact* | string | The customer's phone number. | +| amount* | integer | The amount you want to charge your customer. This should be the same as the amount in the order. | +| currency* | string | The 3-letter ISO currency code for the payment. Currently, only `INR` is supported. | +| order_id* | string | The unique identifier of the order created. | +| customer_id* | string | The `customer_id` for the customer you want to charge. | +| token* | string | The `token_id` generated when the customer successfully completes the authorization payment. Different payment instruments for the same customer have different `token_id`.| +| recurring* | string | Determines if recurring payment is enabled or not. Possible values:
* `1` - Recurring is enabled.* `0` - Recurring is not enabled.| +| description* | string | A user-entered description for the payment.| +| notes* | object | Key-value pair that can be used to store additional information about the entity. Maximum 15 key-value pairs, 256 characters (maximum) each. | + +**Response:** +```json +{ + "razorpay_payment_id" : "pay_1Aa00000000001", + "razorpay_order_id" : "order_1Aa00000000001", + "razorpay_signature" : "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d" +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/recurring-payments/emandate/authorization-transaction/)** \ No newline at end of file diff --git a/documents/fund.md b/documents/fund.md new file mode 100644 index 00000000..347d60e6 --- /dev/null +++ b/documents/fund.md @@ -0,0 +1,77 @@ +## Funds + +### Create a fund account +```py +client.fund_account.create({ + "customer_id":"cust_Aa000000000001", + "account_type":"bank_account", + "bank_account":{ + "name":"Gaurav Kumar", + "account_number":"11214311215411", + "ifsc":"HDFC0000053" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| account_type* | string | The bank_account to be linked to the customer ID | +| bank_account* | object | A key-value pair | + +**Response:** +```json +{ + "id":"fa_Aa00000000001", + "entity":"fund_account", + "customer_id":"cust_Aa000000000001", + "account_type":"bank_account", + "bank_account":{ + "name":"Gaurav Kumar", + "account_number":"11214311215411", + "ifsc":"HDFC0000053", + "bank_name":"HDFC Bank" + }, + "active":true, + "created_at":1543650891 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all fund accounts + +```py +client.fund_account.fetch(customerId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "id":"fa_Aa00000000001", + "entity":"fund_account", + "customer_id":"cust_Aa000000000001", + "account_type":"bank_account", + "bank_account":{ + "name":"Gaurav Kumar", + "account_number":"11214311215411", + "ifsc":"HDFC0000053", + "bank_name":"HDFC Bank" + }, + "active":true, + "created_at":1543650891 +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/payments/customers/customer-fund-account-api/)** \ No newline at end of file diff --git a/documents/invoice.md b/documents/invoice.md new file mode 100644 index 00000000..b240a80c --- /dev/null +++ b/documents/invoice.md @@ -0,0 +1,523 @@ +## Invoices + +### Create Invoice + +Request #1 +In this example, an invoice is created using the customer and item details. Here, the customer and item are created while creating the invoice. +```py +client.order.create({ + "type": "invoice", + "description": "Invoice for the month of January 2020", + "partial_payment": 1, + "customer": { + "name": "Gaurav Kumar", + "contact": 9999999999, + "email": "gaurav.kumar@example.com", + "billing_address": { + "line1": "Ground & 1st Floor, SJR Cyber Laskar", + "line2": "Hosur Road", + "zipcode": 560068, + "city": "Bengaluru", + "state": "Karnataka", + "country": "in" + }, + "shipping_address": { + "line1": "Ground & 1st Floor, SJR Cyber Laskar", + "line2": "Hosur Road", + "zipcode": 560068, + "city": "Bengaluru", + "state": "Karnataka", + "country": "in" + } + }, + "line_items": [ + { + "name": "Master Cloud Computing in 30 Days", + "description": "Book by Ravena Ravenclaw", + "amount": 399, + "currency": "USD", + "quantity": 1 + } + ], + "sms_notify": 1, + "email_notify": 1, + "currency": "USD", + "expire_by": 1589765167 +}) +``` + +Request #2 +In this example, an invoice is created using existing `customer_id` and `item_id` +```py +client.invoice.create({ + "type:": "invoice", + "date": 1589994898, + "customer_id": "cust_E7q0trFqXgExmT", + "line_items": [ + { + "item_id": "item_DRt61i2NnL8oy6" + } + ] +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|type* | string | entity type (here its invoice) | +|description | string | A brief description of the invoice. | +|customer_id | string | customer id for which invoice need be raised | +|customer | object | customer details in a object format | + +**Response:** +For create invoice response please click [here](https://razorpay.com/docs/api/invoices/#create-an-invoice) + +------------------------------------------------------------------------------------------------------- + +### Fetch all invoices + +```py +client.invoice.all() +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|type | string | entity type (here its invoice) | +|payment_id | string | The unique identifier of the payment made by the customer against the invoice. | +|customer_id | string | The unique identifier of the customer. | +|receipt | string | The unique receipt number that you entered for internal purposes. | + +**Response:** +For fetch all invoice response please click [here](https://razorpay.com/docs/api/invoices/#fetch-multiple-invoices) + +------------------------------------------------------------------------------------------------------- + +### Fetch invoice + +```py +client.invoice.fetch(invoiceId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be fetched | + +**Response:** +```json +{ + "id": "inv_E7q0tqkxBRzdau", + "entity": "invoice", + "receipt": null, + "invoice_number": null, + "customer_id": "cust_E7q0trFqXgExmT", + "customer_details": { + "id": "cust_E7q0trFqXgExmT", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9999999999", + "gstin": null, + "billing_address": { + "id": "addr_E7q0ttqh4SGhAC", + "type": "billing_address", + "primary": true, + "line1": "Ground & 1st Floor, SJR Cyber Laskar", + "line2": "Hosur Road", + "zipcode": "560068", + "city": "Bengaluru", + "state": "Karnataka", + "country": "in" + }, + "shipping_address": { + "id": "addr_E7q0ttKwVA1h2V", + "type": "shipping_address", + "primary": true, + "line1": "Ground & 1st Floor, SJR Cyber Laskar", + "line2": "Hosur Road", + "zipcode": "560068", + "city": "Bengaluru", + "state": "Karnataka", + "country": "in" + }, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9999999999" + }, + "order_id": "order_E7q0tvRpC0WJwg", + "line_items": [ + { + "id": "li_E7q0tuPNg84VbZ", + "item_id": null, + "ref_id": null, + "ref_type": null, + "name": "Master Cloud Computing in 30 Days", + "description": "Book by Ravena Ravenclaw", + "amount": 399, + "unit_amount": 399, + "gross_amount": 399, + "tax_amount": 0, + "taxable_amount": 399, + "net_amount": 399, + "currency": "INR", + "type": "invoice", + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "unit": null, + "quantity": 1, + "taxes": [] + } + ], + "payment_id": null, + "status": "issued", + "expire_by": 1589765167, + "issued_at": 1579765167, + "paid_at": null, + "cancelled_at": null, + "expired_at": null, + "sms_status": "pending", + "email_status": "pending", + "date": 1579765167, + "terms": null, + "partial_payment": true, + "gross_amount": 399, + "tax_amount": 0, + "taxable_amount": 399, + "amount": 399, + "amount_paid": 0, + "amount_due": 399, + "currency": "INR", + "currency_symbol": "₹", + "description": "Invoice for the month of January 2020", + "notes": [], + "comment": null, + "short_url": "https://rzp.io/i/2wxV8Xs", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "invoice", + "group_taxes_discounts": false, + "created_at": 1579765167 +} +``` +------------------------------------------------------------------------------------------------------- + +### Update invoice + +```py +client.invoice.edit(invoiceId,{ + "line_items": [ + { + "id": "li_DAweOizsysoJU6", + "name": "Book / English August - Updated name and quantity", + "quantity": 1 + }, + { + "name": "Book / A Wild Sheep Chase", + "amount": 200, + "currency": "INR", + "quantity": 1 + } + ], + "notes": { + "updated-key": "An updated note." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be fetched | + +**Response:** +For update invoice response please click [here](https://razorpay.com/docs/api/invoices/#update-an-invoice) + +------------------------------------------------------------------------------------------------------- + +### Issue an invoice + +```py +client.invoice.issue(invoiceId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be issued | + +**Response:** +```json +{ + "id": "inv_DAweOiQ7amIUVd", + "entity": "invoice", + "receipt": "#0961", + "invoice_number": "#0961", + "customer_id": "cust_DAtUWmvpktokrT", + "customer_details": { + "id": "cust_DAtUWmvpktokrT", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9977886633", + "gstin": null, + "billing_address": { + "id": "addr_DAtUWoxgu91obl", + "type": "billing_address", + "primary": true, + "line1": "318 C-Wing, Suyog Co. Housing Society Ltd.", + "line2": "T.P.S Road, Vazira, Borivali", + "zipcode": "400092", + "city": "Mumbai", + "state": "Maharashtra", + "country": "in" + }, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9977886633" + }, + "order_id": "order_DBG3P8ZgDd1dsG", + "line_items": [ + { + "id": "li_DAweOizsysoJU6", + "item_id": null, + "name": "Book / English August - Updated name and quantity", + "description": "150 points in Quidditch", + "amount": 400, + "unit_amount": 400, + "gross_amount": 400, + "tax_amount": 0, + "taxable_amount": 400, + "net_amount": 400, + "currency": "INR", + "type": "invoice", + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "unit": null, + "quantity": 1, + "taxes": [] + }, + { + "id": "li_DAwjWQUo07lnjF", + "item_id": null, + "name": "Book / A Wild Sheep Chase", + "description": null, + "amount": 200, + "unit_amount": 200, + "gross_amount": 200, + "tax_amount": 0, + "taxable_amount": 200, + "net_amount": 200, + "currency": "INR", + "type": "invoice", + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "unit": null, + "quantity": 1, + "taxes": [] + } + ], + "payment_id": null, + "status": "issued", + "expire_by": 1567103399, + "issued_at": 1566974805, + "paid_at": null, + "cancelled_at": null, + "expired_at": null, + "sms_status": null, + "email_status": null, + "date": 1566891149, + "terms": null, + "partial_payment": false, + "gross_amount": 600, + "tax_amount": 0, + "taxable_amount": 600, + "amount": 600, + "amount_paid": 0, + "amount_due": 600, + "currency": "INR", + "currency_symbol": "₹", + "description": "This is a test invoice.", + "notes": { + "updated-key": "An updated note." + }, + "comment": null, + "short_url": "https://rzp.io/i/K8Zg72C", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "invoice", + "group_taxes_discounts": false, + "created_at": 1566906474, + "idempotency_key": null +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete an invoice + +```py +client.invoice.delete(invoiceId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be deleted | + +**Response:** +``` +[] +``` +------------------------------------------------------------------------------------------------------- + +### Cancel an invoice + +```py +client.invoice.cancel(invoiceId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be cancelled | + +**Response:** +```json +{ + "id": "inv_E7q0tqkxBRzdau", + "entity": "invoice", + "receipt": null, + "invoice_number": null, + "customer_id": "cust_E7q0trFqXgExmT", + "customer_details": { + "id": "cust_E7q0trFqXgExmT", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9972132594", + "gstin": null, + "billing_address": { + "id": "addr_E7q0ttqh4SGhAC", + "type": "billing_address", + "primary": true, + "line1": "Ground & 1st Floor, SJR Cyber Laskar", + "line2": "Hosur Road", + "zipcode": "560068", + "city": "Bengaluru", + "state": "Karnataka", + "country": "in" + }, + "shipping_address": { + "id": "addr_E7q0ttKwVA1h2V", + "type": "shipping_address", + "primary": true, + "line1": "Ground & 1st Floor, SJR Cyber Laskar", + "line2": "Hosur Road", + "zipcode": "560068", + "city": "Bengaluru", + "state": "Karnataka", + "country": "in" + }, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9972132594" + }, + "order_id": "order_E7q0tvRpC0WJwg", + "line_items": [ + { + "id": "li_E7q0tuPNg84VbZ", + "item_id": null, + "ref_id": null, + "ref_type": null, + "name": "Master Cloud Computing in 30 Days", + "description": "Book by Ravena Ravenclaw", + "amount": 399, + "unit_amount": 399, + "gross_amount": 399, + "tax_amount": 0, + "taxable_amount": 399, + "net_amount": 399, + "currency": "INR", + "type": "invoice", + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "unit": null, + "quantity": 1, + "taxes": [] + } + ], + "payment_id": null, + "status": "cancelled", + "expire_by": null, + "issued_at": 1579765167, + "paid_at": null, + "cancelled_at": 1579768206, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1579765167, + "terms": null, + "partial_payment": false, + "gross_amount": 399, + "tax_amount": 0, + "taxable_amount": 399, + "amount": 399, + "amount_paid": 0, + "amount_due": 399, + "currency": "INR", + "currency_symbol": "₹", + "description": null, + "notes": [], + "comment": null, + "short_url": "https://rzp.io/i/2wxV8Xs", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "invoice", + "group_taxes_discounts": false, + "created_at": 1579765167, + "idempotency_key": null +} +``` +------------------------------------------------------------------------------------------------------- + +### Send notification + +```py +client.invoice.notify_by(invoiceId,medium) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be notified | +| medium* | string | `sms`/`email`, Medium through which notification should be sent. | + +**Response:** +```json +{ + "success": true +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/invoices)** \ No newline at end of file diff --git a/documents/items.md b/documents/items.md new file mode 100644 index 00000000..17ef35ae --- /dev/null +++ b/documents/items.md @@ -0,0 +1,169 @@ +## items + +### Create item + +```py +client.item.create({ + "name": "Book / English August", + "description": "An indian story, Booker prize winner.", + "amount": 20000, + "currency": "INR" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| name* | string | Name of the item. | +| description | string | A brief description of the item. | +| amount | integer | Amount of the order to be paid | +| currency | string | Currency of the order. Currently only `INR` is supported. | + +**Response:** +```json +{ + "id": "item_7Oxp4hmm6T4SCn", + "active": true, + "name": "Book / English August", + "description": "An indian story, Booker prize winner.", + "amount": 20000, + "currency": "INR" +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch all items + +```py +client.item.all(options) +``` +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the item were created | +| to | timestamp | timestamp before which the item were created | +| count | integer | number of item to fetch (default: 10) | +| skip | integer | number of item to be skipped (default: 0) | +| name | string | Name of the item. | +| description | string | A brief description of the item. | +| amount | integer | Amount of the order to be paid | +| currency | string | Currency of the order. Currently only `INR` is supported. | +| active | boolean | Possible values is `0` or `1` | + +**Response:** +```json +{ + "entity": "collection", + "count": 3, + "items": [ + { + "id": "item_7Oy8OMV6BdEAac", + "active": true, + "name": "Book / Ignited Minds", + "description": null, + "amount": 15000, + "currency": "INR" + }, + { + "id": "item_7Oxp4hmm6T4SCn", + "active": true, + "name": "Book / English August", + "description": "An indian story, Booker prize winner.", + "amount": 20000, + "currency": "INR" + }, + { + "id": "item_7OxoGnoxCuUKbo", + "active": true, + "name": "Book / English August", + "description": null, + "amount": 20000, + "currency": "INR" + } + ] +} +``` +------------------------------------------------------------------------------------------------------- +### Fetch particular item + +```py +client.item.fetch(itemId) +``` +**Parameters** + +| Name | Type | Description | +|----------|--------|-------------------------------------| +| itemId* | string | The id of the item to be fetched | + +**Response:** +```json +{ + "id": "item_7Oxp4hmm6T4SCn", + "active": true, + "name": "Book / English August", + "description": "An indian story, Booker prize winner.", + "amount": 20000, + "currency": "INR" +} +``` + +------------------------------------------------------------------------------------------------------- + +### Update item + +```py +client.item.edit({ + "name": "Book / Ignited Minds - Updated name!", + "description": "New descirption too. :).", + "amount": 20000, + "currency": "INR", + "active": true +}) +``` +**Parameters** + +| Name | Type | Description | +|----------|--------|-------------------------------------| +| itemId* | string | The id of the item to be fetched | +| name | string | Name of the item. | +| description | string | A brief description of the item. | +| amount | integer | Amount of the order to be paid | +| currency | string | Currency of the order. Currently only `INR` is supported. | +| active | boolean | Possible values is `0` or `1` | + +**Response:** +```json +{ + "id": "item_7Oy8OMV6BdEAac", + "active": true, + "name": "Book / Ignited Minds - Updated name!", + "description": "New descirption too. :)", + "amount": 15000, + "currency": "INR" +} +``` +------------------------------------------------------------------------------------------------------- +### Delete item + +```py +client.item.delete(itemId) +``` +**Parameters** + +| Name | Type | Description | +|----------|--------|-------------------------------------| +| itemId* | string | The id of the item to be fetched | + +**Response:** +```json +[] +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/items)** \ No newline at end of file diff --git a/documents/order.md b/documents/order.md new file mode 100644 index 00000000..27ffa94e --- /dev/null +++ b/documents/order.md @@ -0,0 +1,212 @@ +## Orders + +### Create order + +```py +client.order.create({ + "amount": 50000, + "currency": "INR", + "receipt": "receipt#1", + "notes": { + "key1": "value3", + "key2": "value2" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | Amount of the order to be paid | +| currency* | string | Currency of the order. Currently only `INR` is supported. | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | + +**Response:** + +```json +{ + "id": "order_EKwxwAgItmmXdp", + "entity": "order", + "amount": 50000, + "amount_paid": 0, + "amount_due": 50000, + "currency": "INR", + "receipt": "receipt#1", + "offer_id": null, + "status": "created", + "attempts": 0, + "notes": [], + "created_at": 1582628071 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch all orders + +```py +client.order.all(option) +``` + +**Parameters** + +| Name | Type | Description | +|------------|-----------|--------------------------------------------------------------| +| from | timestamp | timestamp after which the orders were created | +| to | timestamp | timestamp before which the orders were created | +| count | integer | number of orders to fetch (default: 10) | +| skip | integer | number of orders to be skipped (default: 0) | +| authorized | boolean | Orders for which orders are currently in authorized state. | +| receipt | string | Orders with the provided value for receipt. | + +**Response:** + +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "order_EKzX2WiEWbMxmx", + "entity": "order", + "amount": 1234, + "amount_paid": 0, + "amount_due": 1234, + "currency": "INR", + "receipt": "Receipt No. 1", + "offer_id": null, + "status": "created", + "attempts": 0, + "notes": [], + "created_at": 1582637108 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch particular order + +```py +client.order.fetch(orderId) +``` +**Parameters** + +| Name | Type | Description | +|----------|--------|-------------------------------------| +| orderId* | string | The id of the order to be fetched | + +**Response:** + +```json +{ + "id":"order_DaaS6LOUAASb7Y", + "entity":"order", + "amount":2200, + "amount_paid":0, + "amount_due":2200, + "currency":"INR", + "receipt":"Receipt #211", + "status":"attempted", + "attempts":1, + "notes":[], + "created_at":1572505143 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch payments for an order + +```py +client.order.payment(orderId) +``` +**Parameters** + +| Name | Type | Description | +|----------|--------|-------------------------------------| +| orderId* | string | The id of the order to be retrieve payment info | + +**Response:** +```json +{ + "entity":"collection", + "count":1, + "items":[ + { + "id":"pay_DaaSOvhgcOfzgR", + "entity":"payment", + "amount":2200, + "currency":"INR", + "status":"captured", + "order_id":"order_DaaS6LOUAASb7Y", + "invoice_id":null, + "international":false, + "method":"card", + "amount_refunded":0, + "refund_status":null, + "captured":true, + "description":"Beans in every imaginable flavour", + "card_id":"card_DZon6fd8J3IcA2", + "bank":null, + "wallet":null, + "vpa":null, + "email":"gaurav.kumar@example.com", + "contact":"+919999999988", + "notes":[], + "fee":44, + "tax":0, + "error_code":null, + "error_description":null, + "created_at":1572505160 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Update order + +```py +client.order.edit({ + "notes": { + "key1": "value3", + "key2": "value2" + } +}) +``` +**Parameters** + +| Name | Type | Description | +|----------|--------|-------------------------------------| +| orderId* | string | The id of the order to be retrieve payment info | +| notes* | object | A key-value pair | + +**Response:** +```json +{ + "id":"order_DaaS6LOUAASb7Y", + "entity":"order", + "amount":2200, + "amount_paid":0, + "amount_due":2200, + "currency":"INR", + "receipt":"Receipt #211", + "offer_id":null, + "status":"attempted", + "attempts":1, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1572505143 +} +``` +------------------------------------------------------------------------------------------------------- + + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/orders/)** \ No newline at end of file diff --git a/documents/papernach.md b/documents/papernach.md new file mode 100644 index 00000000..a346f9d2 --- /dev/null +++ b/documents/papernach.md @@ -0,0 +1,679 @@ +## Paper NACH + +### Create customer +```py +client.customer.create({ + "name": "Gaurav Kumar", + "contact": 9123456780, + "email": "gaurav.kumar@example.com", + "fail_existing": 0, + "gstin": "29XAbbA4369J1PA", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| name* | string | Name of the customer | +| email | string | Email of the customer | +| contact | string | Contact number of the customer | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "cust_1Aa00000000003", + "entity": "customer", + "name": "Gaurav Kumar", + "email": "Gaurav.Kumar@example.com", + "contact": "9000000000", + "gstin": null, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1582033731 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create order + +```py +client.order.create({ + "amount": 0, + "currency": "INR", + "method": "emandate", + "customer_id": "cust_1Aa00000000001", + "receipt": "Receipt No. 1", + "notes": { + "notes_key_1": "Beam me up Scotty", + "notes_key_2": "Engage" + }, + "token": { + "auth_type": "netbanking", + "max_amount": 9999900, + "expire_at": 4102444799, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "bank_account": { + "beneficiary_name": "Gaurav Kumar", + "account_number": 1121431121541121, + "account_type": "savings", + "ifsc_code": "HDFC0000001" + } + } +}) +``` + +**Parameters:** +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | Amount of the order to be paid | +| currency* | string | Currency of the order. Currently only `INR` is supported. | +| method* | string | The authorization method. In this case the value will be `emandate` | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | +| token | object | A key-value pair | + +All parameters listed [here](https://razorpay.com/docs/api/route/#create-transfers-from-payments) are supported + +**Response:** +```json +{ + "id":"order_1Aa00000000001", + "entity":"order", + "amount":0, + "amount_paid":0, + "amount_due":0, + "currency":"INR", + "receipt":"rcptid #10", + "offer_id":null, + "offers":{ + "entity":"collection", + "count":0, + "items":[ + + ] + }, + "status":"created", + "attempts":0, + "notes":{ + "notes_key_1":"Beam me up Scotty", + "notes_key_2":"Engage" + }, + "created_at":1579775420, + "token":{ + "method":"nach", + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "recurring_status":null, + "failure_reason":null, + "currency":"INR", + "max_amount":10000000, + "auth_type":"physical", + "expire_at":1580480689, + "nach":{ + "create_form":true, + "form_reference1":"Recurring Payment for Gaurav Kumar", + "form_reference2":"Method Paper NACH", + "prefilled_form":"https://rzp.io/i/bitw", + "upload_form_url":"https://rzp.io/i/gts", + "description":"Paper NACH Gaurav Kumar" + }, + "bank_account":{ + "ifsc":"HDFC0000001", + "bank_name":"HDFC Bank", + "name":"Gaurav Kumar", + "account_number":"11214311215411", + "account_type":"savings", + "beneficiary_email":"gaurav.kumar@example.com", + "beneficiary_mobile":"9876543210" + }, + "first_payment_amount":0 + } +} +``` + +------------------------------------------------------------------------------------------------------- + +### Create an Authorization Payment + +Please refer this [doc](https://razorpay.com/docs/api/recurring-payments/paper-nach/authorization-transaction/#113-create-an-authorization-payment) for authorization payment + +------------------------------------------------------------------------------------------------------- + +### Create registration link + +```py +client.registration_link.create({ + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": 9123456780 + }, + "amount": 0, + "currency": "INR", + "type": "link", + "description": "12 p.m. Meals", + "subscription_registration": { + "method": "nach", + "auth_type": "physical", + "bank_account": { + "beneficiary_name": "Gaurav Kumar", + "account_number": 11214311215411, + "account_type": "savings", + "ifsc_code": "HDFC0001233" + }, + "nach": { + "form_reference1": "Recurring Payment for Gaurav Kumar", + "form_reference2": "Method Paper NACH" + }, + "expire_at": 1947483647, + "max_amount": 50000 + }, + "receipt": "Receipt No. 1", + "sms_notify": 1, + "email_notify": 1, + "expire_by": 1647483647, + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } +}) +``` + +**Parameters:** +All parameters listed [here](https://razorpay.com/docs/api/recurring-payments/paper-nach/authorization-transaction/#121-create-a-registration-link) are supported + +**Response:** +```json +{ + "id": "inv_FHrZiAubEzDdaq", + "entity": "invoice", + "receipt": "Receipt No. 1", + "invoice_number": "Receipt No. 1", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrZiBOkWHZPOp", + "line_items": [], + "payment_id": null, + "status": "issued", + "expire_by": 1647483647, + "issued_at": 1595491154, + "paid_at": null, + "cancelled_at": null, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1595491154, + "terms": null, + "partial_payment": false, + "gross_amount": 0, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 0, + "amount_paid": 0, + "amount_due": 0, + "currency": "INR", + "currency_symbol": "₹", + "description": "12 p.m. Meals", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/bzDYbNg", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491154, + "idempotency_key": null, + "token": { + "method": "nach", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "recurring_status": null, + "failure_reason": null, + "currency": "INR", + "max_amount": 50000, + "auth_type": "physical", + "expire_at": 1947483647, + "nach": { + "create_form": true, + "form_reference1": "Recurring Payment for Gaurav Kumar", + "form_reference2": "Method Paper NACH", + "prefilled_form": "https://rzp.io/i/exdIzYN", + "upload_form_url": "https://rzp.io/i/bzDYbNg", + "description": "12 p.m. Meals" + }, + "bank_account": { + "ifsc": "HDFC0001233", + "bank_name": "HDFC Bank", + "name": "Gaurav Kumar", + "account_number": "11214311215411", + "account_type": "savings", + "beneficiary_email": "gaurav.kumar@example.com", + "beneficiary_mobile": "9123456780" + }, + "first_payment_amount": 0 + }, + "nach_form_url": "https://rzp.io/i/exdIzYN" +} +``` +------------------------------------------------------------------------------------------------------- + +### Send/Resend notifications + +```py +client.invoice.notify_by(invoiceId, medium) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be notified | +| medium* | string | `sms`/`email`, Medium through which notification should be sent. | + +**Response:** +```json +{ + "success": true +} +``` +------------------------------------------------------------------------------------------------------- + +### Cancel a registration link + +```py +client.invoice.cancel(invoiceId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be cancelled | + +**Response:** +```json +{ + "id": "inv_FHrZiAubEzDdaq", + "entity": "invoice", + "receipt": "Receipt No. 27", + "invoice_number": "Receipt No. 27", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrZiBOkWHZPOp", + "line_items": [], + "payment_id": null, + "status": "cancelled", + "expire_by": 1647483647, + "issued_at": 1595491154, + "paid_at": null, + "cancelled_at": 1595491339, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1595491154, + "terms": null, + "partial_payment": false, + "gross_amount": 0, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 0, + "amount_paid": 0, + "amount_due": 0, + "currency": "INR", + "currency_symbol": "₹", + "description": "12 p.m. Meals", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/bzDYbNg", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491154, + "idempotency_key": null, + "token": { + "method": "nach", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "recurring_status": null, + "failure_reason": null, + "currency": "INR", + "max_amount": 50000, + "auth_type": "physical", + "expire_at": 1947483647, + "nach": { + "create_form": true, + "form_reference1": "Recurring Payment for Gaurav Kumar", + "form_reference2": "Method Paper NACH", + "prefilled_form": "https://rzp.io/i/tSYd5aV", + "upload_form_url": "https://rzp.io/i/bzDYbNg", + "description": "12 p.m. Meals" + }, + "bank_account": { + "ifsc": "HDFC0001233", + "bank_name": "HDFC Bank", + "name": "Gaurav Kumar", + "account_number": "11214311215411", + "account_type": "savings", + "beneficiary_email": "gaurav.kumar@example.com", + "beneficiary_mobile": "9123456780" + }, + "first_payment_amount": 0 + }, + "nach_form_url": "https://rzp.io/i/tSYd5aV" +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch Payment ID using Order ID + +```py +client.order.payment(orderId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| orderId* | string | Order id for which payment id need to be fetched | + +**Response:** +```json +{ + "entity":"collection", + "count":1, + "items":[ + { + "id":"pay_1Aa00000000003", + "entity":"payment", + "amount":0, + "currency":"INR", + "status":"captured", + "order_id":"order_1Aa00000000003", + "invoice_id":"inv_1Aa00000000003", + "international":false, + "method":"nach", + "amount_refunded":0, + "refund_status":null, + "captured":true, + "description":"12 p.m. Meals", + "card_id":null, + "bank":"HDFC", + "wallet":null, + "vpa":null, + "email":"gaurav.kumar@example.com", + "contact":"99876543210", + "customer_id":"cust_1Aa00000000002", + "token_id":"token_1Aa00000000003", + "notes":{ + "note_key 1":"Beam me up Scotty", + "note_key 2":"Tea. Earl Gray. Hot." + }, + "fee":0, + "tax":0, + "error_code":null, + "error_description":null, + "created_at":1580109147 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch token by payment ID + +```py +client.payment.fetch(paymentId) +``` + +**Parameters:** + +| Name | Type | Description | +|------------|--------|-----------------------------------| +| paymentId* | string | Id of the payment to be retrieved | + +**Response:** +```json +{ + "id": "pay_EnLNTjINiPkMEZ", + "entity": "payment", + "amount": 0, + "currency": "INR", + "status": "captured", + "order_id": "order_EnLLfglmKksr4K", + "invoice_id": "inv_EnLLfgCzRfcMuh", + "international": false, + "method": "nach", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "Invoice #inv_EnLLfgCzRfcMuh", + "card_id": null, + "bank": "UTIB", + "wallet": null, + "vpa": null, + "email": "gaurav.kumar@example.com", + "contact": "+919876543210", + "customer_id": "cust_DtHaBuooGHTuyZ", + "token_id": "token_EnLNTnn7uyRg5V", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": {}, + "created_at": 1588827564 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch tokens by customer ID + +```py +client.token.all(customerId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "token_EhYgIE3pOyMQpD", + "entity": "token", + "token": "3mQ5Czc6APNppI", + "bank": "HDFC", + "wallet": null, + "method": "nach", + "vpa": null, + "recurring": true, + "recurring_details": { + "status": "confirmed", + "failure_reason": null + }, + "auth_type": "physical", + "mrn": null, + "used_at": 1587564373, + "created_at": 1587564373, + "dcc_enabled": false + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete token + +```py +client.token.delete(customerId,tokenId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | + +**Response:** +```json +{ + "deleted": true +} +``` +------------------------------------------------------------------------------------------------------- + +### Create an order to charge the customer + +```py +client.order.create({ + "amount":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "notes": { + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | Amount of the order to be paid | +| currency* | string | Currency of the order. Currently only `INR` is supported. | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | +**Response:** +```json +{ + "id":"order_1Aa00000000002", + "entity":"order", + "amount":1000, + "amount_paid":0, + "amount_due":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "offer_id":null, + "status":"created", + "attempts":0, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1579782776 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create a Recurring Payment + +```py +client.payment.createRecurring({ + "email": "gaurav.kumar@example.com", + "contact": "9123456789", + "amount": 1000, + "currency": "INR", + "order_id": "order_1Aa00000000002", + "customer_id": "cust_1Aa00000000001", + "token": "token_1Aa00000000001", + "recurring": "1", + "description": "Creating recurring payment for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| email* | string | The customer's email address. | +| contact* | string | The customer's phone number. | +| amount* | integer | The amount you want to charge your customer. This should be the same as the amount in the order. | +| currency* | string | The 3-letter ISO currency code for the payment. Currently, only `INR` is supported. | +| order_id* | string | The unique identifier of the order created. | +| customer_id* | string | The `customer_id` for the customer you want to charge. | +| token* | string | The `token_id` generated when the customer successfully completes the authorization payment. Different payment instruments for the same customer have different `token_id`.| +| recurring* | string | Determines if recurring payment is enabled or not. Possible values:
* `1` - Recurring is enabled.* `0` - Recurring is not enabled.| +| description* | string | A user-entered description for the payment.| +| notes* | object | Key-value pair that can be used to store additional information about the entity. Maximum 15 key-value pairs, 256 characters (maximum) each. | + +**Response:** +```json +{ + "razorpay_payment_id" : "pay_1Aa00000000001", + "razorpay_order_id" : "order_1Aa00000000001", + "razorpay_signature" : "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d" +} +``` +------------------------------------------------------------------------------------------------------- + + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/recurring-payments/paper-nach/authorization-transaction/)** \ No newline at end of file diff --git a/documents/payment.md b/documents/payment.md new file mode 100644 index 00000000..b9addc4a --- /dev/null +++ b/documents/payment.md @@ -0,0 +1,444 @@ +## Payments + +### Capture payment + +```py +client.payment.capture(paymentId,{ + "amount" : 1000, + "currency" : "INR" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------|---------|--------------------------------------------------------------------------------| +| paymentId* | string | Id of the payment to capture | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency | string | The currency of the payment (defaults to INR) | + +**Response:** +```json +{ + "id": "pay_G8VQzjPLoAvm6D", + "entity": "payment", + "amount": 1000, + "currency": "INR", + "status": "captured", + "order_id": "order_G8VPOayFxWEU28", + "invoice_id": null, + "international": false, + "method": "upi", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "Purchase Shoes", + "card_id": null, + "bank": null, + "wallet": null, + "vpa": "gaurav.kumar@exampleupi", + "email": "gaurav.kumar@example.com", + "contact": "+919999999999", + "customer_id": "cust_DitrYCFtCIokBO", + "notes": [], + "fee": 24, + "tax": 4, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "rrn": "033814379298" + }, + "created_at": 1606985209 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all payments + +```py +client.payment.all(option) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 2, + "items": [ + { + "id": "pay_G8VaL2Z68LRtDs", + "entity": "payment", + "amount": 900, + "currency": "INR", + "status": "captured", + "order_id": "order_G8VXfKDWDEOHHd", + "invoice_id": null, + "international": false, + "method": "netbanking", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "Purchase Shoes", + "card_id": null, + "bank": "KKBK", + "wallet": null, + "vpa": null, + "email": "gaurav.kumar@example.com", + "contact": "+919999999999", + "customer_id": "cust_DitrYCFtCIokBO", + "notes": [], + "fee": 22, + "tax": 4, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "bank_transaction_id": "0125836177" + }, + "created_at": 1606985740 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch a payment + +```py +client.payment.fetch(paymentId) +``` + +**Parameters:** + +| Name | Type | Description | +|------------|--------|-----------------------------------| +| paymentId* | string | Id of the payment to be retrieved | + +**Response:** +```json +{ + "id": "pay_G8VQzjPLoAvm6D", + "entity": "payment", + "amount": 1000, + "currency": "INR", + "status": "captured", + "order_id": "order_G8VPOayFxWEU28", + "invoice_id": null, + "international": false, + "method": "upi", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "Purchase Shoes", + "card_id": null, + "bank": null, + "wallet": null, + "vpa": "gaurav.kumar@exampleupi", + "email": "gaurav.kumar@example.com", + "contact": "+919999999999", + "customer_id": "cust_DitrYCFtCIokBO", + "notes": [], + "fee": 24, + "tax": 4, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "rrn": "033814379298" + }, + "created_at": 1606985209 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch payments for an order + +```py +client.order.payment(orderId) +``` +**Parameters** + +| Name | Type | Description | +|----------|--------|-------------------------------------| +| orderId* | string | The id of the order to be retrieve payment info | + +**Response:** +```json +{ + "count": 1, + "entity": "collection", + "items": [ + { + "id": "pay_DovGQXOkPBJjjU", + "entity": "payment", + "amount": 600, + "currency": "INR", + "status": "captured", + "order_id": "order_DovFx48wjYEr2I", + "method": "netbanking", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "A Wild Sheep Chase is a novel by Japanese author Haruki Murakami", + "card_id": null, + "bank": "SBIN", + "wallet": null, + "vpa": null, + "email": "gaurav.kumar@example.com", + "contact": "9364591752", + "fee": 70, + "tax": 10, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "notes": [], + "acquirer_data": { + "bank_transaction_id": "0125836177" + }, + "created_at": 1400826750 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Update a payment + +```py +client.payment.edit(paymentId,{ + "notes": { + "key1": "value1", + "key2": "value2" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|---------|--------------------------------------| +| paymentId* | string | Id of the payment to update | +| notes* | object | A key-value pair | + +**Response:** +```json +{ + "id": "pay_CBYy6tLmJTzn3Q", + "entity": "payment", + "amount": 1000, + "currency": "INR", + "status": "authorized", + "order_id": null, + "invoice_id": null, + "international": false, + "method": "netbanking", + "amount_refunded": 0, + "refund_status": null, + "captured": false, + "description": null, + "card_id": null, + "bank": "UTIB", + "wallet": null, + "vpa": null, + "email": "testme@acme.com", + "notes": { + "key1": "value1", + "key2": "value2" + }, + "fee": null, + "tax": null, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "bank_transaction_id": "0125836177" + }, + "created_at": 1553504328 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch expanded card or emi details for payments + +Request #1: Card + +```py +client.payment.all({'expand[]':'card'}) +``` + +Request #2: EMI + +```py +client.payment.all({'expand[]':'emi'}) +``` + +**Response:**
+For expanded card or emi details for payments response please click [here](https://razorpay.com/docs/api/payments/#fetch-expanded-card-or-emi-details-for-payments) + +------------------------------------------------------------------------------------------------------- + +### Fetch card details with paymentId + +```py +client.payment.fetchCardDetails(paymentId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|---------|--------------------------------------| +| paymentId* | string | Id of the payment to update | + +**Response:** +```json +{ + "id": "card_6krZ6bcjoeqyV9", + "entity": "card", + "name": "Gaurav", + "last4": "3335", + "network": "Visa", + "type": "debit", + "issuer": "SBIN", + "international": false, + "emi": null, + "sub_type": "business" +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch Payment Downtime Details + +```py +client.payment.fetchPaymentDowntime() +``` +**Response:**
+For payment downtime response please click [here](https://razorpay.com/docs/api/payments/downtime/#fetch-payment-downtime-details) + +------------------------------------------------------------------------------------------------------- + +### Fetch Payment Downtime + +```py +client.payment.fetchPaymentDowntimeById(downtimeId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|---------|--------------------------------------| +| downtimeId* | string | Id to fetch payment downtime | + +**Response:** +For payment downtime by id response please click [here](https://razorpay.com/docs/api/payments/downtime/#fetch-payment-downtime-details-by-id) +------------------------------------------------------------------------------------------------------- + +### Payment capture settings API + +```py +client.order.create({ + 'amount':50000, + 'currency': 'INR', + 'receipt': 'rcptid_11', + 'payment': { + 'capture': 'automatic', + 'capture_options': { + 'automatic_expiry_period': 12, + 'manual_expiry_period': 7200, + 'refund_speed': 'optimum' + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|---------|--------------------------------------| +| amount* | integer | Amount of the order to be paid | +| currency* | string | Currency of the order. Currently only `INR` is supported. | +| receipt | string | Your system order reference id. | +| payment | object | please refer this [doc](https://razorpay.com/docs/payments/payments/capture-settings/api/) for params | + +**Response:**
+```json +{ + "id": "order_DBJOWzybf0sJbb", + "entity": "order", + "amount": 50000, + "amount_paid": 0, + "amount_due": 50000, + "currency": "INR", + "receipt": "rcptid_11", + "status": "created", + "attempts": 0, + "notes": [], + "created_at": 1566986570 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create Payment Json + +```py +client.payment.createPaymentJson({ + "amount": 100, + "currency": "INR", + "order_id": "order_EAkbvXiCJlwhHR", + "email": "gaurav.kumar@example.com", + "contact": 9090909090, + "method": "card", + "card":{ + "number": 4111111111111111, + "name": "Gaurav", + "expiry_month": 11, + "expiry_year": 23, + "cvv": 100 + } +}) +``` + +**Parameters:** + please refer this [doc](https://razorpay.com/docs/payment-gateway/s2s-integration/payment-methods/) for params + +**Response:**
+```json +{ + "razorpay_payment_id": "pay_FVmAstJWfsD3SO", + "next": [ + { + "action": "redirect", + "url": "https://api.razorpay.com/v1/payments/FVmAtLUe9XZSGM/authorize" + }, + { + "action": "otp_generate", + "url": "https://api.razorpay.com/v1/payments/pay_FVmAstJWfsD3SO/otp_generate?track_id=FVmAtLUe9XZSGM&key_id=" + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/payments/)** \ No newline at end of file diff --git a/documents/paymentLink.md b/documents/paymentLink.md new file mode 100644 index 00000000..afa6e3d7 --- /dev/null +++ b/documents/paymentLink.md @@ -0,0 +1,971 @@ +## Payment Links + +### Create payment link + +Request #1 +Standard Payment Link + +```py +client.payment_link.create({ + "amount": 500, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "description": "For XYZ purpose", + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "+919999999999" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "notes": { + "policy_name": "Jeevan Bima" + }, + "callback_url": "https://example-callback-url.com/", + "callback_method": "get" +}) +``` + +Request #2 +UPI Payment Link + +```py +client.payment_link.create({ + "upi_link": true, + "amount": 500, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "description": "For XYZ purpose", + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "+919999999999" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "notes": { + "policy_name": "Jeevan Bima" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|upi_link* | boolean | boolean Must be set to true // to creating UPI Payment Link only | +|amount* | integer | Amount to be paid using the Payment Link. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|description | string | A brief description of the Payment Link | +|reference_id | string | AReference number tagged to a Payment Link. | +|customer | object | name, email, contact | +|expire_by | integer | Timestamp, in Unix, at which the Payment Link will expire. By default, a Payment Link will be valid for six months from the date of creation. | +|notify | object | sms or email (boolean) | +|notes | json object | Key-value pair that can be used to store additional information about the entity. Maximum 15 key-value pairs, 256 characters (maximum) each. For example, "note_key": "Beam me up Scotty” | + +**Response:** +For create payment link response please click [here](https://razorpay.com/docs/api/payment-links/#create-payment-link) + +------------------------------------------------------------------------------------------------------- + +### Fetch all payment link + +```py +client.payment_link.all() +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|payment_id | string | Unique identifier of the payment associated with the Payment Link. | +|reference_id | string | The unique reference number entered by you while creating the Payment Link. | + +**Response:** +For fetch all payment link response please click [here](https://razorpay.com/docs/api/payment-links/#all-payment-links) + +------------------------------------------------------------------------------------------------------- + +### Fetch specific payment link + +```py +client.payment_link.fetch(paymentLinkId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| paymentLinkId* | string | Unique identifier of the Payment Link. | + +**Response:** +For fetch specific payment link response please click [here](https://razorpay.com/docs/api/payment-links/#specific-payment-links-by-id) + +------------------------------------------------------------------------------------------------------- + +### Update payment link + +```py +client.payment_link.edit({ + "reference_id": "TS35", + "expire_by": 1653347540, + "reminder_enable":false, + "notes":{ + "policy_name": "Jeevan Saral" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| paymentLinkId* | string | The unique identifier of the Payment Link that needs to be updated. | +| accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values: true - Customer can make partial payments. false (default) - Customer cannot make partial payments. | +| reference_id | string | Adds a unique reference number to an existing link. | +| expire_by | integer | Timestamp, in Unix format, when the payment links should expire. | +| notes | string | object Key-value pair that can be used to store additional information about the entity. Maximum 15 key-value pairs, 256 characters (maximum) each. For example, "note_key": "Beam me up Scotty”. | + +**Response:** +For updating payment link response please click [here](https://razorpay.com/docs/api/payment-links/#update-payment-link) + +------------------------------------------------------------------------------------------------------- + +### Cancel a payment link + +```py +client.payment_link.cancel(paymentLinkId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| paymentLinkId* | string | Unique identifier of the Payment Link. | + +**Response:** +For canceling payment link response please click [here](https://razorpay.com/docs/api/payment-links/#cancel-payment-link) +------------------------------------------------------------------------------------------------------- + +### Send notification + +```py +client.payment_link.notifyBy(paymentLinkId, medium) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| paymentLinkId* | string | Unique identifier of the Payment Link that should be resent. | +| medium* | string | `sms`/`email`,Medium through which the Payment Link must be resent. Allowed values are: | + +**Response:** +```json +{ + "success": true +} +``` +------------------------------------------------------------------------------------------------------- + +### Transfer payments received using payment links + +```py +client.payment_link.create({ + "amount": 20000, + "currency": "INR", + "accept_partial": false, + "description": "For XYZ purpose", + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "+919999999999" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "options": { + "order": [ + { + "account": "acc_CNo3jSI8OkFJJJ", + "amount": 500, + "currency": "INR", + "notes": { + "branch": "Acme Corp Bangalore North", + "name": "Saurav Kumar", + "linked_account_notes": [ + "branch" + ] + } + } + ] + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|options* | array | Options to configure the transfer in the Payment Link. Parent parameter under which the order child parameter must be passed. | + +**Response:** +```json +{ + "accept_partial": false, + "amount": 1500, + "amount_paid": 0, + "callback_method": "", + "callback_url": "", + "cancelled_at": 0, + "created_at": 1596526969, + "currency": "INR", + "customer": { + "contact": "+919999999999", + "email": "gaurav.kumar@example.com", + "name": "Gaurav Kumar" + }, + "deleted_at": 0, + "description": "Payment for policy no #23456", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 0, + "id": "plink_FMbhpT6nqDjDei", + "notes": null, + "notify": { + "email": true, + "sms": true + }, + "payments": null, + "reference_id": "#aasasw8", + "reminder_enable": true, + "reminders": [], + "short_url": "https://rzp.io/i/ORor1MT", + "source": "", + "source_id": "", + "status": "created", + "updated_at": 1596526969, + "user_id": "" +} +``` +------------------------------------------------------------------------------------------------------- + +### Offers on payment links + +```py +client.payment_link.create({ + "amount": 3400, + "currency": "INR", + "accept_partial": false, + "reference_id": "#425", + "description": "Payment for policy no #23456", + "customer": { + "name": "Gaurav Kumar", + "contact": "+919999999999", + "email": "gaurav.kumar@example.com" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": false, + "options": { + "order": { + "offers": [ + "offer_F4WMTC3pwFKnzq", + "offer_F4WJHqvGzw8dWF" + ] + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|description | string | A brief description of the Payment Link | +|reference_id | string | AReference number tagged to a Payment Link. | +|customer | array | name, email, contact | +|expire_by | integer | Timestamp, in Unix, at which the Payment Link will expire. By default, a Payment Link will be valid for six months from the date of creation. | +|notify | object | sms or email (boolean) | +|options* | array | Options to associate the offer_id with the Payment Link. Parent parameter under which the order child parameter must be passed. | + +**Response:** +```json +{ + "accept_partial": false, + "amount": 3400, + "amount_paid": 0, + "cancelled_at": 0, + "created_at": 1600183040, + "currency": "INR", + "customer": { + "contact": "+919999999999", + "email": "gaurav.kumar@example.com", + "name": "Gaurav Kumar" + }, + "description": "Payment for policy no #23456", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 0, + "id": "plink_FdLt0WBldRyE5t", + "notes": null, + "notify": { + "email": true, + "sms": true + }, + "payments": null, + "reference_id": "#425", + "reminder_enable": false, + "reminders": [], + "short_url": "https://rzp.io/i/CM5ohDC", + "status": "created", + "user_id": "" +} +``` +------------------------------------------------------------------------------------------------------- + +### Managing reminders for payment links + +```py +client.payment_link.create({ + "amount": 1000, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "reference_id": "#425", + "description": "Payment for policy no #23456", + "customer": { + "name": "Gaurav Kumar", + "contact": "+919999999999", + "email": "gaurav.kumar@example.com" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": false +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values:true - Customer can make partial payments.false (default) - Customer cannot make partial payments. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|description | string | A brief description of the Payment Link | +|customer | object | name, email, contact | +|expire_by | integer | Timestamp, in Unix, at which the Payment Link will expire. By default, a Payment Link will be valid for six months from the date of creation. | +|notify | object | sms or email (boolean) | +|reminder_enable | boolean | To disable reminders for a Payment Link, pass reminder_enable as false | + +**Response:** +```json +{ + "amount": 340000, + "amount_due": 340000, + "amount_paid": 0, + "billing_end": null, + "billing_start": null, + "cancelled_at": null, + "comment": null, + "created_at": 1592579126, + "currency": "INR", + "currency_symbol": "₹", + "customer_details": { + "billing_address": null, + "contact": "9900990099", + "customer_contact": "9900990099", + "customer_email": "gaurav.kumar@example.com", + "customer_name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "gstin": null, + "id": "cust_F4WNtqj1xb0Duv", + "name": "Gaurav Kumar", + "shipping_address": null + }, + "customer_id": "cust_F4WNtqj1xb0Duv", + "date": 1592579126, + "description": "Salon at Home Service", + "email_status": null, + "entity": "invoice", + "expire_by": 1608390326, + "expired_at": null, + "first_payment_min_amount": 0, + "gross_amount": 340000, + "group_taxes_discounts": false, + "id": "inv_F4WfpZLk1ct35b", + "invoice_number": null, + "issued_at": 1592579126, + "line_items": [], + "notes": [], + "order_id": "order_F4WfpxUzWmYOTl", + "paid_at": null, + "partial_payment": false, + "payment_id": null, + "receipt": "5757", + "reminder_enable": false, + "short_url": "https://rzp.io/i/vitLptM", + "sms_status": null, + "status": "issued", + "tax_amount": 0, + "taxable_amount": 0, + "terms": null, + "type": "link", + "user_id": "", + "view_less": true +} +``` +------------------------------------------------------------------------------------------------------- + +### Rename labels in checkout section + +```py +client.payment_link.create({ + "amount": 500, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "description": "For XYZ purpose", + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "+919999999999" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "options": { + "checkout": { + "partial_payment": { + "min_amount_label": "Minimum Money to be paid", + "partial_amount_label": "Pay in parts", + "partial_amount_description": "Pay at least ₹100", + "full_amount_label": "Pay the entire amount" + } + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values:true - Customer can make partial payments.false (default) - Customer cannot make partial payments. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|description | string | A brief description of the Payment Link | +|customer | object | name, email, contact | +|expire_by | integer | Timestamp, in Unix, at which the Payment Link will expire. By default, a Payment Link will be valid for six months from the date of creation. | +|notify | object | sms or email (boolean) | +|reminder_enable | boolean | To disable reminders for a Payment Link, pass reminder_enable as false | +|options* | object | Options to rename the labels for partial payment fields in the checkout form. Parent parameter under which the checkout and partial_payment child parameters must be passed. | + +**Response:** +```json +{ + "accept_partial": true, + "amount": 1000, + "amount_paid": 0, + "callback_method": "", + "callback_url": "", + "cancelled_at": 0, + "created_at": 1596193199, + "currency": "INR", + "customer": { + "contact": "+919999999999", + "email": "gaurav.kumar@example.com", + "name": "Gaurav Kumar" + }, + "deleted_at": 0, + "description": "Payment for policy no #23456", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 100, + "id": "plink_FL4vbXVKfW7PAz", + "notes": null, + "notify": { + "email": true, + "sms": true + }, + "payments": null, + "reference_id": "#42321", + "reminder_enable": true, + "reminders": [], + "short_url": "https://rzp.io/i/F4GC9z1", + "source": "", + "source_id": "", + "status": "created", + "updated_at": 1596193199, + "user_id": "" +} +``` +------------------------------------------------------------------------------------------------------- + +### Change Business name + +```py +client.payment_link.create({ + "amount": 1000, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "reference_id": "#2234542", + "description": "Payment for policy no #23456", + "customer": { + "name": "Gaurav Kumar", + "contact": "+919999999999", + "email": "gaurav.kumar@example.com" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "options": { + "checkout": { + "name": "Lacme Corp" + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values:true - Customer can make partial payments.false (default) - Customer cannot make partial payments. | +|first_min_partial_amount | integer | | +|description | string | A brief description of the Payment Link | +|customer | object | name, email, contact | +|notify | object | sms or email (boolean) | +|reminder_enable | boolean | To disable reminders for a Payment Link, pass reminder_enable as false | +|options* | object | Option to customize the business name. Parent parameter under which the checkout child parameter must be passed.| + +**Response:** +```json +{ + "accept_partial": true, + "amount": 1000, + "amount_paid": 0, + "callback_method": "", + "callback_url": "", + "cancelled_at": 0, + "created_at": 1596187657, + "currency": "INR", + "customer": { + "contact": "+919999999999", + "email": "gaurav.kumar@example.com", + "name": "Gaurav Kumar" + }, + "description": "Payment for policy no #23456", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 100, + "id": "plink_FL3M2gJFs1Jkma", + "notes": null, + "notify": { + "email": true, + "sms": true + }, + "payments": null, + "reference_id": "#2234542", + "reminder_enable": true, + "reminders": [], + "short_url": "https://rzp.io/i/at2OOsR", + "source": "", + "source_id": "", + "status": "created", + "updated_at": 1596187657, + "user_id": "" +} +``` +------------------------------------------------------------------------------------------------------- + +### Prefill checkout fields + +```py +client.payment_link.create({ + "amount": 1000, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "reference_id": "#417", + "description": "Payment for policy no #23456", + "customer": { + "name": "Gaurav Kumar", + "contact": "+919999999999", + "email": "gaurav.kumar@example.com" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "options": { + "checkout": { + "prefill": { + "method": "card", + "card[name]": "Gaurav Kumar", + "card[number]": "4111111111111111", + "card[expiry]": "12/21", + "card[cvv]": "123" + } + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values:true - Customer can make partial payments.false (default) - Customer cannot make partial payments. | +|first_min_partial_amount | integer | | +|description | string | A brief description of the Payment Link | +|customer | object | name, email, contact | +|notify | object | sms or email (boolean) | +|reminder_enable | boolean | To disable reminders for a Payment Link, pass reminder_enable as false | +|options* | array | Options to customize Checkout. Parent parameter under which the checkout and prefill child parameters must be passed.| + +**Response:** +For prefill checkout fields response please click [here](https://razorpay.com/docs/payment-links/api/new/advanced-options/customize/prefill/) + +------------------------------------------------------------------------------------------------------- + +### Customize payment methods + +```py +client.payment_link.create({ + "amount": 500, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "description": "For XYZ purpose", + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "+919999999999" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "options": { + "checkout": { + "method": { + "netbanking": "1", + "card": "1", + "upi": "0", + "wallet": "0" + } + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values:true - Customer can make partial payments.false (default) - Customer cannot make partial payments. | +|first_min_partial_amount | integer | | +|description | string | A brief description of the Payment Link | +|customer | object | name, email, contact | +|notify | object | sms or email (boolean) | +|reminder_enable | boolean | To disable reminders for a Payment Link, pass reminder_enable as false | +|options* | object | Options to display or hide payment methods on the Checkout section. Parent parameter under which the checkout and method child parameters must be passed.| + +**Response:** +```json +{ + "accept_partial": true, + "amount": 1000, + "amount_paid": 0, + "callback_method": "", + "callback_url": "", + "cancelled_at": 0, + "created_at": 1596188371, + "currency": "INR", + "customer": { + "contact": "+919999999999", + "email": "gaurav.kumar@example.com", + "name": "Gaurav Kumar" + }, + "deleted_at": 0, + "description": "Payment for policy no #23456", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 100, + "id": "plink_FL3YbdvN2Cj6gh", + "notes": null, + "notify": { + "email": true, + "sms": true + }, + "payments": null, + "reference_id": "#543422", + "reminder_enable": true, + "reminders": [], + "short_url": "https://rzp.io/i/wKiXKud", + "source": "", + "source_id": "", + "status": "created", + "updated_at": 1596188371, + "user_id": "" +} +``` +------------------------------------------------------------------------------------------------------- + +### Set checkout fields as read-only + +```py +client.payment_link.create({ + "amount": 1000, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "reference_id": "#20", + "description": "Payment for policy no #23456", + "customer": { + "name": "Gaurav Kumar", + "contact": "+919999999999", + "email": "gaurav.kumar@example.com" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "options": { + "checkout": { + "readonly": { + "email": "1", + "contact": "1" + } + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values:true - Customer can make partial payments.false (default) - Customer cannot make partial payments. | +|first_min_partial_amount | integer | | +|description | string | A brief description of the Payment Link | +|customer | object | name, email, contact | +|notify | object | sms or email (boolean) | +|reminder_enable | boolean | To disable reminders for a Payment Link, pass reminder_enable as false | +|options* | object | Options to set contact and email as read-only fields on Checkout. Parent parameter under which the checkout and readonly child parameters must be passed.| + +**Response:** +```json +{ + "accept_partial": true, + "amount": 1000, + "amount_paid": 0, + "callback_method": "", + "callback_url": "", + "cancelled_at": 0, + "created_at": 1596190845, + "currency": "INR", + "customer": { + "contact": "+919999999999", + "email": "gaurav.kumar@example.com", + "name": "Gaurav Kumar" + }, + "deleted_at": 0, + "description": "Payment for policy no #23456", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 100, + "id": "plink_FL4GA1t6FBcaVR", + "notes": null, + "notify": { + "email": true, + "sms": true + }, + "payments": null, + "reference_id": "#19129", + "reminder_enable": true, + "reminders": [], + "short_url": "https://rzp.io/i/QVwUglR", + "source": "", + "source_id": "", + "status": "created", + "updated_at": 1596190845, + "user_id": "" +} +``` +------------------------------------------------------------------------------------------------------- + +### Implement thematic changes in payment links checkout section + +```py +client.payment_link.create({ + "amount": 1000, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "reference_id": "#423212", + "description": "Payment for policy no #23456", + "customer": { + "name": "Gaurav Kumar", + "contact": "+919999999999", + "email": "gaurav.kumar@example.com" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "options": { + "checkout": { + "theme": { + "hide_topbar": true + } + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values:true - Customer can make partial payments.false (default) - Customer cannot make partial payments. | +|first_min_partial_amount | integer | | +|description | string | A brief description of the Payment Link | +|customer | object | name, email, contact | +|notify | object | sms or email (boolean) | +|reminder_enable | boolean | To disable reminders for a Payment Link, pass reminder_enable as false | +|options* | object | Options to show or hide the top bar. Parent parameter under which the checkout and theme child parameters must be passed.| + +**Response:** +```json +{ + "accept_partial": true, + "amount": 1000, + "amount_paid": 0, + "callback_method": "", + "callback_url": "", + "cancelled_at": 0, + "created_at": 1596187814, + "currency": "INR", + "customer": { + "contact": "+919999999999", + "email": "gaurav.kumar@example.com", + "name": "Gaurav Kumar" + }, + "description": "Payment for policy no #23456", + "expire_by": 0, + "expired_at": 0, + "first_min_partial_amount": 100, + "id": "plink_FL3Oncr7XxXFf6", + "notes": null, + "notify": { + "email": true, + "sms": true + }, + "payments": null, + "reference_id": "#423212", + "reminder_enable": true, + "reminders": [], + "short_url": "https://rzp.io/i/j45EmLE", + "source": "", + "source_id": "", + "status": "created", + "updated_at": 1596187814, + "user_id": "" +} +``` +------------------------------------------------------------------------------------------------------- + +### Rename labels in payment details section + +```py +client.payment_link.create({ + "amount": 1000, + "currency": "INR", + "accept_partial": true, + "first_min_partial_amount": 100, + "reference_id": "#421", + "description": "Payment for policy no #23456", + "customer": { + "name": "Gaurav Kumar", + "contact": "+919999999999", + "email": "gaurav.kumar@example.com" + }, + "notify": { + "sms": true, + "email": true + }, + "reminder_enable": true, + "options": { + "checkout": { + "partial_payment": { + "min_amount_label": "Minimum Money to be paid", + "partial_amount_label": "Pay in parts", + "partial_amount_description": "Pay at least ₹100", + "full_amount_label": "Pay the entire amount" + } + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +|amount* | integer | Amount to be paid using the Payment Link. | +|currency | string | A three-letter ISO code for the currency in which you want to accept the payment. For example, INR. | +|accept_partial | boolean | Indicates whether customers can make partial payments using the Payment Link. Possible values:true - Customer can make partial payments.false (default) - Customer cannot make partial payments. | +|first_min_partial_amount | integer | | +|description | string | A brief description of the Payment Link | +|customer | object | name, email, contact | +|notify | object | sms or email (boolean) | +|reminder_enable | boolean | To disable reminders for a Payment Link, pass reminder_enable as false | +|options* | object | Parent parameter under which the hosted_page and label child parameters must be passed.| + +**Response:** +For rename labels in payment details section response please click [here](https://razorpay.com/docs/payment-links/api/new/advanced-options/customize/rename-payment-details-labels/) + +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/payment-links/)** \ No newline at end of file diff --git a/documents/paymentVerfication.md b/documents/paymentVerfication.md new file mode 100644 index 00000000..babb3f39 --- /dev/null +++ b/documents/paymentVerfication.md @@ -0,0 +1,71 @@ +## payment verification + + +### Verify payment verification + +```py +client.utility.verify_payment_signature({ + 'razorpay_order_id': razorpay_order_id, + 'razorpay_payment_id': razorpay_payment_id, + 'razorpay_signature': razorpay_signature + }) +``` + +**Parameters:** + + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| razorpay_order_id* | string | The id of the order to be fetched | +| razorpay_payment_id* | string | The id of the payment to be fetched | +| razorpay_signature* | string | Signature returned by the Checkout. This is used to verify the payment. | + +------------------------------------------------------------------------------------------------------- +### Verify subscription verification + +```py +client.utility.verify_subscription_payment_signature({ + 'razorpay_subscription_id': razorpay_order_id, + 'razorpay_payment_id': razorpay_payment_id, + 'razorpay_signature': razorpay_signature + }) +``` + +**Parameters:** + + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| razorpay_subscription_id* | string | The id of the subscription to be fetched | +| razorpay_payment_id* | string | The id of the payment to be fetched | +| razorpay_signature* | string | Signature returned by the Checkout. This is used to verify the payment. | + +------------------------------------------------------------------------------------------------------- +### Verify paymentlink verification + +```py +client.utility.verify_payment_link_signature({ + 'payment_link_id': payment_link_id, + 'payment_link_reference_id': payment_link_reference_id, + 'payment_link_status':payment_link_status, + 'razorpay_payment_id': razorpay_payment_id, + 'razorpay_signature': razorpay_signature + }) +``` + +**Parameters:** + + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| payment_link_id* | string | The id of the paymentlink to be fetched | +| razorpay_payment_id* | string | The id of the payment to be fetched | +| payment_link_reference_id* | string | A reference number tagged to a Payment Link | +| payment_link_status* | string | Current status of the link | +| razorpay_signature* | string | Signature returned by the Checkout. This is used to verify the payment. | + +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
\ No newline at end of file diff --git a/documents/plans.md b/documents/plans.md new file mode 100644 index 00000000..99ebc869 --- /dev/null +++ b/documents/plans.md @@ -0,0 +1,172 @@ +## Plans + +### Create plan + +```py +client.plan.create({ + "period": "weekly", + "interval": 1, + "item": { + "name": "Test plan - Weekly", + "amount": 69900, + "currency": "INR", + "description": "Description for the test plan" + }, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| period* | string | Used together with `interval` to define how often the customer should be charged.Possible values:
1.`daily`
2.`weekly`
3.`monthly`
4.`yearly` | +| interval* | string | Used together with `period` to define how often the customer should be charged | +| items* | array | Details of the plan. For more details please refer [here](https://razorpay.com/docs/api/subscriptions/#create-a-plan) | +| notes | array | Notes you can enter for the contact for future reference. | + +**Response:** +```json +{ + "id":"plan_00000000000001", + "entity":"plan", + "interval":1, + "period":"weekly", + "item":{ + "id":"item_00000000000001", + "active":true, + "name":"Test plan - Weekly", + "description":"Description for the test plan - Weekly", + "amount":69900, + "unit_amount":69900, + "currency":"INR", + "type":"plan", + "unit":null, + "tax_inclusive":false, + "hsn_code":null, + "sac_code":null, + "tax_rate":null, + "tax_id":null, + "tax_group_id":null, + "created_at":1580219935, + "updated_at":1580219935 + }, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1580219935 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all plans + +```py +client.plan.all(options) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "plan_00000000000001", + "entity": "plan", + "interval": 1, + "period": "weekly", + "item": { + "id": "item_00000000000001", + "active": true, + "name": "Test plan - Weekly", + "description": "Description for the test plan - Weekly", + "amount": 69900, + "unit_amount": 69900, + "currency": "INR", + "type": "plan", + "unit": null, + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "tax_id": null, + "tax_group_id": null, + "created_at": 1580220492, + "updated_at": 1580220492 + }, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1580220492 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch particular plan + +```py +client.plan.fetch(planId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| planId | string | The id of the plan to be fetched | + +**Response:** +```json +{ + "id":"plan_00000000000001", + "entity":"plan", + "interval":1, + "period":"weekly", + "item":{ + "id":"item_00000000000001", + "active":true, + "name":"Test plan - Weekly", + "description":"Description for the test plan - Weekly", + "amount":69900, + "unit_amount":69900, + "currency":"INR", + "type":"plan", + "unit":null, + "tax_inclusive":false, + "hsn_code":null, + "sac_code":null, + "tax_rate":null, + "tax_id":null, + "tax_group_id":null, + "created_at":1580220492, + "updated_at":1580220492 + }, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1580220492 +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/subscriptions/#plans)** \ No newline at end of file diff --git a/documents/qrcode.md b/documents/qrcode.md new file mode 100644 index 00000000..7ef09181 --- /dev/null +++ b/documents/qrcode.md @@ -0,0 +1,413 @@ +## Qr Codes + +### Create Qr code + +```py +client.qrcode.create({ + "type": "upi_qr", + "name": "Store_1", + "usage": "single_use", + "fixed_amount": true, + "payment_amount": 300, + "description": "For Store 1", + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "notes": { + "purpose": "Test UPI QR code notes" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| type* | string | The type of QR code i.e, `upi_qr`/`bharat_qr` | +| name | string | Label entered to identify the QR code. | +| usage* | string | Indicates if the QR code should be allowed to accept single payment or multiple payments i.e, `single_use`/`multiple_use` | +| fixed_amount | boolean | Indicates if the QR should accept payments of specific amounts or any amount. | +| payment_amount(* mandatory if fixed_amount is true) | integer | Indicates if the QR should accept payments of specific amounts or any amount. | +| customer_id | string | Unique identifier of the customer the QR code is linked with | +| description | string | A brief description about the QR code. | +| close_by | integer | UNIX timestamp at which the QR code is scheduled to be automatically closed. The time must be at least 15 minutes after the current time. | +| notes | object | Key-value pair that can be used to store additional information about the QR code. Maximum 15 key-value pairs, 256 characters (maximum) each. | + +**Response:** +```json +{ + "id": "qr_HMsVL8HOpbMcjU", + "entity": "qr_code", + "created_at": 1623660301, + "name": "Store_1", + "usage": "single_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/BWcUVrLp", + "payment_amount": 300, + "status": "active", + "description": "For Store 1", + "fixed_amount": true, + "payments_amount_received": 0, + "payments_count_received": 0, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create Qr code with GST + +```py +client.qrcode.create({ + "type": "upi_qr", + "name": "Store_1", + "usage": "single_use", + "fixed_amount": true, + "payment_amount": 300, + "description": "For Store 1", + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "tax_invoice": { + "number": "INV001", + "date": 1589994898, + "customer_name": "Gaurav Kumar", + "business_gstin": "06AABCU9605R1ZR", + "gst_amount": 4000, + "cess_amount": 0, + "supply_type": "interstate" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| type* | string | The type of QR code i.e, `upi_qr`/`bharat_qr` | +| name | string | Label entered to identify the QR code. | +| usage* | string | Indicates if the QR code should be allowed to accept single payment or multiple payments i.e, `single_use`/`multiple_use` | +| fixed_amount | boolean | Indicates if the QR should accept payments of specific amounts or any amount. | +| payment_amount(* mandatory if fixed_amount is true) | integer | Indicates if the QR should accept payments of specific amounts or any amount. | +| customer_id | string | Unique identifier of the customer the QR code is linked with | +| description | string | A brief description about the QR code. | +| close_by | integer | UNIX timestamp at which the QR code is scheduled to be automatically closed. The time must be at least 15 minutes after the current time. | +| notes | object | Key-value pair that can be used to store additional information about the QR code. Maximum 15 key-value pairs, 256 characters (maximum) each. | +| tax_invoice | object | This block contains information about the invoices. If not provided, the transaction will default to non-GST compliant UPI flow. | + +**Response:** +```json +{ + "id": "qr_HMsVL8HOpbMcjU", + "entity": "qr_code", + "created_at": 1623660301, + "name": "Store_1", + "usage": "single_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/BWcUVrLp", + "payment_amount": 300, + "status": "active", + "description": "For Store 1", + "fixed_amount": true, + "payments_amount_received": 0, + "payments_count_received": 0, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "tax_invoice": { + "number": "INV001", + "date": 1589994898, + "customer_name": "Gaurav Kumar", + "business_gstin": "06AABCU9605R1ZR", + "gst_amount": 4000, + "cess_amount": 0, + "supply_type": "interstate" + } +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all Qr code + +```py +client.qrcode.all() +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "qr_HO2jGkWReVBMNu", + "entity": "qr_code", + "created_at": 1623914648, + "name": "Store_1", + "usage": "single_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/w2CEwYmkAu", + "payment_amount": 300, + "status": "active", + "description": "For Store 1", + "fixed_amount": true, + "payments_amount_received": 0, + "payments_count_received": 0, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "closed_at": null, + "close_reason": null + } + ] +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch a Qr code + +```py +client.qrcode.fetch(qrCodeId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| qrCodeId | string | The id of the qr code to be fetched | + +**Response:** +```json +{ + "id": "qr_HO2r1MDprYtWRT", + "entity": "qr_code", + "created_at": 1623915088, + "name": "Store_1", + "usage": "single_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/oCswTOcCo", + "payment_amount": 300, + "status": "active", + "description": "For Store 1", + "fixed_amount": true, + "payments_amount_received": 0, + "payments_count_received": 0, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "closed_at": null, + "close_reason": null +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch a Qr code for customer id + +```py + client.qrcode.all({"customer_id":customerId}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customerId* | string | The id of the customer to which qr code need to be fetched | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "qr_HMsgvioW64f0vh", + "entity": "qr_code", + "created_at": 1623660959, + "name": "Store_1", + "usage": "single_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/DTa2eQR", + "payment_amount": 300, + "status": "active", + "description": "For Store 1", + "fixed_amount": true, + "payments_amount_received": 0, + "payments_count_received": 0, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch a Qr code for payment id + +```py + client.qrcode.all({"payment_id":paymentId}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| paymentId* | string | The id of the payment to which qr code need to be fetched | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "qr_HMsqRoeVwKbwAF", + "entity": "qr_code", + "created_at": 1623661499, + "name": "Fresh Groceries", + "usage": "multiple_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/eI9XD54Q", + "payment_amount": null, + "status": "active", + "description": "Buy fresh groceries", + "fixed_amount": false, + "payments_amount_received": 1000, + "payments_count_received": 1, + "notes": [], + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1624472999, + "close_reason": null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch Payments for a QR Code + +```py +client.qrcode.fetch_all_payments(qrCodeId, options) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| qrCodeId* | string | The id of the qr code to which payment where made | +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "pay_HMtDKn3TnF4D8x", + "entity": "payment", + "amount": 500, + "currency": "INR", + "status": "captured", + "order_id": null, + "invoice_id": null, + "international": false, + "method": "upi", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "QRv2 Payment", + "card_id": null, + "bank": null, + "wallet": null, + "vpa": "gauri.kumari@okhdfcbank", + "email": "gauri.kumari@example.com", + "contact": "+919999999999", + "customer_id": "cust_HKsR5se84c5LTO", + "notes": [], + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "rrn": "116514257019" + }, + "created_at": 1623662800 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Close a QR Code + +```py +client.qrcode.close(qrCodeId); +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| qrCodeId* | string | The id of the qr code to be closed | + +**Response:** +```json +{ + "id": "qr_HMsVL8HOpbMcjU", + "entity": "qr_code", + "created_at": 1623660301, + "name": "Store_1", + "usage": "single_use", + "type": "upi_qr", + "image_url": "https://rzp.io/i/BWcUVrLp", + "payment_amount": 300, + "status": "closed", + "description": "For Store 1", + "fixed_amount": true, + "payments_amount_received": 0, + "payments_count_received": 0, + "notes": { + "purpose": "Test UPI QR code notes" + }, + "customer_id": "cust_HKsR5se84c5LTO", + "close_by": 1681615838, + "closed_at": 1623660445, + "close_reason": "on_demand" +} +``` +------------------------------------------------------------------------------------------------------- + + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/qr-codes/)** \ No newline at end of file diff --git a/documents/refund.md b/documents/refund.md new file mode 100644 index 00000000..debdecf6 --- /dev/null +++ b/documents/refund.md @@ -0,0 +1,295 @@ +## Refunds + +### Create a normal refund + +```py +client.payment.refund(paymentId,{ + "amount": "100", + "speed": "normal", + "notes": { + "notes_key_1": "Beam me up Scotty.", + "notes_key_2": "Engage" + }, + "receipt": "Receipt No. 31" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment | +| amount | integer | The amount to be captured (should be equal to the authorized amount, in paise) | | +| speed | string | Here, it must be normal | +| notes | array | A key-value pair | +| receipt | string | A unique identifier provided by you for your internal reference. | + +**Response:** +```json +{ + "id": "rfnd_FP8QHiV938haTz", + "entity": "refund", + "amount": 500100, + "receipt": "Receipt No. 31", + "currency": "INR", + "payment_id": "pay_FCXKPFtYfPXJPy", + "notes": [], + "acquirer_data": { + "arn": null + }, + "created_at": 1597078866, + "batch_id": null, + "status": "processed", + "speed_processed": "normal" +} +``` +------------------------------------------------------------------------------------------------------- + +### Create an instant refund + +```py +client.payment.refund(paymentId,{ + "amount": "100", + "speed": "optimum", + "receipt": "Receipt No. 31" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment | +| amount | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| speed* | string | Here, it must be optimum | +| receipt | string | A unique identifier provided by you for your internal reference. | + +**Response:** +```json +{ + "id": "rfnd_FP8R8EGjGbPkVb", + "entity": "refund", + "amount": 500100, + "currency": "INR", + "payment_id": "pay_FC8MmhMBZPKDHF", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "receipt": "Receipt No. 31", + "acquirer_data": { + "arn": null + }, + "created_at": 1597078914, + "batch_id": null, + "status": "processed", + "speed_requested": "optimum" +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch multiple refunds for a payment + +```py +client.payment.fetch_multiple_refund(paymentId,option) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| paymentId* | string | The id of the payment | +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Refund:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "rfnd_FP8DDKxqJif6ca", + "entity": "refund", + "amount": 300100, + "currency": "INR", + "payment_id": "pay_FIKOnlyii5QGNx", + "notes": { + "comment": "Comment for refund" + }, + "receipt": null, + "acquirer_data": { + "arn": "10000000000000" + }, + "created_at": 1597078124, + "batch_id": null, + "status": "processed", + "speed_processed": "normal", + "speed_requested": "optimum" + } + ] +} + ``` +------------------------------------------------------------------------------------------------------- + +### Fetch a specific refund for a payment +```py +client.payment.fetch_refund_id(paymentId,refundId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | +| refundId* | string | The id of the refund to be fetched | + +**Response:** +```json +{ + "id": "rfnd_FP8DDKxqJif6ca", + "entity": "refund", + "amount": 300100, + "currency": "INR", + "payment_id": "pay_FIKOnlyii5QGNx", + "notes": { + "comment": "Comment for refund" + }, + "receipt": null, + "acquirer_data": { + "arn": "10000000000000" + }, + "created_at": 1597078124, + "batch_id": null, + "status": "processed", + "speed_processed": "normal", + "speed_requested": "optimum" +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all refunds +```py +client.refund.all(options) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 2, + "items": [ + { + "id": "rfnd_FFX6AnnIN3puqW", + "entity": "refund", + "amount": 88800, + "currency": "INR", + "payment_id": "pay_FFX5FdEYx8jPwA", + "notes": { + "comment": "Issuing an instant refund" + }, + "receipt": null, + "acquirer_data": {}, + "created_at": 1594982363, + "batch_id": null, + "status": "processed", + "speed_processed": "optimum", + "speed_requested": "optimum" + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch particular refund +```py +client.refund.fetch(refundId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| refundId* | string | The id of the refund to be fetched | + +**Response:** +```json +{ + "id": "rfnd_EqWThTE7dd7utf", + "entity": "refund", + "amount": 6000, + "currency": "INR", + "payment_id": "pay_EpkFDYRirena0f", + "notes": { + "comment": "Issuing an instant refund" + }, + "receipt": null, + "acquirer_data": { + "arn": "10000000000000" + }, + "created_at": 1589521675, + "batch_id": null, + "status": "processed", + "speed_processed": "optimum", + "speed_requested": "optimum" +} +``` +------------------------------------------------------------------------------------------------------- + +### Update the refund +```py +client.refund.edit({ + "notes": { + "notes_key_1": "Beam me up Scotty.", + "notes_key_2": "Engage" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| refundId* | string | The id of the refund to be fetched | +| notes* | array | A key-value pair | + +**Response:** +```json +{ + "id": "rfnd_FP8DDKxqJif6ca", + "entity": "refund", + "amount": 300100, + "currency": "INR", + "payment_id": "pay_FIKOnlyii5QGNx", + "notes": { + "notes_key_1": "Beam me up Scotty.", + "notes_key_2": "Engage" + }, + "receipt": null, + "acquirer_data": { + "arn": "10000000000000" + }, + "created_at": 1597078124, + "batch_id": null, + "status": "processed", + "speed_processed": "normal", + "speed_requested": "optimum" +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/refunds/)** \ No newline at end of file diff --git a/documents/registerEmandate.md b/documents/registerEmandate.md new file mode 100644 index 00000000..a3647478 --- /dev/null +++ b/documents/registerEmandate.md @@ -0,0 +1,420 @@ +## Register emandate and charge first payment together + +### Create customer +```py +client.customer.create({ + "name": "Gaurav Kumar", + "contact": 9123456780, + "email": "gaurav.kumar@example.com", + "fail_existing": 0, + "gstin": "29XAbbA4369J1PA", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| name* | string | Name of the customer | +| email | string | Email of the customer | +| contact | string | Contact number of the customer | +| fail_existing | string | If a customer with the same details already exists, the request throws an exception by default. Possible value is `0` or `1`| +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "cust_1Aa00000000003", + "entity": "customer", + "name": "Gaurav Kumar", + "email": "Gaurav.Kumar@example.com", + "contact": "9000000000", + "gstin": null, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1582033731 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create order + +```py +client.order.create({ + "amount": 0, + "currency": "INR", + "method": "emandate", + "customer_id": "cust_1Aa00000000001", + "receipt": "Receipt No. 1", + "notes": { + "notes_key_1": "Beam me up Scotty", + "notes_key_2": "Engage" + }, + "token": { + "auth_type": "netbanking", + "max_amount": 9999900, + "expire_at": 4102444799, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "bank_account": { + "beneficiary_name": "Gaurav Kumar", + "account_number": 1121431121541121, + "account_type": "savings", + "ifsc_code": "HDFC0000001" + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| customerId* | string | The id of the customer to be fetched | +| method* | string | Payment method used to make the registration transaction. Possible value is `emandate`. | +| receipt | string | Your system order reference id. | +| token | object | All keys listed [here](https://razorpay.com/docs/api/recurring-payments/emandate/auto-debit/#112-create-an-order) are supported | +| notes | object | A key-value pair | + +**Response:** +For create order response please click [here](https://razorpay.com/docs/api/recurring-payments/emandate/auto-debit/#112-create-an-order) + +------------------------------------------------------------------------------------------------------- + +### Create an Authorization Payment + +Please refer this [doc](https://razorpay.com/docs/api/recurring-payments/emandate/auto-debit/#113-create-an-authorization-payment) for authorization payment + +----------------------------------------------------------------------------------------------------- + +### Create registration link + +```py +client.registration_link.create({ + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": 9123456780 + }, + "type": "link", + "amount": 0, + "currency": "INR", + "description": "12 p.m. Meals", + "subscription_registration": { + "method": "emandate", + "auth_type": "netbanking", + "expire_at": 1580480689, + "max_amount": 50000, + "bank_account": { + "beneficiary_name": "Gaurav Kumar", + "account_number": 11214311215411, + "account_type": "savings", + "ifsc_code": "HDFC0001233" + } + }, + "receipt": "Receipt no. 1", + "expire_by": 1880480689, + "sms_notify": 1, + "email_notify": 1, + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|---------------------------------------------------------------| +| customer | object | Details of the customer to whom the registration link will be sent. | +| type* | object | the value is `link`. | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| description* | string | A brief description of the payment. | +| subscription_registration | object | All keys listed [here](https://razorpay.com/docs/api/recurring-payments/emandate/auto-debit/#121-create-a-registration-link) are supported | +| receipt | string | Your system order reference id. | +| sms_notify | boolean | SMS notifications are to be sent by Razorpay (default : 1) | +| email_notify | boolean | Email notifications are to be sent by Razorpay (default : 1) | +| expire_by | integer | The timestamp, in Unix format, till when the customer can make the authorization payment. | +| notes | object | A key-value pair | + +**Response:** +For create registration link response please click [here](https://razorpay.com/docs/api/recurring-payments/emandate/auto-debit/#12-using-a-registration-link) +------------------------------------------------------------------------------------------------------- + +## Create an order to charge the customer + +```py +client.order.create({ + "amount":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "notes": { + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + } +}) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id":"order_1Aa00000000002", + "entity":"order", + "amount":1000, + "amount_paid":0, + "amount_due":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "offer_id":null, + "status":"created", + "attempts":0, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1579782776 +} +``` +------------------------------------------------------------------------------------------------------- + +## Create a recurring payment + +```py +client.payment.createRecurring({ + "email": "gaurav.kumar@example.com", + "contact": 9123456789, + "amount": 1000, + "currency": "INR", + "recurring": 1, + "description": "Creating recurring payment for Gaurav Kumar", + "notes": { + "key1": "value3", + "key2": "value2" + } +}) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| email* | string | The customer's email address | +| contact* | string | The customer's phone number | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| orderId* | string | The id of the order to be fetched | +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | +| recurring* | boolean | Possible values is `0` or `1` | +| description | string | A brief description of the payment. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "razorpay_payment_id" : "pay_1Aa00000000001", + "razorpay_order_id" : "order_1Aa00000000001", + "razorpay_signature" : "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d" +} +``` +------------------------------------------------------------------------------------------------------- + +## Send/Resend notifications + +```py +client.invoice.notify_by(invoiceId, medium) +``` +**Parameters:** + +| Name | Type |Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be fetched | +| medium* | string | Possible values are `sms` or `email` | + +**Response:** +```json +{ + "success": true +} +``` +------------------------------------------------------------------------------------------------------- + +## Cancel registration link + +```py +client.invoice.cancel(invoiceId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be fetched | + +**Response:** +```json +{ + "id": "inv_FHrfRupD2ouKIt", + "entity": "invoice", + "receipt": "Receipt No. 1", + "invoice_number": "Receipt No. 1", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrfRw4TZU5Q2L", + "line_items": [], + "payment_id": null, + "status": "cancelled", + "expire_by": 4102444799, + "issued_at": 1595491479, + "paid_at": null, + "cancelled_at": 1595491488, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1595491479, + "terms": null, + "partial_payment": false, + "gross_amount": 100, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 100, + "amount_paid": 0, + "amount_due": 100, + "currency": "INR", + "currency_symbol": "₹", + "description": "Registration Link for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/QlfexTj", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491480, + "idempotency_key": null +} +``` +------------------------------------------------------------------------------------------------------- + +## Fetch token by payment id + +```py +client.payment.fetch(paymentId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | + +**Response:** +For fetch token by payment id response please click [here](https://razorpay.com/docs/api/recurring-payments/emandate/auto-debit/#21-fetch-token-by-payment-id) + +------------------------------------------------------------------------------------------------------- + +## Fetch tokens by customer id + +```py +client.token.all(customerId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "token_FHf94Uym9tdYFJ", + "entity": "token", + "token": "2wDPM7VAlXtjAR", + "bank": "HDFC", + "wallet": null, + "method": "emandate", + "vpa": null, + "recurring": true, + "recurring_details": { + "status": "confirmed", + "failure_reason": null + }, + "auth_type": "netbanking", + "mrn": null, + "used_at": 1595447381, + "created_at": 1595447381, + "bank_details": { + "beneficiary_name": "Gaurav Kumar", + "account_number": "1121431121541121", + "ifsc": "HDFC0000001", + "account_type": "savings" + }, + "max_amount": 9999900, + "expired_at": 1689971140, + "dcc_enabled": false + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +## Delete tokens + +```py +client.token.delete(customerId,tokenId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | + +**Response:** +```json +{ + "deleted": true +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/recurring-payments/emandate/auto-debit/)** \ No newline at end of file diff --git a/documents/registerNach.md b/documents/registerNach.md new file mode 100644 index 00000000..c026f662 --- /dev/null +++ b/documents/registerNach.md @@ -0,0 +1,632 @@ +## Register nach and charge first payment together + +### Create customer +```py +client.customer.create({ + "name": "Gaurav Kumar", + "contact": 9123456780, + "email": "gaurav.kumar@example.com", + "fail_existing": 0, + "gstin": "29XAbbA4369J1PA", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| name* | string | Name of the customer | +| email | string | Email of the customer | +| contact | string | Contact number of the customer | +| fail_existing | string | If a customer with the same details already exists, the request throws an exception by default. Possible value is `0` or `1`| +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "cust_1Aa00000000003", + "entity": "customer", + "name": "Gaurav Kumar", + "email": "Gaurav.Kumar@example.com", + "contact": "9000000000", + "gstin": null, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1582033731 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create Order + +```py +client.order.create({ + "amount": 100, + "currency": "INR", + "method": "nach", + "receipt": "Receipt No. 5", + "notes": { + "note_key 1"": "Beam me up Scotty", + "note_key 2"": "Tea. Earl Gray. Hot." + }, + "token": { + "first_payment_amount": 10000, + "auth_type": "physical", + "max_amount": 50000, + "expire_at": 1634215992, + "notes": { + "note_key 1": "Tea, Earl Grey… decaf.", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "bank_account": { + "beneficiary_name": "Gaurav Kumar", + "account_number": 11214311215411, + "account_type": "savings", + "ifsc_code": "HDFC0001233" + }, + "nach": { + "form_reference1": "Recurring Payment for Gaurav Kumar", + "form_reference2": "Method Paper NACH", + "description": "Paper NACH Gaurav Kumar" + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| customerId* | string | The id of the customer to be fetched | +| method* | string | Payment method used to make the registration transaction. Possible value is `nach`. | +| receipt | string | Your system order reference id. | +| token | object | All keys listed [here](https://razorpay.com/docs/api/recurring-payments/paper-nach/auto-debit/#112-create-an-order) are supported | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id":"order_1Aa00000000001", + "entity":"order", + "amount":0, + "amount_paid":0, + "amount_due":0, + "currency":"INR", + "receipt":"rcptid #10", + "offer_id":null, + "offers":{ + "entity":"collection", + "count":0, + "items":[] + }, + "status":"created", + "attempts":0, + "notes": { + "notes_key_1": "Beam me up Scotty", + "notes_key_2": "Engage" + }, + "created_at":1579775420, + "token":{ + "method":"nach", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "recurring_status":null, + "failure_reason":null, + "currency":"INR", + "max_amount":10000000, + "auth_type":"physical", + "expire_at":1580480689, + "nach":{ + "create_form":true, + "form_reference1":"Recurring Payment for Gaurav Kumar", + "form_reference2":"Method Paper NACH", + "prefilled_form":"https://rzp.io/i/bitw", + "upload_form_url":"https://rzp.io/i/gts", + "description":"Paper NACH Gaurav Kumar" + }, + "bank_account":{ + "ifsc":"HDFC0000001", + "bank_name":"HDFC Bank", + "name":"Gaurav Kumar", + "account_number":"11214311215411", + "account_type":"savings", + "beneficiary_email":"gaurav.kumar@example.com", + "beneficiary_mobile":"9876543210" + }, + "first_payment_amount":10000 + } +} +``` +------------------------------------------------------------------------------------------------------- + +### Create an Authorization Payment + +Please refer this [doc](https://razorpay.com/docs/api/recurring-payments/paper-nach/auto-debit/#113-create-an-authorization-payment) for authorization payment + +----------------------------------------------------------------------------------------------------- + +### Create registration link + +```py +client.payment.createRecurring({ + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": 9123456780 + }, + "amount": 100, + "type": "link", + "currency": "INR", + "description": "Registration Link for Gaurav Kumar", + "subscription_registration": { + "first_payment_amount": 100, + "method": "nach", + "auth_type": "physical", + "max_amount": 50000, + "expire_at": 1634215992, + "bank_account": { + "beneficiary_name": "Gaurav Kumar", + "account_number": 11214311215411, + "account_type": "savings", + "ifsc_code": "HDFC0001233" + }, + "nach": { + "form_reference1": "Recurring Payment for Gaurav Kumar", + "form_reference2": "Method Paper NACH" + } + }, + "receipt": "Receipt No. 5", + "email_notify": 1, + "sms_notify": 1, + "expire_by": 1634215992, + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|---------------------------------------------------------------| +| customer | object | Details of the customer to whom the registration link will be sent. | +| type* | object | the value is `link`. | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| description* | string | A brief description of the payment. | +| subscription_registration | object | All keys listed [here](https://razorpay.com/docs/api/recurring-payments/paper-nach/auto-debit/#121-create-a-registration-link) are supported | +| receipt | string | Your system order reference id. | +| sms_notify | boolean | SMS notifications are to be sent by Razorpay (default : 1) | +| email_notify | boolean | Email notifications are to be sent by Razorpay (default : 1) | +| expire_by | integer | The timestamp, in Unix format, till when the customer can make the authorization payment. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "inv_FHrZiAubEzDdaq", + "entity": "invoice", + "receipt": "Receipt No. 27", + "invoice_number": "Receipt No. 27", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrZiBOkWHZPOp", + "line_items": [], + "payment_id": null, + "status": "issued", + "expire_by": 1647483647, + "issued_at": 1595491154, + "paid_at": null, + "cancelled_at": null, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1595491154, + "terms": null, + "partial_payment": false, + "gross_amount": 0, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 0, + "amount_paid": 0, + "amount_due": 0, + "currency": "INR", + "currency_symbol": "₹", + "description": "12 p.m. Meals", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/bzDYbNg", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491154, + "idempotency_key": null, + "token": { + "method": "nach", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "recurring_status": null, + "failure_reason": null, + "currency": "INR", + "max_amount": 50000, + "auth_type": "physical", + "expire_at": 1947483647, + "nach": { + "create_form": true, + "form_reference1": "Recurring Payment for Gaurav Kumar", + "form_reference2": "Method Paper NACH", + "prefilled_form": "https://rzp.io/i/exdIzYN", + "upload_form_url": "https://rzp.io/i/bzDYbNg", + "description": "12 p.m. Meals" + }, + "bank_account": { + "ifsc": "HDFC0001233", + "bank_name": "HDFC Bank", + "name": "Gaurav Kumar", + "account_number": "11214311215411", + "account_type": "savings", + "beneficiary_email": "gaurav.kumar@example.com", + "beneficiary_mobile": "9123456780" + }, + "first_payment_amount": 0 + }, + "nach_form_url": "https://rzp.io/i/exdIzYN" +} +``` +------------------------------------------------------------------------------------------------------- + +## Create an order to charge the customer + +```py +client.order.create({ + "amount":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "notes": { + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + } +}) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id":"order_1Aa00000000002", + "entity":"order", + "amount":1000, + "amount_paid":0, + "amount_due":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "offer_id":null, + "status":"created", + "attempts":0, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1579782776 +} +``` +------------------------------------------------------------------------------------------------------- + +## Create a recurring payment + +```py +client.payment.createRecurring({ + "email": "gaurav.kumar@example.com", + "contact": "9123456789", + "amount": 1000, + "currency": "INR", + "recurring": "1", + "description": "Creating recurring payment for Gaurav Kumar", + "notes": { + "key1": "value3", + "key2": "value2" + } +}) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| email* | string | The customer's email address | +| contact* | string | The customer's phone number | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | +| orderId* | string | The id of the order to be fetched | +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | +| recurring* | boolean | Possible values is `0` or `1` | +| description | string | A brief description of the payment. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "razorpay_payment_id" : "pay_1Aa00000000001", + "razorpay_order_id" : "order_1Aa00000000001", + "razorpay_signature" : "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d" +} +``` +------------------------------------------------------------------------------------------------------- + +## Send/Resend notifications + +```py +client.invoice.notify_by(invoiceId, medium) +``` +**Parameters:** + +| Name | Type |Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be fetched | +| medium* | string | Possible values are `sms` or `email` | + +**Response:** +```json +{ + "success": true +} +``` + +------------------------------------------------------------------------------------------------------- + +## Cancel registration link + +```py +client.invoice.cancel(invoiceId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be fetched | + +**Response:** +```json +{ + "id": "inv_FHrZiAubEzDdaq", + "entity": "invoice", + "receipt": "Receipt No. 27", + "invoice_number": "Receipt No. 27", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrZiBOkWHZPOp", + "line_items": [], + "payment_id": null, + "status": "cancelled", + "expire_by": 1647483647, + "issued_at": 1595491154, + "paid_at": null, + "cancelled_at": 1595491339, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1595491154, + "terms": null, + "partial_payment": false, + "gross_amount": 0, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 0, + "amount_paid": 0, + "amount_due": 0, + "currency": "INR", + "currency_symbol": "₹", + "description": "12 p.m. Meals", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/bzDYbNg", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491154, + "idempotency_key": null, + "token": { + "method": "nach", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "recurring_status": null, + "failure_reason": null, + "currency": "INR", + "max_amount": 50000, + "auth_type": "physical", + "expire_at": 1947483647, + "nach": { + "create_form": true, + "form_reference1": "Recurring Payment for Gaurav Kumar", + "form_reference2": "Method Paper NACH", + "prefilled_form": "https://rzp.io/i/tSYd5aV", + "upload_form_url": "https://rzp.io/i/bzDYbNg", + "description": "12 p.m. Meals" + }, + "bank_account": { + "ifsc": "HDFC0001233", + "bank_name": "HDFC Bank", + "name": "Gaurav Kumar", + "account_number": "11214311215411", + "account_type": "savings", + "beneficiary_email": "gaurav.kumar@example.com", + "beneficiary_mobile": "9123456780" + }, + "first_payment_amount": 0 + }, + "nach_form_url": "https://rzp.io/i/tSYd5aV" +} +``` +------------------------------------------------------------------------------------------------------- + +## Fetch token by payment id + +```py +client.payment.fetch(paymentId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | + +**Response:** +```json +{ + "id": "pay_EnLNTjINiPkMEZ", + "entity": "payment", + "amount": 0, + "currency": "INR", + "status": "captured", + "order_id": "order_EnLLfglmKksr4K", + "invoice_id": "inv_EnLLfgCzRfcMuh", + "international": false, + "method": "nach", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "Invoice #inv_EnLLfgCzRfcMuh", + "card_id": null, + "bank": "UTIB", + "wallet": null, + "vpa": null, + "email": "gaurav.kumar@example.com", + "contact": "+919876543210", + "customer_id": "cust_DtHaBuooGHTuyZ", + "token_id": "token_EnLNTnn7uyRg5V", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": {}, + "created_at": 1588827564 +} +``` +------------------------------------------------------------------------------------------------------- + +## Fetch tokens by customer id + +```py +client.token.all(customerId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "token_EhYgIE3pOyMQpD", + "entity": "token", + "token": "3mQ5Czc6APNppI", + "bank": "HDFC", + "wallet": null, + "method": "nach", + "vpa": null, + "recurring": true, + "recurring_details": { + "status": "confirmed", + "failure_reason": null + }, + "auth_type": "physical", + "mrn": null, + "used_at": 1587564373, + "created_at": 1587564373, + "dcc_enabled": false + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +## Delete tokens + +```py +client.token.delete(customerId,tokenId) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | + +**Response:** +```json +{ + "deleted": true +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/recurring-payments/paper-nach/auto-debit/)** \ No newline at end of file diff --git a/documents/settlement.md b/documents/settlement.md new file mode 100644 index 00000000..693f8a15 --- /dev/null +++ b/documents/settlement.md @@ -0,0 +1,454 @@ +## Settlements + +### Fetch all settlements + +```py +client.settlement.all(options) +``` + +**Parameters:** + + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the settlement were created | +| to | timestamp | timestamp before which the settlement were created | +| count | integer | number of settlements to fetch (default: 10) | +| skip | integer | number of settlements to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "setl_DGlQ1Rj8os78Ec", + "entity": "settlement", + "amount": 9973635, + "status": "processed", + "fees": 471699, + "tax": 42070, + "utr": "1568176960vxp0rj", + "created_at": 1568176960 + } + ] +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch a settlement + +```py +client.settlement.fetch(settlementId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| settlementId* | string | The id of the settlement to be fetched | + +**Response:** +```json +{ + "id": "setl_DGlQ1Rj8os78Ec", + "entity": "settlement", + "amount": 9973635, + "status": "processed", + "fees": 471699, + "tax": 42070, + "utr": "1568176960vxp0rj", + "created_at": 1568176960 +} +``` +------------------------------------------------------------------------------------------------------- + +### Settlement report for a month + +```py +client.settlement.report({ + year: 2020, + month: 9 +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| year* | integer | The year the settlement was received in the `YYYY` format. For example, `2020` | +| month* | integer | The month the settlement was received in the `MM` format. For example, `09` | +| day | integer | The date the settlement was received in the `DD` format. For example, `01` | +| count | integer | number of settlements to fetch (default: 10) | +| skip | integer | number of settlements to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 4, + "items": [ + { + "entity_id": "pay_DEXrnipqTmWVGE", + "type": "payment", + "debit": 0, + "credit": 97100, + "amount": 100000, + "currency": "INR", + "fee": 2900, + "tax": 0, + "on_hold": false, + "settled": true, + "created_at": 1567692556, + "settled_at": 1568176960, + "settlement_id": "setl_DGlQ1Rj8os78Ec", + "posted_at": null, + "credit_type": "default", + "description": "Recurring Payment via Subscription", + "notes": "{}", + "payment_id": null, + "settlement_utr": "1568176960vxp0rj", + "order_id": "order_DEXrnRiR3SNDHA", + "order_receipt": null, + "method": "card", + "card_network": "MasterCard", + "card_issuer": "KARB", + "card_type": "credit", + "dispute_id": null + }, + { + "entity_id": "rfnd_DGRcGzZSLyEdg1", + "type": "refund", + "debit": 242500, + "credit": 0, + "amount": 242500, + "currency": "INR", + "fee": 0, + "tax": 0, + "on_hold": false, + "settled": true, + "created_at": 1568107224, + "settled_at": 1568176960, + "settlement_id": "setl_DGlQ1Rj8os78Ec", + "posted_at": null, + "credit_type": "default", + "description": null, + "notes": "{}", + "payment_id": "pay_DEXq1pACSqFxtS", + "settlement_utr": "1568176960vxp0rj", + "order_id": "order_DEXpmZgffXNvuI", + "order_receipt": null, + "method": "card", + "card_network": "MasterCard", + "card_issuer": "KARB", + "card_type": "credit", + "dispute_id": null + }, + { + "entity_id": "trf_DEUoCEtdsJgvl7", + "type": "transfer", + "debit": 100296, + "credit": 0, + "amount": 100000, + "currency": "INR", + "fee": 296, + "tax": 46, + "on_hold": false, + "settled": true, + "created_at": 1567681786, + "settled_at": 1568176960, + "settlement_id": "setl_DGlQ1Rj8os78Ec", + "posted_at": null, + "credit_type": "default", + "description": null, + "notes": null, + "payment_id": "pay_DEApNNTR6xmqJy", + "settlement_utr": "1568176960vxp0rj", + "order_id": null, + "order_receipt": null, + "method": null, + "card_network": null, + "card_issuer": null, + "card_type": null, + "dispute_id": null + }, + { + "entity_id": "adj_EhcHONhX4ChgNC", + "type": "adjustment", + "debit": 0, + "credit": 1012, + "amount": 1012, + "currency": "INR", + "fee": 0, + "tax": 0, + "on_hold": false, + "settled": true, + "created_at": 1567681786, + "settled_at": 1568176960, + "settlement_id": "setl_DGlQ1Rj8os78Ec", + "posted_at": null, + "description": "test reason", + "notes": null, + "payment_id": null, + "settlement_utr": null, + "order_id": null, + "order_receipt": null, + "method": null, + "card_network": null, + "card_issuer": null, + "card_type": null, + "dispute_id": null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Settlement recon + +```py +client.settlement.report({ + year: 2020, + month: 9, + day:11 +}) +``` +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| year* | integer | The year the settlement was received in the `YYYY` format. For example, `2020` | +| month* | integer | The month the settlement was received in the `MM` format. For example, `09` | +| day | integer | The day the settlement was received in the `DD` format. For example, | + +**Response:** +```json +{ + "entity": "collection", + "count": 4, + "items": [ + { + "entity_id": "pay_DEXrnipqTmWVGE", + "type": "payment", + "debit": 0, + "credit": 97100, + "amount": 100000, + "currency": "INR", + "fee": 2900, + "tax": 0, + "on_hold": false, + "settled": true, + "created_at": 1567692556, + "settled_at": 1568176960, + "settlement_id": "setl_DGlQ1Rj8os78Ec", + "posted_at": null, + "credit_type": "default", + "description": "Recurring Payment via Subscription", + "notes": "{}", + "payment_id": null, + "settlement_utr": "1568176960vxp0rj", + "order_id": "order_DEXrnRiR3SNDHA", + "order_receipt": null, + "method": "card", + "card_network": "MasterCard", + "card_issuer": "KARB", + "card_type": "credit", + "dispute_id": null + }, + { + "entity_id": "rfnd_DGRcGzZSLyEdg1", + "type": "refund", + "debit": 242500, + "credit": 0, + "amount": 242500, + "currency": "INR", + "fee": 0, + "tax": 0, + "on_hold": false, + "settled": true, + "created_at": 1568107224, + "settled_at": 1568176960, + "settlement_id": "setl_DGlQ1Rj8os78Ec", + "posted_at": null, + "credit_type": "default", + "description": null, + "notes": "{}", + "payment_id": "pay_DEXq1pACSqFxtS", + "settlement_utr": "1568176960vxp0rj", + "order_id": "order_DEXpmZgffXNvuI", + "order_receipt": null, + "method": "card", + "card_network": "MasterCard", + "card_issuer": "KARB", + "card_type": "credit", + "dispute_id": null + }, + { + "entity_id": "trf_DEUoCEtdsJgvl7", + "type": "transfer", + "debit": 100296, + "credit": 0, + "amount": 100000, + "currency": "INR", + "fee": 296, + "tax": 46, + "on_hold": false, + "settled": true, + "created_at": 1567681786, + "settled_at": 1568176960, + "settlement_id": "setl_DGlQ1Rj8os78Ec", + "posted_at": null, + "credit_type": "default", + "description": null, + "notes": null, + "payment_id": "pay_DEApNNTR6xmqJy", + "settlement_utr": "1568176960vxp0rj", + "order_id": null, + "order_receipt": null, + "method": null, + "card_network": null, + "card_issuer": null, + "card_type": null, + "dispute_id": null + }, + { + "entity_id": "adj_EhcHONhX4ChgNC", + "type": "adjustment", + "debit": 0, + "credit": 1012, + "amount": 1012, + "currency": "INR", + "fee": 0, + "tax": 0, + "on_hold": false, + "settled": true, + "created_at": 1567681786, + "settled_at": 1568176960, + "settlement_id": "setl_DGlQ1Rj8os78Ec", + "posted_at": null, + "description": "test reason", + "notes": null, + "payment_id": null, + "settlement_utr": null, + "order_id": null, + "order_receipt": null, + "method": null, + "card_network": null, + "card_issuer": null, + "card_type": null, + "dispute_id": null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Create on-demand settlement + +```py +client.settlement.create_ondemand_settlement({ + "amount": 1221, + "settle_full_balance": 0, + "description": "Testing", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| amount*| integer | Maximum amount that can be settled | +| settle_full_balance* | boolean | true or false | +| description | string | The description may not be greater than 30 characters | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "setlod_FNj7g2YS5J67Rz", + "entity": "settlement.ondemand", + "amount_requested": 200000, + "amount_settled": 0, + "amount_pending": 199410, + "amount_reversed": 0, + "fees": 590, + "tax": 90, + "currency": "INR", + "settle_full_balance": false, + "status": "initiated", + "description": "Need this to make vendor payments.", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1596771429, + "ondemand_payouts": { + "entity": "collection", + "count": 1, + "items": [ + { + "id": "setlodp_FNj7g2cbvw8ueO", + "entity": "settlement.ondemand_payout", + "initiated_at": null, + "processed_at": null, + "reversed_at": null, + "amount": 200000, + "amount_settled": null, + "fees": 590, + "tax": 90, + "utr": null, + "status": "created", + "created_at": 1596771429 + } + ] + } +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all on-demand settlements + +```py +client.settlement.fetch_all_ondemand_settlement(options) +``` +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:**
+For all on-demand settlements response please click [here](https://razorpay.com/docs/api/settlements/#fetch-all-on-demand-settlements) + +------------------------------------------------------------------------------------------------------- + +### Fetch on-demand settlement by ID + +```py +client.settlement.fetch_ondemand_settlement_id(settlementId) +``` + +**Parameters:** + +| Name | Type | Description | +|------------|--------|-----------------------------------| +| settlementId* | string | Settlement Id of the On-demand settlement| + +**Response:** +For on-demand settlement by ID response please click [here](https://razorpay.com/docs/api/settlements/#fetch-on-demand-settlements-by-id) + +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/settlements/)** \ No newline at end of file diff --git a/documents/subscription.md b/documents/subscription.md new file mode 100644 index 00000000..7c26f15c --- /dev/null +++ b/documents/subscription.md @@ -0,0 +1,726 @@ +## Subscriptions + +### Create subscription + +```py +client.subscription.create({ + "plan_id": "plan_7wAosPWtrkhqZw", + "customer_notify": 1, + "quantity": 5, + "total_count": 6, + "start_at": 1495995837, + "addons": [ + { + "item": { + "name": "Delivery charges", + "amount": 30000, + "currency": "INR" + } + } + ], + "notes": { + "key1": "value3", + "key2": "value2" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| plan_id* | string | The unique identifier for a plan that should be linked to the subscription.| +| total_count* | string | The number of billing cycles for which the customer should be charged | +| customer_notify | boolean | Indicates whether the communication to the customer would be handled by you or us | +| quantity | integer | The number of times the customer should be charged the plan amount per invoice | +| start_at | integer | The timestamp, in Unix format, for when the subscription should start. If not passed, the subscription starts immediately after the authorization payment. | +| expire_by | integer | The timestamp, in Unix format, till when the customer can make the authorization payment. | +| addons | object | Object that contains details of any upfront amount you want to collect as part of the authorization transaction. | +| notes | object | Notes you can enter for the contact for future reference. | + +**Response:** +```json +{ + "id": "sub_00000000000001", + "entity": "subscription", + "plan_id": "plan_00000000000001", + "status": "created", + "current_start": null, + "current_end": null, + "ended_at": null, + "quantity": 1, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "charge_at": 1580453311, + "start_at": 1580626111, + "end_at": 1583433000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 0, + "customer_notify": true, + "created_at": 1580280581, + "expire_by": 1580626111, + "short_url": "https://rzp.io/i/z3b1R61A9", + "has_scheduled_changes": false, + "change_scheduled_at": null, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count": 5 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create subscription link + +```py +client.subscription.create({ + "plan_id": "plan_HoYg68p5kmuvzD", + "total_count": 12, + "quantity": 1, + "expire_by": 1633237807, + "customer_notify": 1, + "addons": [ + { + "item": { + "name": "Delivery charges", + "amount": 30000, + "currency": "INR" + } + } + ], + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "notify_info": { + "notify_phone": 9123456789, + "notify_email": "gaurav.kumar@example.com" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| plan_id* | string | The unique identifier for a plan that should be linked to the subscription.| +| total_count* | string | The number of billing cycles for which the customer should be charged | +| customer_notify | boolean | Indicates whether the communication to the customer would be handled by you or us | +| quantity | integer | The number of times the customer should be charged the plan amount per invoice | +| start_at | integer | The timestamp, in Unix format, for when the subscription should start. If not passed, the subscription starts immediately after the authorization payment. | +| expire_by | integer | The timestamp, in Unix format, till when the customer can make the authorization payment. | +| addons | object | Object that contains details of any upfront amount you want to collect as part of the authorization transaction. | +| notes | object | Notes you can enter for the contact for future reference. | +| notify_info | object | The customer's email and phone number to which notifications are to be sent. (PN: Use this object only if you have set the `customer_notify` parameter to 1. That is, Razorpay sends notifications to the customer.) | + +**Response:** +```json +{ + "id":"sub_00000000000002", + "entity":"subscription", + "plan_id":"plan_00000000000001", + "status":"created", + "current_start":null, + "current_end":null, + "ended_at":null, + "quantity":1, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "charge_at":1580453311, + "start_at":1580453311, + "end_at":1587061800, + "auth_attempts":0, + "total_count":12, + "paid_count":0, + "customer_notify":true, + "created_at":1580283117, + "expire_by":1581013800, + "short_url":"https://rzp.io/i/m0y0f", + "has_scheduled_changes":false, + "change_scheduled_at":null, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count":12 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all subscriptions + +```py +client.subscription.all(options) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | +| plan_id | string | The unique identifier of the plan for which you want to retrieve all the subscriptions | + +**Response:** +```json + +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "sub_00000000000001", + "entity": "subscription", + "plan_id": "plan_00000000000001", + "customer_id": "cust_D00000000000001", + "status": "active", + "current_start": 1577355871, + "current_end": 1582655400, + "ended_at": null, + "quantity": 1, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "charge_at": 1577385991, + "offer_id": "offer_JHD834hjbxzhd38d", + "start_at": 1577385991, + "end_at": 1603737000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 1, + "customer_notify": true, + "created_at": 1577356081, + "expire_by": 1577485991, + "short_url": "https://rzp.io/i/z3b1R61A9", + "has_scheduled_changes": false, + "change_scheduled_at": null, + "remaining_count": 5 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch particular subscription + +```py +client.subscription.fetch(subscriptionId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to be fetched | + +**Response:** +```json +{ + "id": "sub_00000000000001", + "entity": "subscription", + "plan_id": "plan_00000000000001", + "customer_id": "cust_D00000000000001", + "status": "active", + "current_start": 1577355871, + "current_end": 1582655400, + "ended_at": null, + "quantity": 1, + "notes":{ + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "charge_at": 1577385991, + "start_at": 1577385991, + "end_at": 1603737000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 1, + "customer_notify": true, + "created_at": 1577356081, + "expire_by": 1577485991, + "short_url": "https://rzp.io/i/z3b1R61A9", + "has_scheduled_changes": false, + "change_scheduled_at": null, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count": 5 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Cancel particular subscription + +```py +client.subscription.cancel(subscriptionId,options) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to be cancelled | +| cancel_at_cycle_end | boolean | Possible values:
0 (default): Cancel the subscription immediately.
1: Cancel the subscription at the end of the current billing cycle. | + +**Response:** +```json +{ + "id": "sub_00000000000001", + "entity": "subscription", + "plan_id": "plan_00000000000001", + "customer_id": "cust_D00000000000001", + "status": "cancelled", + "current_start": 1580453311, + "current_end": 1581013800, + "ended_at": 1580288092, + "quantity": 1, + "notes":{ + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "charge_at": 1580453311, + "start_at": 1577385991, + "end_at": 1603737000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 1, + "customer_notify": true, + "created_at": 1580283117, + "expire_by": 1581013800, + "short_url": "https://rzp.io/i/z3b1R61A9", + "has_scheduled_changes": false, + "change_scheduled_at": null, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count": 5 +} +``` +------------------------------------------------------------------------------------------------------- + +### Update particular subscription + +```py +client.subscription.update(subscriptionId,options) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to be updated | +| options | object | All parameters listed [here](https://razorpay.com/docs/api/subscriptions/#update-a-subscription) for update | + +**Response:** +```json +{ + "id":"sub_00000000000002", + "entity":"subscription", + "plan_id":"plan_00000000000002", + "customer_id":"cust_00000000000002", + "status":"authenticated", + "current_start":null, + "current_end":null, + "ended_at":null, + "quantity":3, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "charge_at":1580453311, + "start_at":1580453311, + "end_at":1606588200, + "auth_attempts":0, + "total_count":6, + "paid_count":0, + "customer_notify":true, + "created_at":1580283807, + "expire_by":1580626111, + "short_url":"https://rzp.io/i/yeDkUKy", + "has_scheduled_changes":false, + "change_scheduled_at":null, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count":6 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch details of pending update + +```py +client.subscription.pending_update(subscriptionId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to fetch pending update | + +**Response:** +```json +{ + "id":"sub_00000000000001", + "entity":"subscription", + "plan_id":"plan_00000000000003", + "customer_id":"cust_00000000000001", + "status":"active", + "current_start":1580284732, + "current_end":1580841000, + "ended_at":null, + "quantity":25, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "charge_at":1580841000, + "start_at":1580284732, + "end_at":1611081000, + "auth_attempts":0, + "total_count":6, + "paid_count":1, + "customer_notify":true, + "created_at":1580284702, + "expire_by":1580626111, + "short_url":"https://rzp.io/i/fFWTkbf", + "has_scheduled_changes":true, + "change_scheduled_at":1557253800, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count":5 +} +``` +------------------------------------------------------------------------------------------------------- + +### Cancel a update + +```py +client.subscription.cancel_scheduled_changes(subscriptionId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to be cancel an update | + +**Response:** +```json +{ + "id": "sub_00000000000001", + "entity": "subscription", + "plan_id": "plan_00000000000003", + "customer_id": "cust_00000000000001", + "status": "active", + "current_start": 1580284732, + "current_end": 1580841000, + "ended_at": null, + "quantity": 1, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "charge_at": 1580841000, + "start_at": 1580284732, + "end_at": 1611081000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 1, + "customer_notify": true, + "created_at": 1580284702, + "expire_by": 1580626111, + "short_url": "https://rzp.io/i/fFWTkbf", + "has_scheduled_changes": false, + "change_scheduled_at": 1527858600, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count": 5 +} +``` +------------------------------------------------------------------------------------------------------- + +### Pause a subscription + +```py +client.subscription.pause(subscriptionId,{ + "pause_at" : "now" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to be paused | +| pause_at | string | To pause the subscription, possible values: `now` | + +**Response:** +```json +{ + "id": "sub_00000000000001", + "entity": "subscription", + "plan_id": "plan_00000000000001", + "status": "paused", + "current_start": null, + "current_end": null, + "ended_at": null, + "quantity": 1, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "charge_at": null, + "start_at": 1580626111, + "end_at": 1583433000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 0, + "customer_notify": true, + "created_at": 1580280581, + "paused_at": 1590280581, + "expire_by": 1580626111, + "pause_initiated_by": "self", + "short_url": "https://rzp.io/i/z3b1R61A9", + "has_scheduled_changes": false, + "change_scheduled_at": null, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count": 6 +} +``` +------------------------------------------------------------------------------------------------------- + +### Resume a subscription + +```py +client.subscription.resume(subscriptionId,{ + "resume_at" : "now" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to be resumed | +| resume_at | string | To resume the subscription, possible values: `now` | + +**Response:** +```json +{ + "id": "sub_00000000000001", + "entity": "subscription", + "plan_id": "plan_00000000000001", + "status": "active", + "current_start": null, + "current_end": null, + "ended_at": null, + "quantity": 1, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "charge_at": 1580453311, + "start_at": 1580626111, + "end_at": 1583433000, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 0, + "customer_notify": true, + "created_at": 1580280581, + "paused_at": 1590280581, + "expire_by": 1580626111, + "pause_initiated_by": null, + "short_url": "https://rzp.io/i/z3b1R61A9", + "has_scheduled_changes": false, + "change_scheduled_at": null, + "source": "api", + "offer_id":"offer_JHD834hjbxzhd38d", + "remaining_count": 6 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all invoices for a subscription + +```py +client.invoice.all({ + 'subscription_id':subscriptionId +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to fetch invoices | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "inv_00000000000003", + "entity": "invoice", + "receipt": null, + "invoice_number": null, + "customer_id": "cust_00000000000001", + "customer_details": { + "id": "cust_00000000000001", + "name": null, + "email": "gaurav.kumar@example.com", + "contact": "+919876543210", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": null, + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "+919876543210" + }, + "order_id": "order_00000000000002", + "subscription_id": "sub_00000000000001", + "line_items": [ + { + "id": "li_00000000000003", + "item_id": null, + "ref_id": null, + "ref_type": null, + "name": "Monthly Plan", + "description": null, + "amount": 99900, + "unit_amount": 99900, + "gross_amount": 99900, + "tax_amount": 0, + "taxable_amount": 99900, + "net_amount": 99900, + "currency": "INR", + "type": "plan", + "tax_inclusive": false, + "hsn_code": null, + "sac_code": null, + "tax_rate": null, + "unit": null, + "quantity": 1, + "taxes": [] + } + ], + "payment_id": "pay_00000000000002", + "status": "paid", + "expire_by": null, + "issued_at": 1593344888, + "paid_at": 1593344889, + "cancelled_at": null, + "expired_at": null, + "sms_status": null, + "email_status": null, + "date": 1593344888, + "terms": null, + "partial_payment": false, + "gross_amount": 99900, + "tax_amount": 0, + "taxable_amount": 99900, + "amount": 99900, + "amount_paid": 99900, + "amount_due": 0, + "currency": "INR", + "currency_symbol": "₹", + "description": null, + "notes": [], + "comment": null, + "short_url": "https://rzp.io/i/Ys4feGqEp", + "view_less": true, + "billing_start": 1594405800, + "billing_end": 1597084200, + "type": "invoice", + "group_taxes_discounts": false, + "created_at": 1593344888, + "idempotency_key": null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete offer linked to a subscription + +```py +client.subscription.delete_offer(subscriptionId, offerId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| subscriptionId* | string | The id of the subscription to offer need to be deleted | +| offerId* | string | The id of the offer linked to subscription | + +**Response:** +```json +{ + "id": "sub_I3GGEs7Xgmnozy", + "entity": "subscription", + "plan_id": "plan_HuXrfsI0ZZ3peu", + "customer_id": "cust_I3FToKbnExwDLu", + "status": "active", + "current_start": 1632914901, + "current_end": 1635445800, + "ended_at": null, + "quantity": 1, + "notes": [], + "charge_at": 1635445800, + "start_at": 1632914901, + "end_at": 1645986600, + "auth_attempts": 0, + "total_count": 6, + "paid_count": 1, + "customer_notify": true, + "created_at": 1632914246, + "expire_by": 1635532200, + "short_url": "https://rzp.io/i/SOvRWaYP81", + "has_scheduled_changes": false, + "change_scheduled_at": null, + "source": "dashboard", + "payment_method": "card", + "offer_id": null, + "remaining_count": 5 +} +``` +------------------------------------------------------------------------------------------------------- + +### Authentication Transaction + +Please refer this [doc](https://razorpay.com/docs/api/subscriptions/#authentication-transaction) for authentication of transaction + +------------------------------------------------------------------------------------------------------- + +### Payment verification +```py +client.utility.verify_payment_signature({ + 'razorpay_order_id': razorpay_order_id, + 'razorpay_payment_id': razorpay_payment_id, + 'razorpay_signature': razorpay_signature + }) +``` +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| body* | object | the response object of the successful payment `payment_id`, `order_id` and `signature` | +| secret* | string | The secret that was generated from the Dashboard | + +Please refer this [doc](https://razorpay.com/docs/api/subscriptions/#payment-verification) for payment verification + +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/subscriptions/#subscriptions)** \ No newline at end of file diff --git a/documents/token.md b/documents/token.md new file mode 100644 index 00000000..25aa91e9 --- /dev/null +++ b/documents/token.md @@ -0,0 +1,190 @@ +## Tokens + +### Fetch token by payment id +```py +client.payment.fetch(paymentId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | + +**Response:** +```json +{ + "id": "pay_FHfqtkRzWvxky4", + "entity": "payment", + "amount": 100, + "currency": "INR", + "status": "captured", + "order_id": "order_FHfnswDdfu96HQ", + "invoice_id": null, + "international": false, + "method": "card", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": null, + "card_id": "card_F0zoXUp4IPPGoI", + "bank": null, + "wallet": null, + "vpa": null, + "email": "gaurav.kumar@example.com", + "contact": "+919876543210", + "customer_id": "cust_DtHaBuooGHTuyZ", + "token_id": "token_FHfn3rIiM1Z8nr", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "auth_code": "541898" + }, + "created_at": 1595449871 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch tokens by customer id + +```py +client.token.all(customerId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "entity":"collection", + "count":1, + "items":[ + { + "id":"token_HouA2OQR5Z2jTL", + "entity":"token", + "token":"2JPRk664pZHUWG", + "bank":null, + "wallet":null, + "method":"card", + "card":{ + "entity":"card", + "name":"Gaurav Kumar", + "last4":"8950", + "network":"Visa", + "type":"credit", + "issuer":"STCB", + "international":false, + "emi":false, + "sub_type":"consumer", + "expiry_month":12, + "expiry_year":2021, + "flows":{ + "otp":true, + "recurring":true + } + }, + "recurring":true, + "recurring_details":{ + "status":"confirmed", + "failure_reason":null + }, + "auth_type":null, + "mrn":null, + "used_at":1629779657, + "created_at":1629779657, + "expired_at":1640975399, + "dcc_enabled":false, + "billing_address":null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch particular token +```py +client.token.fetch(customerId, tokenId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | + +**Response:** +```json +{ + "id": "token_Hxe0skTXLeg9pF", + "entity": "token", + "token": "F85BgXnGVwcuqV", + "bank": null, + "wallet": null, + "method": "card", + "card": { + "entity": "card", + "name": "ankit", + "last4": "5449", + "network": "MasterCard", + "type": "credit", + "issuer": "UTIB", + "international": false, + "emi": false, + "sub_type": "consumer", + "expiry_month": 12, + "expiry_year": 2024, + "flows": { + "recurring": true + } + }, + "recurring": true, + "auth_type": null, + "mrn": null, + "used_at": 1632976165, + "created_at": 1631687852, + "expired_at": 1634215992, + "dcc_enabled": false +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete token + +```py +client.token.delete(customerId, tokenId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | + +**Response:** +```json +{ + "deleted": true +} +``` +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/recurring-payments/upi/tokens/)** \ No newline at end of file diff --git a/documents/transfer.md b/documents/transfer.md new file mode 100644 index 00000000..4b05d266 --- /dev/null +++ b/documents/transfer.md @@ -0,0 +1,641 @@ +## Transfers + +### Create transfers from payment + +```py +client.payment.fetch({ + "transfers": { + "amount": 1000, + "currency": "INR", + "notes": { + "name": "Gaurav Kumar", + "roll_no": "IEC2011025" + }, + "linked_account_notes": [ + "branch" + ], + "on_hold": 1, + "on_hold_until": 1671222870 + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | +| transfers | object | All parameters listed [here](https://razorpay.com/docs/api/route/#create-transfers-from-payments) are supported | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "trf_E9uhYLFLLZ2pks", + "entity": "transfer", + "source": "pay_E8JR8E0XyjUSZd", + "recipient": "acc_CPRsN1LkFccllA", + "amount": 100, + "currency": "INR", + "amount_reversed": 0, + "notes": { + "name": "Gaurav Kumar", + "roll_no": "IEC2011025" + }, + "on_hold": true, + "on_hold_until": 1671222870, + "recipient_settlement_id": null, + "created_at": 1580218356, + "linked_account_notes": [ + "roll_no" + ], + "processed_at": 1580218357 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Create transfers from order + +```py +client.order.create({ + "amount": 2000, + "currency": "INR", + "transfers": [ + { + "account": "acc_CPRsN1LkFccllA", + "amount": 1000, + "currency": "INR", + "notes": { + "branch": "Acme Corp Bangalore North", + "name": "Gaurav Kumar" + }, + "linked_account_notes": [ + "branch" + ], + "on_hold": 1, + "on_hold_until": 1671222870 + }, + { + "account": "acc_CNo3jSI8OkFJJJ", + "amount": 1000, + "currency": "INR", + "notes": { + "branch": "Acme Corp Bangalore South", + "name": "Saurav Kumar" + }, + "linked_account_notes": [ + "branch" + ], + "on_hold": 0 + } + ] +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| amount* | integer | The transaction amount, in paise | +| currency* | string | The currency of the payment (defaults to INR) | +| receipt | string | A unique identifier provided by you for your internal reference. | +| transfers | object | All parameters listed [here](https://razorpay.com/docs/api/route/#create-transfers-from-orders) are supported | + +**Response:** +```json +{ + "id": "order_E9uTczH8uWPCyQ", + "entity": "order", + "amount": 2000, + "amount_paid": 0, + "amount_due": 2000, + "currency": "INR", + "receipt": null, + "offer_id": null, + "status": "created", + "attempts": 0, + "notes": [], + "created_at": 1580217565, + "transfers": [ + { + "recipient": "acc_CPRsN1LkFccllA", + "amount": 1000, + "currency": "INR", + "notes": { + "branch": "Acme Corp Bangalore North", + "name": "Gaurav Kumar" + }, + "linked_account_notes": [ + "branch" + ], + "on_hold": true, + "on_hold_until": 1671222870 + }, + { + "recipient": "acc_CNo3jSI8OkFJJJ", + "amount": 1000, + "currency": "INR", + "notes": { + "branch": "Acme Corp Bangalore South", + "name": "Saurav Kumar" + }, + "linked_account_notes": [ + "branch" + ], + "on_hold": false, + "on_hold_until": null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Direct transfers + +```py +client.transfer.create({ + "amount": 500, + "currency": "INR" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| accountId* | string | The id of the account to be fetched | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| currency* | string | The currency of the payment (defaults to INR) | + +**Response:** +```json +{ + "id": "trf_E9utgtfGTcpcmm", + "entity": "transfer", + "source": "acc_CJoeHMNpi0nC7k", + "recipient": "acc_CPRsN1LkFccllA", + "amount": 100, + "currency": "INR", + "amount_reversed": 0, + "notes": [], + "fees": 1, + "tax": 0, + "on_hold": false, + "on_hold_until": null, + "recipient_settlement_id": null, + "created_at": 1580219046, + "linked_account_notes": [], + "processed_at": 1580219046 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch transfer for a payment + +```py +client.payment.transfers(paymentId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "trf_EAznuJ9cDLnF7Y", + "entity": "transfer", + "source": "pay_E9up5WhIfMYnKW", + "recipient": "acc_CMaomTz4o0FOFz", + "amount": 1000, + "currency": "INR", + "amount_reversed": 100, + "notes": [], + "fees": 3, + "tax": 0, + "on_hold": false, + "on_hold_until": null, + "recipient_settlement_id": null, + "created_at": 1580454666, + "linked_account_notes": [], + "processed_at": 1580454666 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch transfer for an order + +```py +client.order.fetch({ + "expand[]": "transfers" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| orderId* | string | The id of the order to be fetched | +| expand* | string | Supported value is `transfer` | + +**Response:** +```json +{ + "id": "order_DSkl2lBNvueOly", + "entity": "order", + "amount": 1000, + "amount_paid": 1000, + "amount_due": 0, + "currency": "INR", + "receipt": null, + "offer_id": null, + "status": "paid", + "attempts": 1, + "notes": [], + "created_at": 1570794714, + "transfers": { + "entity": "collection", + "count": 1, + "items": [ + { + "id": "trf_DSkl2lXWbiADZG", + "entity": "transfer", + "source": "order_DSkl2lBNvueOly", + "recipient": "acc_CNo3jSI8OkFJJJ", + "amount": 500, + "currency": "INR", + "amount_reversed": 0, + "notes": { + "branch": "Acme Corp Bangalore North", + "name": "Gaurav Kumar" + }, + "fees": 2, + "tax": 0, + "on_hold": true, + "on_hold_until": 1670776632, + "recipient_settlement_id": null, + "created_at": 1570794714, + "linked_account_notes": [ + "Acme Corp Bangalore North" + ], + "processed_at": 1570794772 + } + ] + } +} + +``` +------------------------------------------------------------------------------------------------------- + +### Fetch transfer + +```py +client.transfer.fetch(transferId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| transferId* | string | The id of the transfer to be fetched | + +**Response:** +```json +{ + "id": "trf_E7V62rAxJ3zYMo", + "entity": "transfer", + "source": "pay_E6j30Iu1R7XbIG", + "recipient": "acc_CMaomTz4o0FOFz", + "amount": 100, + "currency": "INR", + "amount_reversed": 0, + "notes": [], + "fees": 1, + "tax": 0, + "on_hold": false, + "on_hold_until": null, + "recipient_settlement_id": null, + "created_at": 1579691505, + "linked_account_notes": [], + "processed_at": 1579691505 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch transfers for a settlement + +```py +client.transfer.all({ + "recipient_settlement_id" : recipientSettlementId +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| recipientSettlementId* | string | The recipient settlement id obtained from the settlement.processed webhook payload. | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "trf_DGSTeXzBkEVh48", + "entity": "transfer", + "source": "pay_DGSRhvMbOqeCe7", + "recipient": "acc_CMaomTz4o0FOFz", + "amount": 500, + "currency": "INR", + "amount_reversed": 0, + "notes": [], + "fees": 2, + "tax": 0, + "on_hold": false, + "on_hold_until": null, + "recipient_settlement_id": "setl_DHYJ3dRPqQkAgV", + "created_at": 1568110256, + "linked_account_notes": [], + "processed_at": null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch settlement details + +```py +client.transfer.all({ + 'expand[]':'recipient_settlement' +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| expand* | string | Supported value is `recipient_settlement` | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "trf_DGSTeXzBkEVh48", + "entity": "transfer", + "source": "pay_DGSRhvMbOqeCe7", + "recipient": "acc_CMaomTz4o0FOFz", + "amount": 500, + "currency": "INR", + "amount_reversed": 0, + "notes": [], + "fees": 2, + "tax": 0, + "on_hold": false, + "on_hold_until": null, + "recipient_settlement_id": "setl_DHYJ3dRPqQkAgV", + "recipient_settlement": { + "id": "setl_DHYJ3dRPqQkAgV", + "entity": "settlement", + "amount": 500, + "status": "failed", + "fees": 0, + "tax": 0, + "utr": "CN0038699836", + "created_at": 1568349124 + }, + "created_at": 1568110256, + "linked_account_notes": [], + "processed_at": null + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Refund payments and reverse transfer from a linked account + +```py +client.payment.refund(paymentId,{ + "amount" : 100, + "reverse_all" : 1 +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | +| amount* | integer | The amount to be captured (should be equal to the authorized amount, in paise) | +| reverse_all | boolean | Reverses transfer made to a linked account. Possible values:
* `1` - Reverses transfer made to a linked account.
* `0` - Does not reverse transfer made to a linked account.| + +**Response:** +```json +{ + "id": "rfnd_EAzovSwG8jBnGf", + "entity": "refund", + "amount": 100, + "currency": "INR", + "payment_id": "pay_EAdwQDe4JrhOFX", + "notes": [], + "receipt": null, + "acquirer_data": { + "rrn": null + }, + "created_at": 1580454723 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch payments of a linked account + +```py +client.payment.all({ + 'X-Razorpay-Account': linkedAccountId +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| X-Razorpay-Account | string | The linked account id to fetch the payments received by linked account | + +**Response:** +```json +{ + "entity": "collection", + "count": 2, + "items": [ + { + "id": "pay_E9uth3WhYbh9QV", + "entity": "payment", + "amount": 100, + "currency": "INR", + "status": "captured", + "order_id": null, + "invoice_id": null, + "international": null, + "method": "transfer", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": null, + "card_id": null, + "bank": null, + "wallet": null, + "vpa": null, + "email": "", + "contact": null, + "notes": [], + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "created_at": 1580219046 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Reverse transfers from all linked accounts + +```py +client.transfer.reverse(transferId,{ + "amount":100 +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| transferId* | string | The id of the transfer to be fetched | +| amount | integer | The amount to be captured (should be equal to the authorized amount, in paise) | + +**Response:** +```json +{ + "id": "rvrsl_EB0BWgGDAu7tOz", + "entity": "reversal", + "transfer_id": "trf_EAznuJ9cDLnF7Y", + "amount": 100, + "fee": 0, + "tax": 0, + "currency": "INR", + "notes": [], + "initiator_id": "CJoeHMNpi0nC7k", + "customer_refund_id": null, + "created_at": 1580456007 +} +``` +------------------------------------------------------------------------------------------------------- + +### Hold settlements for transfers +```py +client.payment.transfer(paymentId,{ + "amount": 500, + "currency": "INR", + "on_hold": "1" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | +| transfers | array | All parameters listed here https://razorpay.com/docs/api/route/#hold-settlements-for-transfers are supported | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "trf_EB1VJ4Ux4GMmxQ", + "entity": "transfer", + "source": "pay_EB1R2s8D4vOAKG", + "recipient": "acc_CMaomTz4o0FOFz", + "amount": 100, + "currency": "INR", + "amount_reversed": 0, + "notes": [], + "fees": 1, + "tax": 0, + "on_hold": true, + "on_hold_until": null, + "recipient_settlement_id": null, + "created_at": 1580460652, + "linked_account_notes": [], + "processed_at": 1580460652 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Modify settlement hold for transfers +```py +client.transfer.edit(paymentId,{ + "on_hold": "1", + "on_hold_until": "1679691505" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| paymentId* | string | The id of the payment to be fetched | +| transfers | array | All parameters listed here https://razorpay.com/docs/api/route/#hold-settlements-for-transfers are supported | + +**Response:** +```json +{ + "id": "trf_EB17rqOUbzSCEE", + "entity": "transfer", + "source": "pay_EAeSM2Xul8xYRo", + "recipient": "acc_CMaomTz4o0FOFz", + "amount": 100, + "currency": "INR", + "amount_reversed": 0, + "notes": [], + "fees": 1, + "tax": 0, + "on_hold": true, + "on_hold_until": 1679691505, + "recipient_settlement_id": null, + "created_at": 1580459321, + "linked_account_notes": [], + "processed_at": 1580459321 +} +``` + +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/route/#transfers/)** \ No newline at end of file diff --git a/documents/upi.md b/documents/upi.md new file mode 100644 index 00000000..3a1471af --- /dev/null +++ b/documents/upi.md @@ -0,0 +1,517 @@ +## UPI + +### Create customer +```py +client.customer.create({ + "name": "Gaurav Kumar", + "contact": 9123456780, + "email": "gaurav.kumar@example.com", + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| name* | string | Name of the customer | +| email | string | Email of the customer | +| contact | string | Contact number of the customer | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "cust_1Aa00000000003", + "entity": "customer", + "name": "Gaurav Kumar", + "email": "Gaurav.Kumar@example.com", + "contact": "9000000000", + "gstin": null, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1582033731 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Create order + +```py +client.order.create({ + "amount": 0, + "currency": "INR", + "method": "upi", + "customer_id": "cust_1Aa00000000001", + "receipt": "Receipt No. 1", + "notes": { + "notes_key_1": "Beam me up Scotty", + "notes_key_2": "Engage" + }, + "token": { + "auth_type": "netbanking", + "max_amount": 9999900, + "expire_at": 4102444799, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + } + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | Amount of the order to be paid | +| currency* | string | Currency of the order. Currently only `INR` is supported. | +| method* | string | The authorization method. In this case the value will be `emandate` | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | +| token | object | A key-value pair | + +**Response:** +```json +{ + "id": "order_1Aa00000000002", + "entity": "order", + "amount": 100, + "amount_paid": 0, + "amount_due": 100, + "currency": "INR", + "receipt": "Receipt No. 1", + "offer_id": null, + "status": "created", + "attempts": 0, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1565172642 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create an Authorization Payment + +Please refer this [doc](https://razorpay.com/docs/api/recurring-payments/upi/authorization-transaction/#113-create-an-authorization-payment) for authorization payment + +------------------------------------------------------------------------------------------------------- + +### Create registration link + +```py +client.registration_link.create({ + "customer": { + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": 9123456780 + }, + "type": "link", + "amount": 100, + "currency": "INR", + "description": "12 p.m. Meals", + "subscription_registration": { + "method": "upi", + "expire_at": 1580480689, + "max_amount": 500, + }, + "receipt": "Receipt no. 1", + "expire_by": 1880480689, + "sms_notify": 1, + "email_notify": 1, + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| customer | object | Details of the customer to whom the registration link will be sent. | +| type* | string | In this case, the value is `link`. | +| currency* | string | The 3-letter ISO currency code for the payment. Currently, only `INR` is supported. | +| amount* | integer | The payment amount in the smallest currency sub-unit. | +| description* | string | A description that appears on the hosted page. For example, `12:30 p.m. Thali meals (Gaurav Kumar`). | +| subscription_registration | object | Details of the authorization payment. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "inv_FHr1ekX0r2VCVK", + "entity": "invoice", + "receipt": "Receipt No. 23", + "invoice_number": "Receipt No. 23", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHr1ehR3nmNeXo", + "line_items": [], + "payment_id": null, + "status": "issued", + "expire_by": 4102444799, + "issued_at": 1595489219, + "paid_at": null, + "cancelled_at": null, + "expired_at": null, + "sms_status": "pending", + "email_status": "pending", + "date": 1595489219, + "terms": null, + "partial_payment": false, + "gross_amount": 100, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 100, + "amount_paid": 0, + "amount_due": 100, + "currency": "INR", + "currency_symbol": "₹", + "description": "Registration Link for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/ak1WxDB", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595489219, + "idempotency_key": null +} +``` +------------------------------------------------------------------------------------------------------- + +### Send/Resend notifications + +```py +client.invoice.notify_by(invoiceId, medium) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be notified | +| medium* | string | `sms`/`email`, Medium through which notification should be sent. | + +**Response:** +```json +{ + "success": true +} +``` +------------------------------------------------------------------------------------------------------- + +### Cancel a registration link + +```py +client.invoice.cancel(invoiceId) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| invoiceId* | string | The id of the invoice to be cancelled | + +**Response:** +```json +{ + "id": "inv_FHrfRupD2ouKIt", + "entity": "invoice", + "receipt": "Receipt No. 1", + "invoice_number": "Receipt No. 1", + "customer_id": "cust_BMB3EwbqnqZ2EI", + "customer_details": { + "id": "cust_BMB3EwbqnqZ2EI", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "contact": "9123456780", + "gstin": null, + "billing_address": null, + "shipping_address": null, + "customer_name": "Gaurav Kumar", + "customer_email": "gaurav.kumar@example.com", + "customer_contact": "9123456780" + }, + "order_id": "order_FHrfRw4TZU5Q2L", + "line_items": [], + "payment_id": null, + "status": "cancelled", + "expire_by": 4102444799, + "issued_at": 1595491479, + "paid_at": null, + "cancelled_at": 1595491488, + "expired_at": null, + "sms_status": "sent", + "email_status": "sent", + "date": 1595491479, + "terms": null, + "partial_payment": false, + "gross_amount": 100, + "tax_amount": 0, + "taxable_amount": 0, + "amount": 100, + "amount_paid": 0, + "amount_due": 100, + "currency": "INR", + "currency_symbol": "₹", + "description": "Registration Link for Gaurav Kumar", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "comment": null, + "short_url": "https://rzp.io/i/QlfexTj", + "view_less": true, + "billing_start": null, + "billing_end": null, + "type": "link", + "group_taxes_discounts": false, + "created_at": 1595491480, + "idempotency_key": null +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch token by payment ID + +```py +client.payment.fetch(paymentId) +``` + +**Parameters:** + +| Name | Type | Description | +|------------|--------|-----------------------------------| +| paymentId* | string | Id of the payment to be retrieved | + +**Response:** +```json +{ + "id": "pay_FHfAzEJ51k8NLj", + "entity": "payment", + "amount": 100, + "currency": "INR", + "status": "captured", + "order_id": "order_FHfANdTUYeP8lb", + "invoice_id": null, + "international": false, + "method": "upi", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": null, + "card_id": null, + "bank": null, + "wallet": null, + "vpa": "gaurav.kumar@upi", + "email": "gaurav.kumar@example.com", + "contact": "+919876543210", + "customer_id": "cust_DtHaBuooGHTuyZ", + "token_id": "token_FHfAzGzREc1ug6", + "notes": { + "note_key 1": "Beam me up Scotty", + "note_key 2": "Tea. Earl Gray. Hot." + }, + "fee": 0, + "tax": 0, + "error_code": null, + "error_description": null, + "error_source": null, + "error_step": null, + "error_reason": null, + "acquirer_data": { + "rrn": "854977234911", + "upi_transaction_id": "D0BED5A062ECDB3E9B3A1071C96BB273" + }, + "created_at": 1595447490 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch tokens by customer ID + +```py +client.token.all(customerId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "token_FHfAzGzREc1ug6", + "entity": "token", + "token": "9KHsdPaCELeQ0t", + "bank": null, + "wallet": null, + "method": "upi", + "vpa": { + "username": "gaurav.kumar", + "handle": "upi", + "name": null + }, + "recurring": true, + "recurring_details": { + "status": "confirmed", + "failure_reason": null + }, + "auth_type": null, + "mrn": null, + "used_at": 1595447490, + "created_at": 1595447490, + "start_time": 1595447455, + "dcc_enabled": false + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete token + +```py +client.token.delete(customerId,tokenId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| tokenId* | string | The id of the token to be fetched | + +**Response:** +```json +{ + "deleted": true +} +``` +------------------------------------------------------------------------------------------------------- + +### Create an order to charge the customer + +```py +client.order.create({ + "amount":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "notes": { + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| amount* | integer | Amount of the order to be paid | +| currency* | string | Currency of the order. Currently only `INR` is supported. | +| receipt | string | Your system order reference id. | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id":"order_1Aa00000000002", + "entity":"order", + "amount":1000, + "amount_paid":0, + "amount_due":1000, + "currency":"INR", + "receipt":"Receipt No. 1", + "offer_id":null, + "status":"created", + "attempts":0, + "notes":{ + "notes_key_1":"Tea, Earl Grey, Hot", + "notes_key_2":"Tea, Earl Grey… decaf." + }, + "created_at":1579782776 +} +``` +------------------------------------------------------------------------------------------------------- + +### Create a recurring payment + +```py +client.payment.createRecurring({ + "email": "gaurav.kumar@example.com", + "contact": "9123456789", + "amount": 1000, + "currency": "INR", + "order_id": "order_1Aa00000000002", + "customer_id": "cust_1Aa00000000001", + "token": "token_1Aa00000000001", + "recurring": "1", + "description": "Creating recurring payment for Gaurav Kumar", +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-----------------|---------|------------------------------------------------------------------------------| +| email* | string | The customer's email address. | +| contact* | string | The customer's phone number. | +| amount* | integer | The amount you want to charge your customer. This should be the same as the amount in the order. | +| currency* | string | The 3-letter ISO currency code for the payment. Currently, only `INR` is supported. | +| order_id* | string | The unique identifier of the order created. | +| customer_id* | string | The `customer_id` for the customer you want to charge. | +| token* | string | The `token_id` generated when the customer successfully completes the authorization payment. Different payment instruments for the same customer have different `token_id`.| +| recurring* | string | Determines if recurring payment is enabled or not. Possible values:
* `1` - Recurring is enabled.* `0` - Recurring is not enabled.| +| description* | string | A user-entered description for the payment.| +| notes* | object | Key-value pair that can be used to store additional information about the entity. Maximum 15 key-value pairs, 256 characters (maximum) each. | + +**Response:** +```json +{ + "razorpay_payment_id" : "pay_1Aa00000000001", + "razorpay_order_id" : "order_1Aa00000000001", + "razorpay_signature" : "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d" +} +``` +------------------------------------------------------------------------------------------------------- + + + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/recurring-payments/upi/authorization-transaction/)** \ No newline at end of file diff --git a/documents/virtualAccount.md b/documents/virtualAccount.md new file mode 100644 index 00000000..9fc8d178 --- /dev/null +++ b/documents/virtualAccount.md @@ -0,0 +1,551 @@ +## Virtual account + +### Create a virtual account +```py +client.virtual_account.create({ + "receivers": { + "types": [ + "bank_account" + ] + }, + "description": "Virtual Account created for Raftar Soft", + "customer_id": "cust_CaVDm8eDRSXYME", + "close_by": 1681615838, + "notes": { + "project_name": "Banking Software" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| receivers* | object | Array that defines what receivers are available for this Virtual Account | +| description | string | A brief description of the virtual account. | +| customer_id | string | Unique identifier of the customer to whom the virtual account must be tagged. | +| close_by | integer | UNIX timestamp at which the virtual account is scheduled to be automatically closed. | +| notes | integer | Any custom notes you might want to add to the virtual account can be entered here. | + +**Response:** +```json +{ + "id":"va_DlGmm7jInLudH9", + "name":"Acme Corp", + "entity":"virtual_account", + "status":"active", + "description":"Virtual Account created for Raftar Soft", + "amount_expected":null, + "notes":{ + "project_name":"Banking Software" + }, + "amount_paid":0, + "customer_id":"cust_CaVDm8eDRSXYME", + "receivers":[ + { + "id":"ba_DlGmm9mSj8fjRM", + "entity":"bank_account", + "ifsc":"RATN0VAAPIS", + "bank_name": "RBL Bank", + "name":"Acme Corp", + "notes":[], + "account_number":"2223330099089860" + } + ], + "close_by":1681615838, + "closed_at":null, + "created_at":1574837626 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Create a virtual account with TPV +```py +client.virtual_account.create({ + "receivers": { + "types": [ + "bank_account" + ] + }, + "allowed_payers": [ + { + "type": "bank_account", + "bank_account": { + "ifsc": "RATN0VAAPIS", + "account_number": 2223330027558515 + } + } + ], + "description": "Virtual Account created for Raftar Soft", + "customer_id": "cust_HssUOFiOd2b1TJ", + "notes": { + "project_name": "Banking Software" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| receivers* | object | Array that defines what receivers are available for this Virtual Account | +| allowed_payers* | object | All parameters listed [here](https://razorpay.com/docs/api/smart-collect-tpv/#create-virtual-account) are supported | +| description | string | A brief description of the virtual account. | +| customer_id | string | Unique identifier of the customer to whom the virtual account must be tagged. | +| notes | integer | Any custom notes you might want to add to the virtual account can be entered here. | + +**Response:** +```json +{ + "id":"va_DlGmm7jInLudH9", + "name":"Acme Corp", + "entity":"virtual_account", + "status":"active", + "description":"Virtual Account created for Raftar Soft", + "amount_expected":null, + "notes":{ + "project_name":"Banking Software" + }, + "amount_paid":0, + "customer_id":"cust_CaVDm8eDRSXYME", + "receivers":[ + { + "id":"ba_DlGmm9mSj8fjRM", + "entity":"bank_account", + "ifsc":"RATN0VAAPIS", + "bank_name": "RBL Bank", + "name":"Acme Corp", + "notes":[], + "account_number":"2223330099089860" + } + ], + "allowed_payers": [ + { + "type": "bank_account", + "id":"ba_DlGmm9mSj8fjRM", + "bank_account": { + "ifsc": "UTIB0000013", + "account_number": "914010012345679" + } + }, + { + "type": "bank_account", + "id":"ba_Cmtnm5tSj6agUW", + "bank_account": { + "ifsc": "UTIB0000014", + "account_number": "914010012345680" + } + } + ], + "close_by":1681615838, + "closed_at":null, + "created_at":1574837626 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Create static/dynamic qr +```py +client.virtual_account.create({ + receivers: { + types: [ + "qr_code" + ] + }, + description: "First QR code", + amount_expected: 100, + notes: { + receiver_key: "receiver_value" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| receivers* | array | Array that defines what receivers are available for this Virtual Account | +| description | string | A brief description of the payment. | +| amount_expected | integer | The maximum amount you expect to receive in this virtual account. Pass `69999` for ₹699.99. | +| notes | object | All keys listed [here](https://razorpay.com/docs/payments/payments/payment-methods/bharatqr/api/#create) are supported | + +**Response:** +```json +{ + "id": "va_4xbQrmEoA5WJ0G", + "name": "Acme Corp", + "entity": "virtual_account", + "status": "active", + "description": "First Payment by BharatQR", + "amount_expected": null, + "notes": { + "reference_key": "reference_value" + }, + "amount_paid": 0, + "customer_id": "cust_805c8oBQdBGPwS", + "receivers": [ + { + "id": "qr_4lsdkfldlteskf", + "entity": "qr_code", + "reference": "AgdeP8aBgZGckl", + "short_url": "https://rzp.io/i/PLs03pOc" + } + ], + "close_by": null, + "closed_at": null, + "created_at": 1607938184 +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch virtual account by id +```py +client.virtual_account.fetch(virtualId) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| virtualId* | string | The id of the virtual to be updated | + +**Response:** +For fetch virtual account by id response please click [here](https://razorpay.com/docs/api/smart-collect/#fetch-a-virtual-account-by-id) +------------------------------------------------------------------------------------------------------- + +### Fetch all virtual account +```py +client.virtual_account.all(options) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "va_Di5gbNptcWV8fQ", + "name": "Acme Corp", + "entity": "virtual_account", + "status": "closed", + "description": "Virtual Account created for M/S ABC Exports", + "amount_expected": 2300, + "notes": { + "material": "teakwood" + }, + "amount_paid": 239000, + "customer_id": "cust_DOMUFFiGdCaCUJ", + "receivers": [ + { + "id": "ba_Di5gbQsGn0QSz3", + "entity": "bank_account", + "ifsc": "RATN0VAAPIS", + "bank_name": "RBL Bank", + "name": "Acme Corp", + "notes": [], + "account_number": "1112220061746877" + } + ], + "close_by": 1574427237, + "closed_at": 1574164078, + "created_at": 1574143517 + } + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch payments for a virtual account +```py +client.virtual_account.payments(virtualId,options) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| virtualId* | string | The id of the virtual to be updated | +| from | timestamp | timestamp after which the payments were created | +| to | timestamp | timestamp before which the payments were created | +| count | integer | number of payments to fetch (default: 10) | +| skip | integer | number of payments to be skipped (default: 0) | + +**Response:** +```json +{ + "entity": "collection", + "count": 1, + "items": [ + { + "id": "pay_Di5iqCqA1WEHq6", + "entity": "payment", + "amount": 239000, + "currency": "INR", + "status": "captured", + "order_id": null, + "invoice_id": null, + "international": false, + "method": "bank_transfer", + "amount_refunded": 0, + "refund_status": null, + "captured": true, + "description": "", + "card_id": null, + "bank": null, + "wallet": null, + "vpa": null, + "email": "saurav.kumar@example.com", + "contact": "+919972139994", + "customer_id": "cust_DOMUFFiGdCaCUJ", + "notes": [], + "fee": 2820, + "tax": 430, + "error_code": null, + "error_description": null, + "created_at": 1574143644 + } + ] +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch payment details using id and transfer method +```py +client.payment.bank_transfer(paymentId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| virtualId* | string | The id of the virtual to be updated | + +**Response:** +```json +{ + "id": "bt_Di5iqCElVyRlCb", + "entity": "bank_transfer", + "payment_id": "pay_Di5iqCqA1WEHq6", + "mode": "NEFT", + "bank_reference": "157414364471", + "amount": 239000, + "payer_bank_account": { + "id": "ba_Di5iqSxtYrTzPU", + "entity": "bank_account", + "ifsc": "UTIB0003198", + "bank_name": "Axis Bank", + "name": "Acme Corp", + "notes": [], + "account_number": "765432123456789" + }, + "virtual_account_id": "va_Di5gbNptcWV8fQ", + "virtual_account": { + "id": "va_Di5gbNptcWV8fQ", + "name": "Acme Corp", + "entity": "virtual_account", + "status": "closed", + "description": "Virtual Account created for M/S ABC Exports", + "amount_expected": 2300, + "notes": { + "material": "teakwood" + }, + "amount_paid": 239000, + "customer_id": "cust_DOMUFFiGdCaCUJ", + "receivers": [ + { + "id": "ba_Di5gbQsGn0QSz3", + "entity": "bank_account", + "ifsc": "RATN0VAAPIS", + "bank_name": "RBL Bank", + "name": "Acme Corp", + "notes": [], + "account_number": "1112220061746877" + } + ], + "close_by": 1574427237, + "closed_at": 1574164078, + "created_at": 1574143517 + } +} +``` +------------------------------------------------------------------------------------------------------- + +### Refund payments made to a virtual account +```py +client.payment.refund(paymentId,{ + "amount": "100", + "speed": "normal", + "notes": { + "notes_key_1": "Beam me up Scotty.", + "notes_key_2": "Engage" + }, + "receipt": "Receipt No. 31" +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| paymentId* | string | The id of the payment to be updated | +| amount | integer | The amount to be captured (should be equal to the authorized amount, in paise) | | +| speed | string | Here, it must be normal | +| notes | array | A key-value pair | +| receipt | string | A unique identifier provided by you for your internal reference. | + +**Response:** +```json +{ + "id": "rfnd_E6j36ZEKvsWsEn", + "entity": "refund", + "amount": 100, + "currency": "INR", + "payment_id": "pay_E54n391WnEAV9H", + "notes": { + "key_1": "value1", + "key_2": "value2" + }, + "receipt": null, + "acquirer_data": { + "rrn": null + }, + "created_at": 1579522301 +} +``` +------------------------------------------------------------------------------------------------------- + +### Add receiver to an existing virtual account +```py +client.virtual_account.add_receiver(virtualId,{ + "type": [ + "vpa" + ], + "vpa": { + "descriptor": "gauravkumar" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| virtualId* | string | The id of the virtual to be updated | +| types* | object | The receiver type to be added to the virtual account. Possible values are `vpa` or `bank_account` | +| vpa | object | This is to be passed only when `vpa` is passed as the receiver types. | + +**Response:** +For add receiver to an existing virtual account response please click [here](https://razorpay.com/docs/api/smart-collect/#add-receiver-to-an-existing-virtual-account) + +------------------------------------------------------------------------------------------------------- + +### Add an Allowed Payer Account +```py +client.virtual_account.add_allowed_player(virtualId,{ + "types": "bank_account", + "bank_account": { + "ifsc": "UTIB0000013", + "account_number": 914010012345679 + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| virtualId* | string | The id of the virtual to be updated | +| types* | object | The receiver type to be added to the virtual account. Possible values are `vpa` or `bank_account` | +| bank_account* | object | Indicates the bank account details such as `ifsc` and `account_number` | + +**Response:** +```json +{ + "id":"va_DlGmm7jInLudH9", + "name":"Acme Corp", + "entity":"virtual_account", + "status":"active", + "description":"Virtual Account created for Raftar Soft", + "amount_expected":null, + "notes":{ + "project_name":"Banking Software" + }, + "amount_paid":0, + "customer_id":"cust_CaVDm8eDRSXYME", + "receivers":[ + { + "id":"ba_DlGmm9mSj8fjRM", + "entity":"bank_account", + "ifsc":"RATN0VAAPIS", + "bank_name": "RBL Bank", + "name":"Acme Corp", + "notes":[], + "account_number":"2223330099089860" + } + ], + "allowed_payers": [ + { + "type": "bank_account", + "id":"ba_DlGmm9mSj8fjRM", + "bank_account": { + "ifsc": "UTIB0000013", + "account_number": "914010012345679" + } + } + ], + "close_by":1681615838, + "closed_at":null, + "created_at":1574837626 +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete an Allowed Payer Account +```py +client.virtual_account.delete_allowed_player(virtualId,allowedPayersId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| virtualId* | string | The id of the virtual to be updated | +| allowedPayersId* | string | The id of the allowed payers to be updated | + +**Response:** +```json +{} +``` +------------------------------------------------------------------------------------------------------- +### Close virtual account +```py +client.virtual_account.close(virtualId) +``` + +**Parameters:** + +| Name | Type | Description | +|-------|-----------|--------------------------------------------------| +| virtualId* | string | The id of the virtual to be updated | + +**Response:** +For close virtual account response please click [here](https://razorpay.com/docs/api/smart-collect/#close-a-virtual-account) +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/smart-collect/api/)** \ No newline at end of file diff --git a/setup.py b/setup.py index cccc6709..36562c2c 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setup( name="razorpay", - version="1.2.0", + version="1.3.0", description="Razorpay Python Client", long_description=readme_content, long_description_content_type='text/markdown', From a39c05803d22fbdfbe08601d2975af57ce4c95a5 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Fri, 21 Jan 2022 10:05:30 +0530 Subject: [PATCH 20/25] delete testing file --- test.py | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 test.py diff --git a/test.py b/test.py deleted file mode 100644 index 44fc3081..00000000 --- a/test.py +++ /dev/null @@ -1,31 +0,0 @@ -import razorpay -import requests -from pprint import pprint -import json - -client = razorpay.Client(auth=("rzp_test_k6uL897VPBz20q", "EnLs21M47BllR3X8PSFtjtbd")) - - -DATA = { - "type": "bank_account", - "bank_account": { - "ifsc": "UTIB0000013", - "account_number": "914010012345679" - } -} - -# sig = '07ae18789e35093e51d0a491eb9922646f3f82773547e5b0f67ee3f2d3bf7d5b' -# parameters = {} -# parameters['razorpay_payment_id'] = 'pay_IH3d0ara9bSsjQ' -# parameters['payment_link_id'] = 'plink_IH3cNucfVEgV68' -# parameters['payment_link_reference_id'] = 'TSsd1989' -# parameters['payment_link_status'] = 'paid' -# parameters['razorpay_signature'] = sig - -#x = client.subscription.delete_offer('sub_IjA0wMVJdFnyzx','offer_IjA06IHSz33cw2') -#response = json.load(x) -#print(x) -# if(x==''): -# return True -# else: -# return False From eb0476dbbf5d02c5d4a85fb7e137b8f9c888c7e6 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Mon, 31 Jan 2022 11:51:38 +0530 Subject: [PATCH 21/25] client testcase fixed --- tests/test_client_token.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_client_token.py b/tests/test_client_token.py index 446b24ed..c95efc38 100644 --- a/tests/test_client_token.py +++ b/tests/test_client_token.py @@ -16,7 +16,7 @@ def test_tokens_all(self): url = '{}/{}/tokens'.format(self.base_url, self.customer_id) responses.add(responses.GET, url, status=200, body=json.dumps(result), match_querystring=True) - self.assertEqual(self.client.token.all(self.customer_id, self.token_id), + self.assertEqual(self.client.token.all(self.customer_id), result) @responses.activate From 8edece112736326c50e42c7f6b2eeb8519c54358 Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Mon, 31 Jan 2022 12:41:31 +0530 Subject: [PATCH 22/25] settlement recon testcase fixed --- tests/test_client_settlement.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_client_settlement.py b/tests/test_client_settlement.py index 590517de..0da26777 100644 --- a/tests/test_client_settlement.py +++ b/tests/test_client_settlement.py @@ -37,12 +37,11 @@ def test_settlement_fetch(self): @responses.activate def test_settlement_report(self): - init = {"year":2020,"month":9} result = mock_file('settlement_collection') url = "{}/recon/{}".format(self.base_url, 'combined') responses.add(responses.GET, url, status=200, body=json.dumps(result), match_querystring=True) - self.assertEqual(self.client.settlement.report(self.settlement_id), result) + self.assertEqual(self.client.settlement.report(), result) @responses.activate def test_settlement_create_ondemand_settlement(self): From e6ecaf889702074e2b58303728a7d5145616098c Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Tue, 1 Feb 2022 10:48:48 +0530 Subject: [PATCH 23/25] return empty dict --- razorpay/client.py | 2 +- razorpay/resources/virtual_account.py | 3 +-- tests/mocks/fake_delete_allowed_payer.json | 1 + tests/test_client_virtual_account.py | 9 +++++---- 4 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 tests/mocks/fake_delete_allowed_payer.json diff --git a/razorpay/client.py b/razorpay/client.py index e91d0cc1..ba9ad28b 100644 --- a/razorpay/client.py +++ b/razorpay/client.py @@ -122,7 +122,7 @@ def request(self, method, path, **options): **options) if ((response.status_code >= HTTP_STATUS_CODE.OK) and (response.status_code < HTTP_STATUS_CODE.REDIRECT)): - return response.json() if(len(response.text) > 0) else response.status_code + return json.dumps({}) if(response.status_code==204) else response.json() else: msg = "" code = "" diff --git a/razorpay/resources/virtual_account.py b/razorpay/resources/virtual_account.py index 4a4ad921..eb5834d8 100644 --- a/razorpay/resources/virtual_account.py +++ b/razorpay/resources/virtual_account.py @@ -104,5 +104,4 @@ def delete_allowed_player(self, virtual_account_id, allowed_player_id, data={}, 204 """ url = "{}/{}/allowed_payers/{}".format(self.base_url, virtual_account_id, allowed_player_id) - self.delete_url(url, data, **kwargs) - return json.dumps({ "success" : True }) + return self.delete_url(url, data, **kwargs) \ No newline at end of file diff --git a/tests/mocks/fake_delete_allowed_payer.json b/tests/mocks/fake_delete_allowed_payer.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/tests/mocks/fake_delete_allowed_payer.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/tests/test_client_virtual_account.py b/tests/test_client_virtual_account.py index 49f82086..8034c36c 100644 --- a/tests/test_client_virtual_account.py +++ b/tests/test_client_virtual_account.py @@ -151,14 +151,15 @@ def test_virtual_add_allowed_player(self): @responses.activate def test_virtual_delete_allowed_player(self): - result = json.dumps({ "success" : True }) + result = mock_file('fake_delete_allowed_payer') url = "{}/{}/allowed_payers/{}".format(self.base_url, self.fake_virtual_account_id, 'fake_allowed_player_id') responses.add(responses.DELETE, url, - status=200, + status=204, body=result, match_querystring=True) - self.assertEqual(self.client.virtual_account.delete_allowed_player( - self.fake_virtual_account_id, 'fake_allowed_player_id'), result) + response = self.client.virtual_account.delete_allowed_player( + self.fake_virtual_account_id, 'fake_allowed_player_id'); + self.assertEqual(response, result) \ No newline at end of file From 77c1539ba913f390dc7629460d23db02eafd132b Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Tue, 1 Feb 2022 13:52:03 +0530 Subject: [PATCH 24/25] added python ver --- .github/workflows/python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index b543080b..eed9b5c9 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -18,7 +18,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3, 3.5, 3.6] + python-version: [3, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10] steps: - uses: actions/checkout@v2 From 3df27fdbc534b8f41dfba077de7f3f3887860efc Mon Sep 17 00:00:00 2001 From: ankitdas13 Date: Tue, 1 Feb 2022 14:18:02 +0530 Subject: [PATCH 25/25] added changelog release date --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4ef6fb9..1ff90c41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format ## Unreleased -## [1.3.0][1.3.0] - 2022-01-17 +## [1.3.0][1.3.0] - 2022-02-01 ### Added - Added Item Api