From 4cd5602bfb66a1a3dd214c330fe7e3a0ea26c995 Mon Sep 17 00:00:00 2001 From: Ankit Das <89454448+ankitdas13@users.noreply.github.com> Date: Tue, 7 May 2024 18:26:42 +0530 Subject: [PATCH] feat: Added new api's to customers (#390) --- documents/customer.md | 244 +++++++++++++++++++++++++++++++ lib/resources/customers.js | 26 ++++ lib/types/customers.d.ts | 108 ++++++++++++++ test/resources/customers.spec.js | 100 +++++++++++++ 4 files changed, 478 insertions(+) diff --git a/documents/customer.md b/documents/customer.md index 87f0347e..8b687ed4 100644 --- a/documents/customer.md +++ b/documents/customer.md @@ -146,6 +146,250 @@ instance.customers.fetch(customerId) } ``` +------------------------------------------------------------------------------------------------------- + +### Add Bank Account of Customer + +```js +var customerId = "cust_N5mywh91sXB69O" + +instance.customers.addBankAccount(customerId, { + "ifsc_code" : "UTIB0000194", + "account_number" :"916010082985661", + "beneficiary_name" : "Pratheek", + "beneficiary_address1" : "address 1", + "beneficiary_address2" : "address 2", + "beneficiary_address3" : "address 3", + "beneficiary_address4" : "address 4", + "beneficiary_email" : "random@email.com", + "beneficiary_mobile" : "8762489310", + "beneficiary_city" :"Bangalore", + "beneficiary_state" : "KA", + "beneficiary_country" : "IN" +}); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | Customer's bank account number | +| account_number | integer | The id of the customer to be fetched | +| account_number | string | The name of the beneficiary associated with the bank account. | +| beneficiary_name | string | The virtual payment address. | +| beneficiary_address1 | string | The id of the customer to be fetched | +| beneficiary_email | string | Email address of the beneficiary. | +| beneficiary_mobile | integer | Mobile number of the beneficiary. | +| beneficiary_city | string | The name of the city of the beneficiary. | +| beneficiary_state | string | The state of the beneficiary. | +| beneficiary_pin | interger | The pin code of the beneficiary's address. | +| ifsc_code | string | The IFSC code of the bank branch associated with the account. | + +**Response:** +```json +{ + "id" : "cust_1Aa00000000001", + "entity": "customer", + "name" : "Saurav Kumar", + "email" : "Saurav.kumar@example.com", + "contact" : "+919000000000", + "gstin":"29XAbbA4369J1PA", + "notes" : [], + "created_at ": 1234567890 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Delete Bank Account of Customer + +```js +var customerId = "cust_N5mywh91sXB69O" + +var bankAccountId = "ba_N6aM8uo64IzxHu" + +instance.customers.deleteBankAccount(customerId, bankAccountId); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | Customer's bank account number | +| bank_id | string | The bank_id that needs to be deleted. | + +**Response:** +```json +{ + "id": "ba_Evg09Ll05SIPSD", + "ifsc": "ICIC0001207", + "bank_name": "ICICI Bank", + "name": "Test R4zorpay", + "account_number": "XXXXXXXXXXXXXXX0434", + "status": "deleted" +} +``` + +------------------------------------------------------------------------------------------------------- + +### Eligibility Check API + +```js +instance.customers.requestEligibilityCheck({ + "inquiry": "affordability", + "amount": 500000, + "currency": "INR", + "customer": { + "id": "cust_KhP5dO1dKmc0Rm", + "contact": "+918220276214", + "ip": "105.106.107.108", + "referrer": "https://merchansite.com/example/paybill", + "user_agent": "Mozilla/5.0" + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| inquiry | string | List of methods or instruments on which eligibility check is required. Possible value is `affordability`. | +| amount* | string | The amount for which the order was created, in currency subunits. For example, for an amount of ₹295, enter `29500`. | +| currency* | string | Possible value is `INR`. | +| customer | object | All keys listed [here](https://razorpay.com/docs/payments/payment-gateway/affordability/eligibility-check/#request-parameters) are supported | +| instruments | object | All keys listed [here](https://razorpay.com/docs/payments/payment-gateway/affordability/eligibility-check/#request-parameters) are supported | + +**Response:** +```json +{ + "amount": "500000", + "customer": { + "id": "KkBhM9EC1Y0HTm", + "contact": "+918220722114" + }, + "instruments": [ + { + "method": "emi", + "issuer": "HDFC", + "type": "debit", + "eligibility_req_id": "elig_KkCNLzlNeMYQyZ", + "eligibility": { + "status": "eligible" + } + }, + { + "method": "paylater", + "provider": "getsimpl", + "eligibility_req_id": "elig_KkCNLzlNeMYQyZ", + "eligibility": { + "status": "eligible" + } + }, + { + "method": "paylater", + "provider": "icic", + "eligibility_req_id": "elig_KkCNLzlNeMYQyZ", + "eligibility": { + "status": "eligible" + } + }, + { + "method": "cardless_emi", + "provider": "walnut369", + "eligibility_req_id": "elig_KkCNLzlNeMYQyZ", + "eligibility": { + "status": "ineligible", + "error": { + "code": "GATEWAY_ERROR", + "description": "The customer has not been approved by the partner.", + "source": "business", + "step": "inquiry", + "reason": "user_not_approved" + } + } + }, + { + "method": "cardless_emi", + "provider": "zestmoney", + "eligibility_req_id": "elig_KkCNLzlNeMYQyZ", + "eligibility": { + "status": "ineligible", + "error": { + "code": "GATEWAY_ERROR", + "description": "The customer has exhausted their credit limit.", + "source": "business", + "step": "inquiry", + "reason": "credit_limit_exhausted" + } + } + }, + { + "method": "paylater", + "provider": "lazypay", + "eligibility_req_id": "elig_KkCNLzlNeMYQyZ", + "eligibility": { + "status": "ineligible", + "error": { + "code": "GATEWAY_ERROR", + "description": "The order amount is less than the minimum transaction amount.", + "source": "business", + "step": "inquiry", + "reason": "min_amt_required" + } + } + } + ] +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch Eligibility by id + +```js +var eligibilityId = 'elig_F1cxDoHWD4fkQt' +instance.customers.fetchEligibility(eligibilityId); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | Customer's bank account number | +| bank_id | string | The bank_id that needs to be deleted. | + +**Response:** +```json +{ + "instruments": [ + { + "method": "paylater", + "provider": "lazypay", + "eligibility_req_id": "elig_LBwGKVvS2X48Lq", + "eligibility": { + "status": "eligible" + } + }, + { + "method": "paylater", + "provider": "getsimpl", + "eligibility_req_id": "elig_LBwGKVvS2X48Lq", + "eligibility": { + "status": "ineligible", + "error": { + "code": "GATEWAY_ERROR", + "description": "The customer has exhausted their credit limit", + "source": "gateway", + "step": "inquiry", + "reason": "credit_limit_exhausted" + } + } + } + ] +} +``` + + ------------------------------------------------------------------------------------------------------- **PN: * indicates mandatory fields** diff --git a/lib/resources/customers.js b/lib/resources/customers.js index 2ea7d24b..4642cfe8 100644 --- a/lib/resources/customers.js +++ b/lib/resources/customers.js @@ -53,6 +53,32 @@ module.exports = function (api) { return api.delete({ url: `/customers/${customerId}/tokens/${tokenId}` }, callback) + }, + + addBankAccount(customerId, params ,callback) { + return api.post({ + url: `/customers/${customerId}/bank_account`, + data: params + }, callback) + }, + + deleteBankAccount(customerId, bankId ,callback) { + return api.delete({ + url: `/customers/${customerId}/bank_account/${bankId}` + }, callback) + }, + + requestEligibilityCheck(params ,callback) { + return api.post({ + url: `/customers/eligibility`, + data: params + }, callback) + }, + + fetchEligibility(eligibilityId, callback) { + return api.get({ + url: `/customers/eligibility/${eligibilityId}`, + }, callback) } } } diff --git a/lib/types/customers.d.ts b/lib/types/customers.d.ts index b69ae97b..c18d5c68 100644 --- a/lib/types/customers.d.ts +++ b/lib/types/customers.d.ts @@ -1,6 +1,7 @@ import { IMap, INormalizeError, RazorpayPaginationOptions } from "./api"; import { Invoices } from "./invoices"; import { Tokens } from "./tokens"; +import { VirtualAccounts } from "./virtualAccounts" export declare namespace Customers { interface RazorpayCustomerBaseRequestBody { @@ -57,6 +58,87 @@ export declare namespace Customers { */ shipping_address?: Invoices.RazorpayInvoiceAddress[]; } + + interface RazorpayCustomerBankAccountRequestBody { + /** + * The IFSC code of the bank branch associated with the account. + */ + ifsc_code: string; + /** + * Customer's bank account number. + */ + account_number: string; + /** + * The name of the beneficiary associated with the bank account. + */ + beneficiary_name?: string; + /** + * The virtual payment address. + */ + beneficiary_address1?: string; + beneficiary_address2?: string; + beneficiary_address3?: string; + beneficiary_address4?: string; + /** + * Email address of the beneficiary. For example, `gaurav.kumar@example.com`. + */ + beneficiary_email?: string; + /** + * Mobile number of the beneficiary. + */ + beneficiary_mobile?: string; + /** + * The name of the city of the beneficiary. + */ + beneficiary_city?: string; + /** + * The state of the beneficiary. + */ + beneficiary_state?: string; + /** + * The country of the beneficiary. + */ + beneficiary_country?: string; + /** + * The pin code of the beneficiary's address. + */ + beneficiary_pin?: string; + } + + interface RazorpayCustomerBankAccount extends Partial{ + success?: string; + } + + interface CustomersEligibility { + id: string; + contact: string; + ip: string; + referrer: string; + user_agent: string; + } + + interface RazorpayCustomerEligibilityRequestBody { + inquiry?: string; + amount: number | string; + currency: string; + customer: Partial; + } + + interface Instruments { + method: string; + issuer: string; + type: string; + provider: string; + eligibility_req_id: string; + eligibility: { + status: string; + error: Omit + } + } + + interface RazorpayCustomerEligibility extends RazorpayCustomerEligibilityRequestBody { + instruments? : Array + } } declare function customers(api: any): { @@ -135,6 +217,32 @@ declare function customers(api: any): { */ deleteToken(customerId: string, tokenId: string): Promise<{ deleted: boolean }> deleteToken(customerId: string, tokenId: string, callback: (err: INormalizeError | null, data: { deleted: boolean }) => void): void; + /** + * Add Bank Account of Customer + * + * @param customerId - The unique identifier of the customer. + * @param param - Check [doc](https://razorpay.com/docs/api/customers/bank-accounts/#1-add-bank-account-of-customer) for required params + */ + addBankAccount(customerId: string, params: Customers.RazorpayCustomerBankAccountRequestBody): Promise + /** + * Delete Bank Account of Customer + * + * @param customerId - The unique identifier of the customer. + * @param bankAccountId - The bank_id that needs to be deleted. + */ + deleteBankAccount(customerId: string, bankAccountId: string): Promise + /** + * Eligibility Check API + * + * @param param - Check [doc](https://razorpay.com/docs/payments/payment-gateway/affordability/eligibility-check/#eligibility-check-api) for required params + */ + requestEligibilityCheck(param: Customers.RazorpayCustomerEligibilityRequestBody): Promise> + /** + * Fetch Eligibility by id + * + * @param eligibilityId - The unique identifier of the eligibility request to be retrieved. + */ + fetchEligibility(eligibilityId: string): Promise> } export default customers \ No newline at end of file diff --git a/test/resources/customers.spec.js b/test/resources/customers.spec.js index c7a9bad3..97cc2c9a 100644 --- a/test/resources/customers.spec.js +++ b/test/resources/customers.spec.js @@ -184,4 +184,104 @@ describe('CUSTOMERS', () => { done() }) }) + + it('Add bank account of customer', (done) => { + const TEST_CUSTOMER_ID = 'cust_6fqBqgrfTSuj5v' + const param = { + "ifsc_code" : "UTIB0000194", + "account_number" :"916010082985661", + "beneficiary_name" : "Pratheek", + "beneficiary_address1" : "address 1", + "beneficiary_address2" : "address 2", + "beneficiary_address3" : "address 3", + "beneficiary_address4" : "address 4", + "beneficiary_email" : "random@email.com", + "beneficiary_mobile" : "8762489310", + "beneficiary_city" :"Bangalore", + "beneficiary_state" : "KA", + "beneficiary_country" : "IN" + } + + mocker.mock({ + url: `/customers/${TEST_CUSTOMER_ID}/bank_account`, + method: 'POST' + }) + + rzpInstance.customers.addBankAccount(TEST_CUSTOMER_ID, param).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v1/customers/${TEST_CUSTOMER_ID}/bank_account`, + 'Add bank account of customer url formed correctly' + ) + done() + }) + }) + + it('delete bank account of customer', (done) => { + const TEST_CUSTOMER_ID = 'cust_6fqBqgrfTSuj5v' + + const TEST_BANK_ID = 'ba_NEWc5RgwY8AAUC' + + mocker.mock({ + url: `/customers/${TEST_CUSTOMER_ID}/bank_account/${TEST_BANK_ID}`, + method: 'DELETE' + }) + + rzpInstance.customers.deleteBankAccount(TEST_CUSTOMER_ID, TEST_BANK_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v1/customers/${TEST_CUSTOMER_ID}/bank_account/${TEST_BANK_ID}`, + 'delete bank account of customer url formed correctly' + ) + done() + }) + }) + + it('Fetch eligibility id', (done) => { + + const TEST_ELIGIBILITY_ID = 'elig_F1cxDoHWD4fkQt' + + mocker.mock({ + url: `/customers/eligibility/${TEST_ELIGIBILITY_ID}`, + method: 'GET' + }) + + rzpInstance.customers.fetchEligibility(TEST_ELIGIBILITY_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v1/customers/eligibility/${TEST_ELIGIBILITY_ID}`, + 'fetch eligibility request url formed correctly' + ) + done() + }) + }) + + it('Request for an eligibility check', (done) => { + const param = { + "inquiry": "affordability", + "amount": 500000, + "currency": "INR", + "customer": { + "id": "cust_KhP5dO1dKmc0Rm", + "contact": "+918220276214", + "ip": "105.106.107.108", + "referrer": "https://merchansite.com/example/paybill", + "user_agent": "Mozilla/5.0" + } + } + + mocker.mock({ + url: `/customers/eligibility`, + method: 'POST' + }) + + rzpInstance.customers.requestEligibilityCheck(param).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v1/customers/eligibility`, + 'Request for an eligibility check url formed correctly' + ) + done() + }) + }) })