├── .cursorignore ├── .editorconfig ├── .github ├── dependabot.yml ├── pull_request_template.md └── workflows │ ├── ci.yml │ ├── genesis.yml │ └── python.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── MANIFEST.in ├── README.md ├── documents ├── account.md ├── addon.md ├── card.md ├── customer.md ├── dispute.md ├── document.md ├── emandate.md ├── fund.md ├── iin.md ├── invoice.md ├── items.md ├── order.md ├── papernach.md ├── payment.md ├── paymentLink.md ├── paymentVerfication.md ├── plans.md ├── productConfiguration.md ├── qrcode.md ├── refund.md ├── registerEmandate.md ├── registerNach.md ├── settlement.md ├── stakeholder.md ├── subscription.md ├── token.md ├── transfer.md ├── upi.md ├── virtualAccount.md └── webhook.md ├── razorpay ├── __init__.py ├── ca-bundle.crt ├── client.py ├── constants │ ├── __init__.py │ ├── error_code.py │ ├── http_status_code.py │ └── url.py ├── errors.py ├── resources │ ├── __init__.py │ ├── account.py │ ├── addon.py │ ├── base.py │ ├── card.py │ ├── customer.py │ ├── dispute.py │ ├── document.py │ ├── fund_account.py │ ├── iin.py │ ├── invoice.py │ ├── item.py │ ├── order.py │ ├── payment.py │ ├── payment_link.py │ ├── plan.py │ ├── product.py │ ├── qrcode.py │ ├── refund.py │ ├── registration_link.py │ ├── settlement.py │ ├── stakeholder.py │ ├── subscription.py │ ├── token.py │ ├── transfer.py │ ├── virtual_account.py │ └── webhook.py └── utility │ ├── __init__.py │ └── utility.py ├── setup.py └── tests ├── __init__.py ├── helpers.py ├── mocks ├── addon_collection.json ├── bad_request_error.json ├── bank_account.json ├── cancel_payment_link.json ├── customer_collection.json ├── dispute.json ├── dispute_accept.json ├── dispute_collection.json ├── dispute_contest.json ├── document.json ├── edit_customer.json ├── edit_order.json ├── edit_payment.json ├── edit_payment_link.json ├── eligibility.json ├── eligibility_check.json ├── fake_account.json ├── fake_addon.json ├── fake_app_details.json ├── fake_bank_transfer.json ├── fake_captured_payment.json ├── fake_card.json ├── fake_card_detail_payment.json ├── fake_create_recurring.json ├── fake_customer.json ├── fake_delete_allowed_payer.json ├── fake_iin.json ├── fake_invoice.json ├── fake_invoice_cancel.json ├── fake_invoice_delete.json ├── fake_invoice_edit.json ├── fake_invoice_notify_by.json ├── fake_item.json ├── fake_merchant_token.json ├── fake_order.json ├── fake_otp_generate.json ├── fake_otp_resend.json ├── fake_otp_submit.json ├── fake_payment.json ├── fake_payment_authorized_webhook.json ├── fake_payment_json.json ├── fake_payment_link.json ├── fake_plan.json ├── fake_product.json ├── fake_qrcode.json ├── fake_reference_card.json ├── fake_refund.json ├── fake_registration_link.json ├── fake_reversal.json ├── fake_settlement.json ├── fake_stakeholder.json ├── fake_subscription.json ├── fake_subscription_addon.json ├── fake_subscription_cancelled.json ├── fake_subscription_paused.json ├── fake_subscription_resumed.json ├── fake_token.json ├── fake_transfer.json ├── fake_upi_transfer.json ├── fake_virtual_accounts.json ├── fake_virtual_accounts_closed.json ├── fake_virtual_accounts_receiver.json ├── fake_webhook.json ├── fulfillment.json ├── fund_account_collection.json ├── iin_collection.json ├── init_account.json ├── init_create_recurring.json ├── init_customer.json ├── init_invoice.json ├── init_invoice_edit.json ├── init_order.json ├── init_payment_link.json ├── init_plan.json ├── init_registration_link.json ├── init_settlement.json ├── init_stakeholder.json ├── init_subscription.json ├── init_transfer.json ├── init_virtual_accounts.json ├── init_webhook.json ├── invoice_collection.json ├── invoice_collection_with_one_invoice.json ├── item_collection.json ├── order_collection.json ├── order_collection_with_one_order.json ├── payment_collection.json ├── payment_collection_with_one_payment.json ├── payment_link_collection.json ├── plan_collection.json ├── qrcode_collection.json ├── qrcode_payments_collection.json ├── refund_collection.json ├── reversal_collection.json ├── rto.json ├── settlement_collection.json ├── settlement_collection_with_one_settlement.json ├── stakeholder_collection.json ├── subscription_collection.json ├── token_collection.json ├── token_collection_with_one_token.json ├── transfers_collection.json ├── transfers_collection_with_payment_id.json ├── virtual_accounts_collection.json ├── virtual_accounts_collection_with_one_item.json └── webhook_collection.json ├── test_client_account.py ├── test_client_addon.py ├── test_client_card.py ├── test_client_customer.py ├── test_client_dispute.py ├── test_client_document.py ├── test_client_error.py ├── test_client_fund_account.py ├── test_client_iin.py ├── test_client_invoice.py ├── test_client_item.py ├── test_client_order.py ├── test_client_payment.py ├── test_client_payment_link.py ├── test_client_plan.py ├── test_client_product.py ├── test_client_qrcode.py ├── test_client_refund.py ├── test_client_registration_link.py ├── test_client_settlement.py ├── test_client_stakeholder.py ├── test_client_subscription.py ├── test_client_token.py ├── test_client_transfer.py ├── test_client_utility.py ├── test_client_virtual_account.py ├── test_client_webhook.py ├── test_multiple_client.py └── test_user_agent.py /.cursorignore: -------------------------------------------------------------------------------- 1 | # Distribution and Environment 2 | dist/* 3 | build/* 4 | venv/* 5 | env/* 6 | *.env 7 | .env.* 8 | virtualenv/* 9 | .python-version 10 | .ruby-version 11 | .node-version 12 | 13 | # Logs and Temporary Files 14 | *.log 15 | *.tsv 16 | *.csv 17 | *.txt 18 | tmp/* 19 | temp/* 20 | .tmp/* 21 | *.temp 22 | *.cache 23 | .cache/* 24 | logs/* 25 | 26 | # Sensitive Data 27 | *.json 28 | *.xml 29 | *.yml 30 | *.yaml 31 | *.properties 32 | properties.json 33 | *.sqlite 34 | *.sqlite3 35 | *.dbsql 36 | secrets.* 37 | *secret* 38 | *password* 39 | *credential* 40 | .npmrc 41 | .yarnrc 42 | .aws/* 43 | .config/* 44 | 45 | # Credentials and Keys 46 | *.pem 47 | *.ppk 48 | *.key 49 | *.pub 50 | *.p12 51 | *.pfx 52 | *.htpasswd 53 | *.keystore 54 | *.jks 55 | *.truststore 56 | *.cer 57 | id_rsa* 58 | known_hosts 59 | authorized_keys 60 | .ssh/* 61 | .gnupg/* 62 | .pgpass 63 | 64 | # Config Files 65 | *.conf 66 | *.toml 67 | *.ini 68 | .env.local 69 | .env.development 70 | .env.test 71 | .env.production 72 | config/* 73 | 74 | # Documentation and Notes 75 | *.md 76 | *.mdx 77 | *.rst 78 | *.txt 79 | docs/* 80 | README* 81 | CHANGELOG* 82 | LICENSE* 83 | CONTRIBUTING* 84 | 85 | # Database Files 86 | *.sql 87 | *.db 88 | *.dmp 89 | *.dump 90 | *.backup 91 | *.restore 92 | *.mdb 93 | *.accdb 94 | *.realm* 95 | 96 | # Backup and Archive Files 97 | *.bak 98 | *.backup 99 | *.swp 100 | *.swo 101 | *.swn 102 | *~ 103 | *.old 104 | *.orig 105 | *.archive 106 | *.gz 107 | *.zip 108 | *.tar 109 | *.rar 110 | *.7z 111 | 112 | # Compiled and Binary Files 113 | *.pyc 114 | *.pyo 115 | **/__pycache__/** 116 | *.class 117 | *.jar 118 | *.war 119 | *.ear 120 | *.dll 121 | *.exe 122 | *.so 123 | *.dylib 124 | *.bin 125 | *.obj 126 | 127 | # IDE and Editor Files 128 | .idea/* 129 | *.iml 130 | .vscode/* 131 | .project 132 | .classpath 133 | .settings/* 134 | *.sublime-* 135 | .atom/* 136 | .eclipse/* 137 | *.code-workspace 138 | .history/* 139 | 140 | # Build and Dependency Directories 141 | node_modules/* 142 | bower_components/* 143 | vendor/* 144 | packages/* 145 | jspm_packages/* 146 | .gradle/* 147 | target/* 148 | out/* 149 | 150 | # Testing and Coverage Files 151 | coverage/* 152 | .coverage 153 | htmlcov/* 154 | .pytest_cache/* 155 | .tox/* 156 | junit.xml 157 | test-results/* 158 | 159 | # Mobile Development 160 | *.apk 161 | *.aab 162 | *.ipa 163 | *.xcarchive 164 | *.provisionprofile 165 | google-services.json 166 | GoogleService-Info.plist 167 | 168 | # Certificate and Security Files 169 | *.crt 170 | *.csr 171 | *.ovpn 172 | *.p7b 173 | *.p7s 174 | *.pfx 175 | *.spc 176 | *.stl 177 | *.pem.crt 178 | ssl/* 179 | 180 | # Container and Infrastructure 181 | *.tfstate 182 | *.tfstate.backup 183 | .terraform/* 184 | .vagrant/* 185 | docker-compose.override.yml 186 | kubernetes/* 187 | 188 | # Design and Media Files (often large and binary) 189 | *.psd 190 | *.ai 191 | *.sketch 192 | *.fig 193 | *.xd 194 | assets/raw/* 195 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://EditorConfig.org 3 | 4 | root = true 5 | ; Use 2 spaces for indentation in all files 6 | [*] 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | indent_style = space 11 | indent_size = 4 12 | insert_final_newline = true 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: pip 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "04:00" 8 | timezone: Asia/Calcutta 9 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Note :- Please follow the below points while attaching test cases document link below: 2 | ### - If label `Tested` is added then test cases document URL is mandatory. 3 | ### - Link added should be a valid URL and accessible throughout the org. 4 | ### - If the branch name contains hotfix / revert by default the BVT workflow check will pass. 5 | 6 | | Test Case Document URL | 7 | |-----------------------------------------------| 8 | | Please paste test case document link here.... | 9 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - master 6 | tags: 7 | - v[0-9]+.[0-9]+.[0-9]+* 8 | pull_request: 9 | branches: 10 | - master 11 | jobs: 12 | build: 13 | name: Build 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Set up Python 3 18 | uses: actions/setup-python@v3 19 | with: 20 | python-version: "3.10" 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install build 25 | python -m build 26 | python -m pip install --upgrade twine 27 | python -m twine check dist/* 28 | 29 | - name: 'Upload Artifact' 30 | uses: actions/upload-artifact@v2 31 | with: 32 | name: dist 33 | path: dist/ 34 | test: 35 | name: Test Coverage 36 | needs: build 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: actions/checkout@v3 40 | - name: Set up Python 3 41 | uses: actions/setup-python@v3 42 | with: 43 | python-version: "3.10" 44 | - name: Install dependencies 45 | run: | 46 | python -m pip install --upgrade pip 47 | pip install responses 48 | pip install coverage 49 | python ${{ github.workspace }}/setup.py install 50 | - name: Run Tests 51 | run: | 52 | python -m coverage run -m unittest 53 | python -m coverage xml 54 | - name: Upload coverage to Codecov 55 | uses: codecov/codecov-action@v3 56 | 57 | publish: 58 | if: startsWith(github.ref, 'refs/tags/v') 59 | needs: test 60 | runs-on: ubuntu-latest 61 | steps: 62 | - uses: actions/checkout@v2 63 | - name: Download all workflow run artifacts 64 | uses: actions/download-artifact@v2 65 | with: 66 | name: dist 67 | path: dist 68 | - name: Set up Python 3 69 | uses: actions/setup-python@v3 70 | with: 71 | python-version: "3.10" 72 | - name: Publish packages to PyPi 73 | run: | 74 | python -m pip install --upgrade twine 75 | set -ex 76 | export VERSION=$(python3 setup.py --version) 77 | python -m twine upload --verbose dist/razorpay-$VERSION-py3-none-any.whl dist/razorpay-$VERSION.tar.gz 78 | env: 79 | TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} 80 | TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} 81 | 82 | -------------------------------------------------------------------------------- /.github/workflows/genesis.yml: -------------------------------------------------------------------------------- 1 | name: Quality Checks 2 | on: 3 | schedule: 4 | - cron: "0 17 * * *" 5 | jobs: 6 | Analysis: 7 | uses: razorpay/genesis/.github/workflows/quality-checks.yml@master 8 | secrets: inherit 9 | -------------------------------------------------------------------------------- /.github/workflows/python.yml: -------------------------------------------------------------------------------- 1 | # They are provided by a third-party and are governed by 2 | # separate terms of service, privacy policy, and support 3 | # documentation. 4 | 5 | name: Python Package 6 | 7 | on: 8 | push: 9 | branches: [ master ] 10 | pull_request: 11 | branches: [ master ] 12 | 13 | 14 | jobs: 15 | deploy: 16 | runs-on: ubuntu-latest # nosemgrep : semgrep.dev/s/swati31196:github_provided_runner 17 | strategy: 18 | max-parallel: 4 19 | matrix: 20 | python-version: [3, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10] 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Set up Python 25 | uses: actions/setup-python@v2 26 | - name: Install dependencies 27 | run: | 28 | pip install setuptools 29 | python -m pip install --upgrade pip 30 | pip install responses 31 | python3 setup.py install 32 | - name: Run Tests 33 | run: python3 -m unittest 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | 55 | # Sphinx documentation 56 | docs/_build/ 57 | 58 | # PyBuilder 59 | target/ 60 | 61 | .DS_Store 62 | .idea 63 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright © 2015 Akash Kothawale 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the “Software”), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE, CHANGELOG.md, README.md 2 | recursive-include tests * 3 | recursive-include razorpay * 4 | recursive-include examples * 5 | recursive-exclude razorpay *.pyc 6 | recursive-exclude docs *.pyo 7 | recursive-exclude tests *.pyc 8 | recursive-exclude tests *.pyo -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Razorpay Python Client 2 | 3 | [![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/badge/python-3%20%7C%203.4%20%7C%203.5%20%7C%203.6-blue.svg)]() [![License](https://img.shields.io/:license-mit-blue.svg)](https://opensource.org/licenses/MIT) 4 | 5 | Python bindings for interacting with the Razorpay API 6 | 7 | This is primarily meant for merchants who wish to perform interactions with the Razorpay API programatically. 8 | 9 | ## Installation 10 | 11 | ```sh 12 | $ pip install razorpay 13 | ``` 14 | 15 | ## Usage 16 | 17 | You need to setup your key and secret using the following: 18 | You can find your API keys at . 19 | 20 | ```py 21 | import razorpay 22 | client = razorpay.Client(auth=("", "")) 23 | ``` 24 | 25 | ## App Details 26 | 27 | After setting up client, you can set your app details before making any request 28 | to Razorpay using the following: 29 | 30 | ```py 31 | client.set_app_details({"title" : "", "version" : ""}) 32 | ``` 33 | 34 | For example, you can set the title to `Django` and version to `1.8.17`. Please ensure 35 | that both app title and version are strings. 36 | 37 | ## Supported Resources 38 | - [Account](documents/account.md) 39 | 40 | - [Addon](documents/addon.md) 41 | 42 | - [Item](documents/items.md) 43 | 44 | - [Customer](documents/customer.md) 45 | 46 | - [Token](documents/token.md) 47 | 48 | - [Fund](documents/fund.md) 49 | 50 | - [Order](documents/order.md) 51 | 52 | - [Payments](documents/payment.md) 53 | 54 | - [Settlements](documents/settlement.md) 55 | 56 | - [Refunds](documents/refund.md) 57 | 58 | - [Invoice](documents/invoice.md) 59 | 60 | - [Subscriptions](documents/subscription.md) 61 | 62 | - [Payment Links](documents/paymentLink.md) 63 | 64 | - [Smart Collect](documents/virtualAccount.md) 65 | 66 | - [Route](documents/transfer.md) 67 | 68 | - [QR Code](documents/qrcode.md) 69 | 70 | - [Emandate](documents/emandate.md) 71 | 72 | - [Cards](documents/card.md) 73 | 74 | - [Paper NACH](documents/papernach.md) 75 | 76 | - [UPI](documents/upi.md) 77 | 78 | - [Register Emandate and Charge First Payment Together](documents/registerEmandate.md) 79 | 80 | - [Register NACH and Charge First Payment Together](documents/registerNach.md) 81 | 82 | - [Payment Verification](documents/paymentVerfication.md) 83 | 84 | - [Product Configuration](documents/productConfiguration.md) 85 | 86 | - [Stakeholder](documents/stakeholder.md) 87 | 88 | - [Webhook](documents/webhook.md) 89 | 90 | - [Document](documents/document.md) 91 | 92 | - [Dispute](documents/dispute.md) 93 | 94 | - [Iin](documents/iin.md) 95 | --- 96 | 97 | ## Bugs? Feature requests? Pull requests? 98 | 99 | All of those are welcome. You can [file issues][issues] or [submit pull requests][pulls] in this repository. 100 | 101 | [issues]: https://github.com/razorpay/razorpay-python/issues 102 | [pulls]: https://github.com/razorpay/razorpay-python/pulls 103 | -------------------------------------------------------------------------------- /documents/document.md: -------------------------------------------------------------------------------- 1 | ## Document 2 | 3 | ### Create a Document 4 | 5 | ```py 6 | 7 | file = open('/Users/your_name/Downloads/sample_uploaded.jpeg', 'rb') 8 | 9 | x = client.document.create({ 10 | 'file': file, 11 | 'purpose': 'dispute_evidence' 12 | }) 13 | ``` 14 | 15 | **Parameters:** 16 | 17 | | Name | Type | Description | 18 | |-------|-----------|--------------------------------------------------| 19 | | file* | string | The URL generated once the business proof document is uploaded. | 20 | | purpose | string | Possible value is `dispute_evidence` | 21 | 22 | **Response:** 23 | ```json 24 | { 25 | "id": "doc_EsyWjHrfzb59Re", 26 | "entity": "document", 27 | "purpose": "dispute_evidence", 28 | "name": "doc_19_12_2020.jpg", 29 | "mime_type": "image/png", 30 | "size": 2863, 31 | "created_at": 1590604200 32 | } 33 | ``` 34 | ------------------------------------------------------------------------------------------------------- 35 | 36 | ### Fetch Document Information 37 | 38 | ```py 39 | documentId = "doc_NiyXWXXXXXXXXX" 40 | 41 | client.document.fetch(documentId) 42 | ``` 43 | 44 | **Parameters:** 45 | 46 | | Name | Type | Description | 47 | |-------|-----------|--------------------------------------------------| 48 | | documentId | string | The unique identifier of the document. | 49 | 50 | **Response:** 51 | ```json 52 | { 53 | "entity": "document", 54 | "id": "doc_00000000000000", 55 | "purpose": "dispute_evidence", 56 | "created_at": 1701701378, 57 | "mime_type": "application/pdf", 58 | "display_name": "ppm_00000000000000", 59 | "size": 404678, 60 | "url": "" 61 | } 62 | ``` 63 | ------------------------------------------------------------------------------------------------------- 64 | 65 | **PN: * indicates mandatory fields** 66 |
67 |
68 | **For reference click [here](https://razorpay.com/docs/api/documents)** -------------------------------------------------------------------------------- /documents/fund.md: -------------------------------------------------------------------------------- 1 | ## Funds 2 | 3 | ### Create a fund account 4 | ```py 5 | client.fund_account.create({ 6 | "customer_id":"cust_Aa000000000001", 7 | "account_type":"bank_account", 8 | "bank_account":{ 9 | "name":"Gaurav Kumar", 10 | "account_number":"11214311215411", 11 | "ifsc":"HDFC0000053" 12 | } 13 | }) 14 | ``` 15 | 16 | **Parameters:** 17 | 18 | | Name | Type | Description | 19 | |---------------|-------------|---------------------------------------------| 20 | | customerId* | string | The id of the customer to be fetched | 21 | | account_type* | string | The bank_account to be linked to the customer ID | 22 | | bank_account* | object | All keys listed [here](https://razorpay.com/docs/payments/customers/customer-fund-account-api/#create-a-fund-account) are supported | 23 | 24 | **Response:** 25 | ```json 26 | { 27 | "id": "fa_JexSeA2SS1S19D", 28 | "entity": "fund_account", 29 | "customer_id": "cust_JdumbHq5F3kKu6", 30 | "account_type": "bank_account", 31 | "bank_account": { 32 | "ifsc": "HDFC0000053", 33 | "bank_name": "HDFC Bank", 34 | "name": "Gaurav Kumar", 35 | "notes": [], 36 | "account_number": "11214311215411" 37 | }, 38 | "batch_id": null, 39 | "active": true, 40 | "created_at": 1654682051 41 | } 42 | ``` 43 | ------------------------------------------------------------------------------------------------------- 44 | 45 | ### Fetch all fund accounts 46 | 47 | ```py 48 | client.fund_account.all({"customer_id":customerId}) 49 | ``` 50 | 51 | **Parameters:** 52 | 53 | | Name | Type | Description | 54 | |---------------|-------------|---------------------------------------------| 55 | | customerId* | string | The id of the customer to be fetched | 56 | 57 | **Response:** 58 | ```json 59 | { 60 | "entity": "collection", 61 | "count": 2, 62 | "items": [ 63 | { 64 | "id": "fa_JcXaLomo4ck5IY", 65 | "entity": "fund_account", 66 | "customer_id": "cust_JZse2vlC5nK9AQ", 67 | "account_type": "bank_account", 68 | "bank_account": { 69 | "ifsc": "HDFC0000053", 70 | "bank_name": "HDFC Bank", 71 | "name": "Gaurav Kumar", 72 | "notes": [], 73 | "account_number": "11214311215411" 74 | }, 75 | "batch_id": null, 76 | "active": true, 77 | "created_at": 1654154246 78 | }, 79 | { 80 | "id": "fa_JcXYtecLkhW74k", 81 | "entity": "fund_account", 82 | "customer_id": "cust_JZse2vlC5nK9AQ", 83 | "account_type": "bank_account", 84 | "bank_account": { 85 | "ifsc": "HDFC0000053", 86 | "bank_name": "HDFC Bank", 87 | "name": "Gaurav Kumar", 88 | "notes": [], 89 | "account_number": "11214311215411" 90 | }, 91 | "batch_id": null, 92 | "active": true, 93 | "created_at": 1654154163 94 | } 95 | ] 96 | } 97 | ``` 98 | ------------------------------------------------------------------------------------------------------- 99 | 100 | **PN: * indicates mandatory fields** 101 |
102 |
103 | **For reference click [here](https://razorpay.com/docs/payments/customers/customer-fund-account-api/)** -------------------------------------------------------------------------------- /documents/iin.md: -------------------------------------------------------------------------------- 1 | ### Iin 2 | 3 | ### Token IIN API 4 | 5 | ```py 6 | tokenIin = "412345" 7 | 8 | client.iin.fetch(tokenIin) 9 | ``` 10 | 11 | **Parameters:** 12 | 13 | | Name | Type | Description | 14 | |------------|--------|-----------------------------------| 15 | | tokenIin* | string | The token IIN. | 16 | 17 | **Response:** 18 | ```json 19 | { 20 | "iin": "412345", 21 | "entity": "iin", 22 | "network": "Visa", 23 | "type": "credit", 24 | "sub_type": "business", 25 | "issuer_code": "HDFC", 26 | "issuer_name": "HDFC Bank Ltd", 27 | "international": false, 28 | "is_tokenized": true, 29 | "card_iin": "411111", 30 | "emi":{ 31 | "available": true 32 | }, 33 | "recurring": { 34 | "available": true 35 | }, 36 | "authentication_types": [ 37 | { 38 | "type":"3ds" 39 | }, 40 | { 41 | "type":"otp" 42 | } 43 | ] 44 | } 45 | ``` 46 | ------------------------------------------------------------------------------------------------------- 47 | 48 | ### Fetch All IINs Supporting Native OTP 49 | 50 | ```py 51 | client.iin.all({"flow":"otp"}) 52 | ``` 53 | 54 | **Parameters:** 55 | 56 | | Name | Type | Description | 57 | |------------|--------|-----------------------------------| 58 | | flow | string | Authentication flow is Native OTP. Possible value is `otp`. | 59 | 60 | **Response:** 61 | ```json 62 | { 63 | "count": 24, 64 | "iins": [ 65 | "512967", 66 | "180005", 67 | "401704", 68 | "401806", 69 | "123456", 70 | "411111", 71 | "123512967", 72 | "180012305", 73 | "401123704" 74 | ] 75 | } 76 | ``` 77 | ------------------------------------------------------------------------------------------------------- 78 | 79 | ### Fetch All IINs with Business Sub-type 80 | 81 | ```py 82 | client.iin.all({"sub_type":"business"}) 83 | ``` 84 | 85 | **Parameters:** 86 | 87 | | Name | Type | Description | 88 | |------------|--------|-----------------------------------| 89 | | sub_type | string | The sub_type of the IIN. Possible value is `business`. | 90 | 91 | **Response:** 92 | ```json 93 | { 94 | "count": 24, 95 | "iins": [ 96 | "512967", 97 | "180005", 98 | "401704", 99 | "401806", 100 | "607389", 101 | "652203", 102 | "414367", 103 | "787878", 104 | "123456", 105 | "411111", 106 | "123512967", 107 | "180012305", 108 | "401123704" 109 | ] 110 | } 111 | ``` 112 | ------------------------------------------------------------------------------------------------------- 113 | 114 | **PN: * indicates mandatory fields** 115 |
116 |
117 | **For reference click [here](https://razorpay.com/docs/api/payments/cards/iin-api/#iin-entity)** -------------------------------------------------------------------------------- /documents/paymentVerfication.md: -------------------------------------------------------------------------------- 1 | ## payment verification 2 | 3 | 4 | ### Verify payment verification 5 | 6 | ```py 7 | client.utility.verify_payment_signature({ 8 | 'razorpay_order_id': razorpay_order_id, 9 | 'razorpay_payment_id': razorpay_payment_id, 10 | 'razorpay_signature': razorpay_signature 11 | }) 12 | ``` 13 | 14 | **Parameters:** 15 | 16 | 17 | | Name | Type | Description | 18 | |-------|-----------|--------------------------------------------------| 19 | | razorpay_order_id* | string | The id of the order to be fetched | 20 | | razorpay_payment_id* | string | The id of the payment to be fetched | 21 | | razorpay_signature* | string | Signature returned by the Checkout. This is used to verify the payment. | 22 | 23 | ------------------------------------------------------------------------------------------------------- 24 | ### Verify subscription verification 25 | 26 | ```py 27 | client.utility.verify_subscription_payment_signature({ 28 | 'razorpay_subscription_id': razorpay_order_id, 29 | 'razorpay_payment_id': razorpay_payment_id, 30 | 'razorpay_signature': razorpay_signature 31 | }) 32 | ``` 33 | 34 | **Parameters:** 35 | 36 | 37 | | Name | Type | Description | 38 | |-------|-----------|--------------------------------------------------| 39 | | razorpay_subscription_id* | string | The id of the subscription to be fetched | 40 | | razorpay_payment_id* | string | The id of the payment to be fetched | 41 | | razorpay_signature* | string | Signature returned by the Checkout. This is used to verify the payment. | 42 | 43 | ------------------------------------------------------------------------------------------------------- 44 | ### Verify paymentlink verification 45 | 46 | ```py 47 | client.utility.verify_payment_link_signature({ 48 | 'payment_link_id': payment_link_id, 49 | 'payment_link_reference_id': payment_link_reference_id, 50 | 'payment_link_status':payment_link_status, 51 | 'razorpay_payment_id': razorpay_payment_id, 52 | 'razorpay_signature': razorpay_signature 53 | }) 54 | ``` 55 | 56 | **Parameters:** 57 | 58 | 59 | | Name | Type | Description | 60 | |-------|-----------|--------------------------------------------------| 61 | | payment_link_id* | string | The id of the paymentlink to be fetched | 62 | | razorpay_payment_id* | string | The id of the payment to be fetched | 63 | | payment_link_reference_id* | string | A reference number tagged to a Payment Link | 64 | | payment_link_status* | string | Current status of the link | 65 | | razorpay_signature* | string | Signature returned by the Checkout. This is used to verify the payment. | 66 | 67 | ------------------------------------------------------------------------------------------------------- 68 | 69 | **PN: * indicates mandatory fields** 70 |
71 |
-------------------------------------------------------------------------------- /razorpay/__init__.py: -------------------------------------------------------------------------------- 1 | from .client import Client 2 | from .resources import Order 3 | from .resources import Payment 4 | from .resources import Refund 5 | from .resources import Invoice 6 | from .resources import PaymentLink 7 | from .resources import Customer 8 | from .resources import Card 9 | from .resources import Token 10 | from .resources import Transfer 11 | from .resources import VirtualAccount 12 | from .resources import Addon 13 | from .resources import Subscription 14 | from .resources import RegistrationLink 15 | from .resources import Plan 16 | from .resources import Settlement 17 | from .resources import Item 18 | from .resources import Qrcode 19 | from .resources import FundAccount 20 | from .utility import Utility 21 | from .constants import ERROR_CODE 22 | from .constants import HTTP_STATUS_CODE 23 | from .resources import Account 24 | from .resources import Stakeholder 25 | from .resources import Product 26 | from .resources import Iin 27 | from .resources import Webhook 28 | from .resources import Document 29 | from .resources import Dispute 30 | 31 | __all__ = [ 32 | 'Payment', 33 | 'Refund', 34 | 'Order', 35 | 'Client', 36 | 'Invoice', 37 | 'PaymentLink', 38 | 'Utility', 39 | 'Customer', 40 | 'Card', 41 | 'Token', 42 | 'Transfer', 43 | 'VirtualAccount', 44 | 'Addon', 45 | 'Subscription', 46 | 'RegistrationLink', 47 | 'Plan', 48 | 'FundAccount', 49 | 'Settlement', 50 | 'Item', 51 | 'Qrcode', 52 | 'HTTP_STATUS_CODE', 53 | 'ERROR_CODE', 54 | 'Account', 55 | 'Stakeholder', 56 | 'Product', 57 | 'Iin', 58 | 'Webhook', 59 | 'Document', 60 | 'Dispute', 61 | ] 62 | -------------------------------------------------------------------------------- /razorpay/constants/__init__.py: -------------------------------------------------------------------------------- 1 | from .http_status_code import HTTP_STATUS_CODE 2 | from .error_code import ERROR_CODE 3 | from .url import URL 4 | 5 | __all__ = [ 6 | 'HTTP_STATUS_CODE', 7 | 'ERROR_CODE', 8 | 'URL', 9 | ] 10 | -------------------------------------------------------------------------------- /razorpay/constants/error_code.py: -------------------------------------------------------------------------------- 1 | class ERROR_CODE(object): 2 | BAD_REQUEST_ERROR = "BAD_REQUEST_ERROR" 3 | GATEWAY_ERROR = "GATEWAY_ERROR" 4 | SERVER_ERROR = "SERVER_ERROR" 5 | -------------------------------------------------------------------------------- /razorpay/constants/http_status_code.py: -------------------------------------------------------------------------------- 1 | class HTTP_STATUS_CODE(object): 2 | OK = 200 3 | REDIRECT = 300 4 | -------------------------------------------------------------------------------- /razorpay/constants/url.py: -------------------------------------------------------------------------------- 1 | class URL(object): 2 | BASE_URL = 'https://api.razorpay.com' 3 | V1 = '/v1' 4 | V2 = '/v2' 5 | ORDER_URL = "/orders" 6 | INVOICE_URL = "/invoices" 7 | PAYMENT_LINK_URL = "/payment_links" 8 | PAYMENTS_URL = "/payments" 9 | REFUNDS_URL = "/refunds" 10 | CARD_URL = "/cards" 11 | CUSTOMER_URL = "/customers" 12 | TRANSFER_URL = "/transfers" 13 | VIRTUAL_ACCOUNT_URL = "/virtual_accounts" 14 | SUBSCRIPTION_URL = "/subscriptions" 15 | ADDON_URL = "/addons" 16 | PLAN_URL = "/plans" 17 | SETTLEMENT_URL = "/settlements" 18 | ITEM_URL = "/items" 19 | QRCODE_URL = "/payments/qr_codes" 20 | REGISTRATION_LINK_URL = "/subscription_registration" 21 | FUND_ACCOUNT_URL = "/fund_accounts" 22 | ACCOUNT = "/accounts" 23 | STAKEHOLDER = "/stakeholders" 24 | PRODUCT = "/products" 25 | TNC = "/tnc" 26 | TOKEN = "/tokens" 27 | IIN = "/iins" 28 | WEBHOOK = "/webhooks" 29 | DOCUMENT= "/documents" 30 | DISPUTE= "/disputes" 31 | 32 | -------------------------------------------------------------------------------- /razorpay/errors.py: -------------------------------------------------------------------------------- 1 | class BadRequestError(Exception): 2 | def __init__(self, message=None, *args, **kwargs): 3 | super(BadRequestError, self).__init__(message) 4 | 5 | 6 | class GatewayError(Exception): 7 | def __init__(self, message=None, *args, **kwargs): 8 | super(GatewayError, self).__init__(message) 9 | 10 | 11 | class ServerError(Exception): 12 | def __init__(self, message=None, *args, **kwargs): 13 | super(ServerError, self).__init__(message) 14 | 15 | 16 | class SignatureVerificationError(Exception): 17 | def __init__(self, message=None, *args, **kwargs): 18 | super(SignatureVerificationError, self).__init__(message) 19 | -------------------------------------------------------------------------------- /razorpay/resources/__init__.py: -------------------------------------------------------------------------------- 1 | from .payment import Payment 2 | from .refund import Refund 3 | from .order import Order 4 | from .invoice import Invoice 5 | from .payment_link import PaymentLink 6 | from .customer import Customer 7 | from .card import Card 8 | from .token import Token 9 | from .transfer import Transfer 10 | from .virtual_account import VirtualAccount 11 | from .addon import Addon 12 | from .plan import Plan 13 | from .subscription import Subscription 14 | from .qrcode import Qrcode 15 | from .registration_link import RegistrationLink 16 | from .settlement import Settlement 17 | from .item import Item 18 | from .fund_account import FundAccount 19 | from .account import Account 20 | from .stakeholder import Stakeholder 21 | from .product import Product 22 | from .iin import Iin 23 | from .webhook import Webhook 24 | from .document import Document 25 | from .dispute import Dispute 26 | 27 | __all__ = [ 28 | 'Payment', 29 | 'Refund', 30 | 'Order', 31 | 'Invoice', 32 | 'PaymentLink', 33 | 'Customer', 34 | 'Card', 35 | 'Token', 36 | 'Transfer', 37 | 'VirtualAccount', 38 | 'Addon', 39 | 'Plan', 40 | 'Subscription', 41 | 'RegistrationLink', 42 | 'Settlement', 43 | 'Item', 44 | 'QrCode', 45 | 'FundAccount', 46 | 'Account', 47 | 'Stakeholder', 48 | 'Product', 49 | 'Iin', 50 | 'Webhook', 51 | 'Document', 52 | 'Dispute', 53 | ] 54 | -------------------------------------------------------------------------------- /razorpay/resources/account.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Account(Resource): 6 | def __init__(self, client=None): 7 | super(Account, self).__init__(client) 8 | self.base_url = URL.V2 + URL.ACCOUNT 9 | 10 | def create(self, data={}, **kwargs): 11 | """ 12 | Create account from given dict 13 | 14 | Returns: 15 | Account Dict which was created 16 | """ 17 | url = self.base_url 18 | return self.post_url(url, data, **kwargs) 19 | 20 | def fetch(self, account_id, data={}, **kwargs): 21 | """ 22 | Fetch account for given Id 23 | 24 | Args: 25 | account_id : Id for which addon object has to be retrieved 26 | 27 | Returns: 28 | account dict for given account_id 29 | """ 30 | return super(Account, self).fetch(account_id, data, **kwargs) 31 | 32 | def edit(self, account_id, data={}, **kwargs): 33 | """ 34 | Edit account information from given dict 35 | 36 | Returns: 37 | Account Dict which was edited 38 | """ 39 | url = '{}/{}'.format(self.base_url, account_id) 40 | 41 | return self.patch_url(url, data, **kwargs) 42 | 43 | def delete(self, account_id, data={}, **kwargs): 44 | """ 45 | Delete account for given id 46 | 47 | Args: 48 | account_id : Id for which account object has to be deleted 49 | """ 50 | url = '{}/{}'.format(self.base_url, account_id) 51 | 52 | return self.delete_url(url, data, **kwargs) 53 | 54 | def uploadAccountDoc(self, account_id, data={}, **kwargs): 55 | """ 56 | Upload Account Documents 57 | 58 | Returns: 59 | Account Document dict which was created 60 | """ 61 | url = '{}/{}/{}'.format(self.base_url, account_id, "documents") 62 | 63 | return self.file_url(url, data, **kwargs) 64 | 65 | def fetchAccountDoc(self, account_id, data={}, **kwargs): 66 | """ 67 | Fetch Account Documents 68 | 69 | Returns: 70 | Account Document dict for given account_id 71 | """ 72 | url = '{}/{}/{}'.format(self.base_url, account_id, "documents") 73 | 74 | return self.get_url(url, data, **kwargs) 75 | -------------------------------------------------------------------------------- /razorpay/resources/addon.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Addon(Resource): 6 | def __init__(self, client=None): 7 | super(Addon, self).__init__(client) 8 | self.base_url = URL.V1 + URL.ADDON_URL 9 | 10 | def fetch(self, addon_id, data={}, **kwargs): 11 | """ 12 | Fetch addon for given Id 13 | 14 | Args: 15 | addon_id : Id for which addon object has to be retrieved 16 | 17 | Returns: 18 | addon dict for given subscription Id 19 | """ 20 | return super(Addon, self).fetch(addon_id, data, **kwargs) 21 | 22 | def delete(self, addon_id, data={}, **kwargs): 23 | """ 24 | Delete addon for given id 25 | 26 | Args: 27 | addon_id : Id for which addon object has to be deleted 28 | """ 29 | url = '{}/{}'.format(self.base_url, addon_id) 30 | 31 | return self.delete_url(url, data, **kwargs) 32 | 33 | def all(self, data={}, **kwargs): 34 | """ 35 | Fetch all Add-ons 36 | Returns: 37 | Dictionary of Add-ons 38 | """ 39 | return super(Addon, self).all(data, **kwargs) 40 | -------------------------------------------------------------------------------- /razorpay/resources/base.py: -------------------------------------------------------------------------------- 1 | class Resource(object): 2 | 3 | def __init__(self, client=None): 4 | self.client = client 5 | 6 | def all(self, data, **kwargs): 7 | return self.get_url(self.base_url, data, **kwargs) 8 | 9 | def fetch(self, id, data, **kwargs): 10 | url = "{}/{}".format(self.base_url, id) 11 | return self.get_url(url, data, **kwargs) 12 | 13 | def get_url(self, url, data, **kwargs): 14 | return self.client.get(url, data, **kwargs) 15 | 16 | def patch_url(self, url, data, **kwargs): 17 | return self.client.patch(url, data, **kwargs) 18 | 19 | def post_url(self, url, data, **kwargs): 20 | return self.client.post(url, data, **kwargs) 21 | 22 | def put_url(self, url, data, **kwargs): 23 | return self.client.put(url, data, **kwargs) 24 | 25 | def delete_url(self, url, data, **kwargs): 26 | return self.client.delete(url, data, **kwargs) 27 | 28 | def delete(self, id, data, **kwargs): 29 | url = "{}/{}/delete".format(self.base_url, id) 30 | return self.delete_url(url, data, **kwargs) 31 | 32 | def file_url(self, url, data, **kwargs): 33 | return self.client.file(url, data, **kwargs) -------------------------------------------------------------------------------- /razorpay/resources/card.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Card(Resource): 6 | def __init__(self, client=None): 7 | super(Card, self).__init__(client) 8 | self.base_url = URL.V1 + URL.CARD_URL 9 | 10 | def fetch(self, card_id, data={}, **kwargs): 11 | """ 12 | Fetch Card for given Id 13 | 14 | Args: 15 | card_id : Id for which card object has to be retrieved 16 | 17 | Returns: 18 | Card dict for given card Id 19 | """ 20 | return super(Card, self).fetch(card_id, data, **kwargs) 21 | 22 | def requestCardReference(self, data={}, **kwargs): 23 | """ 24 | Fetch card reference number for a specific card 25 | 26 | Args: 27 | number : The card number whose PAR or network reference id should be retrieved. 28 | 29 | Returns: 30 | Card dict for given card Id 31 | """ 32 | url = "{}/{}".format(self.base_url, "fingerprints") 33 | return self.post_url(url, data, **kwargs) 34 | -------------------------------------------------------------------------------- /razorpay/resources/customer.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Customer(Resource): 6 | def __init__(self, client=None): 7 | super(Customer, self).__init__(client) 8 | self.base_url = URL.V1 + URL.CUSTOMER_URL 9 | 10 | def fetch(self, customer_id, data={}, **kwargs): 11 | """ 12 | Fetch Customer for given Id 13 | 14 | Args: 15 | customer_id : Id for which customer object has to be retrieved 16 | 17 | Returns: 18 | Order dict for given customer Id 19 | """ 20 | return super(Customer, self).fetch(customer_id, data, **kwargs) 21 | 22 | def create(self, data={}, **kwargs): 23 | """ 24 | Create Customer from given dict 25 | 26 | Returns: 27 | Customer Dict which was created 28 | """ 29 | url = self.base_url 30 | return self.post_url(url, data, **kwargs) 31 | 32 | def edit(self, customer_id, data={}, **kwargs): 33 | """ 34 | Edit Customer information from given dict 35 | 36 | Returns: 37 | Customer Dict which was edited 38 | """ 39 | url = '{}/{}'.format(self.base_url, customer_id) 40 | 41 | return self.put_url(url, data, **kwargs) 42 | 43 | def all(self, data={}, **kwargs): 44 | """ 45 | Fetch all customer 46 | 47 | Returns: 48 | Dictionary of Customers data 49 | """ 50 | return super(Customer, self).all(data, **kwargs) 51 | 52 | def addBankAccount(self, customer_id, data={}, **kwargs): 53 | """ 54 | Add Bank Account of Customer 55 | 56 | Returns: 57 | Dictionary of Customers data 58 | """ 59 | url = f"{self.base_url}/{customer_id}/bank_account" 60 | return self.post_url(url, data, **kwargs) 61 | 62 | def deleteBankAccount(self, customer_id, bank_id, data={}, **kwargs): 63 | """ 64 | Delete Bank Account of Customer 65 | 66 | Returns: 67 | Dictionary of Customers data 68 | """ 69 | url = f"{self.base_url}/{customer_id}/bank_account/{bank_id}" 70 | return self.delete_url(url, data, **kwargs) 71 | 72 | def requestEligibilityCheck(self, data={}, **kwargs): 73 | """ 74 | Eligibility Check 75 | 76 | Returns: 77 | Dictionary of eligibility data 78 | """ 79 | url = f"{self.base_url}/eligibility" 80 | return self.post_url(url, data, **kwargs) 81 | 82 | def fetchEligibility(self, eligibility_id, data={}, **kwargs): 83 | """ 84 | Fetch Eligibility by id 85 | 86 | Returns: 87 | Eligibility dict for given eligibility Id 88 | """ 89 | url = f"{self.base_url}/eligibility/{eligibility_id}" 90 | return self.get_url(url, data, **kwargs) 91 | -------------------------------------------------------------------------------- /razorpay/resources/dispute.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Dispute(Resource): 6 | def __init__(self, client=None): 7 | super(Dispute, self).__init__(client) 8 | self.base_url = URL.V1 + URL.DISPUTE 9 | 10 | def fetch(self, dispute_id, data={}, **kwargs): 11 | """ 12 | Fetch dispute for given Id 13 | 14 | Returns: 15 | dispute dict for given dispute Id 16 | """ 17 | return super(Dispute, self).fetch(dispute_id, data, **kwargs) 18 | 19 | def accept(self, dispute_id, data={}, **kwargs): 20 | """ 21 | Accept a dispute 22 | 23 | Returns: 24 | Dictionary of disputes 25 | """ 26 | url = f"{self.base_url}/{dispute_id}/accept" 27 | return self.post_url(url, data, **kwargs) 28 | 29 | def contest(self, dispute_id, data={}, **kwargs): 30 | """ 31 | Contest a Dispute 32 | 33 | Returns: 34 | Dictionary of disputes 35 | """ 36 | url = f"{self.base_url}/{dispute_id}/contest" 37 | return self.patch_url(url, data, **kwargs) 38 | 39 | def all(self, data={}, **kwargs): 40 | """ 41 | Fetch all disputes 42 | 43 | Returns: 44 | Dictionary of disputes 45 | """ 46 | return super(Dispute, self).all(data, **kwargs) 47 | -------------------------------------------------------------------------------- /razorpay/resources/document.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Document(Resource): 6 | def __init__(self, client=None): 7 | super(Document, self).__init__(client) 8 | self.base_url = URL.V1 + URL.DOCUMENT 9 | 10 | def create(self, data={}, **kwargs): 11 | """ 12 | Create a Document 13 | 14 | Returns: 15 | Dictionary of document 16 | """ 17 | url = self.base_url 18 | return self.file_url(url, data, **kwargs) 19 | 20 | def fetch(self, dispute_id, data={}, **kwargs): 21 | """ 22 | Fetch Document 23 | 24 | Returns: 25 | Dictionary of document 26 | """ 27 | return super(Document, self).fetch(dispute_id, data, **kwargs) 28 | -------------------------------------------------------------------------------- /razorpay/resources/fund_account.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class FundAccount(Resource): 6 | def __init__(self, client=None): 7 | super(FundAccount, self).__init__(client) 8 | self.base_url = URL.V1 + URL.FUND_ACCOUNT_URL 9 | 10 | def all(self, data={}, **kwargs): 11 | """ 12 | Fetch all Fund Account entities 13 | 14 | Returns: 15 | Dictionary of Fund Account 16 | """ 17 | return super(FundAccount, self).all(data, **kwargs) 18 | 19 | def create(self, data={}, **kwargs): 20 | """ 21 | Create a fund account 22 | 23 | Args: 24 | data : Dictionary having keys using which order have to be created 25 | 'customerId' : Customer Id for the customer 26 | 'account_type' : The bank_account to be linked to the customer ID 27 | 'bank_account' : key value pair 28 | 29 | Returns: 30 | fund account Dict which was created 31 | """ 32 | url = self.base_url 33 | return self.post_url(url, data, **kwargs) -------------------------------------------------------------------------------- /razorpay/resources/iin.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Iin(Resource): 6 | def __init__(self, client=None): 7 | super(Iin, self).__init__(client) 8 | self.base_url = URL.V1 + URL.IIN 9 | 10 | def fetch(self, token_iin, data={}, **kwargs): 11 | """ 12 | fetch card properties using token iin 13 | 14 | Returns: 15 | Iin dict for given token iin 16 | """ 17 | 18 | return super(Iin, self).fetch(token_iin, data, **kwargs) 19 | 20 | def all(self, data={}, **kwargs): 21 | """ 22 | Fetch all iins supporting native otp 23 | Fetch all iins with business sub-type 24 | 25 | Returns: 26 | Dictionary of Iin data 27 | """ 28 | url = f"{self.base_url}/list" 29 | return self.get_url(url, data, **kwargs) 30 | -------------------------------------------------------------------------------- /razorpay/resources/item.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Item(Resource): 6 | def __init__(self, client=None): 7 | super(Item, self).__init__(client) 8 | self.base_url = URL.V1 + URL.ITEM_URL 9 | 10 | def create(self, data={}, **kwargs): 11 | """ 12 | Create item 13 | 14 | Returns: 15 | Item Dict which was created 16 | """ 17 | url = self.base_url 18 | return self.post_url(url, data, **kwargs) 19 | 20 | def fetch(self, item_id, data={}, **kwargs): 21 | """ 22 | Fetch an Item 23 | 24 | Args: 25 | item_id : The id of the item to be fetched 26 | 27 | Returns: 28 | Item dict for given card Id 29 | """ 30 | return super(Item, self).fetch(item_id, data, **kwargs) 31 | 32 | def all(self, data={}, **kwargs): 33 | """ 34 | Fetch all items 35 | 36 | Returns: 37 | Dictionary of Items data 38 | """ 39 | return super(Item, self).all(data, **kwargs) 40 | 41 | def edit(self, item_id, data={}, **kwargs): 42 | """ 43 | Update an Item 44 | 45 | Returns: 46 | Item Dict which was edited 47 | """ 48 | url = '{}/{}'.format(self.base_url, item_id) 49 | 50 | return self.patch_url(url, data, **kwargs) 51 | 52 | def delete(self, item_id, **kwargs): 53 | """ 54 | Delete an Item 55 | 56 | Args: 57 | item_id : The id of the item to be deleted 58 | 59 | Returns: 60 | The response is always be an empty array like this - [] 61 | """ 62 | url = "{}/{}".format(self.base_url, item_id) 63 | return self.delete_url(url, {}, **kwargs) -------------------------------------------------------------------------------- /razorpay/resources/order.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | import warnings 4 | 5 | 6 | class Order(Resource): 7 | def __init__(self, client=None): 8 | super(Order, self).__init__(client) 9 | self.base_url = URL.V1 + URL.ORDER_URL 10 | 11 | def fetch_all(self, data={}, **kwargs): # pragma: no cover 12 | warnings.warn("Will be Deprecated in next release, use all", 13 | DeprecationWarning) 14 | return self.all(data, **kwargs) 15 | 16 | def all(self, data={}, **kwargs): 17 | """ 18 | Fetch all Order entities 19 | 20 | Returns: 21 | Dictionary of Order data 22 | """ 23 | return super(Order, self).all(data, **kwargs) 24 | 25 | def fetch(self, order_id, data={}, **kwargs): 26 | """ 27 | Fetch Order for given Id 28 | 29 | Args: 30 | order_id : Id for which order object has to be retrieved 31 | 32 | Returns: 33 | Order dict for given order Id 34 | """ 35 | return super(Order, self).fetch(order_id, data, **kwargs) 36 | 37 | def fetch_all_payments(self, order_id, data={}, **kwargs): # pragma: no cover 38 | warnings.warn("Will be Deprecated in next release, use payments", 39 | DeprecationWarning) 40 | return self.payments(order_id, data, **kwargs) 41 | 42 | def payments(self, order_id, data={}, **kwargs): 43 | """ 44 | Fetch Payment for Order Id 45 | 46 | Args: 47 | order_id : Id for which payment objects has to be retrieved 48 | 49 | Returns: 50 | Payment dict for given Order Id 51 | """ 52 | url = "{}/{}/payments".format(self.base_url, order_id) 53 | return self.get_url(url, data, **kwargs) 54 | 55 | def create(self, data={}, **kwargs): 56 | """ 57 | Create Order from given dict 58 | 59 | Args: 60 | data : Dictionary having keys using which order have to be created 61 | 'amount' : Amount of Order 62 | 'currency' : Currency used in Order 63 | 'receipt' : Receipt Id for the order 64 | 'notes' : key value pair as notes 65 | 'payment_capture': 0/1 if payment should be auto captured or not 66 | 67 | Returns: 68 | Order Dict which was created 69 | """ 70 | url = self.base_url 71 | return self.post_url(url, data, **kwargs) 72 | 73 | def edit(self, order_id, data={}, **kwargs): 74 | """ 75 | Update order 76 | 77 | Args: 78 | data : Dictionary having keys using which order have to be edited 79 | 'notes' : key value pair as notes 80 | 81 | Returns: 82 | Order Dict which was edited 83 | 84 | """ 85 | url = f"{self.base_url}/{order_id}" 86 | return self.patch_url(url, data, **kwargs) 87 | 88 | def viewRtoReview(self, order_id, data={}, **kwargs): 89 | """ 90 | View rto risk reasons 91 | 92 | Returns: 93 | Dict for given Order Id 94 | """ 95 | url = f"{self.base_url}/{order_id}/rto_review" 96 | return self.post_url(url, data, **kwargs) 97 | 98 | def editFulfillment(self, order_id, data={}, **kwargs): 99 | """ 100 | Update the Fulfillment Details 101 | 102 | Returns: 103 | Dict for given Order Id 104 | """ 105 | url = f"{self.base_url}/{order_id}/fulfillment" 106 | return self.post_url(url, data, **kwargs) 107 | -------------------------------------------------------------------------------- /razorpay/resources/payment_link.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | import warnings 4 | 5 | 6 | class PaymentLink(Resource): 7 | def __init__(self, client=None): 8 | super(PaymentLink, self).__init__(client) 9 | self.base_url = URL.V1 + URL.PAYMENT_LINK_URL 10 | 11 | def fetch_all(self, data={}, **kwargs): # pragma: no cover 12 | warnings.warn("Will be Deprecated in next release", DeprecationWarning) 13 | return self.all(data, **kwargs) 14 | 15 | def all(self, data={}, **kwargs): 16 | """ 17 | Fetch all Payment link entities 18 | 19 | Returns: 20 | Dictionary of Payment link data 21 | """ 22 | return super(PaymentLink, self).all(data, **kwargs) 23 | 24 | def fetch(self, payment_link_id, data={}, **kwargs): 25 | """ 26 | Fetch Payment link for given Id 27 | 28 | Args: 29 | payment_link_id : Id for which Payment link object has to be retrieved 30 | 31 | Returns: 32 | Payment link dict for given payment_link_id Id 33 | """ 34 | return super(PaymentLink, self).fetch(payment_link_id, data, **kwargs) 35 | 36 | def create(self, data={}, **kwargs): 37 | """ 38 | Create Payment link from given dict 39 | 40 | Args: 41 | data : Dictionary having keys using which Payment link have to be created 42 | 43 | Returns: 44 | Payment link Dict which was created 45 | """ 46 | url = self.base_url 47 | return self.post_url(url, data, **kwargs) 48 | 49 | def cancel(self, payment_link_id, **kwargs): 50 | """ 51 | Cancel an unpaid Payment link with given ID via API 52 | It can only be called on an Payment link that is not in the paid state. 53 | 54 | Args: 55 | payment_link_id : Id for cancel the Payment link 56 | Returns: 57 | The response for the API will be the Payment link entity, similar to create/update API response, with status attribute's value as cancelled 58 | """ 59 | url = "{}/{}/cancel".format(self.base_url, payment_link_id) 60 | return self.post_url(url, {}, **kwargs) 61 | 62 | def edit(self, payment_link_id, data={}, **kwargs): 63 | """ 64 | Edit the Payment link 65 | Args: 66 | data : Dictionary having keys using which order have to be edited 67 | reference_id : Adds a unique reference number to an existing link. 68 | 69 | expire_by : Timestamp, in Unix format, when the payment links should expire. 70 | 71 | notes : key value pair as notes 72 | 73 | Returns: 74 | Payment Link Dict which was edited 75 | """ 76 | url = '{}/{}'.format(self.base_url, payment_link_id) 77 | return self.patch_url(url, data, **kwargs) 78 | 79 | def notifyBy(self, payment_link_id, medium, **kwargs): 80 | """ 81 | Send notification 82 | 83 | Args: 84 | payment_link_id : Unique identifier of the Payment Link that should be resent. 85 | 86 | medium : sms/email 87 | """ 88 | url = "{}/{}/notify_by/{}".format(self.base_url, payment_link_id, medium) 89 | return self.post_url(url, {}, **kwargs) 90 | -------------------------------------------------------------------------------- /razorpay/resources/plan.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Plan(Resource): 6 | def __init__(self, client=None): 7 | super(Plan, self).__init__(client) 8 | self.base_url = URL.V1 + URL.PLAN_URL 9 | 10 | def create(self, data={}, **kwargs): 11 | """ 12 | Create Plan from given dict 13 | 14 | Args: 15 | data : Dictionary having keys using which Plan has to be created 16 | 17 | Returns: 18 | Plan Dict which was created 19 | """ 20 | url = self.base_url 21 | return self.post_url(url, data, **kwargs) 22 | 23 | def fetch(self, plan_id, data={}, **kwargs): 24 | """ 25 | Fetch Plan for given Id 26 | 27 | Args: 28 | plan_id : Id for which Plan object has to be retrieved 29 | 30 | Returns: 31 | Plan dict for given subscription Id 32 | """ 33 | return super(Plan, self).fetch(plan_id, data, **kwargs) 34 | 35 | def all(self, data={}, **kwargs): 36 | """ 37 | Fetch all plan entities 38 | 39 | Returns: 40 | Dictionary of plan data 41 | """ 42 | return super(Plan, self).all(data, **kwargs) 43 | -------------------------------------------------------------------------------- /razorpay/resources/product.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Product(Resource): 6 | def __init__(self, client=None): 7 | super(Product, self).__init__(client) 8 | self.base_url = URL.V2 + URL.ACCOUNT 9 | 10 | def requestProductConfiguration(self, account_id, data={}, **kwargs): 11 | """ 12 | Request a Product Configuration from given dict 13 | 14 | Returns: 15 | Product Configuration Dict which was created 16 | """ 17 | url = '{}/{}{}'.format(self.base_url, account_id, URL.PRODUCT) 18 | 19 | return self.post_url(url, data, **kwargs) 20 | 21 | def fetch(self, account_id, product_id, data={}, **kwargs): 22 | """ 23 | Fetch product for given accound and product id 24 | 25 | Returns: 26 | account dict for given account_id 27 | """ 28 | url = '{}/{}{}/{}'.format(self.base_url, account_id, URL.PRODUCT, product_id) 29 | return self.get_url(url, data, **kwargs) 30 | 31 | def edit(self, account_id, product_id, data={}, **kwargs): 32 | """ 33 | Edit account information from given dict 34 | 35 | Returns: 36 | Account Dict which was edited 37 | """ 38 | url = '{}/{}{}/{}'.format(self.base_url, account_id, URL.PRODUCT, product_id) 39 | return self.patch_url(url, data, **kwargs) 40 | 41 | def fetchTnc(self, product_name, data={}, **kwargs): 42 | """ 43 | Fetch Terms and Conditions for a Sub-Merchant 44 | 45 | Returns: 46 | Tnc dict for given account_id 47 | """ 48 | url = '{}{}/{}{}'.format(URL.V2, URL.PRODUCT, product_name, URL.TNC ) 49 | return self.get_url(url, data, **kwargs) -------------------------------------------------------------------------------- /razorpay/resources/qrcode.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Qrcode(Resource): 6 | def __init__(self, client=None): 7 | super(Qrcode, self).__init__(client) 8 | self.base_url = URL.V1 + URL.QRCODE_URL 9 | 10 | def fetch(self, qrcode_id, data={}, **kwargs): 11 | """ 12 | Fetch a Qr code 13 | 14 | Args: 15 | customer_id : Id for which customer object has to be retrieved 16 | 17 | Returns: 18 | Qrcode dict for given qrcode id 19 | """ 20 | return super(Qrcode, self).fetch(qrcode_id, data, **kwargs) 21 | 22 | def create(self, data={}, **kwargs): 23 | """ 24 | Create a QR Code 25 | 26 | Returns: 27 | QrCode Dict which was created 28 | """ 29 | url = self.base_url 30 | return self.post_url(url, data, **kwargs) 31 | 32 | def all(self, data={}, **kwargs): 33 | """ 34 | Fetch All Qr Code 35 | 36 | Returns: 37 | Qrcode dict 38 | """ 39 | return super(Qrcode, self).all(data, **kwargs) 40 | 41 | def fetch_all_payments(self, qrcode_id, data={}, **kwargs): 42 | """ 43 | Fetch Payments for a QR Code 44 | 45 | Returns: 46 | Qrcode payment dict 47 | """ 48 | url = "{}/{}/payments".format(self.base_url, qrcode_id) 49 | return self.get_url(url, data, **kwargs) 50 | 51 | def close(self, qrcode_id, **kwargs): 52 | """ 53 | Close a QR Code 54 | 55 | Returns: 56 | Qrcode Dict which was closed 57 | """ 58 | url = '{}/{}/close'.format(self.base_url, qrcode_id) 59 | 60 | return self.post_url(url, {}, **kwargs) 61 | -------------------------------------------------------------------------------- /razorpay/resources/refund.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | import warnings 4 | 5 | 6 | class Refund(Resource): 7 | def __init__(self, client=None): 8 | super(Refund, self).__init__(client) 9 | self.base_url = URL.V1 + URL.REFUNDS_URL 10 | 11 | def fetch_all(self, data={}, **kwargs): # pragma: no cover 12 | warnings.warn("Will be Deprecated in next release, use all", 13 | DeprecationWarning) 14 | return self.all(data, **kwargs) 15 | 16 | def create(self, data={}, **kwargs): 17 | """ 18 | Create refund for given payment id 19 | """ 20 | url = self.base_url 21 | return self.post_url(url, data, **kwargs) 22 | 23 | def all(self, data={}, **kwargs): 24 | """ 25 | Fetch All Refund 26 | 27 | Returns: 28 | Refund dict 29 | """ 30 | return super(Refund, self).all(data, **kwargs) 31 | 32 | def fetch(self, refund_id, data={}, **kwargs): 33 | """ 34 | Refund object for given paymnet Id 35 | 36 | Args: 37 | refund_id : Refund Id for which refund has to be retrieved 38 | 39 | Returns: 40 | Refund dict for given refund Id 41 | """ 42 | return super(Refund, self).fetch(refund_id, data, **kwargs) 43 | 44 | def edit(self, refund_id, data={}, **kwargs): 45 | """ 46 | Update Refund 47 | 48 | Returns: 49 | Refund Dict which was edited 50 | """ 51 | url = "{}/{}".format(self.base_url, refund_id) 52 | return self.patch_url(url, data, **kwargs) 53 | -------------------------------------------------------------------------------- /razorpay/resources/registration_link.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class RegistrationLink(Resource): 6 | def __init__(self, client=None): 7 | super(RegistrationLink, self).__init__(client) 8 | self.base_url = URL.V1 + URL.REGISTRATION_LINK_URL 9 | 10 | def create(self, data={}, **kwargs): 11 | """ 12 | Create a Registration Link 13 | Args: 14 | customer : Details of the customer to whom the registration link will be sent. 15 | type* : In this case the value is link. 16 | currency* : Currency used in Order 17 | amount* : Amount of Order 18 | description : The count may not be greater than 100. 19 | subscription_registration : Details of the authorization payment. 20 | notes : A key-value pair 21 | 22 | Returns: 23 | {"success": true} 24 | """ 25 | url = "{}/{}".format(self.base_url, 'auth_links') 26 | return self.post_url(url, data, **kwargs) -------------------------------------------------------------------------------- /razorpay/resources/settlement.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Settlement(Resource): 6 | def __init__(self, client=None): 7 | super(Settlement, self).__init__(client) 8 | self.base_url = URL.V1 + URL.SETTLEMENT_URL 9 | 10 | def all(self, data={}, **kwargs): 11 | """ 12 | Fetch all Settlement entities 13 | 14 | Returns: 15 | Dictionary of Settlement data 16 | """ 17 | return super(Settlement, self).all(data, **kwargs) 18 | 19 | def fetch(self, settlement_id, data={}, **kwargs): 20 | """ 21 | Fetch Settlement data for given Id 22 | 23 | Args: 24 | settlement_id : Id for which settlement object has to be retrieved 25 | 26 | Returns: 27 | settlement dict for given settlement id 28 | """ 29 | return super(Settlement, self).fetch(settlement_id, data, **kwargs) 30 | 31 | def report(self, data={}, **kwargs): 32 | """ 33 | Settlement report for a month 34 | 35 | Returns: 36 | settlement dict 37 | """ 38 | url = "{}/recon/{}".format(self.base_url, 'combined') 39 | return self.get_url(url, data, **kwargs) 40 | 41 | def create_ondemand_settlement(self, data={}, **kwargs): 42 | """ 43 | create Ondemand Settlemententity 44 | 45 | Returns: 46 | settlement dict which was created 47 | """ 48 | url = "{}/{}".format(self.base_url,"ondemand") 49 | return self.post_url(url, data, **kwargs) 50 | 51 | def fetch_all_ondemand_settlement(self, data={}, **kwargs): 52 | """ 53 | create Ondemand Settlemententity 54 | 55 | Returns: 56 | settlement dict which was created 57 | """ 58 | url = "{}/{}".format(self.base_url,"ondemand") 59 | return self.get_url(url, data, **kwargs) 60 | 61 | def fetch_ondemand_settlement_id(self, settlement_id, data={}, **kwargs): 62 | """ 63 | fetch Ondemand Settlement by Id 64 | 65 | Returns: 66 | settlement dict for given settlement id 67 | """ 68 | url = "{}/ondemand/{}".format(self.base_url, settlement_id) 69 | return self.get_url(url, data, **kwargs) 70 | -------------------------------------------------------------------------------- /razorpay/resources/stakeholder.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Stakeholder(Resource): 6 | def __init__(self, client=None): 7 | super(Stakeholder, self).__init__(client) 8 | self.base_url = URL.V2 + URL.ACCOUNT 9 | 10 | def create(self, account_id, data={}, **kwargs): 11 | """ 12 | Create stakeholder from given dict and account id 13 | 14 | Returns: 15 | Stakeholder Dict which was created 16 | """ 17 | url = '{}/{}{}'.format(self.base_url, account_id, URL.STAKEHOLDER) 18 | 19 | return self.post_url(url, data, **kwargs) 20 | 21 | def fetch(self, account_id, stakeholder_id, data={}, **kwargs): 22 | """ 23 | Fetch stakeholder for given account & stakeholder id 24 | 25 | Args: 26 | account_id : Id for which account object has to be retrieved 27 | stakeholder_id : Id for which stakeholder object has to be retrieved 28 | 29 | Returns: 30 | stakeholder dict for given account_id 31 | """ 32 | url = '{}/{}{}/{}'.format(self.base_url, account_id, URL.STAKEHOLDER, stakeholder_id) 33 | 34 | return self.get_url(url, data, **kwargs) 35 | 36 | def all(self, account_id, data={}, **kwargs): 37 | """ 38 | Fetch all stakeholder 39 | 40 | Args: 41 | account_id : Id for which account object has to be retrieved 42 | 43 | Returns: 44 | stakeholder dict for given account_id 45 | """ 46 | url = '{}/{}{}'.format(self.base_url, account_id, URL.STAKEHOLDER) 47 | 48 | return self.get_url(url, data, **kwargs) 49 | 50 | def edit(self, account_id, stakeholder_id, data={}, **kwargs): 51 | """ 52 | Edit stakeholder information from given dict 53 | 54 | Returns: 55 | Stakeholder Dict which was edited 56 | """ 57 | url = '{}/{}{}/{}'.format(self.base_url, account_id, URL.STAKEHOLDER, stakeholder_id) 58 | 59 | return self.patch_url(url, data, **kwargs) 60 | 61 | def uploadStakeholderDoc(self, account_id, stakeholder_id, data={}, **kwargs): 62 | """ 63 | Upload Stakeholder Documents 64 | 65 | Returns: 66 | Stakeholder Document dict which was created 67 | """ 68 | url = '{}/{}{}/{}/{}'.format(self.base_url, account_id, URL.STAKEHOLDER, stakeholder_id, "documents") 69 | 70 | return self.file_url(url, data, **kwargs) 71 | 72 | def fetchStakeholderDoc(self, account_id, stakeholder_id, data={}, **kwargs): 73 | """ 74 | Fetch Stakeholder Documents 75 | 76 | Returns: 77 | Stakeholder Document dict for given account & stakeholder Id 78 | """ 79 | url = '{}/{}{}/{}/{}'.format(self.base_url, account_id, URL.STAKEHOLDER, stakeholder_id, "documents") 80 | 81 | return self.get_url(url, data, **kwargs) -------------------------------------------------------------------------------- /razorpay/resources/token.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Token(Resource): 6 | def __init__(self, client=None): 7 | super(Token, self).__init__(client) 8 | self.base_url = URL.V1 + URL.CUSTOMER_URL 9 | 10 | def create(self, data={}, **kwargs): 11 | """ 12 | Create token from given dict 13 | 14 | Returns: 15 | token Dict which was created 16 | """ 17 | url = '{}{}'.format(URL.V1, URL.TOKEN) 18 | 19 | return self.post_url(url, data, **kwargs) 20 | 21 | def fetch(self, customer_id, token_id, data={}, **kwargs): 22 | """ 23 | Fetch Token for given Id and given customer Id 24 | 25 | Args: 26 | customer_id : Customer Id for which tokens have to be fetched 27 | token_id : Id for which TOken object has to be fetched 28 | 29 | Returns: 30 | Token dict for given token Id 31 | """ 32 | url = "{}/{}/tokens/{}".format(self.base_url, customer_id, token_id) 33 | return self.get_url(url, data, **kwargs) 34 | 35 | def all(self, customer_id, data={}, **kwargs): 36 | """ 37 | Get all tokens for given customer Id 38 | 39 | Args: 40 | customer_id : Customer Id for which tokens have to be fetched 41 | 42 | Returns: 43 | Token dicts for given cutomer Id 44 | """ 45 | url = "{}/{}/tokens".format(self.base_url, customer_id) 46 | return self.get_url(url, data, **kwargs) 47 | 48 | def delete(self, customer_id, token_id, data={}, **kwargs): 49 | """ 50 | Delete Given Token For a Customer 51 | 52 | Args: 53 | customer_id : Customer Id for which tokens have to be deleted 54 | token_id : Id for which TOken object has to be deleted 55 | Returns: 56 | Dict for deleted token 57 | """ 58 | url = "{}/{}/tokens/{}".format(self.base_url, customer_id, token_id) 59 | return self.delete_url(url, data, **kwargs) 60 | 61 | def fetchToken(self, data={}, **kwargs): 62 | """ 63 | fetch Given Token For a Customer 64 | 65 | Returns: 66 | Dict for fetch token 67 | """ 68 | url = '{}{}/{}'.format(URL.V1, URL.TOKEN, "fetch") 69 | return self.post_url(url, data, **kwargs) 70 | 71 | def deleteToken(self, data={}, **kwargs): 72 | """ 73 | Delete Given Token 74 | 75 | Returns: 76 | Dict for deleted token 77 | """ 78 | url = '{}{}/{}'.format(URL.V1, URL.TOKEN, "delete") 79 | return self.post_url(url, data, **kwargs) 80 | 81 | def processPaymentOnAlternatePAorPG(self, data={}, **kwargs): 82 | """ 83 | Process a Payment on another PA/PG with Token Created on Razorpay 84 | 85 | Returns: 86 | 87 | """ 88 | url = '{}{}/{}'.format(URL.V1, URL.TOKEN, "service_provider_tokens/token_transactional_data") 89 | return self.post_url(url, data, **kwargs) 90 | -------------------------------------------------------------------------------- /razorpay/resources/transfer.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | import warnings 4 | 5 | 6 | class Transfer(Resource): 7 | def __init__(self, client=None): 8 | super(Transfer, self).__init__(client) 9 | self.base_url = URL.V1 + URL.TRANSFER_URL 10 | 11 | def fetch_all(self, data={}, **kwargs): # pragma: no cover 12 | warnings.warn("Will be Deprecated in next release, use all", 13 | DeprecationWarning) 14 | return self.all(data, **kwargs) 15 | 16 | def all(self, data={}, **kwargs): 17 | """ 18 | Fetch all Transfer entities 19 | 20 | Returns: 21 | Dictionary of Transfer data 22 | """ 23 | if 'payment_id' in data: 24 | url = URL.V1 + "/payments/{}/transfers".format(data['payment_id']) 25 | 26 | del data['payment_id'] 27 | return self.get_url(url, data, **kwargs) 28 | 29 | return super(Transfer, self).all(data, **kwargs) 30 | 31 | def fetch(self, transfer_id, data={}, **kwargs): 32 | """ 33 | Fetch Transfer for given Id 34 | 35 | Args: 36 | transfer_id : Id for which transfer object has to be retrieved 37 | 38 | Returns: 39 | Transfer dict for given transfer Id 40 | """ 41 | return super(Transfer, self).fetch(transfer_id, data, **kwargs) 42 | 43 | def create(self, data={}, **kwargs): 44 | """ 45 | Create Transfer from given dict 46 | 47 | Args: 48 | 49 | Returns: 50 | Transfer Dict which was created 51 | """ 52 | url = self.base_url 53 | return self.post_url(url, data, **kwargs) 54 | 55 | def edit(self, transfer_id, data={}, **kwargs): 56 | """ 57 | Edit Transfer from given id 58 | 59 | Args: 60 | transfer_id : Id for which transfer object has to be edited 61 | 62 | Returns: 63 | Transfer Dict which was edited 64 | """ 65 | url = "{}/{}".format(self.base_url, transfer_id) 66 | return self.patch_url(url, data, **kwargs) 67 | 68 | def reverse(self, transfer_id, data={}, **kwargs): 69 | """ 70 | Reverse Transfer from given id 71 | 72 | Args: 73 | transfer_id : Id for which transfer object has to be reversed 74 | 75 | Returns: 76 | Transfer Dict which was reversed 77 | """ 78 | url = "{}/{}/reversals".format(self.base_url, transfer_id) 79 | return self.post_url(url, data, **kwargs) 80 | 81 | def reversals(self, transfer_id, data={}, **kwargs): 82 | """ 83 | Get all Reversal Transfer from given id 84 | 85 | Args: 86 | transfer_id : 87 | Id for which reversal transfer object has to be fetched 88 | 89 | Returns: 90 | Transfer Dict 91 | """ 92 | url = "{}/{}/reversals".format(self.base_url, transfer_id) 93 | return self.get_url(url, data, **kwargs) 94 | -------------------------------------------------------------------------------- /razorpay/resources/virtual_account.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | import json 4 | 5 | 6 | class VirtualAccount(Resource): 7 | def __init__(self, client=None): 8 | super(VirtualAccount, self).__init__(client) 9 | self.base_url = URL.V1 + URL.VIRTUAL_ACCOUNT_URL 10 | 11 | def all(self, data={}, **kwargs): 12 | """ 13 | Fetch all Virtual Account entities 14 | 15 | Returns: 16 | Dictionary of Virtual Account data 17 | """ 18 | return super(VirtualAccount, self).all(data, **kwargs) 19 | 20 | def fetch(self, virtual_account_id, data={}, **kwargs): 21 | """ 22 | Fetch Virtual Account for given Id 23 | 24 | Args: 25 | virtual_account_id : 26 | Id for which Virtual Account object has to be retrieved 27 | 28 | Returns: 29 | Virtual Account dict for given Virtual Account Id 30 | """ 31 | return super(VirtualAccount, self).fetch( 32 | virtual_account_id, 33 | data, 34 | **kwargs) 35 | 36 | def create(self, data={}, **kwargs): 37 | """ 38 | Create Virtual Account from given dict 39 | 40 | Args: 41 | Param for Creating Virtual Account 42 | 43 | Returns: 44 | Virtual Account dict 45 | """ 46 | url = self.base_url 47 | return self.post_url(url, data, **kwargs) 48 | 49 | def close(self, virtual_account_id, data={}, **kwargs): 50 | """ 51 | Close Virtual Account from given Id 52 | 53 | Args: 54 | virtual_account_id : 55 | Id for which Virtual Account objects has to be Closed 56 | """ 57 | url = "{}/{}/close".format(self.base_url, virtual_account_id) 58 | return self.post_url(url, data, **kwargs) 59 | 60 | def payments(self, virtual_account_id, data={}, **kwargs): 61 | """ 62 | Fetch Payment for Virtual Account Id 63 | 64 | Args: 65 | virtual_account_id : 66 | Id for which Virtual Account objects has to be retrieved 67 | 68 | Returns: 69 | Payment dict for given Virtual Account Id 70 | """ 71 | url = "{}/{}/payments".format(self.base_url, virtual_account_id) 72 | return self.get_url(url, data, **kwargs) 73 | 74 | def add_receiver(self, virtual_account_id, data={}, **kwargs): 75 | """ 76 | Add receiver to an existing virtual account 77 | 78 | Args: 79 | virtual_account_id : 80 | Id for which Virtual Account objects has to be Closed 81 | """ 82 | url = "{}/{}/receivers".format(self.base_url, virtual_account_id) 83 | return self.post_url(url, data, **kwargs) 84 | 85 | def add_allowed_player(self, virtual_account_id, data={}, **kwargs): 86 | """ 87 | Add an Allowed Payer Account 88 | 89 | Args: 90 | virtual_account_id : 91 | Id for which Virtual Account objects has to be Closed 92 | """ 93 | url = "{}/{}/allowed_payers".format(self.base_url, virtual_account_id) 94 | return self.post_url(url, data, **kwargs) 95 | 96 | def delete_allowed_player(self, virtual_account_id, allowed_player_id, data={}, **kwargs): 97 | """ 98 | Delete an Allowed Payer Account 99 | 100 | Args: 101 | virtual_account_id : 102 | Id for which Virtual Account objects has to be Closed 103 | Returns: 104 | 204 105 | """ 106 | url = "{}/{}/allowed_payers/{}".format(self.base_url, virtual_account_id, allowed_player_id) 107 | return self.delete_url(url, data, **kwargs) -------------------------------------------------------------------------------- /razorpay/resources/webhook.py: -------------------------------------------------------------------------------- 1 | from .base import Resource 2 | from ..constants.url import URL 3 | 4 | 5 | class Webhook(Resource): 6 | def __init__(self, client=None): 7 | super(Webhook, self).__init__(client) 8 | self.base_url = URL.V2 + URL.ACCOUNT 9 | 10 | def create(self, data={}, account_id=None, **kwargs): 11 | """ 12 | Create webhook from given dict 13 | 14 | Returns: 15 | Webhook Dict which was created 16 | """ 17 | if account_id is None: 18 | url = '{}{}'.format(URL.V1, URL.WEBHOOK) 19 | else: 20 | url = '{}/{}{}'.format(self.base_url, account_id, URL.WEBHOOK) 21 | 22 | return self.post_url(url, data, **kwargs) 23 | 24 | def fetch(self, webhook_id, account_id, data={}, **kwargs): 25 | """ 26 | Fetch webhook for given webhook id 27 | 28 | Args: 29 | account_id : Id for which webhook object has to be retrieved 30 | webhook_id : Id for which account object has to be retrieved 31 | 32 | Returns: 33 | webhook dict for given webhook_id 34 | """ 35 | if(account_id): 36 | url = '{}/{}{}/{}'.format(self.base_url, account_id, URL.WEBHOOK, webhook_id) 37 | else: 38 | url = '{}{}/{}'.format(URL.V1, URL.WEBHOOK, webhook_id) 39 | 40 | return self.get_url(url, data, **kwargs) 41 | 42 | def all(self, data={}, account_id=None, **kwargs): 43 | """ 44 | Fetch all webhooks 45 | 46 | Args: 47 | account_id : Id for which webhook object has to be retrieved 48 | 49 | Returns: 50 | webhook dict for given account_id 51 | """ 52 | if account_id is None: 53 | url = '{}{}'.format(URL.V1, URL.WEBHOOK) 54 | else: 55 | url = '{}/{}{}'.format(self.base_url, account_id, URL.WEBHOOK) 56 | 57 | return self.get_url(url, data, **kwargs) 58 | 59 | def edit(self, webhook_id, account_id, data={}, **kwargs): 60 | """ 61 | Edit webhook from given dict 62 | 63 | Returns: 64 | Webhook Dict which was edited 65 | """ 66 | if(account_id): 67 | url = '{}/{}{}/{}'.format(self.base_url, account_id, URL.WEBHOOK, webhook_id) 68 | return self.patch_url(url, data, **kwargs) 69 | 70 | else: 71 | url = '{}{}/{}'.format(URL.V1, URL.WEBHOOK, webhook_id) 72 | return self.put_url(url, data, **kwargs) 73 | 74 | def delete(self, webhook_id, account_id, data={}, **kwargs): 75 | """ 76 | delete webhook for given webhook id 77 | 78 | Args: 79 | account_id : Id for which webhook object has to be retrieved 80 | webhook_id : Id for which account object has to be retrieved 81 | 82 | Returns: 83 | The response is always be an empty array like this - [] 84 | """ 85 | url = '{}/{}{}/{}'.format(self.base_url, account_id, URL.WEBHOOK, webhook_id) 86 | return self.delete_url(url, data, **kwargs) -------------------------------------------------------------------------------- /razorpay/utility/__init__.py: -------------------------------------------------------------------------------- 1 | from .utility import Utility 2 | 3 | __all__ = [ 4 | 'Utility', 5 | ] 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | with open('README.md') as readme: 4 | readme_content = readme.read() 5 | 6 | setup( 7 | name="razorpay", 8 | version="1.4.2", 9 | description="Razorpay Python Client", 10 | long_description=readme_content, 11 | long_description_content_type='text/markdown', 12 | url="https://github.com/razorpay/razorpay-python", 13 | author="Team Razorpay", 14 | license="MIT", 15 | install_requires=["requests"], 16 | include_package_data=True, 17 | package_dir={'razorpay': 'razorpay', 'razorpay.resources': 'razorpay/resources'}, 18 | packages=['razorpay', 'razorpay.resources'], 19 | keywords='razorpay payment gateway india', 20 | classifiers=[ 21 | "Development Status :: 4 - Beta", 22 | "Intended Audience :: Developers", 23 | "License :: OSI Approved :: MIT License", 24 | 25 | # List of supported Python versions 26 | # Make sure that this is reflected in .github/workflows/python.yml as well 27 | "Programming Language :: Python", 28 | 'Programming Language :: Python :: 3', 29 | 'Programming Language :: Python :: 3.4', 30 | 'Programming Language :: Python :: 3.5', 31 | 'Programming Language :: Python :: 3.6', 32 | 33 | "Topic :: Software Development :: Libraries :: Python Modules", 34 | ] 35 | ) 36 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/razorpay/razorpay-python/283773b4aba0a4a423f1a80966188186c6272c6f/tests/__init__.py -------------------------------------------------------------------------------- /tests/helpers.py: -------------------------------------------------------------------------------- 1 | import razorpay 2 | import os 3 | import unittest 4 | 5 | 6 | def mock_file(filename): 7 | if not filename: 8 | return '' 9 | file_dir = os.path.dirname(__file__) 10 | file_path = "{}/mocks/{}.json".format(file_dir, filename) 11 | with open(file_path) as f: 12 | mock_file_data = f.read() 13 | return mock_file_data 14 | 15 | 16 | class ClientTestCase(unittest.TestCase): 17 | def setUp(self): 18 | self.base_url = 'https://api.razorpay.com/v1' 19 | self.base_url_v2 = 'https://api.razorpay.com/v2' 20 | self.secondary_url = 'https://test-api.razorpay.com' 21 | self.v1 = 'v1' 22 | self.v2 = 'v2' 23 | self.payment_id = 'fake_payment_id' 24 | self.refund_id = 'fake_refund_id' 25 | self.card_id = 'fake_card_id' 26 | self.customer_id = 'fake_customer_id' 27 | self.token_id = 'fake_token_id' 28 | self.addon_id = 'fake_addon_id' 29 | self.subscription_id = 'fake_subscription_id' 30 | self.plan_id = 'fake_plan_id' 31 | self.settlement_id = 'fake_settlement_id' 32 | self.client = razorpay.Client(auth=('key_id', 'key_secret')) 33 | self.secondary_client = razorpay.Client(auth=('key_id', 'key_secret'), 34 | base_url=self.secondary_url) 35 | -------------------------------------------------------------------------------- /tests/mocks/addon_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 2, 4 | "items": [ 5 | { 6 | "id": "ao_IZfz8DsvzEu2w4", 7 | "entity": "addon", 8 | "item": { 9 | "id": "item_IZfz8DdzVw4Sda", 10 | "active": true, 11 | "name": "Shipping charges", 12 | "description": "Shipping charges", 13 | "amount": 500, 14 | "unit_amount": 500, 15 | "currency": "INR", 16 | "type": "addon", 17 | "unit": null, 18 | "tax_inclusive": false, 19 | "hsn_code": null, 20 | "sac_code": null, 21 | "tax_rate": null, 22 | "tax_id": null, 23 | "tax_group_id": null, 24 | "created_at": 1639991720, 25 | "updated_at": 1639991720 26 | }, 27 | "quantity": 1, 28 | "created_at": 1639991720, 29 | "subscription_id": "sub_IZfz84gerEXmVG", 30 | "invoice_id": "inv_IZfz8cWWBAjU12" 31 | }, 32 | { 33 | "id": "ao_IZe1vykIM4hmFv", 34 | "entity": "addon", 35 | "item": { 36 | "id": "item_IZe1vyVGweG3ya", 37 | "active": true, 38 | "name": "Shipping charges", 39 | "description": "Shipping charges", 40 | "amount": 500, 41 | "unit_amount": 500, 42 | "currency": "INR", 43 | "type": "addon", 44 | "unit": null, 45 | "tax_inclusive": false, 46 | "hsn_code": null, 47 | "sac_code": null, 48 | "tax_rate": null, 49 | "tax_id": null, 50 | "tax_group_id": null, 51 | "created_at": 1639984836, 52 | "updated_at": 1639984836 53 | }, 54 | "quantity": 1, 55 | "created_at": 1639984836, 56 | "subscription_id": "sub_IZe1vrmbHpvgCh", 57 | "invoice_id": "inv_IZe1wNpGVcDHZD" 58 | } 59 | ] 60 | } -------------------------------------------------------------------------------- /tests/mocks/bad_request_error.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": { 3 | "code": "BAD_REQUEST_ERROR", 4 | "description": "The amount is invalid", 5 | "field": "amount" 6 | } 7 | } -------------------------------------------------------------------------------- /tests/mocks/bank_account.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "ba_LSZht1Cm7xFTwF", 3 | "entity": "bank_account", 4 | "ifsc": "ICIC0001207", 5 | "bank_name": "ICICI Bank", 6 | "name": "Gaurav Kumar", 7 | "notes": [], 8 | "account_number": "XXXXXXXXXXXXXXX0434" 9 | } 10 | -------------------------------------------------------------------------------- /tests/mocks/cancel_payment_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "accept_partial": false, 3 | "amount": 100, 4 | "amount_paid": 0, 5 | "cancelled_at": 1602524667, 6 | "created_at": 1602524646, 7 | "currency": "INR", 8 | "customer": { 9 | "contact": "9999999999", 10 | "email": "gaurav.kumar@razorpay.com" 11 | }, 12 | "description": "Payment for Acme Inc", 13 | "expire_by": 0, 14 | "expired_at": 0, 15 | "first_min_partial_amount": 0, 16 | "id": "plink_Fo4oI0cXjpQIz3", 17 | "notes": null, 18 | "notify": { 19 | "email": true, 20 | "sms": true 21 | }, 22 | "order_id": "order_Fo4oOGcvR4srav", 23 | "payments": [], 24 | "reference_id": "", 25 | "reminder_enable": false, 26 | "reminders": [], 27 | "short_url": "https://rzp.io/i/foDnrXbBD", 28 | "status": "cancelled", 29 | "updated_at": 1602524667, 30 | "upi_link": true, 31 | "user_id": "FmjfFPCOUOAcSH" 32 | } -------------------------------------------------------------------------------- /tests/mocks/customer_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity":"collection", 3 | "count":1, 4 | "items":[ 5 | { 6 | "id":"cust_1Aa00000000001", 7 | "entity":"customer", 8 | "name":"Gaurav Kumar", 9 | "email":"gaurav.kumar@example.com", 10 | "contact":"9876543210", 11 | "gstin":"29XAbbA4369J1PA", 12 | "notes":{ 13 | "note_key_1":"September", 14 | "note_key_2":"Make it so." 15 | }, 16 | "created_at ":1234567890 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /tests/mocks/dispute.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "disp_9GTZ2XXXXXXXXX", 3 | "entity": "dispute", 4 | "payment_id": "pay_9GMNcXXXXXXXXX", 5 | "amount": 5000, 6 | "currency": "INR", 7 | "amount_deducted": 0, 8 | "gateway_dispute_id": "test", 9 | "reason_code": "goods_or_services_not_received_or_partially_received", 10 | "respond_by": 1514658600, 11 | "status": "under_review", 12 | "phase": "chargeback", 13 | "comments": null, 14 | "created_at": 1513965738 15 | } 16 | -------------------------------------------------------------------------------- /tests/mocks/dispute_accept.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "disp_AHfqOvkldwsbqt", 3 | "entity": "dispute", 4 | "payment_id": "pay_EsyWjHrfzb59eR", 5 | "amount": 10000, 6 | "currency": "INR", 7 | "amount_deducted": 10000, 8 | "reason_code": "pre_arbitration", 9 | "respond_by": 1590604200, 10 | "status": "lost", 11 | "phase": "pre_arbitration", 12 | "created_at": 1590059211, 13 | "evidence": { 14 | "amount": 10000, 15 | "summary": null, 16 | "shipping_proof": null, 17 | "billing_proof": null, 18 | "cancellation_proof": null, 19 | "customer_communication": null, 20 | "proof_of_service": null, 21 | "explanation_letter": null, 22 | "refund_confirmation": null, 23 | "access_activity_log": null, 24 | "refund_cancellation_policy": null, 25 | "term_and_conditions": null, 26 | "others": null, 27 | "submitted_at": null 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/mocks/dispute_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 2, 4 | "items": [ 5 | { 6 | "id": "disp_Esz7KAitoYM7PJ", 7 | "entity": "dispute", 8 | "payment_id": "pay_EsyWjHrfzb59eR", 9 | "amount": 10000, 10 | "currency": "INR", 11 | "amount_deducted": 0, 12 | "reason_code": "pre_arbitration", 13 | "respond_by": 1590604200, 14 | "status": "open", 15 | "phase": "pre_arbitration", 16 | "created_at": 1590059211, 17 | "evidence": { 18 | "amount": 10000, 19 | "summary": null, 20 | "shipping_proof": null, 21 | "billing_proof": null, 22 | "cancellation_proof": null, 23 | "customer_communication": null, 24 | "proof_of_service": null, 25 | "explanation_letter": null, 26 | "refund_confirmation": null, 27 | "access_activity_log": null, 28 | "refund_cancellation_policy": null, 29 | "term_and_conditions": null, 30 | "others": null, 31 | "submitted_at": null 32 | } 33 | }, 34 | { 35 | "id": "disp_Esyvk3kZj0isXk", 36 | "entity": "dispute", 37 | "payment_id": "pay_EsyWjHrfzb59eR", 38 | "amount": 5000, 39 | "currency": "INR", 40 | "amount_deducted": 0, 41 | "reason_code": "warning_bulletin_or_exception_file", 42 | "respond_by": 1590604200, 43 | "status": "won", 44 | "phase": "chargeback", 45 | "created_at": 1590058554, 46 | "evidence": { 47 | "amount": 5000, 48 | "summary": null, 49 | "shipping_proof": [ 50 | "doc_EFtmUsbwpXwBH9", 51 | "doc_EFtmUsbwpXwBH8" 52 | ], 53 | "billing_proof": null, 54 | "cancellation_proof": null, 55 | "customer_communication": null, 56 | "proof_of_service": null, 57 | "explanation_letter": null, 58 | "refund_confirmation": null, 59 | "access_activity_log": null, 60 | "refund_cancellation_policy": null, 61 | "term_and_conditions": null, 62 | "others": null, 63 | "submitted_at": 1590604100 64 | } 65 | } 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /tests/mocks/dispute_contest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "disp_AHfqOvkldwsbqt", 3 | "entity": "dispute", 4 | "payment_id": "pay_EsyWjHrfzb59eR", 5 | "amount": 10000, 6 | "currency": "INR", 7 | "amount_deducted": 0, 8 | "reason_code": "chargeback", 9 | "respond_by": 1590604200, 10 | "status": "open", 11 | "phase": "chargeback", 12 | "created_at": 1590059211, 13 | "evidence": { 14 | "amount": 5000, 15 | "summary": "goods delivered", 16 | "shipping_proof": [ 17 | "doc_EFtmUsbwpXwBH9", 18 | "doc_EFtmUsbwpXwBH8" 19 | ], 20 | "billing_proof": null, 21 | "cancellation_proof": null, 22 | "customer_communication": null, 23 | "proof_of_service": null, 24 | "explanation_letter": null, 25 | "refund_confirmation": null, 26 | "access_activity_log": null, 27 | "refund_cancellation_policy": null, 28 | "term_and_conditions": null, 29 | "others": [ 30 | { 31 | "type": "receipt_signed_by_customer", 32 | "document_ids": [ 33 | "doc_EFtmUsbwpXwBH1", 34 | "doc_EFtmUsbwpXwBH7" 35 | ] 36 | } 37 | ], 38 | "submitted_at": null 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/mocks/document.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "doc_EsyWjHrfzb59Re", 3 | "entity": "document", 4 | "purpose": "dispute_evidence", 5 | "name": "doc_19_12_2020.jpg", 6 | "mime_type": "image/png", 7 | "size": 2863, 8 | "created_at": 1590604200 9 | } 10 | -------------------------------------------------------------------------------- /tests/mocks/edit_customer.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "test@test.com", 3 | } 4 | -------------------------------------------------------------------------------- /tests/mocks/edit_order.json: -------------------------------------------------------------------------------- 1 | { 2 | "id":"order_DaaS6LOUAASb7Y", 3 | "entity":"order", 4 | "amount":2200, 5 | "amount_paid":0, 6 | "amount_due":2200, 7 | "currency":"INR", 8 | "receipt":"Receipt #211", 9 | "offer_id":null, 10 | "status":"attempted", 11 | "attempts":1, 12 | "notes":{ 13 | "notes_key_1":"Tea, Earl Grey, Hot", 14 | "notes_key_2":"Tea, Earl Grey… decaf." 15 | }, 16 | "created_at":1572505143 17 | } -------------------------------------------------------------------------------- /tests/mocks/edit_payment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "pay_CBYy6tLmJTzn3Q", 3 | "entity": "payment", 4 | "amount": 1000, 5 | "currency": "INR", 6 | "status": "authorized", 7 | "order_id": null, 8 | "invoice_id": null, 9 | "international": false, 10 | "method": "netbanking", 11 | "amount_refunded": 0, 12 | "refund_status": null, 13 | "captured": false, 14 | "description": null, 15 | "card_id": null, 16 | "bank": "UTIB", 17 | "wallet": null, 18 | "vpa": null, 19 | "email": "testme@acme.com", 20 | "notes": { 21 | "key1": "value1", 22 | "key2": "value2" 23 | }, 24 | "fee": null, 25 | "tax": null, 26 | "error_code": null, 27 | "error_description": null, 28 | "error_source": null, 29 | "error_step": null, 30 | "error_reason": null, 31 | "acquirer_data": { 32 | "bank_transaction_id": "0125836177" 33 | }, 34 | "created_at": 1553504328 35 | } -------------------------------------------------------------------------------- /tests/mocks/edit_payment_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "accept_partial": false, 3 | "amount": 100, 4 | "amount_paid": 100, 5 | "cancelled_at": 0, 6 | "created_at": 1602522293, 7 | "currency": "INR", 8 | "customer": { 9 | "contact": "9999999999", 10 | "email": "gaurav.kumar@razorpay.com" 11 | }, 12 | "description": "Payment for Acme Inc", 13 | "expire_by": 1653347540, 14 | "expired_at": 0, 15 | "first_min_partial_amount": 0, 16 | "id": "plink_Fo48rl281ENAg9", 17 | "notes": { 18 | "policy_name": "Jeevan Saral" 19 | }, 20 | "notify": { 21 | "email": true, 22 | "sms": true 23 | }, 24 | "order_id": "order_Fo491cL6NGAjkI", 25 | "payments": [ 26 | { 27 | "amount": 100, 28 | "created_at": 1602522351, 29 | "method": "upi", 30 | "payment_id": "pay_Fo49sHbQ78PCMI", 31 | "status": "captured" 32 | } 33 | ], 34 | "reference_id": "TS35", 35 | "reminder_enable": false, 36 | "reminders": [], 37 | "short_url": "https://rzp.io/i/XQiMe4w", 38 | "status": "paid", 39 | "updated_at": 1602523645, 40 | "upi_link": true, 41 | "user_id": "FmjfFPCOUOAcSH" 42 | } -------------------------------------------------------------------------------- /tests/mocks/eligibility.json: -------------------------------------------------------------------------------- 1 | { 2 | "instruments": [ 3 | { 4 | "method": "paylater", 5 | "provider": "lazypay", 6 | "eligibility_req_id": "elig_LBwGKVvS2X48Lq", 7 | "eligibility": { 8 | "status": "eligible" 9 | } 10 | }, 11 | { 12 | "method": "paylater", 13 | "provider": "getsimpl", 14 | "eligibility_req_id": "elig_LBwGKVvS2X48Lq", 15 | "eligibility": { 16 | "status": "ineligible", 17 | "error": { 18 | "code": "GATEWAY_ERROR", 19 | "description": "The customer has exhausted their credit limit", 20 | "source": "gateway", 21 | "step": "inquiry", 22 | "reason": "credit_limit_exhausted" 23 | } 24 | } 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/mocks/eligibility_check.json: -------------------------------------------------------------------------------- 1 | { 2 | "amount": "500000", 3 | "customer": { 4 | "id": "KkBhM9EC1Y0HTm", 5 | "contact": "+918220722114" 6 | }, 7 | "instruments": [ 8 | { 9 | "method": "emi", 10 | "issuer": "HDFC", 11 | "type": "debit", 12 | "eligibility_req_id": "elig_KkCNLzlNeMYQyZ", 13 | "eligibility": { 14 | "status": "eligible" 15 | } 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/mocks/fake_account.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "acc_GRWKk7qQsLnDjX", 3 | "type": "standard", 4 | "status": "created", 5 | "email": "gauriagain.kumar@example.org", 6 | "profile": { 7 | "category": "healthcare", 8 | "subcategory": "clinic", 9 | "addresses": { 10 | "registered": { 11 | "street1": "507, Koramangala 1st block", 12 | "street2": "MG Road", 13 | "city": "Bengaluru", 14 | "state": "KARNATAKA", 15 | "postal_code": 560034, 16 | "country": "IN" 17 | }, 18 | "operation": { 19 | "street1": "507, Koramangala 6th block", 20 | "street2": "Kormanagalo", 21 | "city": "Bengaluru", 22 | "state": "KARNATAKA", 23 | "country": "IN", 24 | "postal_code": 560047 25 | } 26 | }, 27 | "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." 28 | }, 29 | "notes": { 30 | "internal_ref_id": "123123" 31 | }, 32 | "created_at": 1611136837, 33 | "phone": "9000090000", 34 | "business_type": "partnership", 35 | "legal_business_name": "Acme Corp", 36 | "customer_facing_business_name": "Example", 37 | "legal_info": { 38 | "pan": "AAACL1234C", 39 | "gst": "18AABCU9603R1ZM" 40 | }, 41 | "apps": { 42 | "websites": [ 43 | "https://www.example.org" 44 | ], 45 | "android": [ 46 | { 47 | "url": "playstore.example.org", 48 | "name": "Example" 49 | } 50 | ], 51 | "ios": [ 52 | { 53 | "url": "appstore.example.org", 54 | "name": "Example" 55 | } 56 | ] 57 | }, 58 | "brand": { 59 | "color": "#FFFFFF" 60 | }, 61 | "contact_info": { 62 | "chargeback": { 63 | "email": "cb@example.org", 64 | "phone": null, 65 | "policy_url": null 66 | }, 67 | "refund": { 68 | "email": "cb@example.org", 69 | "phone": null, 70 | "policy_url": null 71 | }, 72 | "support": { 73 | "email": "support@example.org", 74 | "phone": "9999999998", 75 | "policy_url": "https://www.google.com" 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/mocks/fake_addon.json: -------------------------------------------------------------------------------- 1 | { 2 | "invoice_id": null, 3 | "created_at": 1508769839, 4 | "entity": "addon", 5 | "item": { 6 | "description": null, 7 | "tax_inclusive": false, 8 | "tax_group_id": null, 9 | "created_at": 1508769839, 10 | "updated_at": 1508769839, 11 | "currency": "INR", 12 | "amount": 30000, 13 | "unit_amount": 30000, 14 | "active": true, 15 | "tax_id": null, 16 | "type": "addon", 17 | "id": "item_8sg8LTuRkjcVnH", 18 | "unit": null, 19 | "name": "Extra Chair" 20 | }, 21 | "subscription_id": "sub_8RlLljfA4AnDVx", 22 | "id": "ao_8sg8LU73Y3ieav", 23 | "quantity": 2 24 | } 25 | -------------------------------------------------------------------------------- /tests/mocks/fake_app_details.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Django", 3 | "version": "1.8.17" 4 | } 5 | 6 | -------------------------------------------------------------------------------- /tests/mocks/fake_bank_transfer.json: -------------------------------------------------------------------------------- 1 | { 2 | "amount": 10000, 3 | "payer_bank_account": null, 4 | "payer_bank_name": "Razorpay", 5 | "payment_id": "fake_payment_id", 6 | "virtual_account_id": "va_8J2ny4Naokqbpe" 7 | } 8 | -------------------------------------------------------------------------------- /tests/mocks/fake_captured_payment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "pay_29QQoUBi66xm2f", 3 | "entity": "payment", 4 | "amount": 500, 5 | "currency": "INR", 6 | "status": "captured", 7 | "amount_refunded": 0, 8 | "refund_status": null, 9 | "error_code": null, 10 | "error_description": null, 11 | "udf": {}, 12 | "created_at": 1400826750 13 | } 14 | -------------------------------------------------------------------------------- /tests/mocks/fake_card.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "fake_card_id", 3 | "entity": "card", 4 | "international": false, 5 | "last4": 1111, 6 | "name": "sample name", 7 | "network": "Visa", 8 | "type": "debit", 9 | } 10 | -------------------------------------------------------------------------------- /tests/mocks/fake_card_detail_payment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "card_6krZ6bcjoeqyV9", 3 | "entity": "card", 4 | "name": "Gaurav", 5 | "last4": "3335", 6 | "network": "Visa", 7 | "type": "debit", 8 | "issuer": "SBIN", 9 | "international": false, 10 | "emi": null, 11 | "sub_type": "business" 12 | } -------------------------------------------------------------------------------- /tests/mocks/fake_create_recurring.json: -------------------------------------------------------------------------------- 1 | { 2 | "razorpay_payment_id": "pay_Ia5nRCnwjqXGxv", 3 | "razorpay_order_id": "order_Ia5nABHSOWXg0Q", 4 | "razorpay_signature": "1aa6e8472135fad2925071d547c6682a95a42d8b773e8346ddffec1c67ef3edf", 5 | "org_logo": "", 6 | "org_name": "Razorpay Software Private Ltd", 7 | "checkout_logo": "https://cdn.razorpay.com/logo.png", 8 | "custom_branding": false 9 | } -------------------------------------------------------------------------------- /tests/mocks/fake_customer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "fake_customer_id", 3 | "entity": "customer", 4 | "email": "test@test.com", 5 | "contact": 9876543210, 6 | "name": "sample name", 7 | "notes": [], 8 | } 9 | -------------------------------------------------------------------------------- /tests/mocks/fake_delete_allowed_payer.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /tests/mocks/fake_iin.json: -------------------------------------------------------------------------------- 1 | { 2 | "iin": "412345", 3 | "entity": "iin", 4 | "network": "Visa", 5 | "type": "credit", 6 | "sub_type": "business", 7 | "issuer_code": "HDFC", 8 | "issuer_name": "HDFC Bank Ltd", 9 | "international": false, 10 | "is_tokenized": true, 11 | "card_iin": "411111", 12 | "emi": { 13 | "available": true 14 | }, 15 | "recurring": { 16 | "available": true 17 | }, 18 | "authentication_types": [ 19 | { 20 | "type": "3ds" 21 | }, 22 | { 23 | "type": "otp" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tests/mocks/fake_invoice.json: -------------------------------------------------------------------------------- 1 | { 2 | "issued_at": 1481541533, 3 | "customer_details": 4 | { 5 | 6 | "customer_contact": null, 7 | "customer_address": null, 8 | "customer_email": null, 9 | "customer_name": null 10 | }, 11 | "short_url": "http://bit.ly/link", 12 | "receipt": null, 13 | "entity": "invoice", 14 | "currency": "INR", 15 | "paid_at": null, 16 | "view_less": true, 17 | "id": "random_id", 18 | "customer_id": null, 19 | "type": null, 20 | "status": "issued", 21 | "description": "random decsription", 22 | "order_id": "order_random_id", 23 | "sms_status": null, 24 | "date": 1481541533, 25 | "payment_id": null, 26 | "line_items": [], 27 | "notes": [], 28 | "amount": 100, 29 | "email_status": null, 30 | "created_at": 1481541534 31 | } 32 | -------------------------------------------------------------------------------- /tests/mocks/fake_invoice_cancel.json: -------------------------------------------------------------------------------- 1 | { 2 | "issued_at": 1481541533, 3 | "customer_details": 4 | { 5 | 6 | "customer_contact": null, 7 | "customer_address": null, 8 | "customer_email": null, 9 | "customer_name": null 10 | }, 11 | "short_url": "http://bit.ly/link", 12 | "receipt": null, 13 | "entity": "invoice", 14 | "currency": "INR", 15 | "paid_at": null, 16 | "view_less": true, 17 | "id": "random_id", 18 | "customer_id": null, 19 | "type": null, 20 | "status": "cancelled", 21 | "description": "random decsription", 22 | "order_id": "order_random_id", 23 | "sms_status": null, 24 | "date": 1481541533, 25 | "payment_id": null, 26 | "line_items": [], 27 | "notes": [], 28 | "amount": 100, 29 | "email_status": null, 30 | "created_at": 1481541534 31 | } 32 | -------------------------------------------------------------------------------- /tests/mocks/fake_invoice_delete.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /tests/mocks/fake_invoice_edit.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "inv_gHQwerty123ggd", 3 | "entity": "invoice", 4 | "receipt": "BILL13375649", 5 | "invoice_number": null, 6 | "customer_id": "cust_00000000000001", 7 | "customer_details": { 8 | "name": "Gaurav Kumar", 9 | "email": "gaurav.kumar@razorpay.com", 10 | "contact": "9123456789", 11 | "billing_address": null, 12 | }, 13 | "order_id": null, 14 | "line_items": [ 15 | { 16 | "id": "li_gHQwerty123gg1", 17 | "item_id": null, 18 | "name": "Book / English August - Updated name and quantity", 19 | "description": "Funny story of an IAS officer wanting to be aything other than an IAS.", 20 | "amount": 20000, 21 | "unit_amount": 20000, 22 | "gross_amount": 20000, 23 | "tax_amount": 0, 24 | "net_amount": 20000, 25 | "currency": "INR", 26 | "type": "invoice", 27 | "tax_inclusive": false, 28 | "unit": null, 29 | "quantity": 1, 30 | "taxes": [] 31 | }, 32 | { 33 | "id": "li_gHQwerty123gg2", 34 | "item_id": null, 35 | "name": "Book / A Wild Sheep Chase", 36 | "description": null, 37 | "amount": 20000, 38 | "unit_amount": 20000, 39 | "gross_amount": 20000, 40 | "tax_amount": 0, 41 | "net_amount": 20000, 42 | "currency": "INR", 43 | "type": "invoice", 44 | "tax_inclusive": false, 45 | "unit": null, 46 | "quantity": 1, 47 | "taxes": [] 48 | }, 49 | { 50 | "id": "li_gHQwerty123gg3", 51 | "item_id": "null", 52 | "name": "Book / Rocket Man: Elon Musk in His Own Words", 53 | "description": "Elon Musk, the South African--born entrepreneur who made his first fortune with Internet companies such as PayPal, has risen to global prominence as the visionary CEO of both Tesla Motors and SpaceX", 54 | "amount": 20000, 55 | "unit_amount": 20000, 56 | "gross_amount": 20000, 57 | "tax_amount": 0, 58 | "net_amount": 20000, 59 | "currency": "INR", 60 | "type": "invoice", 61 | "tax_inclusive": false, 62 | "unit": null, 63 | "quantity": 1, 64 | "taxes": [] 65 | } 66 | ], 67 | "payment_id": null, 68 | "status": "draft", 69 | "expire_by": null, 70 | "issued_at": null, 71 | "paid_at": null, 72 | "cancelled_at": null, 73 | "expired_at": null, 74 | "sms_status": "pending", 75 | "email_status": "pending", 76 | "date": 1505937098, 77 | "terms": null, 78 | "partial_payment": false, 79 | "gross_amount": 20000, 80 | "tax_amount": 0, 81 | "amount": 20000, 82 | "amount_paid": null, 83 | "amount_due": null, 84 | "currency": "INR", 85 | "description": null, 86 | "notes": { 87 | "updated-key": "An updated note." 88 | }, 89 | "comment": null, 90 | "short_url": null, 91 | "view_less": true, 92 | "billing_start": null, 93 | "billing_end": null, 94 | "type": "invoice", 95 | "group_taxes_discounts": false, 96 | "user_id": null, 97 | "created_at": 1505935715 98 | } 99 | -------------------------------------------------------------------------------- /tests/mocks/fake_invoice_notify_by.json: -------------------------------------------------------------------------------- 1 | { 2 | "success": true 3 | } 4 | -------------------------------------------------------------------------------- /tests/mocks/fake_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "item_7Oxp4hmm6T4SCn", 3 | "active": true, 4 | "name": "Book / English August", 5 | "description": "An indian story, Booker prize winner.", 6 | "amount": 20000, 7 | "currency": "INR" 8 | } -------------------------------------------------------------------------------- /tests/mocks/fake_merchant_token.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "token_IJmat4GwYATMtx", 3 | "entity": "token", 4 | "method": "card", 5 | "card": { 6 | "last4": "1111", 7 | "network": "Visa", 8 | "type": "credit", 9 | "issuer": "IDFB", 10 | "international": false, 11 | "emi": false, 12 | "sub_type": "consumer" 13 | }, 14 | "customer": { 15 | "id": "cust_1Aa00000000001", 16 | "entity": "customer", 17 | "name": "Bob", 18 | "email": "bob@gmail.com", 19 | "contact": "9000090000", 20 | "gstin": null, 21 | "notes": { 22 | "notes_key_1": "Tea, Earl Grey, Hot", 23 | "notes_key_2": "Tea, Earl Grey… decaf." 24 | }, 25 | "created_at": 1658390470 26 | }, 27 | "expired_at": 1701368999, 28 | "customer_id": "cust_1Aa00000000001", 29 | "compliant_with_tokenisation_guidelines": true, 30 | "status": "active", 31 | "notes": [] 32 | } 33 | -------------------------------------------------------------------------------- /tests/mocks/fake_order.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "fake_order_id", 3 | "entity": "order", 4 | "amount": 500, 5 | "attempts": 1, 6 | "currency": "INR", 7 | "status": "attempted", 8 | "notes": [], 9 | "created_at": 1400826750, 10 | "receipt": "12121" 11 | } 12 | -------------------------------------------------------------------------------- /tests/mocks/fake_otp_generate.json: -------------------------------------------------------------------------------- 1 | { 2 | "razorpay_payment_id": "pay_FVmAstJWfsD3SO", 3 | "next": [ 4 | { 5 | "action": "otp_submit", 6 | "url": "https://api.razorpay.com/v1/payments/pay_FVmAstJWfsD3SO/otp_submit/ac2d415a8be7595de09a24b41661729fd9028fdc?key_id=" 7 | }, 8 | { 9 | "action": "otp_resend", 10 | "url": "https://api.razorpay.com/v1/payments/pay_FVmAstJWfsD3SO/otp_resend/json?key_id=" 11 | } 12 | ], 13 | "metadata": { 14 | "issuer": "HDFC", 15 | "network": "MC", 16 | "last4": "1111", 17 | "iin": "411111" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/mocks/fake_otp_resend.json: -------------------------------------------------------------------------------- 1 | { 2 | "next": [ 3 | "otp_submit", 4 | "otp_resend" 5 | ], 6 | "razorpay_payment_id": "pay_JWaNvYmrx75sXo" 7 | } -------------------------------------------------------------------------------- /tests/mocks/fake_otp_submit.json: -------------------------------------------------------------------------------- 1 | { 2 | "razorpay_payment_id": "pay_D5jmY2H6vC7Cy3", 3 | "razorpay_order_id": "order_9A33XWu170gUtm", 4 | "razorpay_signature": "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d" 5 | } 6 | -------------------------------------------------------------------------------- /tests/mocks/fake_payment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "fake_payment_id", 3 | "entity": "payment", 4 | "amount": 500, 5 | "currency": "INR", 6 | "status": "created", 7 | "amount_refunded": 0, 8 | "refund_status": null, 9 | "error_code": null, 10 | "error_description": null, 11 | "udf": {}, 12 | "created_at": 1400826750 13 | } -------------------------------------------------------------------------------- /tests/mocks/fake_payment_authorized_webhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "event": "payment.authorized", 3 | "entity": "event", 4 | "contains": [ 5 | "payment" 6 | ], 7 | "payload": { 8 | "payment": { 9 | "entity": { 10 | "id": "pay_6koWN7bvxujzxM", 11 | "entity": "payment", 12 | "amount": 1000000, 13 | "currency": "INR", 14 | "status": "captured", 15 | "order_id": "order_100000000order", 16 | "international": false, 17 | "method": "card", 18 | "amount_refunded": 0, 19 | "refund_status": null, 20 | "captured": true, 21 | "description": "random description", 22 | "card_id": "card_6koWNAT6LASUqy", 23 | "bank": null, 24 | "wallet": null, 25 | "vpa": null, 26 | "email": "a@b.com", 27 | "contact": "+919999999999", 28 | "notes": { 29 | "merchant_order_id": "random order id" 30 | }, 31 | "fee": 23000, 32 | "service_tax": 3000, 33 | "error_code": null, 34 | "error_description": null, 35 | "created_at": 1479978483 36 | } 37 | } 38 | }, 39 | "created_at": 1400826760 40 | } 41 | -------------------------------------------------------------------------------- /tests/mocks/fake_payment_json.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "respawn", 3 | "request": { 4 | "url": "https://api.razorpay.com/v1/payments?key_id=rzp_test_pNL6H0AmbBEyjD", 5 | "method": "POST", 6 | "content": { 7 | "amount": "500", 8 | "currency": "INR", 9 | "email": "gaurav.kumar@example.com", 10 | "contact": "9123456789", 11 | "order_id": "order_IfCiyxcRYv1bbf", 12 | "method": "upi", 13 | "card": { 14 | "number": "4854980604708430", 15 | "cvv": "123", 16 | "expiry_month": "12", 17 | "expiry_year": "21", 18 | "name": "Gaurav Kumar" 19 | }, 20 | "_": { 21 | "library": "s2s" 22 | }, 23 | "upi": { 24 | "flow": "collect", 25 | "type": "default" 26 | } 27 | } 28 | }, 29 | "image": null, 30 | "theme": "#3594E2", 31 | "method": "upi", 32 | "version": "1", 33 | "missing": [ 34 | "vpa" 35 | ], 36 | "base": "api.razorpay.com", 37 | "org_logo": "", 38 | "org_name": "Razorpay Software Private Ltd", 39 | "checkout_logo": "https://cdn.razorpay.com/logo.png", 40 | "custom_branding": false 41 | } -------------------------------------------------------------------------------- /tests/mocks/fake_payment_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "accept_partial": false, 3 | "amount": 100, 4 | "amount_paid": 100, 5 | "cancelled_at": 0, 6 | "created_at": 1602522293, 7 | "currency": "INR", 8 | "customer": { 9 | "contact": "9999999999", 10 | "email": "gaurav.kumar@razorpay.com" 11 | }, 12 | "description": "Payment for Acme Inc", 13 | "expire_by": 0, 14 | "expired_at": 0, 15 | "first_min_partial_amount": 0, 16 | "id": "plink_Fo48rl281ENAg9", 17 | "notes": { 18 | "policy_name": "Jivan Asha" 19 | }, 20 | "notify": { 21 | "email": true, 22 | "sms": true 23 | }, 24 | "order_id": "order_Fo491cL6NGAjkI", 25 | "payments": [ 26 | { 27 | "amount": 100, 28 | "created_at": 1602522351, 29 | "method": "upi", 30 | "payment_id": "pay_Fo49sHbQ78PCMI", 31 | "status": "captured" 32 | } 33 | ], 34 | "reference_id": "", 35 | "reminder_enable": false, 36 | "reminders": [], 37 | "short_url": "https://rzp.io/i/XQiMe4w", 38 | "status": "paid", 39 | "updated_at": 1602522351, 40 | "upi_link": true, 41 | "user_id": "FmjfFPCOUOAcSH" 42 | } 43 | -------------------------------------------------------------------------------- /tests/mocks/fake_plan.json: -------------------------------------------------------------------------------- 1 | { 2 | "created_at": 1507032151, 3 | "notes": [], 4 | "interval": 2, 5 | "period": "monthly", 6 | "entity": "plan", 7 | "item": { 8 | "description": null, 9 | "tax_inclusive": false, 10 | "tax_group_id": null, 11 | "created_at": 1507032151, 12 | "updated_at": 1507032151, 13 | "currency": "INR", 14 | "amount": 20000, 15 | "unit_amount": 20000, 16 | "active": true, 17 | "tax_id": null, 18 | "type": "plan", 19 | "id": "item_8kihN0AVflTXjt", 20 | "unit": null, 21 | "name": "test plan" 22 | }, 23 | "id": "plan_8kihN0YqhnF8a7" 24 | } 25 | -------------------------------------------------------------------------------- /tests/mocks/fake_qrcode.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "qr_HO2r1MDprYtWRT", 3 | "entity": "qr_code", 4 | "created_at": 1623915088, 5 | "name": "Store_1", 6 | "usage": "single_use", 7 | "type": "upi_qr", 8 | "image_url": "https://rzp.io/i/oCswTOcCo", 9 | "payment_amount": 300, 10 | "status": "active", 11 | "description": "For Store 1", 12 | "fixed_amount": true, 13 | "payments_amount_received": 0, 14 | "payments_count_received": 0, 15 | "notes": { 16 | "purpose": "Test UPI QR code notes" 17 | }, 18 | "customer_id": "cust_HKsR5se84c5LTO", 19 | "close_by": 1681615838, 20 | "closed_at": null, 21 | "close_reason": null 22 | } -------------------------------------------------------------------------------- /tests/mocks/fake_reference_card.json: -------------------------------------------------------------------------------- 1 | mock_file('fake_card') -------------------------------------------------------------------------------- /tests/mocks/fake_refund.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "rfnd_FP8DDKxqJif6ca", 3 | "entity": "refund", 4 | "amount": 300100, 5 | "currency": "INR", 6 | "payment_id": "pay_FIKOnlyii5QGNx", 7 | "notes": { 8 | "notes_key_1": "Beam me up Scotty.", 9 | "notes_key_2": "Engage" 10 | }, 11 | "receipt": "#126", 12 | "acquirer_data": { 13 | "arn": "10000000000000" 14 | }, 15 | "created_at": 1597078124, 16 | "status": "processed", 17 | "speed_processed": "normal", 18 | "speed_requested": "optimum" 19 | } -------------------------------------------------------------------------------- /tests/mocks/fake_registration_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "inv_FHrZAOeCuB9HtK", 3 | "entity": "invoice", 4 | "receipt": "Receipt no. 26", 5 | "invoice_number": "Receipt no. 26", 6 | "customer_id": "cust_BMB3EwbqnqZ2EI", 7 | "customer_details": { 8 | "id": "cust_BMB3EwbqnqZ2EI", 9 | "name": "Gaurav Kumar", 10 | "email": "gaurav.kumar@example.com", 11 | "contact": "9123456780", 12 | "gstin": null, 13 | "billing_address": null, 14 | "shipping_address": null, 15 | "customer_name": "Gaurav Kumar", 16 | "customer_email": "gaurav.kumar@example.com", 17 | "customer_contact": "9123456780" 18 | }, 19 | "order_id": "order_FHrZAPOStKd4xS", 20 | "line_items": [], 21 | "payment_id": null, 22 | "status": "issued", 23 | "expire_by": 1880480689, 24 | "issued_at": 1595491123, 25 | "paid_at": null, 26 | "cancelled_at": null, 27 | "expired_at": null, 28 | "sms_status": "pending", 29 | "email_status": "pending", 30 | "date": 1595491123, 31 | "terms": null, 32 | "partial_payment": false, 33 | "gross_amount": 0, 34 | "tax_amount": 0, 35 | "taxable_amount": 0, 36 | "amount": 0, 37 | "amount_paid": 0, 38 | "amount_due": 0, 39 | "currency": "INR", 40 | "currency_symbol": "₹", 41 | "description": "test registration link", 42 | "notes": { 43 | "note_key 1": "Beam me up Scotty", 44 | "note_key 2": "Tea. Earl Gray. Hot." 45 | }, 46 | "comment": null, 47 | "short_url": "https://rzp.io/i/RllVOmA", 48 | "view_less": true, 49 | "billing_start": null, 50 | "billing_end": null, 51 | "type": "link", 52 | "group_taxes_discounts": false, 53 | "created_at": 1595491123, 54 | "idempotency_key": null 55 | } -------------------------------------------------------------------------------- /tests/mocks/fake_reversal.json: -------------------------------------------------------------------------------- 1 | { 2 | "amount": 1000, 3 | "created_at": 1496665032, 4 | "currency": "INR", 5 | "entity": "reversal", 6 | "id": "fake_id", 7 | "notes": [], 8 | "transfer_id": "fake_transfer_id" 9 | } 10 | -------------------------------------------------------------------------------- /tests/mocks/fake_settlement.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "setl_7IZKKI4Pnt2kEe", 3 | "entity": "settlement", 4 | "amount": 60000, 5 | "status": "processed", 6 | "fees": 123, 7 | "tax": 12, 8 | "utr": "RZRP111111111111", 9 | "created_at": 1455696913 10 | } 11 | -------------------------------------------------------------------------------- /tests/mocks/fake_stakeholder.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "stakeholder", 3 | "relationship": { 4 | "director": true 5 | }, 6 | "phone": { 7 | "primary": "9000090000", 8 | "secondary": "9000090000" 9 | }, 10 | "notes": { 11 | "random_key_by_partner": "random_value" 12 | }, 13 | "kyc": { 14 | "pan": "AVOPB1111K" 15 | }, 16 | "id": "sth_GLGgm8fFCKc92m", 17 | "name": "Gaurav Kumar", 18 | "email": "gaurav.kumar@example.com", 19 | "percentage_ownership": 10, 20 | "addresses": { 21 | "residential": { 22 | "street": "506, Koramangala 1st block", 23 | "city": "Bengaluru", 24 | "state": "Karnataka", 25 | "postal_code": "560034", 26 | "country": "IN" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /tests/mocks/fake_subscription.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "active", 3 | "created_at": 1507032592, 4 | "current_end": 1512239400, 5 | "customer_notify": false, 6 | "plan_id": "plan_8kihN0YqhnF8a7", 7 | "charge_at": 1512239400, 8 | "current_start": 1507032611, 9 | "total_count": 6, 10 | "notes": [], 11 | "paid_count": 1, 12 | "entity": "subscription", 13 | "end_at": 1533234600, 14 | "start_at": 1507032611, 15 | "ended_at": null, 16 | "customer_id": "cust_8kipRefUGdjnqY", 17 | "id": "sub_8kip7ybbcOyc9J", 18 | "auth_attempts": 0, 19 | "quantity": 1 20 | } 21 | -------------------------------------------------------------------------------- /tests/mocks/fake_subscription_addon.json: -------------------------------------------------------------------------------- 1 | { 2 | "invoice_id": null, 3 | "created_at": 1508769839, 4 | "entity": "addon", 5 | "item": { 6 | "description": null, 7 | "updated_at": 1508769839, 8 | "currency": "INR", 9 | "active": true, 10 | "id": "item_8sg8LTuRkjcVnH", 11 | "unit": null, 12 | "tax_id": null, 13 | "name": "Extra Chair", 14 | "tax_inclusive": false, 15 | "tax_group_id": null, 16 | "created_at": 1508769839, 17 | "amount": 30000, 18 | "unit_amount": 30000, 19 | "type": "addon" 20 | }, 21 | "subscription_id": "sub_8RlLljfA4AnDVx", 22 | "id": "ao_8sg8LU73Y3ieav", 23 | "quantity": 2 24 | } 25 | -------------------------------------------------------------------------------- /tests/mocks/fake_subscription_cancelled.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "cancelled", 3 | "created_at": 1502893027, 4 | "current_end": null, 5 | "customer_notify": false, 6 | "plan_id": "plan_8RlDCnQzY7Muqj", 7 | "charge_at": null, 8 | "current_start": null, 9 | "total_count": 6, 10 | "notes": [], 11 | "paid_count": 0, 12 | "entity": "subscription", 13 | "end_at": 1714847400, 14 | "start_at": 1701793619, 15 | "ended_at": 1508767050, 16 | "customer_id": null, 17 | "id": "sub_8RlLljfA4AnDVx", 18 | "auth_attempts": 0, 19 | "quantity": 1 20 | } 21 | -------------------------------------------------------------------------------- /tests/mocks/fake_subscription_paused.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "sub_8RlLljfA4AnDVx", 3 | "entity": "subscription", 4 | "plan_id": "plan_IdJJ47TH0TdW9R", 5 | "customer_id": "cust_IOyIY3JvbVny9o", 6 | "status": "paused", 7 | "current_start": 1640854635, 8 | "current_end": 1643481000, 9 | "ended_at": null, 10 | "quantity": 1, 11 | "notes": { 12 | "source": "magento-subscription", 13 | "magento_quote_id": "25" 14 | }, 15 | "charge_at": null, 16 | "start_at": 1640854635, 17 | "end_at": 1653849000, 18 | "auth_attempts": 0, 19 | "total_count": 6, 20 | "paid_count": 1, 21 | "customer_notify": false, 22 | "created_at": 1640854612, 23 | "expire_by": null, 24 | "short_url": "https://rzp.io/i/TfApecvk", 25 | "has_scheduled_changes": true, 26 | "change_scheduled_at": 1643481000, 27 | "source": "magento-subscription", 28 | "payment_method": "card", 29 | "offer_id": null, 30 | "remaining_count": 5 31 | } -------------------------------------------------------------------------------- /tests/mocks/fake_subscription_resumed.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "sub_8RlLljfA4AnDVx", 3 | "entity": "subscription", 4 | "plan_id": "plan_IdJJ47TH0TdW9R", 5 | "customer_id": "cust_IOyIY3JvbVny9o", 6 | "status": "active", 7 | "current_start": 1640854635, 8 | "current_end": 1643481000, 9 | "ended_at": null, 10 | "quantity": 1, 11 | "notes": { 12 | "source": "magento-subscription", 13 | "magento_quote_id": "25" 14 | }, 15 | "charge_at": 1643481000, 16 | "start_at": 1640854635, 17 | "end_at": 1653849000, 18 | "auth_attempts": 0, 19 | "total_count": 6, 20 | "paid_count": 1, 21 | "customer_notify": false, 22 | "created_at": 1640854612, 23 | "expire_by": null, 24 | "short_url": "https://rzp.io/i/TfApecvk", 25 | "has_scheduled_changes": true, 26 | "change_scheduled_at": 1643481000, 27 | "source": "magento-subscription", 28 | "payment_method": "card", 29 | "offer_id": null, 30 | "remaining_count": 5 31 | } -------------------------------------------------------------------------------- /tests/mocks/fake_token.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "fake_token_id", 3 | "entity": "token", 4 | "method": "card", 5 | "recurring": true, 6 | "token": "token_id", 7 | "used_at": 1482751390, 8 | "wallet": null, 9 | "card":[ 10 | "emi":true, 11 | "entity":"card", 12 | expiry_month:"2", 13 | expiry_year:"2022", 14 | "international":false, 15 | "issuer":"HDFC", 16 | "last4":1111, 17 | "name":"test name", 18 | "network":"Visa", 19 | "type":"credit" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /tests/mocks/fake_transfer.json: -------------------------------------------------------------------------------- 1 | { 2 | "amount": 100, 3 | "amount_reversed": 0, 4 | "created_at": 1506722466, 5 | "currency": "INR", 6 | "entity": "transfer", 7 | "fees": 0, 8 | "id": "trf_8jIlBetfktf1dG", 9 | "notes": [], 10 | "on_hold": false, 11 | "on_hold_until": null, 12 | "recipient": "acc_7jO4N6LScw5CEG", 13 | "recipient_settlement_id": null, 14 | "service_tax": 0, 15 | "source": "acc_10000000000000", 16 | "tax": 0 17 | } 18 | -------------------------------------------------------------------------------- /tests/mocks/fake_upi_transfer.json: -------------------------------------------------------------------------------- 1 | { 2 | "amount": 10000, 3 | "payer_vpa": null, 4 | "payer_account": null, 5 | "payer_bank": "Razorpay", 6 | "payment_id": "fake_payment_id", 7 | "virtual_account_id": "va_8J2ny4Naokqbpf" 8 | } 9 | -------------------------------------------------------------------------------- /tests/mocks/fake_virtual_accounts.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "va_4xbQrmEoA5WJ0G", 3 | "entity": "virtual_account", 4 | "description": "First Virtual Account", 5 | "customer_id": "cust_805c8oBQdBGPwS", 6 | "status": "active", 7 | "amount_paid": 0, 8 | "notes": { 9 | "reference_key": "reference_value" 10 | }, 11 | "receivers": [ 12 | { 13 | "id": "ba_4lsdkfldlteskf", 14 | "entity": "bank_account", 15 | "name": "Merchant Billing Label", 16 | "account_number": "RAZORPAY9876543210", 17 | "ifsc": "RZPB0000001" 18 | } 19 | ], 20 | "created_at": 1455696638 21 | } 22 | -------------------------------------------------------------------------------- /tests/mocks/fake_virtual_accounts_closed.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "va_4xbQrmEoA5WJ0G", 3 | "entity": "virtual_account", 4 | "description": "First Virtual Account", 5 | "customer_id": "cust_805c8oBQdBGPwS", 6 | "status": "closed", 7 | "amount_paid": 0, 8 | "notes": { 9 | "reference_key": "reference_value" 10 | }, 11 | "receivers": [ 12 | { 13 | "id": "ba_4lsdkfldlteskf", 14 | "entity": "bank_account", 15 | "name": "Merchant Billing Label", 16 | "account_number": "RAZORPAY9876543210", 17 | "ifsc": "RZPB0000001" 18 | } 19 | ], 20 | "created_at": 1455696638 21 | } 22 | -------------------------------------------------------------------------------- /tests/mocks/fake_virtual_accounts_receiver.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "va_4xbQrmEoA5WJ0G", 3 | "name": "Acme Corp", 4 | "entity": "virtual_account", 5 | "status": "active", 6 | "description": "", 7 | "amount_expected": null, 8 | "notes": [], 9 | "amount_paid": 0, 10 | "customer_id": "cust_DzbSeP2RJD1ZHg", 11 | "receivers": [ 12 | { 13 | "id": "ba_DzcFjVqAMSCEIW", 14 | "entity": "bank_account", 15 | "ifsc":"RATN0VAAPIS", 16 | "bank_name": "RBL Bank", 17 | "name": "Acme Corp", 18 | "notes": [], 19 | "account_number": "2223333232194699" 20 | }, 21 | { 22 | "id": "vpa_DzcZR5ofjCUKAx", 23 | "entity": "vpa", 24 | "username": "rpy.payto00000gaurikumar", 25 | "handle": "icici", 26 | "address": "rpy.payto00000gaurikumar@icici" 27 | } 28 | ], 29 | "close_by": null, 30 | "closed_at": null, 31 | "created_at": 1577969986 32 | } -------------------------------------------------------------------------------- /tests/mocks/fake_webhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "HK890egfiItP3H", 3 | "created_at": 1623060358, 4 | "updated_at": 1623060358, 5 | "owner_id": "H3kYHQ635sBwXG", 6 | "owner_type": "merchant", 7 | "context": [], 8 | "disabled_at": 0, 9 | "url": "https://en1mwkqo5ioct.x.pipedream.net", 10 | "alert_email": "gaurav.kumar@example.com", 11 | "secret_exists": true, 12 | "entity": "webhook", 13 | "active": true, 14 | "events": [ 15 | "payment.authorized", 16 | "payment.failed", 17 | "payment.captured", 18 | "payment.dispute.created", 19 | "refund.failed", 20 | "refund.created" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /tests/mocks/fulfillment.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "order.fulfillment", 3 | "order_id": "EKwxwAgItXXXX", 4 | "payment_method": "upi", 5 | "shipping": { 6 | "waybill": "123456789", 7 | "status": "rto", 8 | "provider": "Bluedart" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/mocks/fund_account_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity":"collection", 3 | "count":1, 4 | "items":[ 5 | { 6 | "id": "fa_IJXLAImwGqjlkS", 7 | "entity": "fund_account", 8 | "customer_id": "cust_IEfAt3ruD4OEzo", 9 | "account_type": "bank_account", 10 | "bank_account": { 11 | "ifsc": "HDFC0000053", 12 | "bank_name": "HDFC Bank", 13 | "name": "Gaurav Kumar", 14 | "notes": [], 15 | "account_number": "11214311215411" 16 | }, 17 | "batch_id": null, 18 | "active": true, 19 | "created_at": 1636467835 20 | }, 21 | { 22 | "id": "fa_IJXI5ppTQAc3YB", 23 | "entity": "fund_account", 24 | "customer_id": "cust_IEfAt3ruD4OEzo", 25 | "account_type": "bank_account", 26 | "bank_account": { 27 | "ifsc": "HDFC0000053", 28 | "bank_name": "HDFC Bank", 29 | "name": "Gaurav Kumar", 30 | "notes": [], 31 | "account_number": "11214311215411" 32 | }, 33 | "batch_id": null, 34 | "active": true, 35 | "created_at": 1636467660 36 | } 37 | ] 38 | } -------------------------------------------------------------------------------- /tests/mocks/iin_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "iins": [ 4 | "401347", 5 | "222746" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /tests/mocks/init_account.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "gauriagain.kumar@example.org", 3 | "phone": "9000090000", 4 | "legal_business_name": "Acme Corp", 5 | "business_type": "partnership", 6 | "customer_facing_business_name": "Example", 7 | "profile": { 8 | "category": "healthcare", 9 | "subcategory": "clinic", 10 | "description": "Healthcare E-commerce platform", 11 | "addresses": { 12 | "operation": { 13 | "street1": "507, Koramangala 6th block", 14 | "street2": "Kormanagala", 15 | "city": "Bengaluru", 16 | "state": "Karnataka", 17 | "postal_code": 560047, 18 | "country": "IN" 19 | }, 20 | "registered": { 21 | "street1": "507, Koramangala 1st block", 22 | "street2": "MG Road", 23 | "city": "Bengaluru", 24 | "state": "Karnataka", 25 | "postal_code": 560034, 26 | "country": "IN" 27 | } 28 | }, 29 | "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." 30 | }, 31 | "legal_info": { 32 | "pan": "AAACL1234C", 33 | "gst": "18AABCU9603R1ZM" 34 | }, 35 | "brand": { 36 | "color": "FFFFFF" 37 | }, 38 | "notes": { 39 | "internal_ref_id": "123123" 40 | }, 41 | "contact_name": "Gaurav Kumar", 42 | "contact_info": { 43 | "chargeback": { 44 | "email": "cb@example.org" 45 | }, 46 | "refund": { 47 | "email": "cb@example.org" 48 | }, 49 | "support": { 50 | "email": "support@example.org", 51 | "phone": "9999999998", 52 | "policy_url": "https://www.google.com" 53 | } 54 | }, 55 | "apps": { 56 | "websites": [ 57 | "https://www.example.org" 58 | ], 59 | "android": [ 60 | { 61 | "url": "playstore.example.org", 62 | "name": "Example" 63 | } 64 | ], 65 | "ios": [ 66 | { 67 | "url": "appstore.example.org", 68 | "name": "Example" 69 | } 70 | ] 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/mocks/init_create_recurring.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "gaurav.kumar@example.com", 3 | "contact": "9876543567", 4 | "amount": 10000, 5 | "currency": "INR", 6 | "order_id": "order_Ia5nABHSOWXg0Q", 7 | "customer_id": "cust_DzYEzfJLV03rkp", 8 | "token": "token_Ia5ip8Ix07JDRm", 9 | "recurring": "1", 10 | "notes": { 11 | "note_key_1": "Tea. Earl grey. Hot.", 12 | "note_key_2": "Tea. Earl grey. Decaf." 13 | }, 14 | "description": "Creating recurring payment for Gaurav Kumar" 15 | } -------------------------------------------------------------------------------- /tests/mocks/init_customer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "email": "test@test.com", 4 | } 5 | -------------------------------------------------------------------------------- /tests/mocks/init_invoice.json: -------------------------------------------------------------------------------- 1 | { 2 | "type":"link", 3 | "decsription":"test", 4 | "line_items":[ 5 | { 6 | "name":"name", 7 | "amount":100 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /tests/mocks/init_invoice_edit.json: -------------------------------------------------------------------------------- 1 | { 2 | "line_items": [ 3 | { 4 | "id": "li_gHQwerty123gg1", 5 | "name": "Book / English August - Updated name and quantity", 6 | "quantity": 1 7 | }, 8 | { 9 | "name": "Book / A Wild Sheep Chase", 10 | "amount": 20000, 11 | "currency": "INR", 12 | "quantity": 1 13 | } 14 | ], 15 | "notes": { 16 | "updated-key": "An updated note." 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/mocks/init_order.json: -------------------------------------------------------------------------------- 1 | { 2 | "amount":"100", 3 | "currency":"INR", 4 | "receipt":"dummy" 5 | } 6 | -------------------------------------------------------------------------------- /tests/mocks/init_payment_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "amount": 1000, 3 | "currency": "INR", 4 | "accept_partial": true, 5 | "first_min_partial_amount": 100, 6 | "expire_by": 1691097057, 7 | "reference_id": "TS1989", 8 | "description": "Payment for policy no #23456", 9 | "customer": { 10 | "name": "Gaurav Kumar", 11 | "contact": "+919999999999", 12 | "email": "gaurav.kumar@example.com" 13 | }, 14 | "notify": { 15 | "sms": true, 16 | "email": true 17 | }, 18 | "reminder_enable": true, 19 | "notes": { 20 | "policy_name": "Jeevan Bima" 21 | }, 22 | "callback_url": "https://example-callback-url.com/", 23 | "callback_method": "get" 24 | } -------------------------------------------------------------------------------- /tests/mocks/init_plan.json: -------------------------------------------------------------------------------- 1 | { 2 | "item_id": "item_8kihN0AVflTXjt" 3 | } 4 | -------------------------------------------------------------------------------- /tests/mocks/init_registration_link.json: -------------------------------------------------------------------------------- 1 | { 2 | "customer": { 3 | "name": "Gaurav Kumar", 4 | "email": "gaurav.kumar@example.com", 5 | "contact": 9123456780 6 | }, 7 | "type": "link", 8 | "amount": 0, 9 | "currency": "INR", 10 | "description": "12 p.m. Meals", 11 | "subscription_registration": { 12 | "method": "emandate", 13 | "auth_type": "netbanking", 14 | "expire_at": 1580480689, 15 | "max_amount": 50000, 16 | "bank_account": { 17 | "beneficiary_name" : "Gaurav Kumar", 18 | "account_number" : 11214311215411, 19 | "account_type" : "savings", 20 | "ifsc_code" : "HDFC0001233" 21 | } 22 | }, 23 | "receipt": "Receipt no. 1", 24 | "expire_by" : 1880480689, 25 | "sms_notify": 1, 26 | "email_notify": 1, 27 | "notes" : { 28 | "note_key 1": "Beam me up Scotty", 29 | "note_key 2": "Tea. Earl Gray. Hot." 30 | } 31 | } -------------------------------------------------------------------------------- /tests/mocks/init_settlement.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "setlod_FNj7g2YS5J67Rz", 3 | "entity": "settlement.ondemand", 4 | "amount_requested": 200000, 5 | "amount_settled": 0, 6 | "amount_pending": 199410, 7 | "amount_reversed": 0, 8 | "fees": 590, 9 | "tax": 90, 10 | "currency": "INR", 11 | "settle_full_balance": 0, 12 | "status": "initiated", 13 | "description": "Need this to make vendor payments.", 14 | "notes": { 15 | "notes_key_1": "Tea, Earl Grey, Hot", 16 | "notes_key_2": "Tea, Earl Grey… decaf." 17 | }, 18 | "created_at": 1596771429, 19 | "ondemand_payouts": { 20 | "entity": "collection", 21 | "count": 1, 22 | "items": [ 23 | { 24 | "id": "setlodp_FNj7g2cbvw8ueO", 25 | "entity": "settlement.ondemand_payout", 26 | "initiated_at": null, 27 | "processed_at": null, 28 | "reversed_at": null, 29 | "amount": 200000, 30 | "amount_settled": null, 31 | "fees": 590, 32 | "tax": 90, 33 | "utr": null, 34 | "status": "created", 35 | "created_at": 1596771429 36 | } 37 | ] 38 | } 39 | } -------------------------------------------------------------------------------- /tests/mocks/init_stakeholder.json: -------------------------------------------------------------------------------- 1 | { 2 | "percentage_ownership": 10, 3 | "name": "Gaurav Kumar", 4 | "email": "gaurav.kumar@example.com", 5 | "relationship": { 6 | "director": true, 7 | "executive": false 8 | }, 9 | "phone": { 10 | "primary": "9000090000", 11 | "secondary": "9000090000" 12 | }, 13 | "addresses": { 14 | "residential": { 15 | "street": "506, Koramangala 1st block", 16 | "city": "Bengaluru", 17 | "state": "Karnataka", 18 | "postal_code": "560034", 19 | "country": "IN" 20 | } 21 | }, 22 | "kyc": { 23 | "pan": "AVOPB1111K" 24 | }, 25 | "notes": { 26 | "random_key_by_partner": "random_value" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/mocks/init_subscription.json: -------------------------------------------------------------------------------- 1 | { 2 | "plan_id":"plan_8kihN0YqhnF8a7", 3 | "customer_id":"cust_8kipRefUGdjnqY", 4 | "total_count": 6 5 | } 6 | -------------------------------------------------------------------------------- /tests/mocks/init_transfer.json: -------------------------------------------------------------------------------- 1 | { 2 | "amount": "100", 3 | "currency": "INR", 4 | "account": "dummy" 5 | } 6 | -------------------------------------------------------------------------------- /tests/mocks/init_virtual_accounts.json: -------------------------------------------------------------------------------- 1 | { 2 | "receiver_types": ["bank_account"], 3 | "description": "First Virtual Account" 4 | } 5 | -------------------------------------------------------------------------------- /tests/mocks/init_webhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "https://google.com", 3 | "alert_email": "gaurav.kumar@example.com", 4 | "secret": "12345", 5 | "events": [ 6 | "payment.authorized", 7 | "payment.failed", 8 | "payment.captured", 9 | "payment.dispute.created", 10 | "refund.failed", 11 | "refund.created" 12 | ] 13 | } -------------------------------------------------------------------------------- /tests/mocks/invoice_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "issued_at": 1481541533, 7 | "customer_details": 8 | { 9 | 10 | "customer_contact": null, 11 | "customer_address": null, 12 | "customer_email": null, 13 | "customer_name": null 14 | }, 15 | "short_url": "http://bit.ly/link", 16 | "receipt": null, 17 | "entity": "invoice", 18 | "currency": "INR", 19 | "paid_at": null, 20 | "view_less": true, 21 | "id": "random_id", 22 | "customer_id": null, 23 | "type": null, 24 | "status": "issued", 25 | "description": "random decsription", 26 | "order_id": "order_random_id", 27 | "sms_status": null, 28 | "date": 1481541533, 29 | "payment_id": null, 30 | "line_items": [], 31 | "notes": [], 32 | "amount": 100, 33 | "email_status": null, 34 | "created_at": 1481541534 35 | }, 36 | { 37 | "issued_at": 1481541533, 38 | "customer_details": 39 | { 40 | 41 | "customer_contact": null, 42 | "customer_address": null, 43 | "customer_email": null, 44 | "customer_name": null 45 | }, 46 | "short_url": "http://bit.ly/link_2", 47 | "receipt": null, 48 | "entity": "invoice", 49 | "currency": "INR", 50 | "paid_at": null, 51 | "view_less": true, 52 | "id": "random_id_2", 53 | "customer_id": null, 54 | "type": null, 55 | "status": "issued", 56 | "description": "random decsription", 57 | "order_id": "order_random_id_2", 58 | "sms_status": null, 59 | "date": 1481541533, 60 | "payment_id": null, 61 | "line_items": [], 62 | "notes": [], 63 | "amount": 100, 64 | "email_status": null, 65 | "created_at": 1481541534 66 | } 67 | ] 68 | } 69 | -------------------------------------------------------------------------------- /tests/mocks/invoice_collection_with_one_invoice.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 1, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "issued_at": 1481541533, 7 | "customer_details": 8 | { 9 | 10 | "customer_contact": null, 11 | "customer_address": null, 12 | "customer_email": null, 13 | "customer_name": null 14 | }, 15 | "short_url": "http://bit.ly/link", 16 | "receipt": null, 17 | "entity": "invoice", 18 | "currency": "INR", 19 | "paid_at": null, 20 | "view_less": true, 21 | "id": "random_id", 22 | "customer_id": null, 23 | "type": null, 24 | "status": "issued", 25 | "description": "random decsription", 26 | "order_id": "order_random_id", 27 | "sms_status": null, 28 | "date": 1481541533, 29 | "payment_id": null, 30 | "line_items": [], 31 | "notes": [], 32 | "amount": 100, 33 | "email_status": null, 34 | "created_at": 1481541534 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /tests/mocks/item_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 3, 4 | "items": [ 5 | { 6 | "id": "item_7Oy8OMV6BdEAac", 7 | "active": true, 8 | "name": "Book / Ignited Minds", 9 | "description": null, 10 | "amount": 15000, 11 | "currency": "INR" 12 | }, 13 | { 14 | "id": "item_7Oxp4hmm6T4SCn", 15 | "active": true, 16 | "name": "Book / English August", 17 | "description": "An indian story, Booker prize winner.", 18 | "amount": 20000, 19 | "currency": "INR" 20 | }, 21 | { 22 | "id": "item_7OxoGnoxCuUKbo", 23 | "active": true, 24 | "name": "Book / English August", 25 | "description": null, 26 | "amount": 20000, 27 | "currency": "INR" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /tests/mocks/order_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "id": "fake_order_id", 7 | "entity": "order", 8 | "amount": 500, 9 | "attempts": 1, 10 | "currency": "INR", 11 | "status": "attempted", 12 | "notes": [], 13 | "created_at": 1400826750, 14 | "receipt": "12121" 15 | }, 16 | { 17 | "id": "fake_order_id2", 18 | "entity": "order", 19 | "amount": 5000, 20 | "attempts": 2, 21 | "currency": "INR", 22 | "status": "attempted", 23 | "notes": [], 24 | "created_at": 1400826752, 25 | "receipt": "12123" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tests/mocks/order_collection_with_one_order.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 1, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "id": "fake_order_id", 7 | "entity": "order", 8 | "amount": 500, 9 | "attempts": 1, 10 | "currency": "INR", 11 | "status": "attempted", 12 | "notes": [], 13 | "created_at": 1400826750, 14 | "receipt": "12121" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/mocks/payment_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "id": "pay_29QQoUBi66xm2f", 7 | "entity": "payment", 8 | "amount": 500, 9 | "currency": "INR", 10 | "status": "created", 11 | "amount_refunded": 0, 12 | "refund_status": null, 13 | "error_code": null, 14 | "error_description": null, 15 | "udf": {}, 16 | "created_at": 1400826750 17 | }, 18 | { 19 | "id": "pay_19btGlBig6xZ2f", 20 | "entity": "payment", 21 | "amount": 500, 22 | "currency": "INR", 23 | "status": "created", 24 | "amount_refunded": 0, 25 | "refund_status": null, 26 | "error_code": null, 27 | "error_description": null, 28 | "udf": {}, 29 | "created_at": 1400826750 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /tests/mocks/payment_collection_with_one_payment.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 1, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "id": "pay_29QQoUBi66xm2f", 7 | "entity": "payment", 8 | "amount": 500, 9 | "currency": "INR", 10 | "status": "created", 11 | "amount_refunded": 0, 12 | "refund_status": null, 13 | "error_code": null, 14 | "error_description": null, 15 | "udf": {}, 16 | "created_at": 1400826750 17 | } 18 | ] 19 | } -------------------------------------------------------------------------------- /tests/mocks/payment_link_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "payment_links": [ 3 | { 4 | "accept_partial": false, 5 | "amount": 100, 6 | "amount_paid": 0, 7 | "cancelled_at": 0, 8 | "created_at": 1602523443, 9 | "currency": "INR", 10 | "customer": { 11 | "contact": "9999999999", 12 | "email": "gaurav.kumar@razorpay.com", 13 | "name": "Gaurav Kumar" 14 | }, 15 | "description": "Payment for policy no #23456", 16 | "expire_by": 0, 17 | "expired_at": 0, 18 | "first_min_partial_amount": 0, 19 | "id": "plink_Fo4T7Ht271epg3", 20 | "notes": { 21 | "policy_name": "Jeevan Bima" 22 | }, 23 | "notify": { 24 | "email": false, 25 | "sms": true 26 | }, 27 | "payments": [], 28 | "reference_id": "#41956", 29 | "reminder_enable": true, 30 | "reminders": { 31 | "status": "in_progress" 32 | }, 33 | "short_url": "https://rzp.io/i/LXnmFr3a", 34 | "status": "created", 35 | "updated_at": 1602523443, 36 | "upi_link": true, 37 | "user_id": "" 38 | }, 39 | { 40 | "accept_partial": false, 41 | "amount": 100, 42 | "amount_paid": 0, 43 | "cancelled_at": 1602522621, 44 | "created_at": 1602522615, 45 | "currency": "INR", 46 | "customer": { 47 | "contact": "9999999999", 48 | "email": "gaurav.kumar@razorpay.com" 49 | }, 50 | "description": "Payment for Acme Inc", 51 | "expire_by": 0, 52 | "expired_at": 0, 53 | "first_min_partial_amount": 0, 54 | "id": "plink_Fo4EWsg3KmfWGW", 55 | "notes": [], 56 | "notify": { 57 | "email": true, 58 | "sms": true 59 | }, 60 | "order_id": "order_Fo4EayQh1zSGxn", 61 | "payments": [], 62 | "reference_id": "", 63 | "reminder_enable": false, 64 | "reminders": [], 65 | "short_url": "https://rzp.io/i/2agF8tv", 66 | "status": "cancelled", 67 | "updated_at": 1602522621, 68 | "upi_link": true, 69 | "user_id": "FmjfFPCOUOAcSH" 70 | } 71 | ] 72 | } -------------------------------------------------------------------------------- /tests/mocks/plan_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "items": [ 4 | { 5 | "created_at": 1507032151, 6 | "notes": [], 7 | "interval": 2, 8 | "period": "monthly", 9 | "entity": "plan", 10 | "item": 11 | { 12 | "description": null, 13 | "tax_inclusive": false, 14 | "tax_group_id": null, 15 | "created_at": 1507032151, 16 | "updated_at": 1507032151, 17 | "currency": "INR", 18 | "amount": 20000, 19 | "unit_amount": 20000, 20 | "active": true, 21 | "tax_id": null, 22 | "type": "plan", 23 | "id": "item_8kihN0AVflTXjt", 24 | "unit": null, 25 | "name": "test plan" 26 | }, 27 | "id": "plan_8kihN0YqhnF8a7" 28 | }, 29 | { 30 | "created_at": 1504869309, 31 | "notes": 32 | { 33 | "undefined": "random" 34 | }, 35 | "interval": 1, 36 | "period": "monthly", 37 | "entity": "plan", 38 | "item": 39 | { 40 | "description": null, 41 | "tax_inclusive": false, 42 | "tax_group_id": null, 43 | "created_at": 1504869309, 44 | "updated_at": 1504869309, 45 | "currency": "INR", 46 | "amount": 1100, 47 | "unit_amount": 1100, 48 | "active": true, 49 | "tax_id": null, 50 | "type": "plan", 51 | "id": "item_8aoXJmyXcBKWjC", 52 | "unit": null, 53 | "name": "testing" 54 | }, 55 | "id": "plan_8aoXJnOqQAhq55" 56 | }], 57 | "entity": "collection" 58 | } 59 | -------------------------------------------------------------------------------- /tests/mocks/qrcode_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 2, 4 | "items": [ 5 | { 6 | "id": "qr_HO2jGkWReVBMNu", 7 | "entity": "qr_code", 8 | "created_at": 1623914648, 9 | "name": "Store_1", 10 | "usage": "single_use", 11 | "type": "upi_qr", 12 | "image_url": "https://rzp.io/i/w2CEwYmkAu", 13 | "payment_amount": 300, 14 | "status": "active", 15 | "description": "For Store 1", 16 | "fixed_amount": true, 17 | "payments_amount_received": 0, 18 | "payments_count_received": 0, 19 | "notes": { 20 | "purpose": "Test UPI QR code notes" 21 | }, 22 | "customer_id": "cust_HKsR5se84c5LTO", 23 | "close_by": 1681615838, 24 | "closed_at": null, 25 | "close_reason": null 26 | }, 27 | { 28 | "id": "qr_HO2e0813YlchUn", 29 | "entity": "qr_code", 30 | "created_at": 1623914349, 31 | "name": "Acme Groceries", 32 | "usage": "multiple_use", 33 | "type": "upi_qr", 34 | "image_url": "https://rzp.io/i/X6QM7LL", 35 | "payment_amount": null, 36 | "status": "closed", 37 | "description": "Buy fresh groceries", 38 | "fixed_amount": false, 39 | "payments_amount_received": 200, 40 | "payments_count_received": 1, 41 | "notes": { 42 | "Branch": "Bangalore - Rajaji Nagar" 43 | }, 44 | "customer_id": "cust_HKsR5se84c5LTO", 45 | "close_by": 1625077799, 46 | "closed_at": 1623914515, 47 | "close_reason": "on_demand" 48 | } 49 | ] 50 | } -------------------------------------------------------------------------------- /tests/mocks/qrcode_payments_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 2, 4 | "items": [ 5 | { 6 | "id": "pay_HMtDKn3TnF4D8x", 7 | "entity": "payment", 8 | "amount": 500, 9 | "currency": "INR", 10 | "status": "captured", 11 | "order_id": null, 12 | "invoice_id": null, 13 | "international": false, 14 | "method": "upi", 15 | "amount_refunded": 0, 16 | "refund_status": null, 17 | "captured": true, 18 | "description": "QRv2 Payment", 19 | "card_id": null, 20 | "bank": null, 21 | "wallet": null, 22 | "vpa": "gauri.kumari@okhdfcbank", 23 | "email": "gauri.kumari@example.com", 24 | "contact": "+919999999999", 25 | "customer_id": "cust_HKsR5se84c5LTO", 26 | "notes": [], 27 | "fee": 0, 28 | "tax": 0, 29 | "error_code": null, 30 | "error_description": null, 31 | "error_source": null, 32 | "error_step": null, 33 | "error_reason": null, 34 | "acquirer_data": { 35 | "rrn": "116514257019" 36 | }, 37 | "created_at": 1623662800 38 | }, 39 | { 40 | "id": "pay_HMsr242ZnaLumA", 41 | "entity": "payment", 42 | "amount": 1000, 43 | "currency": "INR", 44 | "status": "refunded", 45 | "order_id": null, 46 | "invoice_id": null, 47 | "international": false, 48 | "method": "upi", 49 | "amount_refunded": 1000, 50 | "refund_status": "full", 51 | "captured": true, 52 | "description": "QRv2 Payment", 53 | "card_id": null, 54 | "bank": null, 55 | "wallet": null, 56 | "vpa": "gauri.kumari@okhdfcbank", 57 | "email": "gauri.kumari@example.com", 58 | "contact": "+919999999999", 59 | "customer_id": "cust_HKsR5se84c5LTO", 60 | "notes": [], 61 | "fee": 0, 62 | "tax": 0, 63 | "error_code": null, 64 | "error_description": null, 65 | "error_source": null, 66 | "error_step": null, 67 | "error_reason": null, 68 | "acquirer_data": { 69 | "rrn": "116514090501" 70 | }, 71 | "created_at": 1623661533 72 | } 73 | ] 74 | } -------------------------------------------------------------------------------- /tests/mocks/refund_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "id": "rfnd_AABBdHIieexn5c", 7 | "entity": "refund", 8 | "amount": 100, 9 | "currency": "INR", 10 | "payment_id": "fake_payment_id", 11 | "created_at": 1500826750 12 | }, 13 | { 14 | "id": "rfnd_19btGlBig6xZ2f", 15 | "entity": "refund", 16 | "amount": 100, 17 | "currency": "INR", 18 | "payment_id": "fake_payment_id", 19 | "created_at": 1500826750 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /tests/mocks/reversal_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 1, 3 | "entity": "collection", 4 | "items": 5 | [ 6 | { 7 | "amount": 1000, 8 | "created_at": 1496665032, 9 | "currency": "INR", 10 | "entity": "reversal", 11 | "id": "fake_id", 12 | "notes": [], 13 | "transfer_id": "fake_transfer_id" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/mocks/rto.json: -------------------------------------------------------------------------------- 1 | { 2 | "risk_tier": "high", 3 | "rto_reasons": [ 4 | { 5 | "reason": "short_shipping_address", 6 | "description": "Short shipping address", 7 | "bucket": "address" 8 | }, 9 | { 10 | "reason": "address_pincode_state_mismatch", 11 | "description": "Incorrect pincode state entered", 12 | "bucket": "address" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /tests/mocks/settlement_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 3, 4 | "items": [ 5 | { 6 | "id": "setl_7IZKKI4Pnt2kEe", 7 | "entity": "settlement", 8 | "amount": 50000, 9 | "status" : "processed", 10 | "fees": 123, 11 | "tax": 12, 12 | "utr": "RZRP173069230703", 13 | "created_at": 1509622307 14 | }, 15 | { 16 | "id": "setl_4xbSwsPABDJ8oK", 17 | "entity": "settlement", 18 | "amount": 50000, 19 | "status" : "processed", 20 | "fees": 123, 21 | "tax": 12, 22 | "utr": "RZRP173069230702", 23 | "created_at": 1509622306 24 | }, 25 | { 26 | "id": "setl_4xbSwsPABDJ8jE", 27 | "entity": "settlement", 28 | "amount": 10000, 29 | "status" : "processed", 30 | "fees": 50000, 31 | "tax": 12, 32 | "utr": "RZRP173069230701", 33 | "created_at": 1509622506 34 | } 35 | ] 36 | } 37 | -------------------------------------------------------------------------------- /tests/mocks/settlement_collection_with_one_settlement.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 1, 4 | "items": [ 5 | { 6 | "id": "setl_7IZKKI4Pnt2kEe", 7 | "entity": "settlement", 8 | "amount": 50000, 9 | "status" : "processed", 10 | "fees": 123, 11 | "tax": 12, 12 | "utr": "RZRP173069230703", 13 | "created_at": 1509622307 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /tests/mocks/stakeholder_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "items": [ 4 | { 5 | "id": "GZ13yPHLJof9IE", 6 | "entity": "stakeholder", 7 | "relationship": { 8 | "director": true 9 | }, 10 | "phone": { 11 | "primary": "9000090000", 12 | "secondary": "9000090000" 13 | }, 14 | "notes": { 15 | "random_key_by_partner": "random_value" 16 | }, 17 | "kyc": { 18 | "pan": "AVOPB1111K" 19 | }, 20 | "name": "Gaurav Kumar", 21 | "email": "gaurav.kumar@acme.org", 22 | "percentage_ownership": 10, 23 | "addresses": { 24 | "residential": { 25 | "street": "506, Koramangala 1st block", 26 | "city": "Bengaluru", 27 | "state": "Karnataka", 28 | "postal_code": "560034", 29 | "country": "in" 30 | } 31 | } 32 | } 33 | ], 34 | "count": 1 35 | } 36 | -------------------------------------------------------------------------------- /tests/mocks/subscription_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "items": [ 4 | { 5 | "status": "active", 6 | "created_at": 1507032592, 7 | "current_end": 1512239400, 8 | "customer_notify": false, 9 | "plan_id": "plan_8kihN0YqhnF8a7", 10 | "charge_at": 1512239400, 11 | "current_start": 1507032611, 12 | "total_count": 6, 13 | "notes": [], 14 | "paid_count": 1, 15 | "entity": "subscription", 16 | "end_at": 1533234600, 17 | "start_at": 1507032611, 18 | "ended_at": null, 19 | "customer_id": "cust_8kipRefUGdjnqY", 20 | "id": "sub_8kip7ybbcOyc9J", 21 | "auth_attempts": 0, 22 | "quantity": 1 23 | }, 24 | { 25 | "status": "active", 26 | "created_at": 1507032162, 27 | "current_end": 1512239400, 28 | "customer_notify": false, 29 | "plan_id": "plan_8kihN0YqhnF8a7", 30 | "charge_at": 1512239400, 31 | "current_start": 1507032343, 32 | "total_count": 6, 33 | "notes": [], 34 | "paid_count": 1, 35 | "entity": "subscription", 36 | "end_at": 1533234600, 37 | "start_at": 1507032343, 38 | "ended_at": null, 39 | "customer_id": "cust_8kikjKS5WOFZHU", 40 | "id": "sub_8kihYqZKXsCSPz", 41 | "auth_attempts": 0, 42 | "quantity": 1 43 | } 44 | ], 45 | "entity": "collection" 46 | } 47 | -------------------------------------------------------------------------------- /tests/mocks/token_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "id": "fake_token_id", 7 | "entity": "token", 8 | "method": "card", 9 | "recurring": true, 10 | "token": "token_id", 11 | "used_at": 1482751390, 12 | "wallet": null, 13 | "card":[ 14 | "emi":true, 15 | "entity":"card", 16 | expiry_month:"2", 17 | expiry_year:"2022", 18 | "international":false, 19 | "issuer":"HDFC", 20 | "last4":1111, 21 | "name":"test name", 22 | "network":"Visa", 23 | "type":"credit" 24 | ] 25 | }, 26 | { 27 | "id": "fake_token_id_2", 28 | "entity": "token", 29 | "method": "card", 30 | "recurring": true, 31 | "token": "token_id_2", 32 | "used_at": 1482751390, 33 | "wallet": null, 34 | "card":[ 35 | "emi":true, 36 | "entity":"card", 37 | expiry_month:"2", 38 | expiry_year:"2022", 39 | "international":false, 40 | "issuer":"HDFC", 41 | "last4":1111, 42 | "name":"test name", 43 | "network":"Visa", 44 | "type":"credit" 45 | ] 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /tests/mocks/token_collection_with_one_token.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 1, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "id": "fake_token_id", 7 | "entity": "token", 8 | "method": "card", 9 | "recurring": true, 10 | "token": "token_id", 11 | "used_at": 1482751390, 12 | "wallet": null, 13 | "card":[ 14 | "emi":true, 15 | "entity":"card", 16 | expiry_month:"2", 17 | expiry_year:"2022", 18 | "international":false, 19 | "issuer":"HDFC", 20 | "last4":1111, 21 | "name":"test name", 22 | "network":"Visa", 23 | "type":"credit" 24 | ] 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tests/mocks/transfers_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "amount": 100, 7 | "amount_reversed": 0, 8 | "created_at": 1506722466, 9 | "currency": "INR", 10 | "entity": "transfer", 11 | "fees": 0, 12 | "id": "trf_8jIlBetfktf1dG", 13 | "notes": [], 14 | "on_hold": false, 15 | "on_hold_until": null, 16 | "recipient": "acc_7jO4N6LScw5CEG", 17 | "recipient_settlement_id": null, 18 | "service_tax": 0, 19 | "source": "acc_10000000000000", 20 | "tax": 0 21 | }, 22 | { 23 | "amount": 100, 24 | "amount_reversed": 0, 25 | "created_at": 1506722466, 26 | "currency": "INR", 27 | "entity": "transfer", 28 | "fees": 0, 29 | "id": "trf_8jIlBetfktf1dG", 30 | "notes": [], 31 | "on_hold": false, 32 | "on_hold_until": null, 33 | "recipient": "acc_7jO4N6LScw5CEG", 34 | "recipient_settlement_id": null, 35 | "service_tax": 0, 36 | "source": "acc_10000000000000", 37 | "tax": 0 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /tests/mocks/transfers_collection_with_payment_id.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "entity": "collection", 4 | "items": [ 5 | { 6 | "amount": 100, 7 | "amount_reversed": 0, 8 | "created_at": 1506722466, 9 | "currency": "INR", 10 | "entity": "transfer", 11 | "fees": 0, 12 | "id": "trf_8jIlBetfktf1dG", 13 | "notes": [], 14 | "on_hold": false, 15 | "on_hold_until": null, 16 | "recipient": "acc_7jO4N6LScw5CEG", 17 | "recipient_settlement_id": null, 18 | "service_tax": 0, 19 | "source": "acc_10000000000000", 20 | "tax": 0 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /tests/mocks/virtual_accounts_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 2, 4 | "items": [ 5 | { 6 | "id": "va_84lyVss1CRZ6eM", 7 | "entity": "virtual_account", 8 | "name": "Merchant Billing Label", 9 | "description": "Second Virtual Account", 10 | "status": "active", 11 | "amount_paid": 1200, 12 | "notes": [], 13 | "customer_id": null, 14 | "receivers": [ 15 | { 16 | "id": "ba_87txVas2oSzzvx", 17 | "entity": "bank_account", 18 | "name": "Merchant Billing Label", 19 | "account_number": "RAZORPAY9KWHB7BL92", 20 | "ifsc": "RZPB0000001" 21 | } 22 | ], 23 | "created_at": 1497873405 24 | }, 25 | { 26 | "id": "va_4xbQrmEoA5WJ0G", 27 | "entity": "virtual_account", 28 | "name": "Merchant Billing Label", 29 | "description": "First Virtual Account", 30 | "status": "active", 31 | "amount_paid": 900, 32 | "notes": { 33 | "reference_key": "reference_value" 34 | }, 35 | "receivers": [ 36 | { 37 | "id": "ba_4lsdkfldlteskf", 38 | "entity": "bank_account", 39 | "name": "Merchant Billing Label", 40 | "account_number": "RAZORPAY9876543210", 41 | "ifsc": "RZPB0000001" 42 | } 43 | ], 44 | "customer_id": "cust_805c8oBQdBGPwS", 45 | "created_at": 1497922042 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /tests/mocks/virtual_accounts_collection_with_one_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 1, 4 | "items": [ 5 | { 6 | "id": "va_84lyVss1CRZ6eM", 7 | "entity": "virtual_account", 8 | "name": "Merchant Billing Label", 9 | "description": "Second Virtual Account", 10 | "status": "active", 11 | "amount_paid": 1200, 12 | "notes": [], 13 | "customer_id": null, 14 | "receivers": [ 15 | { 16 | "id": "ba_87txVas2oSzzvx", 17 | "entity": "bank_account", 18 | "name": "Merchant Billing Label", 19 | "account_number": "RAZORPAY9KWHB7BL92", 20 | "ifsc": "RZPB0000001" 21 | } 22 | ], 23 | "created_at": 1497873405 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tests/mocks/webhook_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "entity": "collection", 3 | "count": 1, 4 | "items": [ 5 | { 6 | "id": "HK890egfiItP3H", 7 | "created_at": 1624060358, 8 | "updated_at": 1624060358, 9 | "service": "beta-api-test", 10 | "owner_id": "H3kYHQ635sBwXG", 11 | "owner_type": "merchant", 12 | "context": [], 13 | "disabled_at": 0, 14 | "url": "https://en1mwkqo5ioct.x.pipedream.net", 15 | "alert_email": "gaurav.kumar@example.com", 16 | "secret_exists": true, 17 | "entity": "webhook", 18 | "active": true, 19 | "events": [ 20 | "payment.authorized", 21 | "payment.failed", 22 | "payment.captured", 23 | "payment.dispute.created", 24 | "refund.failed", 25 | "refund.created" 26 | ] 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /tests/test_client_account.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientAccount(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientAccount, self).setUp() 11 | self.base_url = '{}/accounts'.format(self.base_url_v2) 12 | self.account_id = 'acc_GRWKk7qQsLnDjX' 13 | 14 | @responses.activate 15 | def test_account_create(self): 16 | init = mock_file('init_account') 17 | result = mock_file('fake_account') 18 | url = self.base_url 19 | responses.add(responses.POST, 20 | url, 21 | status=200, 22 | body=json.dumps(result), 23 | match_querystring=True) 24 | 25 | self.assertEqual(self.client.account.create(init), result) 26 | 27 | @responses.activate 28 | def test_account_fetch(self): 29 | result = mock_file('fake_account') 30 | url = '{}/{}'.format(self.base_url, self.account_id) 31 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 32 | match_querystring=True) 33 | self.assertEqual(self.client.account.fetch(self.account_id), result) 34 | 35 | @responses.activate 36 | def test_account_edit(self): 37 | init = { "customer_facing_business_name": "ABCD Ltd" } 38 | result = mock_file('fake_account') 39 | url = '{}/{}'.format(self.base_url, self.account_id) 40 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result), 41 | match_querystring=True) 42 | self.assertEqual(self.client.account.edit(self.account_id, init), result) 43 | 44 | @responses.activate 45 | def test_account_delete(self): 46 | result = mock_file('fake_account') 47 | url = '{}/{}'.format(self.base_url, self.account_id) 48 | responses.add(responses.DELETE, url, status=200, body=json.dumps(result), 49 | match_querystring=True) 50 | self.assertEqual(self.client.account.delete(self.account_id), result) -------------------------------------------------------------------------------- /tests/test_client_addon.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientAddon(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientAddon, self).setUp() 11 | self.base_url = '{}/addons'.format(self.base_url) 12 | self.addon_id = 'ao_8sg8LU73Y3ieav' 13 | 14 | @responses.activate 15 | def test_addon_fetch(self): 16 | result = mock_file('fake_addon') 17 | url = '{}/{}'.format(self.base_url, self.addon_id) 18 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 19 | match_querystring=True) 20 | self.assertEqual(self.client.addon.fetch(self.addon_id), result) 21 | 22 | @responses.activate 23 | def test_addon_delete(self): 24 | result = [] 25 | url = '{}/{}'.format(self.base_url, self.addon_id) 26 | responses.add(responses.DELETE, 27 | url, 28 | status=200, 29 | body=json.dumps(result), 30 | match_querystring=True) 31 | self.assertEqual(self.client.addon.delete(self.addon_id), result) 32 | 33 | 34 | @responses.activate 35 | def test_addon_fetch_all(self): 36 | result = mock_file('addon_collection') 37 | url = self.base_url 38 | responses.add(responses.GET, url, status=200, 39 | body=json.dumps(result), match_querystring=True) 40 | self.assertEqual(self.client.addon.all(), result) 41 | -------------------------------------------------------------------------------- /tests/test_client_card.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientRefund(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientRefund, self).setUp() 11 | self.base_url = '{}/cards'.format(self.base_url) 12 | 13 | @responses.activate 14 | def test_card_fetch(self): 15 | result = mock_file('fake_card') 16 | url = '{}/{}'.format(self.base_url, self.card_id) 17 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 18 | match_querystring=True) 19 | self.assertEqual(self.client.card.fetch(self.card_id), result) 20 | 21 | @responses.activate 22 | def test_card_requestCardReference(self): 23 | init = { 24 | "number": "4854980604708430" 25 | } 26 | result = { 27 | "network": "Visa", 28 | "payment_account_reference": "V0010013819231376539033235990", 29 | "network_reference_id": "1001381923137653903323591234sdfds90" 30 | } 31 | url = "{}/{}".format(self.base_url, "fingerprints") 32 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 33 | match_querystring=True) 34 | self.assertEqual(self.client.card.requestCardReference(init), result) 35 | -------------------------------------------------------------------------------- /tests/test_client_dispute.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientDispute(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientDispute, self).setUp() 11 | self.base_url = '{}/disputes'.format(self.base_url) 12 | 13 | @responses.activate 14 | def test_dispute_fetch_all(self): 15 | result = mock_file('dispute_collection') 16 | url = self.base_url 17 | responses.add(responses.GET, url, status=200, 18 | body=json.dumps(result), match_querystring=True) 19 | self.assertEqual(self.client.dispute.all(), result) 20 | 21 | @responses.activate 22 | def test_fetch_dispute(self): 23 | result = mock_file('dispute') 24 | dispute_id = 'fake_dispute_id' 25 | url = f"{self.base_url}/{dispute_id}" 26 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 27 | match_querystring=True) 28 | self.assertEqual(self.client.dispute.fetch(dispute_id), result) 29 | 30 | @responses.activate 31 | def test_dispute_accept(self): 32 | result = mock_file('dispute_accept') 33 | dispute_id = 'fake_dispute_id' 34 | url = f"{self.base_url}/{dispute_id}/accept" 35 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 36 | match_querystring=True) 37 | self.assertEqual(self.client.dispute.accept(dispute_id), result) 38 | 39 | @responses.activate 40 | def test_dispute_contest(self): 41 | request = { 42 | "amount": 5000, 43 | "summary": "goods delivered", 44 | "shipping_proof": [ 45 | "doc_EFtmUsbwpXwBH9", 46 | "doc_EFtmUsbwpXwBH8" 47 | ], 48 | "others": [ 49 | { 50 | "type": "receipt_signed_by_customer", 51 | "document_ids": [ 52 | "doc_EFtmUsbwpXwBH1", 53 | "doc_EFtmUsbwpXwBH7" 54 | ] 55 | } 56 | ], 57 | "action": "draft" 58 | } 59 | 60 | result = mock_file('dispute_contest') 61 | dispute_id = 'fake_dispute_id' 62 | url = f"{self.base_url}/{dispute_id}/contest" 63 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result), 64 | match_querystring=True) 65 | self.assertEqual(self.client.dispute.contest(dispute_id, request), result) 66 | -------------------------------------------------------------------------------- /tests/test_client_document.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientDocument(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientDocument, self).setUp() 11 | self.base_url = f"{self.base_url}/documents" 12 | 13 | @responses.activate 14 | def test_document_fetch(self): 15 | result = mock_file('document') 16 | id = 'fake_document_id' 17 | url = f"{self.base_url}/{id}" 18 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 19 | match_querystring=True) 20 | self.assertEqual(self.client.document.fetch(id), result) 21 | 22 | @responses.activate 23 | def test_document_create(self): 24 | request = { 25 | 'file': '', 26 | 'purpose': 'dispute_evidence' 27 | } 28 | result = mock_file('document') 29 | url = self.base_url 30 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 31 | match_querystring=True) 32 | self.assertEqual(self.client.document.create(request), result) 33 | -------------------------------------------------------------------------------- /tests/test_client_error.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import ClientTestCase 5 | from razorpay.errors import BadRequestError, GatewayError, ServerError 6 | 7 | 8 | class TestClientError(ClientTestCase): 9 | 10 | def setUp(self): 11 | super(TestClientError, self).setUp() 12 | self.base_url = '{}/payments'.format(self.base_url) 13 | 14 | @responses.activate 15 | def test_payment_with_invalid_options(self): 16 | count = 10000 17 | result = { 18 | 'error': 19 | { 20 | 'field': 'count', 21 | 'code': 'BAD_REQUEST_ERROR', 22 | 'description': 'The count may not be greater than 100.' 23 | } 24 | } 25 | 26 | url = '{}?count={}'.format(self.base_url, count) 27 | responses.add(responses.GET, url, status=400, body=json.dumps(result), 28 | match_querystring=True) 29 | self.assertRaises( 30 | BadRequestError, 31 | self.client.payment.all, 32 | {'count': count}) 33 | 34 | @responses.activate 35 | def test_gateway_error(self): 36 | count = 10 37 | result = { 38 | 'error': 39 | { 40 | 'code': 'GATEWAY_ERROR', 41 | 'description': 'Payment processing failed due to error at bank/wallet gateway' 42 | } 43 | } 44 | 45 | url = '{}?count={}'.format(self.base_url, count) 46 | responses.add(responses.GET, url, status=504, body=json.dumps(result), 47 | match_querystring=True) 48 | self.assertRaises( 49 | GatewayError, 50 | self.client.payment.all, 51 | {'count': count}) 52 | 53 | @responses.activate 54 | def test_server_error(self): 55 | count = 10 56 | result = { 57 | 'error': 58 | { 59 | 'code': 'SERVER_ERROR', 60 | 'description': 'The server encountered an error. The incident has been reported to admins.' 61 | } 62 | } 63 | 64 | url = '{}?count={}'.format(self.base_url, count) 65 | responses.add(responses.GET, url, status=500, body=json.dumps(result), 66 | match_querystring=True) 67 | self.assertRaises( 68 | ServerError, 69 | self.client.payment.all, 70 | {'count': count}) 71 | 72 | @responses.activate 73 | def test_unknown_error(self): 74 | count = 10 75 | result = { 76 | 'error': 77 | { 78 | 'code': 'UNKNOWN_ERROR', 79 | 'description': 'No Description' 80 | } 81 | } 82 | 83 | url = '{}?count={}'.format(self.base_url, count) 84 | responses.add(responses.GET, url, status=500, body=json.dumps(result), 85 | match_querystring=True) 86 | self.assertRaises( 87 | ServerError, 88 | self.client.payment.all, 89 | {'count': count}) 90 | -------------------------------------------------------------------------------- /tests/test_client_fund_account.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientFundAccount(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientFundAccount, self).setUp() 11 | self.base_url = '{}/fund_accounts'.format(self.base_url) 12 | 13 | @responses.activate 14 | def test_all(self): 15 | result = mock_file('fund_account_collection') 16 | url = self.base_url 17 | responses.add(responses.GET, url, status=200, 18 | body=json.dumps(result), match_querystring=True) 19 | self.assertEqual(self.client.fund_account.all(), result) 20 | 21 | @responses.activate 22 | def test_create(self): 23 | param = { 24 | "customer_id": "cust_IEfAt3ruD4OEzo", 25 | "account_type":"bank_account", 26 | "bank_account":{ 27 | "name":"Gaurav Kumar", 28 | "account_number":"11214311215411", 29 | "ifsc":"HDFC0000053" 30 | } 31 | } 32 | result = mock_file('fund_account_collection') 33 | url = self.base_url 34 | responses.add(responses.POST, 35 | url, 36 | status=200, 37 | body=json.dumps(result), 38 | match_querystring=True) 39 | 40 | self.assertEqual(self.client.fund_account.create(param), result) 41 | -------------------------------------------------------------------------------- /tests/test_client_iin.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientIin(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientIin, self).setUp() 11 | self.base_url = '{}/iins'.format(self.base_url) 12 | self.token_iin = '412345' 13 | 14 | @responses.activate 15 | def test_addon_fetch(self): 16 | result = mock_file('fake_iin') 17 | url = '{}/{}'.format(self.base_url, self.token_iin) 18 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 19 | match_querystring=True) 20 | self.assertEqual(self.client.iin.fetch(self.token_iin), result) 21 | 22 | @responses.activate 23 | def test_addon_fetch(self): 24 | result = mock_file('iin_collection') 25 | query = 'sub_type=otp' 26 | url = f"{self.base_url}/list?{query}" 27 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 28 | match_querystring=True) 29 | self.assertEqual(self.client.iin.all({"sub_type":"otp"}), result) 30 | -------------------------------------------------------------------------------- /tests/test_client_item.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientItem(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientItem, self).setUp() 11 | self.base_url = '{}/items'.format(self.base_url) 12 | 13 | @responses.activate 14 | def test_item_all(self): 15 | result = mock_file('item_collection') 16 | url = self.base_url 17 | responses.add(responses.GET, url, status=200, 18 | body=json.dumps(result), match_querystring=True) 19 | self.assertEqual(self.client.item.all(), result) 20 | 21 | @responses.activate 22 | def test_item_fetch(self): 23 | result = mock_file('item_collection') 24 | url = self.base_url 25 | responses.add(responses.GET, url, status=200, 26 | body=json.dumps(result), match_querystring=True) 27 | self.assertEqual(self.client.item.all(), result) 28 | 29 | @responses.activate 30 | def test_item_create(self): 31 | result = mock_file('item_collection') 32 | url = '{}/{}'.format(self.base_url, 'fake_item_id') 33 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 34 | match_querystring=True) 35 | self.assertEqual(self.client.item.fetch('fake_item_id'), result) 36 | 37 | @responses.activate 38 | def test_item_delete(self): 39 | result = [] 40 | url = '{}/{}'.format(self.base_url, 'fake_item_id') 41 | responses.add(responses.DELETE, url, status=200, 42 | body=json.dumps(result), match_querystring=True) 43 | self.assertEqual(self.client.item.delete('fake_item_id'), result) 44 | 45 | -------------------------------------------------------------------------------- /tests/test_client_payment_link.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientPaymentLink(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientPaymentLink, self).setUp() 11 | self.base_url = '{}/payment_links'.format(self.base_url) 12 | 13 | @responses.activate 14 | def test_payment_link_create(self): 15 | init = mock_file('init_payment_link') 16 | 17 | result = mock_file('fake_payment_link') 18 | url = '{}/{}'.format(self.base_url, 'fake_payment_link_id') 19 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result), 20 | match_querystring=True) 21 | self.assertEqual(self.client.payment_link.edit('fake_payment_link_id', init), result) 22 | 23 | 24 | @responses.activate 25 | def test_payment_link_edit(self): 26 | init = { 27 | "reference_id": "TS35", 28 | "expire_by": 1653347540, 29 | "reminder_enable":0, 30 | "notes":{ 31 | "policy_name": "Jeevan Saral" 32 | } 33 | } 34 | 35 | result = mock_file('edit_payment_link') 36 | url = '{}/{}'.format(self.base_url, 'fake_payment_link_id') 37 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result), 38 | match_querystring=True) 39 | self.assertEqual(self.client.payment_link.edit('fake_payment_link_id', init), result) 40 | 41 | @responses.activate 42 | def test_payment_link_notifyBy(self): 43 | result = {"success": 1} 44 | 45 | url = "{}/{}/notify_by/{}".format(self.base_url, 'fake_payment_link_id', 'email') 46 | 47 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 48 | match_querystring=True) 49 | self.assertEqual(self.client.payment_link.notifyBy('fake_payment_link_id',medium='email'), result) 50 | 51 | @responses.activate 52 | def test_payment_link_all(self): 53 | result = mock_file('payment_link_collection') 54 | url = self.base_url 55 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 56 | match_querystring=True) 57 | self.assertEqual(self.client.payment_link.all(), result) 58 | 59 | @responses.activate 60 | def test_payment_all_fetch(self): 61 | result = mock_file('fake_payment_link') 62 | url = '{}/{}'.format(self.base_url, 'fake_payment_link_id') 63 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 64 | match_querystring=True) 65 | self.assertEqual(self.client.payment_link.fetch('fake_payment_link_id'),result) 66 | 67 | @responses.activate 68 | def test_payment_link_cancel(self): 69 | result = mock_file('cancel_payment_link') 70 | 71 | url = "{}/{}/cancel".format(self.base_url, 'fake_payment_link_id') 72 | 73 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 74 | match_querystring=True) 75 | self.assertEqual(self.client.payment_link.cancel('fake_payment_link_id'), result) 76 | -------------------------------------------------------------------------------- /tests/test_client_plan.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientPlan(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientPlan, self).setUp() 11 | self.base_url = '{}/plans'.format(self.base_url) 12 | self.plan_id = 'plan_8kihN0YqhnF8a7' 13 | 14 | @responses.activate 15 | def test_plan_fetch_all(self): 16 | result = mock_file('plan_collection') 17 | url = self.base_url 18 | responses.add(responses.GET, url, status=200, 19 | body=json.dumps(result), match_querystring=True) 20 | self.assertEqual(self.client.plan.all(), result) 21 | 22 | @responses.activate 23 | def test_plan_fetch(self): 24 | result = mock_file('fake_plan') 25 | url = '{}/{}'.format(self.base_url, self.plan_id) 26 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 27 | match_querystring=True) 28 | self.assertEqual(self.client.plan.fetch(self.plan_id), result) 29 | 30 | @responses.activate 31 | def test_plan_create(self): 32 | init = mock_file('init_plan') 33 | result = mock_file('fake_plan') 34 | url = self.base_url 35 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 36 | match_querystring=True) 37 | self.assertEqual(self.client.plan.create(init), result) 38 | -------------------------------------------------------------------------------- /tests/test_client_product.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from razorpay.constants.url import URL 5 | 6 | from .helpers import mock_file, ClientTestCase 7 | 8 | 9 | class TestClientProduct(ClientTestCase): 10 | 11 | def setUp(self): 12 | super(TestClientProduct, self).setUp() 13 | self.base_url = '{}/accounts'.format(self.base_url_v2) 14 | self.account_id = 'acc_GRWKk7qQsLnDjX' 15 | self.product_id = 'acc_prd_HEgNpywUFctQ9e' 16 | 17 | @responses.activate 18 | def test_product_requestProductConfiguration(self): 19 | init = { 20 | "product_name": "payment_gateway", 21 | "tnc_accepted": True, 22 | "ip": "233.233.233.234" 23 | } 24 | result = mock_file('fake_product') 25 | url = '{}/{}{}'.format(self.base_url, self.account_id, URL.PRODUCT) 26 | 27 | responses.add(responses.POST, 28 | url, 29 | status=200, 30 | body=json.dumps(result), 31 | match_querystring=True) 32 | 33 | self.assertEqual(self.client.product.requestProductConfiguration( 34 | self.account_id, init), result) 35 | 36 | @responses.activate 37 | def test_product_fetch(self): 38 | result = mock_file('fake_product') 39 | url = '{}/{}{}/{}'.format(self.base_url, 40 | self.account_id, URL.PRODUCT, self.product_id) 41 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 42 | match_querystring=True) 43 | self.assertEqual(self.client.product.fetch( 44 | self.account_id, self.product_id), result) 45 | 46 | @responses.activate 47 | def test_account_edit(self): 48 | init = { 49 | "notifications": { 50 | "email": [ 51 | "gaurav.kumar@example.com", 52 | "acd@gmail.com" 53 | ] 54 | }, 55 | "checkout": { 56 | "theme_color": "#528FFF" 57 | }, 58 | "refund": { 59 | "default_refund_speed": "optimum" 60 | }, 61 | "settlements": { 62 | "account_number": "1234567890", 63 | "ifsc_code": "HDFC0000317", 64 | "beneficiary_name": "Gaurav Kumar" 65 | }, 66 | "tnc_accepted": True, 67 | "ip": "233.233.233.234" 68 | } 69 | 70 | result = mock_file('fake_account') 71 | url = '{}/{}{}/{}'.format(self.base_url, 72 | self.account_id, URL.PRODUCT, self.product_id) 73 | 74 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result), 75 | match_querystring=True) 76 | self.assertEqual(self.client.product.edit( 77 | self.account_id, self.product_id, init), result) 78 | 79 | @responses.activate 80 | def test_product_fetchTnc(self): 81 | result = { 82 | "entity": "tnc_map", 83 | "product_name": "payments", 84 | "id": "tnc_map_HjOVhIdpVDZ0FB", 85 | "tnc": { 86 | "terms": "https://razorpay.com/terms", 87 | "privacy": "https://razorpay.com/privacy", 88 | "agreement": "https://razorpay.com/agreement" 89 | }, 90 | "last_published_at": 1640589653 91 | } 92 | product_name = "payments" 93 | 94 | url = '{}{}/{}{}'.format(self.base_url_v2, URL.PRODUCT, product_name, URL.TNC ) 95 | 96 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 97 | match_querystring=True) 98 | self.assertEqual(self.client.product.fetchTnc(product_name), result) 99 | -------------------------------------------------------------------------------- /tests/test_client_qrcode.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientQrcode(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientQrcode, self).setUp() 11 | self.base_url = '{}/payments/qr_codes'.format(self.base_url) 12 | self.plan_id = 'qr_IAgePI1GuSMTFN' 13 | 14 | @responses.activate 15 | def test_qrcode_all(self): 16 | result = mock_file('qrcode_collection') 17 | url = self.base_url 18 | responses.add(responses.GET, url, status=200, 19 | body=json.dumps(result), match_querystring=True) 20 | self.assertEqual(self.client.qrcode.all(), result) 21 | 22 | @responses.activate 23 | def test_qrcode_fetch(self): 24 | result = mock_file('fake_qrcode') 25 | url = '{}/{}'.format(self.base_url, 'fake_qrcode_id') 26 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 27 | match_querystring=True) 28 | self.assertEqual(self.client.qrcode.fetch('fake_qrcode_id'), result) 29 | 30 | @responses.activate 31 | def test_qrcode_create(self): 32 | init = { 33 | "type": "upi_qr", 34 | "name": "Store_1", 35 | "usage": "single_use", 36 | "fixed_amount": 1, 37 | "payment_amount": 300, 38 | "description": "For Store 1", 39 | "customer_id": "cust_HKsR5se84c5LTO", 40 | "close_by": 1681615838, 41 | "notes": { 42 | "purpose": "Test UPI QR code notes" 43 | } 44 | } 45 | result = mock_file('fake_qrcode') 46 | url = self.base_url 47 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 48 | match_querystring=True) 49 | self.assertEqual(self.client.qrcode.create(init), result) 50 | 51 | @responses.activate 52 | def test_qrcode_fetch_all_payment(self): 53 | result = mock_file('qrcode_payments_collection') 54 | url = '{}/{}/payments'.format(self.base_url, 'fake_qrcode_id') 55 | responses.add(responses.GET, url, status=200, 56 | body=json.dumps(result), match_querystring=True) 57 | self.assertEqual(self.client.qrcode.fetch_all_payments('fake_qrcode_id'), result) 58 | 59 | @responses.activate 60 | def test_qrcode_close(self): 61 | result = mock_file('fake_qrcode') 62 | url = '{}/{}/close'.format(self.base_url, 'fake_qrcode_id') 63 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 64 | match_querystring=True) 65 | self.assertEqual(self.client.qrcode.close('fake_qrcode_id'), result) -------------------------------------------------------------------------------- /tests/test_client_refund.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientRefund(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientRefund, self).setUp() 11 | self.base_url = '{}/refunds'.format(self.base_url) 12 | 13 | @responses.activate 14 | def test_refund_all(self): 15 | result = mock_file('refund_collection') 16 | url = self.base_url 17 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 18 | match_querystring=True) 19 | self.assertEqual(self.client.refund.all(), result) 20 | 21 | @responses.activate 22 | def test_refund_fetch(self): 23 | result = mock_file('fake_refund') 24 | url = '{}/{}'.format(self.base_url, self.refund_id) 25 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 26 | match_querystring=True) 27 | self.assertEqual(self.client.refund.fetch(self.refund_id), result) 28 | 29 | @responses.activate 30 | def test_refund_create(self): 31 | init = {'payment_id': self.payment_id} 32 | result = mock_file('fake_refund') 33 | url = self.base_url 34 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 35 | match_querystring=True) 36 | self.assertEqual(self.client.refund.create(init), result) 37 | 38 | @responses.activate 39 | def test_refund_edit(self): 40 | param = { 41 | "notes": { 42 | "notes_key_1":"Beam me up Scotty.", 43 | "notes_key_2":"Engage" 44 | } 45 | } 46 | result = mock_file('fake_refund') 47 | url = "{}/{}".format(self.base_url,'rfnd_DfjjhJC6eDvUAi') 48 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result), 49 | match_querystring=True) 50 | self.assertEqual(self.client.refund.edit('rfnd_DfjjhJC6eDvUAi', param), result) 51 | -------------------------------------------------------------------------------- /tests/test_client_registration_link.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientRegistrationLink(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientRegistrationLink, self).setUp() 11 | self.base_url = '{}/subscription_registration/{}'.format(self.base_url, 'auth_links') 12 | 13 | @responses.activate 14 | def test_create(self): 15 | param = mock_file('init_registration_link') 16 | result = mock_file('fake_registration_link') 17 | url = self.base_url 18 | responses.add(responses.POST, 19 | url, 20 | status=200, 21 | body=json.dumps(result), 22 | match_querystring=True) 23 | 24 | self.assertEqual(self.client.registration_link.create(param), result) 25 | -------------------------------------------------------------------------------- /tests/test_client_settlement.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientSettlement(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientSettlement, self).setUp() 11 | self.base_url = '{}/settlements'.format(self.base_url) 12 | 13 | @responses.activate 14 | def test_settlement_fetch_all(self): 15 | result = mock_file('settlement_collection') 16 | url = self.base_url 17 | responses.add(responses.GET, url, status=200, 18 | body=json.dumps(result), match_querystring=True) 19 | self.assertEqual(self.client.settlement.all(), result) 20 | 21 | @responses.activate 22 | def test_settlement_fetch_all_with_options(self): 23 | count = 1 24 | result = mock_file('settlement_collection_with_one_settlement') 25 | url = '{}?count={}'.format(self.base_url, count) 26 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 27 | match_querystring=True) 28 | self.assertEqual(self.client.settlement.all({'count': count}), result) 29 | 30 | @responses.activate 31 | def test_settlement_fetch(self): 32 | result = mock_file('fake_settlement') 33 | url = '{}/{}'.format(self.base_url, self.settlement_id) 34 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 35 | match_querystring=True) 36 | self.assertEqual(self.client.settlement.fetch(self.settlement_id), result) 37 | 38 | @responses.activate 39 | def test_settlement_report(self): 40 | result = mock_file('settlement_collection') 41 | url = "{}/recon/{}".format(self.base_url, 'combined') 42 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 43 | match_querystring=True) 44 | self.assertEqual(self.client.settlement.report(), result) 45 | 46 | @responses.activate 47 | def test_settlement_create_ondemand_settlement(self): 48 | init = { 49 | "amount": 1221, 50 | "description": "Need this to make vendor", 51 | "notes": { 52 | "notes_key_1": "Tea, Earl Grey, Hot", 53 | "notes_key_2": "Tea, Earl Grey… decaf." 54 | } 55 | } 56 | result = mock_file('init_settlement') 57 | url = "{}/{}".format(self.base_url,"ondemand") 58 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 59 | match_querystring=True) 60 | self.assertEqual(self.client.settlement.create_ondemand_settlement(init), result) 61 | 62 | @responses.activate 63 | def test_settlement_fetch_all_ondemand_settlement(self): 64 | result = mock_file('settlement_collection') 65 | url = "{}/{}".format(self.base_url,"ondemand") 66 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 67 | match_querystring=True) 68 | self.assertEqual(self.client.settlement.fetch_all_ondemand_settlement(), result) 69 | 70 | @responses.activate 71 | def test_settlement_fetch_ondemand_settlement_id(self): 72 | result = mock_file('init_settlement') 73 | url = "{}/ondemand/{}".format(self.base_url, 'fake_settlement_id') 74 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 75 | match_querystring=True) 76 | self.assertEqual(self.client.settlement.fetch_ondemand_settlement_id('fake_settlement_id'), result) -------------------------------------------------------------------------------- /tests/test_client_stakeholder.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from razorpay.constants.url import URL 5 | 6 | from .helpers import mock_file, ClientTestCase 7 | 8 | 9 | class TestClientStakeholder(ClientTestCase): 10 | 11 | def setUp(self): 12 | super(TestClientStakeholder, self).setUp() 13 | self.base_url = '{}/accounts'.format(self.base_url_v2) 14 | self.account_id = 'acc_GRWKk7qQsLnDjX' 15 | self.stakeholder_id = 'sth_MDdinTcycAkdK3' 16 | 17 | @responses.activate 18 | def test_stakeholder_create(self): 19 | init = mock_file('init_stakeholder') 20 | result = mock_file('fake_stakeholder') 21 | url = '{}/{}{}'.format(self.base_url, self.account_id, URL.STAKEHOLDER) 22 | responses.add(responses.POST, 23 | url, 24 | status=200, 25 | body=json.dumps(result), 26 | match_querystring=True) 27 | 28 | self.assertEqual(self.client.stakeholder.create( 29 | self.account_id, init), result) 30 | 31 | @responses.activate 32 | def test_stakeholder_fetch(self): 33 | result = mock_file('fake_stakeholder') 34 | url = '{}/{}{}/{}'.format(self.base_url, self.account_id, 35 | URL.STAKEHOLDER, self.stakeholder_id) 36 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 37 | match_querystring=True) 38 | self.assertEqual(self.client.stakeholder.fetch( 39 | self.account_id, self.stakeholder_id), result) 40 | 41 | @responses.activate 42 | def test_stakeholder_edit(self): 43 | init = { 44 | "percentage_ownership": 20, 45 | "name": "Gauri Kumar", 46 | "relationship": { 47 | "director": False, 48 | "executive": True 49 | }, 50 | "phone": { 51 | "primary": "9000090000", 52 | "secondary": "9000090000" 53 | }, 54 | "addresses": { 55 | "residential": { 56 | "street": "507, Koramangala 1st block", 57 | "city": "Bangalore", 58 | "state": "Karnataka", 59 | "postal_code": "560035", 60 | "country": "IN" 61 | } 62 | }, 63 | "kyc": { 64 | "pan": "AVOPB1111J" 65 | }, 66 | "notes": { 67 | "random_key_by_partner": "random_value2" 68 | } 69 | } 70 | result = mock_file('fake_stakeholder') 71 | url = '{}/{}{}/{}'.format(self.base_url, self.account_id, 72 | URL.STAKEHOLDER, self.stakeholder_id) 73 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result), 74 | match_querystring=True) 75 | self.assertEqual(self.client.stakeholder.edit( 76 | self.account_id, self.stakeholder_id, init), result) 77 | 78 | @responses.activate 79 | def test_stakeholder_all(self): 80 | result = mock_file('stakeholder_collection') 81 | url = '{}/{}{}'.format(self.base_url, 82 | self.account_id, URL.STAKEHOLDER) 83 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 84 | match_querystring=True) 85 | self.assertEqual(self.client.stakeholder.all(self.account_id), result) 86 | -------------------------------------------------------------------------------- /tests/test_client_transfer.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientTransfer(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientTransfer, self).setUp() 11 | self.payment_url = '{}/payments'.format(self.base_url) 12 | self.base_url = '{}/transfers'.format(self.base_url) 13 | 14 | @responses.activate 15 | def test_transfer_all(self): 16 | result = mock_file('transfers_collection') 17 | url = self.base_url 18 | responses.add(responses.GET, 19 | url, 20 | status=200, 21 | body=json.dumps(result), 22 | match_querystring=True) 23 | 24 | self.assertEqual(self.client.transfer.all(), result) 25 | 26 | @responses.activate 27 | def test_transfer_all_with_payment_id(self): 28 | result = mock_file('transfers_collection_with_payment_id') 29 | url = "{}/dummy_payment/transfers".format(self.payment_url) 30 | responses.add(responses.GET, 31 | url, 32 | status=200, 33 | body=json.dumps(result), 34 | match_querystring=True) 35 | 36 | self.assertEqual(self.client.transfer.all( 37 | {'payment_id': 'dummy_payment'}), 38 | result) 39 | 40 | @responses.activate 41 | def test_transfer_fetch(self): 42 | result = mock_file('fake_transfer') 43 | url = '{}/{}'.format(self.base_url, 'fake_transfer_id') 44 | responses.add(responses.GET, 45 | url, 46 | status=200, 47 | body=json.dumps(result), 48 | match_querystring=True) 49 | 50 | self.assertEqual(self.client.transfer.fetch('fake_transfer_id'), result) 51 | 52 | @responses.activate 53 | def test_transfer_create(self): 54 | init = mock_file('init_transfer') 55 | result = mock_file('fake_transfer') 56 | url = self.base_url 57 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 58 | match_querystring=True) 59 | self.assertEqual(self.client.transfer.create(init), result) 60 | 61 | @responses.activate 62 | def test_transfer_edit(self): 63 | param = {'on_hold': False} 64 | result = mock_file('fake_transfer') 65 | url = "{}/dummy_id".format(self.base_url) 66 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result), 67 | match_querystring=True) 68 | self.assertEqual(self.client.transfer.edit('dummy_id', param), result) 69 | 70 | @responses.activate 71 | def test_transfer_reversal(self): 72 | result = mock_file('fake_reversal') 73 | url = "{}/dummy_id/reversals".format(self.base_url) 74 | responses.add(responses.POST, url, status=200, body=json.dumps(result), 75 | match_querystring=True) 76 | self.assertEqual(self.client.transfer.reverse('dummy_id'), result) 77 | 78 | @responses.activate 79 | def test_transfer_reversal_fetch(self): 80 | result = mock_file('reversal_collection') 81 | url = "{}/dummy_id/reversals".format(self.base_url) 82 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 83 | match_querystring=True) 84 | self.assertEqual(self.client.transfer.reversals('dummy_id'), result) 85 | -------------------------------------------------------------------------------- /tests/test_client_utility.py: -------------------------------------------------------------------------------- 1 | import responses 2 | 3 | from .helpers import mock_file, ClientTestCase 4 | from razorpay.errors import SignatureVerificationError 5 | 6 | 7 | class TestClientValidator(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientValidator, self).setUp() 11 | 12 | @responses.activate 13 | def test_verify_payment_signature(self): 14 | sig = 'b2335e3b0801106b84a7faff035df56ecffde06918c9ddd1f0fafbb37a51cc89' 15 | parameters = {} 16 | parameters['razorpay_order_id'] = 'fake_order_id' 17 | parameters['razorpay_payment_id'] = 'fake_payment_id' 18 | parameters['razorpay_signature'] = sig 19 | 20 | self.assertEqual( 21 | self.client.utility.verify_payment_signature(parameters), 22 | True) 23 | 24 | @responses.activate 25 | def test_subscription_payment_signature(self): 26 | sig = '601f383334975c714c91a7d97dd723eb56520318355863dcf3821c0d07a17693' 27 | parameters = {} 28 | parameters['razorpay_subscription_id'] = 'sub_ID6MOhgkcoHj9I' 29 | parameters['razorpay_payment_id'] = 'pay_IDZNwZZFtnjyym' 30 | parameters['razorpay_signature'] = sig 31 | parameters['secret'] = 'EnLs21M47BllR3X8PSFtjtbd' 32 | 33 | self.assertEqual( 34 | self.client.utility.verify_subscription_payment_signature(parameters), 35 | True) 36 | 37 | @responses.activate 38 | def test_verify_payment_link_signature(self): 39 | sig = '07ae18789e35093e51d0a491eb9922646f3f82773547e5b0f67ee3f2d3bf7d5b' 40 | parameters = {} 41 | parameters['razorpay_payment_id'] = 'pay_IH3d0ara9bSsjQ' 42 | parameters['payment_link_id'] = 'plink_IH3cNucfVEgV68' 43 | parameters['payment_link_reference_id'] = 'TSsd1989' 44 | parameters['payment_link_status'] = 'paid' 45 | parameters['razorpay_signature'] = sig 46 | parameters['secret'] = 'EnLs21M47BllR3X8PSFtjtbd' 47 | # x = self.client.utility.verify_payment_link_signature(parameters) 48 | 49 | self.assertEqual( 50 | self.client.utility.verify_payment_link_signature(parameters), 51 | True) 52 | 53 | @responses.activate 54 | def test_verify_payment_signature_with_exception(self): 55 | parameters = {} 56 | parameters['razorpay_order_id'] = 'fake_order_id' 57 | parameters['razorpay_payment_id'] = 'fake_payment_id' 58 | parameters['razorpay_signature'] = 'test_signature' 59 | 60 | self.assertRaises( 61 | SignatureVerificationError, 62 | self.client.utility.verify_payment_signature, 63 | parameters) 64 | 65 | @responses.activate 66 | def test_verify_webhook_signature(self): 67 | secret = self.client.auth[1] 68 | sig = 'd60e67fd884556c045e9be7dad57903e33efc7172c17c6e3ef77db42d2b366e9' 69 | body = mock_file('fake_payment_authorized_webhook') 70 | 71 | self.assertEqual( 72 | self.client.utility.verify_webhook_signature(body, sig, secret), 73 | True) 74 | 75 | @responses.activate 76 | def test_verify_webhook_signature_with_exception(self): 77 | secret = self.client.auth[1] 78 | sig = 'test_signature' 79 | body = '' 80 | 81 | self.assertRaises( 82 | SignatureVerificationError, 83 | self.client.utility.verify_webhook_signature, 84 | body, 85 | sig, 86 | secret) 87 | -------------------------------------------------------------------------------- /tests/test_client_webhook.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from razorpay.constants.url import URL 5 | 6 | from .helpers import mock_file, ClientTestCase 7 | 8 | 9 | class TestClientWebhook(ClientTestCase): 10 | 11 | def setUp(self): 12 | super(TestClientWebhook, self).setUp() 13 | self.base_url = '{}{}'.format(self.base_url_v2, URL.ACCOUNT) 14 | self.account_id = "acc_H3kYHQ635sBwXG" 15 | self.webhookId = "HK890egfiItP3H" 16 | 17 | @responses.activate 18 | def test_webhook_all(self): 19 | result = mock_file('webhook_collection') 20 | url = '{}/{}{}'.format(self.base_url, self.account_id, URL.WEBHOOK) 21 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 22 | match_querystring=True) 23 | self.assertEqual(self.client.webhook.all({},self.account_id), 24 | result) 25 | 26 | @responses.activate 27 | def test_webhook_fetch(self): 28 | result = mock_file('fake_webhook') 29 | url = '{}/{}{}/{}'.format(self.base_url, 30 | self.account_id, URL.WEBHOOK, self.webhookId) 31 | responses.add(responses.GET, url, status=200, body=json.dumps(result), 32 | match_querystring=True) 33 | self.assertEqual( 34 | self.client.webhook.fetch(self.webhookId, self.account_id), 35 | result) 36 | 37 | @responses.activate 38 | def test_webhook_create(self): 39 | init = mock_file('init_webhook') 40 | result = mock_file('fake_webhook') 41 | url = '{}/{}{}'.format(self.base_url, self.account_id, URL.WEBHOOK) 42 | responses.add(responses.POST, 43 | url, 44 | status=200, 45 | body=json.dumps(result), 46 | match_querystring=True) 47 | self.assertEqual( 48 | self.client.webhook.create(init, self.account_id), 49 | result) 50 | 51 | @responses.activate 52 | def test_webhook_edit(self): 53 | init = { 54 | "url": "https://www.linkedin.com", 55 | "events": [ 56 | "refund.created" 57 | ] 58 | } 59 | result = mock_file('fake_webhook') 60 | url = '{}/{}{}/{}'.format(self.base_url, 61 | self.account_id, URL.WEBHOOK, self.webhookId) 62 | responses.add(responses.PATCH, url, status=200, body=json.dumps(result)) 63 | self.assertEqual( 64 | self.client.webhook.edit(self.webhookId, self.account_id, init), 65 | result) 66 | 67 | @responses.activate 68 | def test_webhook_delete(self): 69 | 70 | result = mock_file('fake_webhook') 71 | url = '{}/{}{}/{}'.format(self.base_url, 72 | self.account_id, URL.WEBHOOK, self.webhookId) 73 | responses.add(responses.DELETE, url, status=200, body=json.dumps(result), match_querystring=True) 74 | self.assertEqual( 75 | self.client.webhook.delete(self.webhookId, self.account_id), 76 | result) 77 | -------------------------------------------------------------------------------- /tests/test_multiple_client.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import responses 3 | import json 4 | 5 | from .helpers import mock_file, ClientTestCase 6 | 7 | 8 | class TestClientPayment(ClientTestCase): 9 | 10 | def setUp(self): 11 | super(TestClientPayment, self).setUp() 12 | self.base_url = '{}/payments'.format(self.base_url) 13 | self.secondary_base_url = '{}/payments'.format(self.secondary_url) 14 | 15 | @responses.activate 16 | def test_payment_primary_url(self): 17 | result = mock_file('payment_collection') 18 | url = self.base_url 19 | responses.add(responses.GET, url, status=200, 20 | body=json.dumps(result), match_querystring=True) 21 | self.assertEqual(self.client.payment.all(), result) 22 | 23 | @unittest.skip 24 | def test_payment_secondary_url(self): 25 | result = mock_file('payment_collection') 26 | url = self.secondary_base_url 27 | responses.add(responses.GET, url, status=200, 28 | body=json.dumps(result), match_querystring=True) 29 | self.assertEqual(self.secondary_client.payment.all(), result) 30 | 31 | @responses.activate 32 | def test_payment_with_headers(self): 33 | result = mock_file('payment_collection') 34 | url = self.base_url 35 | responses.add(responses.GET, url, status=200, 36 | body=json.dumps(result), match_querystring=True) 37 | self.assertEqual(self.client.payment.all( 38 | headers={'Content-type': 'text'}), 39 | result) 40 | -------------------------------------------------------------------------------- /tests/test_user_agent.py: -------------------------------------------------------------------------------- 1 | import responses 2 | import json 3 | 4 | from .helpers import mock_file, ClientTestCase 5 | 6 | 7 | class TestClientUserAgent(ClientTestCase): 8 | 9 | def setUp(self): 10 | super(TestClientUserAgent, self).setUp() 11 | app_details = json.loads(mock_file('fake_app_details')) 12 | self.client.set_app_details(app_details) 13 | self.base_url = "{}/payments".format(self.base_url) 14 | 15 | @responses.activate 16 | def test_payment_all(self): 17 | result = mock_file('payment_collection') 18 | url = self.base_url 19 | responses.add(responses.GET, url, status=200, 20 | body=json.dumps(result), match_querystring=True) 21 | self.assertEqual(self.client.payment.all(), result) 22 | --------------------------------------------------------------------------------