diff --git a/documents/account.md b/documents/account.md
index 40070cfd..dfc2a68c 100644
--- a/documents/account.md
+++ b/documents/account.md
@@ -402,6 +402,63 @@ Account account = instance.account.fetch(accountId);
-------------------------------------------------------------------------------------------------------
+### Upload account documents
+```java
+String accountId = "acc_M83Uw27KXuC7c8";
+
+JSONObject request = new JSONObject();
+request.put("files","/Users/your_name/Downloads/sample_uploaded.jpeg");
+request.put("document_type","business_proof_url");
+
+Account account = instance.account.uploadAccountDoc(accountId, request);
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|----------------|-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. |
+| file* | string | The URL generated once the business proof document is uploaded. |
+| document_type* | string | The documents valid for the proof type to be shared. Possible values :
business_proof_of_identification: `shop_establishment_certificate`, `gst_certificate`, `msme_certificate`, `business_proof_url`, `business_pan_url`,
additional_documents : `form_12_a_url`, `form_80g_url`, `cancelled_cheque` |
+
+**Response:**
+```json
+{
+ "business_proof_of_identification": [
+ {
+ "type": "business_proof_url",
+ "url": ""
+ }
+ ]
+}
+```
+-------------------------------------------------------------------------------------------------------
+
+### Fetch account documents
+```java
+String accountId = "acc_LryDIBIjBDbOWy";
+
+Account account = instance.account.fetchAccountDoc(accountId);
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|-------------|-------------|------------------------------------------------------------------------|
+| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. |
+
+**Response:**
+```json
+{
+ "business_proof_of_identification": [
+ {
+ "type": "business_proof_url",
+ "url": ""
+ }
+ ]
+}
+```
+-------------------------------------------------------------------------------------------------------
**PN: * indicates mandatory fields**
diff --git a/documents/document.md b/documents/document.md
new file mode 100644
index 00000000..ca936745
--- /dev/null
+++ b/documents/document.md
@@ -0,0 +1,66 @@
+## Document
+
+### Create a Document
+
+```java
+ JSONObject request = new JSONObject();
+ request.put("file","/Users/your_name/Downloads/sample_uploaded.jpeg");
+ request.put("purpose","dispute_evidence");
+
+ Document document = instance.document.create(request);
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|----------|-----------|-----------------------------------------------------------------|
+| file* | string | The URL generated once the business proof document is uploaded. |
+| purpose | string | Possible value is `dispute_evidence` |
+
+**Response:**
+```json
+{
+ "id": "doc_EsyWjHrfzb59Re",
+ "entity": "document",
+ "purpose": "dispute_evidence",
+ "name": "doc_19_12_2020.jpg",
+ "mime_type": "image/png",
+ "size": 2863,
+ "created_at": 1590604200
+}
+```
+-------------------------------------------------------------------------------------------------------
+
+### Fetch Document Information
+
+```java
+String documentId = "doc_EsyWjHrfzb59Re";
+
+Document document = instance.document.fetch(documentId);
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|-------------|--------|--------------------------------------------------|
+| documentId | string | The unique identifier of the document. |
+
+**Response:**
+```json
+{
+ "entity": "document",
+ "id": "doc_00000000000000",
+ "purpose": "dispute_evidence",
+ "created_at": 1701701378,
+ "mime_type": "application/pdf",
+ "display_name": "ppm_00000000000000",
+ "size": 404678,
+ "url": ""
+}
+```
+-------------------------------------------------------------------------------------------------------
+
+**PN: * indicates mandatory fields**
+
+
+**For reference click [here](https://razorpay.com/docs/api/documents)**
\ No newline at end of file
diff --git a/documents/stakeholder.md b/documents/stakeholder.md
index ba1512db..9790364b 100644
--- a/documents/stakeholder.md
+++ b/documents/stakeholder.md
@@ -293,6 +293,68 @@ Stakeholder stakeholder = instance.stakeholder.fetch(accountId, stakeholderId);
}
```
+-------------------------------------------------------------------------------------------------------
+### Upload stakeholders documents
+```java
+String accoundId = "acc_LryDIBIjBDbOWy";
+String stakeholderId = "sth_M0zjeiVOLRJRPW";
+
+JSONObject request = new JSONObject();
+request.put("file","/Users/your_name/Downloads/sample_uploaded.jpeg");
+request.put("document_type","aadhar_front");
+
+Stakeholder stakeholder = instance.stakeholder.uploadStakeholderDoc(accoundId, stakeholderId, request);
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|-------------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. |
+| stakeholderId* | string | The unique identifier of the stakeholder whose details are to be fetched. |
+| file* | string | The URL generated once the business proof document is uploaded. |
+| document_type* | string | The documents valid for the proof type to be shared. In case of individual_proof_of_address, both the front and back of a document proof must be uploaded. Possible values :
individual_proof_of_identification: `personal_pan`
individual_proof_of_address : `voter_id_back`, `voter_id_front`, `aadhar_front`, `aadhar_back`, `passport_front`, `passport_back` |
+
+**Response:**
+```json
+{
+ "individual_proof_of_address": [
+ {
+ "type": "aadhar_front",
+ "url": "https://rzp.io/i/bzDAbNg"
+ }
+ ]
+}
+```
+-------------------------------------------------------------------------------------------------------
+
+### Fetch stakeholders documents
+```java
+
+String accoundId = "acc_LryDIBIjBDbOWy";
+String stakeholderId = "sth_M0zjeiVOLRJRPW";
+
+Stakeholder stakeholder = instance.stakeholder.fetchStakeholderDoc(accoundId, stakeholderId);
+```
+
+**Parameters:**
+
+| Name | Type | Description |
+|----------------|-------------|---------------------------------------------------------------------------|
+| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. |
+| stakeholderId* | string | The unique identifier of the stakeholder whose details are to be fetched. |
+
+**Response:**
+```json
+{
+ "business_proof_of_identification": [
+ {
+ "type": "business_proof_url",
+ "url": ""
+ }
+ ]
+}
+```
-------------------------------------------------------------------------------------------------------
**PN: * indicates mandatory fields**
diff --git a/src/main/java/com/razorpay/AccountClient.java b/src/main/java/com/razorpay/AccountClient.java
index 03e49c3c..b17c230b 100644
--- a/src/main/java/com/razorpay/AccountClient.java
+++ b/src/main/java/com/razorpay/AccountClient.java
@@ -22,4 +22,11 @@ public Account edit(String id, JSONObject request) throws RazorpayException {
public Account delete(String id) throws RazorpayException {
return delete(Constants.VERSION_V2, String.format(Constants.ACCOUNT_DELETE, id), null);
}
+
+ public Account uploadAccountDoc(String id, JSONObject request) throws RazorpayException {
+ return post(Constants.VERSION_V2, String.format(Constants.UPLOAD_ACCOUNT_DOCUMENT, id), request);
+ }
+ public Account fetchAccountDoc(String id) throws RazorpayException {
+ return get(Constants.VERSION_V2, String.format(Constants.UPLOAD_ACCOUNT_DOCUMENT, id), null);
+ }
}
diff --git a/src/main/java/com/razorpay/ApiUtils.java b/src/main/java/com/razorpay/ApiUtils.java
index e4cd386a..20778b08 100755
--- a/src/main/java/com/razorpay/ApiUtils.java
+++ b/src/main/java/com/razorpay/ApiUtils.java
@@ -1,5 +1,6 @@
package com.razorpay;
+import java.io.File;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
@@ -23,6 +24,8 @@
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
+import okhttp3.MultipartBody;
+import okhttp3.MediaType;
class ApiUtils {
@@ -75,8 +78,15 @@ static Response postRequest(String version, String path, JSONObject requestObjec
HttpUrl.Builder builder = getBuilder(version, path, host);
- String requestContent = requestObject == null ? "" : requestObject.toString();
- RequestBody requestBody = RequestBody.create(Constants.MEDIA_TYPE_JSON, requestContent);
+ RequestBody requestBody;
+
+ if(requestObject != null && requestObject.has("file")){
+ requestBody = fileRequestBody(requestObject);
+ }else{
+ String requestContent = requestObject == null ? "" : requestObject.toString();
+ requestBody = RequestBody.create(Constants.MEDIA_TYPE_JSON, requestContent);
+ }
+
Request request =
createRequest(Method.POST.name(), builder.build().toString(), requestBody, auth);
return processRequest(request);
@@ -225,4 +235,34 @@ private static X509TrustManager createDefaultTrustManager() throws NoSuchAlgorit
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
return trustManager;
}
+
+ private static String getMediaType(String fileName){
+ int extensionIndex = fileName.lastIndexOf('.');
+ String extenionName = fileName.substring(extensionIndex + 1);
+ if(extenionName == "jpg" | extenionName == "jpeg" | extenionName == "png" | extenionName == "jfif"){
+ return "image/jpg";
+ }
+ return "image/pdf";
+ }
+
+ private static RequestBody fileRequestBody(JSONObject requestObject){
+ File fileToUpload = new File((String) requestObject.get("file"));
+ String fileName = fileToUpload.getName();
+
+ MediaType mediaType = MediaType.parse(getMediaType(fileName));
+ RequestBody fileBody = RequestBody.create(mediaType, fileToUpload);
+
+ MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
+ multipartBodyBuilder.addFormDataPart("file",fileName, fileBody);
+
+ Iterator> iterator = requestObject.keys();
+ while (iterator.hasNext()) {
+ Object key = iterator.next();
+ Object value = requestObject.get(key.toString());
+ multipartBodyBuilder.addFormDataPart((String) key, (String) value);
+ }
+
+ MultipartBody requestBody = multipartBodyBuilder.build();
+ return requestBody;
+ }
}
diff --git a/src/main/java/com/razorpay/Constants.java b/src/main/java/com/razorpay/Constants.java
index 93cf6abe..d6dda79d 100755
--- a/src/main/java/com/razorpay/Constants.java
+++ b/src/main/java/com/razorpay/Constants.java
@@ -170,6 +170,12 @@ public class Constants {
static final String TOKEN = "/token";
static final String REVOKE = "/revoke";
+ static final String DOCUMENTS = "/documents";
+ static final String DOCUMENT_FETCH = "/documents/%s";
+
+ static final String UPLOAD_ACCOUNT_DOCUMENT = "accounts/%s/documents";
+ static final String UPLOAD_STAKEHOLDER_DOCUMENT = "accounts/%s/stakeholders/%s/documents";
+
static final String VIEW_RTO = "orders/%s/rto_review";
static final String FULFILLMENT = "orders/%s/fulfillment";
diff --git a/src/main/java/com/razorpay/Document.java b/src/main/java/com/razorpay/Document.java
new file mode 100644
index 00000000..2c8a9b95
--- /dev/null
+++ b/src/main/java/com/razorpay/Document.java
@@ -0,0 +1,10 @@
+package com.razorpay;
+
+import org.json.JSONObject;
+
+public class Document extends Entity {
+
+ public Document(JSONObject jsonObject) {
+ super(jsonObject);
+ }
+}
diff --git a/src/main/java/com/razorpay/DocumentClient.java b/src/main/java/com/razorpay/DocumentClient.java
new file mode 100644
index 00000000..d40cba69
--- /dev/null
+++ b/src/main/java/com/razorpay/DocumentClient.java
@@ -0,0 +1,16 @@
+package com.razorpay;
+
+import org.json.JSONObject;
+
+public class DocumentClient extends ApiClient {
+
+ DocumentClient(String auth) {super(auth);}
+
+ public Document create(JSONObject request) throws RazorpayException {
+ return post(Constants.VERSION, Constants.DOCUMENTS, request);
+ }
+
+ public Document fetch(String id) throws RazorpayException {
+ return get(Constants.VERSION, String.format(Constants.DOCUMENT_FETCH, id), null);
+ }
+}
diff --git a/src/main/java/com/razorpay/RazorpayClient.java b/src/main/java/com/razorpay/RazorpayClient.java
index 4eaeeeb1..520ee66d 100755
--- a/src/main/java/com/razorpay/RazorpayClient.java
+++ b/src/main/java/com/razorpay/RazorpayClient.java
@@ -31,7 +31,10 @@ public class RazorpayClient {
public DisputeClient dispute;
public TncMap tncMap;
+ public DocumentClient document;
+
public BankAccountClient bankAccount;
+
public RazorpayClient(String key, String secret) throws RazorpayException {
this(key, secret, false);
}
@@ -69,6 +72,7 @@ private void initializeResources(String auth, Boolean enableLogging) throws Razo
stakeholder = new StakeholderClient(auth);
product = new ProductClient(auth);
webhook = new WebhookClient(auth);
+ document = new DocumentClient(auth);
dispute = new DisputeClient(auth);
bankAccount = new BankAccountClient(auth);
}
diff --git a/src/main/java/com/razorpay/StakeholderClient.java b/src/main/java/com/razorpay/StakeholderClient.java
index a72e8c46..d7c81d59 100644
--- a/src/main/java/com/razorpay/StakeholderClient.java
+++ b/src/main/java/com/razorpay/StakeholderClient.java
@@ -25,4 +25,12 @@ public List fetchAll(String id) throws RazorpayException {
public Stakeholder edit(String id, String stakeholder_id, JSONObject request) throws RazorpayException {
return patch(Constants.VERSION_V2, String.format(Constants.STAKEHOLDER_FETCH, id, stakeholder_id), request);
}
+
+ public Account uploadStakeholderDoc(String id, String stakeholder_id, JSONObject request) throws RazorpayException {
+ return post(Constants.VERSION_V2, String.format(Constants.UPLOAD_STAKEHOLDER_DOCUMENT, id, stakeholder_id), request);
+ }
+
+ public Account fetchStakeholderDoc(String id, String stakeholder_id) throws RazorpayException {
+ return get(Constants.VERSION_V2, String.format(Constants.UPLOAD_STAKEHOLDER_DOCUMENT, id, stakeholder_id), null);
+ }
}
diff --git a/src/test/java/com/razorpay/AccountClientTest.java b/src/test/java/com/razorpay/AccountClientTest.java
index d67a3332..6ebba9dc 100644
--- a/src/test/java/com/razorpay/AccountClientTest.java
+++ b/src/test/java/com/razorpay/AccountClientTest.java
@@ -1,5 +1,6 @@
package com.razorpay;
+import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Test;
import org.mockito.InjectMocks;
@@ -230,4 +231,52 @@ private String getResponse(String account_id) {
" }\n" +
"}";
}
+
+ @Test
+ public void uploadAccountDoc() throws RazorpayException {
+ JSONObject request = new JSONObject();
+ request.put("files","/Users/your_name/Downloads/sample_uploaded.jpeg");
+ request.put("document_type","business_proof_url");
+
+ JSONObject mockedResponseJson = new JSONObject();
+ mockedResponseJson.put("entity","account");
+ JSONArray businessArray = new JSONArray();
+ JSONObject businessObj = new JSONObject();
+ businessObj.put("type","business_proof_url");
+ businessObj.put("url","");
+ businessArray.put(businessObj);
+ mockedResponseJson.put("business_proof_of_identification",businessArray);
+
+ try {
+ mockResponseFromExternalClient(mockedResponseJson.toString());
+ mockResponseHTTPCodeFromExternalClient(200);
+ Account document = accountClient.uploadAccountDoc(ACCOUNT_ID, request);
+ assertNotNull(document);
+ assertEquals(true,document.has("business_proof_of_identification"));
+ } catch (IOException e) {
+ assertTrue(false);
+ }
+ }
+
+ @Test
+ public void fetchAccountDoc() throws RazorpayException {
+
+ JSONObject mockedResponseJson = new JSONObject();
+ mockedResponseJson.put("entity","account");
+ JSONArray businessArray = new JSONArray();
+ JSONObject businessObj = new JSONObject();
+ businessObj.put("type","business_proof_url");
+ businessObj.put("url","");
+ businessArray.put(businessObj);
+ mockedResponseJson.put("business_proof_of_identification",businessArray);
+ try {
+ mockResponseFromExternalClient(mockedResponseJson.toString());
+ mockResponseHTTPCodeFromExternalClient(200);
+ Account document = accountClient.fetchAccountDoc(ACCOUNT_ID);
+ assertNotNull(document);
+ assertEquals(true,document.has("business_proof_of_identification"));
+ } catch (IOException e) {
+ assertTrue(false);
+ }
+ }
}
diff --git a/src/test/java/com/razorpay/DocumentClientTest.java b/src/test/java/com/razorpay/DocumentClientTest.java
new file mode 100644
index 00000000..4bccc645
--- /dev/null
+++ b/src/test/java/com/razorpay/DocumentClientTest.java
@@ -0,0 +1,72 @@
+package com.razorpay;
+
+import org.json.JSONObject;
+import org.junit.Test;
+import org.mockito.InjectMocks;
+import java.io.IOException;
+import static org.junit.Assert.*;
+
+public class DocumentClientTest extends BaseTest{
+
+ @InjectMocks
+ protected DocumentClient documentClient = new DocumentClient(TEST_SECRET_KEY);
+
+ private static final String DOCUMENT_ID = "doc_EsyWjHrfzb59Re";
+
+ @Test
+ public void create() throws RazorpayException {
+ JSONObject request = new JSONObject();
+ request.put("files","/Users/your_name/Downloads/sample_uploaded.jpeg");
+ request.put("purpose","dispute_evidence");
+
+ JSONObject mockedResponseJson = new JSONObject();
+ mockedResponseJson.put("id","doc_EsyWjHrfzb59Re");
+ mockedResponseJson.put("entity","document");
+ mockedResponseJson.put("purpose","dispute_evidence");
+ mockedResponseJson.put("name","sample_uploaded.jpg");
+ mockedResponseJson.put("mime_type","image/png");
+ mockedResponseJson.put("size","2863");
+ mockedResponseJson.put("created_at","1590604200");
+
+ try {
+ mockResponseFromExternalClient(mockedResponseJson.toString());
+ mockResponseHTTPCodeFromExternalClient(200);
+ Document document = documentClient.create(request);
+ assertNotNull(document);
+ assertEquals("document",document.get("entity"));
+ assertTrue(document.has("name"));
+ assertTrue(document.has("size"));
+ String createRequest = getHost(Constants.DOCUMENTS);
+ verifySentRequest(true, request.toString(), createRequest);
+ } catch (IOException e) {
+ assertTrue(false);
+ }
+ }
+
+ @Test
+ public void fetch() throws RazorpayException {
+
+ JSONObject mockedResponseJson = new JSONObject();
+ mockedResponseJson.put("id","doc_EsyWjHrfzb59Re");
+ mockedResponseJson.put("entity","document");
+ mockedResponseJson.put("purpose","dispute_evidence");
+ mockedResponseJson.put("name","doc_19_12_2020.jpg");
+ mockedResponseJson.put("mime_type","image/png");
+ mockedResponseJson.put("size","2863");
+ mockedResponseJson.put("created_at","1590604200");
+
+ try {
+ mockResponseFromExternalClient(mockedResponseJson.toString());
+ mockResponseHTTPCodeFromExternalClient(200);
+ Document fetch = documentClient.fetch(DOCUMENT_ID);
+ assertNotNull(fetch);
+ assertEquals(DOCUMENT_ID,fetch.get("id"));
+ assertTrue(fetch.has("purpose"));
+ assertTrue(fetch.has("name"));
+ String fetchRequest = getHost(String.format(Constants.DOCUMENT_FETCH,DOCUMENT_ID));
+ verifySentRequest(false, null, fetchRequest);
+ } catch (IOException e) {
+ assertTrue(false);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/razorpay/StakeholderClientTest.java b/src/test/java/com/razorpay/StakeholderClientTest.java
index 46e4b2d3..c2758a63 100644
--- a/src/test/java/com/razorpay/StakeholderClientTest.java
+++ b/src/test/java/com/razorpay/StakeholderClientTest.java
@@ -1,5 +1,6 @@
package com.razorpay;
+import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Test;
import org.mockito.InjectMocks;
@@ -200,4 +201,53 @@ private String getResponseCollection(){
" \"count\": 1\n" +
"}";
}
+
+ @Test
+ public void testuploadStakeholderDoc() throws RazorpayException {
+ JSONObject request = new JSONObject();
+ request.put("files","/Users/your_name/Downloads/sample_uploaded.jpeg");
+ request.put("document_type","aadhar_front");
+
+ JSONObject mockedResponseJson = new JSONObject();
+ mockedResponseJson.put("entity", "account");
+ JSONArray addressArray = new JSONArray();
+ JSONObject addressObj = new JSONObject();
+ addressObj.put("type","aadhar_front");
+ addressObj.put("url","https://rzp.io/i/bzDAbNg");
+ addressArray.put(addressObj);
+ mockedResponseJson.put("individual_proof_of_address", addressArray);
+
+ try {
+ mockResponseFromExternalClient(mockedResponseJson.toString());
+ mockResponseHTTPCodeFromExternalClient(200);
+ Account document = stakeholderClient.uploadStakeholderDoc(ACCOUNT_ID, STAKEHOLDER_ID, request);
+ assertNotNull(document);
+ assertEquals(true,document.has("individual_proof_of_address"));
+ } catch (IOException e) {
+ assertTrue(false);
+ }
+ }
+
+ @Test
+ public void testfetchStakeholderDoc() throws RazorpayException {
+
+ JSONObject mockedResponseJson = new JSONObject();
+ mockedResponseJson.put("entity", "account");
+ JSONArray addressArray = new JSONArray();
+ JSONObject addressObj = new JSONObject();
+ addressObj.put("type","aadhar_front");
+ addressObj.put("url","https://rzp.io/i/bzDAbNg");
+ addressArray.put(addressObj);
+ mockedResponseJson.put("individual_proof_of_address", addressArray);
+
+ try {
+ mockResponseFromExternalClient(mockedResponseJson.toString());
+ mockResponseHTTPCodeFromExternalClient(200);
+ Account document = stakeholderClient.fetchStakeholderDoc(ACCOUNT_ID, STAKEHOLDER_ID);
+ assertNotNull(document);
+ assertEquals(true,document.has("individual_proof_of_address"));
+ } catch (IOException e) {
+ assertTrue(false);
+ }
+ }
}