diff --git a/documents/payment.md b/documents/payment.md
index b9addc4a..00c87dab 100644
--- a/documents/payment.md
+++ b/documents/payment.md
@@ -438,6 +438,101 @@ client.payment.createPaymentJson({
```
-------------------------------------------------------------------------------------------------------
+### OTP Generate
+
+```py
+client.payment.otpGenerate(paymentId)
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|-------------|---------|--------------------------------------|
+| paymentId* | integer | Unique identifier of the payment |
+
+Doc reference [doc](https://razorpay.com/docs/payments/payment-gateway/s2s-integration/json/v2/build-integration/cards/#otp-generation-)
+
+**Response:**
+
+```json
+{
+ "razorpay_payment_id": "pay_FVmAstJWfsD3SO",
+ "next": [
+ {
+ "action": "otp_submit",
+ "url": "https://api.razorpay.com/v1/payments/pay_FVmAstJWfsD3SO/otp_submit/ac2d415a8be7595de09a24b41661729fd9028fdc?key_id="
+ },
+ {
+ "action": "otp_resend",
+ "url": "https://api.razorpay.com/v1/payments/pay_FVmAstJWfsD3SO/otp_resend/json?key_id="
+ }
+ ],
+ "metadata": {
+ "issuer": "HDFC",
+ "network": "MC",
+ "last4": "1111",
+ "iin": "411111"
+ }
+}
+```
+-------------------------------------------------------------------------------------------------------
+
+### OTP Submit
+
+```py
+client.payment.otpSubmit(paymentId,{
+ "otp": "12345"
+ })
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|-------------|---------|--------------------------------------|
+| paymentId* | integer | Unique identifier of the payment |
+| otp* | string | The customer receives the OTP using their preferred notification medium - SMS or email |
+
+Doc reference [doc](https://razorpay.com/docs/payments/payment-gateway/s2s-integration/json/v2/build-integration/cards/#response-on-submitting-otp)
+
+**Response:**
+Success
+```json
+{
+ "razorpay_payment_id": "pay_D5jmY2H6vC7Cy3",
+ "razorpay_order_id": "order_9A33XWu170gUtm",
+ "razorpay_signature": "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d"
+}
+```
+-------------------------------------------------------------------------------------------------------
+
+### OTP Resend
+
+```py
+client.payment.otpResend(paymentId)
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|-------------|---------|--------------------------------------|
+| paymentId* | integer | Unique identifier of the payment |
+
+Doc reference [doc](https://razorpay.com/docs/payments/payment-methods/cards/authentication/native-otp/#otp-resend)
+
+**Response:**
+
+```json
+{
+ "next": [
+ "otp_submit",
+ "otp_resend"
+ ],
+ "razorpay_payment_id": "pay_JWaNvYmrx75sXo"
+}
+```
+
+-------------------------------------------------------------------------------------------------------
+
**PN: * indicates mandatory fields**
diff --git a/razorpay/resources/payment.py b/razorpay/resources/payment.py
index 93a448d2..4cb36c36 100644
--- a/razorpay/resources/payment.py
+++ b/razorpay/resources/payment.py
@@ -223,3 +223,43 @@ def createRecurring(self, data={}, **kwargs):
"""
url = "{}/{}/recurring".format(self.base_url,'create')
return self.post_url(url, data, **kwargs)
+
+ def otpGenerate(self, payment_id, data={}, **kwargs):
+ """"
+ Otp Generate
+
+ Args:
+ payment_id : Id for which upi transfer entity has to be fetched
+
+ Returns:
+ Otp Dict which was created
+ """
+ url = "{}/{}/otp_generate".format(self.base_url, payment_id)
+ return self.post_url(url, data, **kwargs)
+
+ def otpSubmit(self, payment_id, data={}, **kwargs):
+ """"
+ Otp Submit
+
+ Args:
+ payment_id : Id for which upi transfer entity has to be fetched
+
+ Returns:
+ Otp Dict which was created
+ """
+ url = "{}/{}/otp/submit".format(self.base_url, payment_id)
+ return self.post_url(url, data, **kwargs)
+
+ def otpResend(self, payment_id, data={}, **kwargs):
+ """"
+ Otp Resend
+
+ Args:
+ payment_id : Id for which upi transfer entity has to be fetched
+
+ Returns:
+ Otp Dict which was created
+ """
+ url = "{}/{}/otp/resend".format(self.base_url, payment_id)
+ return self.post_url(url, data, **kwargs)
+
\ No newline at end of file
diff --git a/tests/mocks/fake_otp_generate.json b/tests/mocks/fake_otp_generate.json
new file mode 100644
index 00000000..26f14941
--- /dev/null
+++ b/tests/mocks/fake_otp_generate.json
@@ -0,0 +1,19 @@
+{
+ "razorpay_payment_id": "pay_FVmAstJWfsD3SO",
+ "next": [
+ {
+ "action": "otp_submit",
+ "url": "https://api.razorpay.com/v1/payments/pay_FVmAstJWfsD3SO/otp_submit/ac2d415a8be7595de09a24b41661729fd9028fdc?key_id="
+ },
+ {
+ "action": "otp_resend",
+ "url": "https://api.razorpay.com/v1/payments/pay_FVmAstJWfsD3SO/otp_resend/json?key_id="
+ }
+ ],
+ "metadata": {
+ "issuer": "HDFC",
+ "network": "MC",
+ "last4": "1111",
+ "iin": "411111"
+ }
+}
diff --git a/tests/mocks/fake_otp_resend.json b/tests/mocks/fake_otp_resend.json
new file mode 100644
index 00000000..1cca81f1
--- /dev/null
+++ b/tests/mocks/fake_otp_resend.json
@@ -0,0 +1,7 @@
+{
+ "next": [
+ "otp_submit",
+ "otp_resend"
+ ],
+ "razorpay_payment_id": "pay_JWaNvYmrx75sXo"
+ }
\ No newline at end of file
diff --git a/tests/mocks/fake_otp_submit.json b/tests/mocks/fake_otp_submit.json
new file mode 100644
index 00000000..b13b5b23
--- /dev/null
+++ b/tests/mocks/fake_otp_submit.json
@@ -0,0 +1,5 @@
+{
+ "razorpay_payment_id": "pay_D5jmY2H6vC7Cy3",
+ "razorpay_order_id": "order_9A33XWu170gUtm",
+ "razorpay_signature": "9ef4dffbfd84f1318f6739a3ce19f9d85851857ae648f114332d8401e0949a3d"
+}
diff --git a/tests/test_client_payment.py b/tests/test_client_payment.py
index 794ccad0..0440f94f 100644
--- a/tests/test_client_payment.py
+++ b/tests/test_client_payment.py
@@ -196,8 +196,9 @@ def test_payment_json(self):
responses.add(responses.POST, url, status=200, body=json.dumps(result),
match_querystring=True)
self.assertEqual(self.client.payment.createPaymentJson(param), result)
-
- def createRecurring(self):
+
+ @responses.activate
+ def test_createRecurring(self):
init = mock_file('init_create_recurring')
result = mock_file('fake_create_recurring')
url = "{}/{}/recurring".format(self.base_url,'create')
@@ -208,3 +209,43 @@ def createRecurring(self):
match_querystring=True)
self.assertEqual(self.client.payment.createRecurring(init), result)
+
+ @responses.activate
+ def test_otpGenerate(self):
+ result = mock_file('fake_otp_generate')
+ url = "{}/{}/otp_generate".format(self.base_url,'dummy_id')
+ responses.add(responses.POST,
+ url,
+ status=200,
+ body=json.dumps(result),
+ match_querystring=True)
+
+ self.assertEqual(self.client.payment.otpGenerate('dummy_id'), result)
+
+ @responses.activate
+ def test_otpSubmit(self):
+ param = {
+ "otp": "123456"
+ }
+
+ result = mock_file('fake_otp_submit')
+ url = "{}/{}/otp/submit".format(self.base_url,'dummy_id')
+ responses.add(responses.POST,
+ url,
+ status=200,
+ body=json.dumps(result),
+ match_querystring=True)
+
+ self.assertEqual(self.client.payment.otpSubmit('dummy_id',param), result)
+
+ @responses.activate
+ def test_otpResend(self):
+ result = mock_file('fake_otp_resend')
+ url = "{}/{}/otp/resend".format(self.base_url,'dummy_id')
+ responses.add(responses.POST,
+ url,
+ status=200,
+ body=json.dumps(result),
+ match_querystring=True)
+
+ self.assertEqual(self.client.payment.otpResend('dummy_id'), result)
\ No newline at end of file