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); + } + } }