diff --git a/documents/account.md b/documents/account.md new file mode 100644 index 00000000..d96036a1 --- /dev/null +++ b/documents/account.md @@ -0,0 +1,448 @@ +## Account + +### Create an Account +```js +instance.accounts.create({ + "email": "gauriagain.kumar@example.org", + "phone": "9000090000", + "legal_business_name": "Acme Corp", + "business_type": "partnership", + "customer_facing_business_name": "Example", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "description": "Healthcare E-commerce platform", + "addresses": { + "operation": { + "street1": "507, Koramangala 6th block", + "street2": "Kormanagala", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560047, + "country": "IN" + }, + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560034, + "country": "IN" + } + }, + "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." + }, + "legal_info": { + "pan": "AAACL1234C", + "gst": "18AABCU9603R1ZM" + }, + "brand": { + "color": "FFFFFF" + }, + "notes": { + "internal_ref_id": "123123" + }, + "contact_name": "Gaurav Kumar", + "contact_info": { + "chargeback": { + "email": "cb@example.org" + }, + "refund": { + "email": "cb@example.org" + }, + "support": { + "email": "support@example.org", + "phone": "9999999998", + "policy_url": "https://www.google.com" + } + }, + "apps": { + "websites": [ + "https://www.example.org" + ], + "android": [ + { + "url": "playstore.example.org", + "name": "Example" + } + ], + "ios": [ + { + "url": "appstore.example.org", + "name": "Example" + } + ] + } +}) +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| email* | string | The sub-merchant's business email address. | +| phone* | integer | The sub-merchant's business phone number. The minimum length is 8 characters and the maximum length is 15. | +| legal_business_name* | string | The name of the sub-merchant's business. For example, Acme Corp. The minimum length is 4 characters and the maximum length is 200. | +| customer_facing_business_name | string | The sub-merchant billing label as it appears on the Razorpay Dashboard. The minimum length is 1 character and the maximum length is 255. | +| business_type | string | The type of business operated by the sub-merchant.Possible value is `proprietorship`, `partnership`, `private_limited`, `public_limited`, `llp`, `ngo`, `trust`, `society`, `not_yet_registered`, `huf` | +| reference_id | string | Partner's external account reference id. The minimum length is 1 character and the maximum length is 512. | +| profile | object | All keys listed [here](https://razorpay.com/docs/api/partners/account-onboarding/#create-an-account) are supported | +| legal_info | object | All keys listed [here](hhttps://razorpay.com/docs/api/partners/account-onboarding/#create-an-account) are supported | +| brand | object | All keys listed [here](https://razorpay.com/docs/api/partners/account-onboarding/#create-an-account) are supported | +| notes | object | A key-value pair | +| contact_name* | string | The name of the contact. The minimum length is 4 and the maximum length is 255 characters. | +| contact_info | object | All keys listed [here](https://razorpay.com/docs/api/partners/account-onboarding/#create-an-account) are supported | +| apps | object | All keys listed [here](https://razorpay.com/docs/api/partners/account-onboarding/#create-an-account) are supported | + + +**Response:** +```json +{ + "id": "acc_GRWKk7qQsLnDjX", + "type": "standard", + "status": "created", + "email": "gauriagain.kumar@example.org", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "addresses": { + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road", + "city": "Bengaluru", + "state": "KARNATAKA", + "postal_code": 560034, + "country": "IN" + }, + "operation": { + "street1": "507, Koramangala 6th block", + "street2": "Kormanagalo", + "city": "Bengaluru", + "state": "KARNATAKA", + "country": "IN", + "postal_code": 560047 + } + }, + "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." + }, + "notes": { + "internal_ref_id": "123123" + }, + "created_at": 1611136837, + "phone": "9000090000", + "business_type": "partnership", + "legal_business_name": "Acme Corp", + "customer_facing_business_name": "Example", + "legal_info": { + "pan": "AAACL1234C", + "gst": "18AABCU9603R1ZM" + }, + "apps": { + "websites": [ + "https://www.example.org" + ], + "android": [ + { + "url": "playstore.example.org", + "name": "Example" + } + ], + "ios": [ + { + "url": "appstore.example.org", + "name": "Example" + } + ] + }, + "brand": { + "color": "#FFFFFF" + }, + "contact_info": { + "chargeback": { + "email": "cb@example.org", + "phone": null, + "policy_url": null + }, + "refund": { + "email": "cb@example.org", + "phone": null, + "policy_url": null + }, + "support": { + "email": "support@example.org", + "phone": "9999999998", + "policy_url": "https://www.google.com" + } + } +} +``` + +------------------------------------------------------------------------------------------------------- + +### Edit Account + +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +instance.accounts.edit(accountId,{ + "customer_facing_business_name": "ABCD Ltd" +}); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| phone | integer | The sub-merchant's business phone number. The minimum length is 8 characters and the maximum length is 15. | +| legal_business_name | string | The name of the sub-merchant's business. For example, Acme Corp. The minimum length is 4 characters and the maximum length is 200. | +| customer_facing_business_name | string | The sub-merchant billing label as it appears on the Razorpay Dashboard. The minimum length is 1 character and the maximum length is 255. | +| profile | object | All keys listed [here](https://razorpay.com/docs/api/partners/account-onboarding/#update-an-account) are supported | +| legal_info | object | All keys listed [here](hhttps://razorpay.com/docs/api/partners/account-onboarding/#update-an-account) are supported | +| brand | object | All keys listed [here](https://razorpay.com/docs/api/partners/account-onboarding/#update-an-account) are supported | +| notes | object | A key-value pair | +| contact_name* | string | The name of the contact. The minimum length is 4 and the maximum length is 255 characters. | +| contact_info | object | All keys listed [here](https://razorpay.com/docs/api/partners/account-onboarding/#update-an-account) are supported | +| apps | object | All keys listed [here](https://razorpay.com/docs/api/partners/account-onboarding/#update-an-account) are supported | + +**Response:** +```json +{ + "id": "acc_GP4lfNA0iIMn5B", + "type": "standard", + "status": "created", + "email": "gauri@example.org", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "addresses": { + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road-1", + "city": "Bengalore", + "state": "KARNATAKA", + "postal_code": "560034", + "country": "IN" + } + } + }, + "notes": [], + "created_at": 1610603081, + "phone": "9000090000", + "reference_id": "randomId", + "business_type": "partnership", + "legal_business_name": "Acme Corp", + "customer_facing_business_name": "ABCD Ltd" +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete an account +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +instance.accounts.delete(accountId); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account that must be deleted. | + +**Response:** +```json +{ + "id": "acc_GXQAkO2MrvBYg4", + "type": "standard", + "status": "suspended", + "email": "gaurav.kumar@acme.org", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "addresses": { + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road", + "city": "Bengaluru", + "state": "KARNATAKA", + "postal_code": "560034", + "country": "IN" + }, + "operation": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road", + "city": "Bengaluru", + "state": "KARNATAKA", + "country": "IN", + "postal_code": "560034" + } + }, + "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." + }, + "notes": { + "internal_ref_id": "123123" + }, + "created_at": 1612425180, + "suspended_at": 1612425235, + "phone": "9000090000", + "reference_id": "account_COdeRandom", + "business_type": "partnership", + "legal_business_name": "Acme Corp Pvt Ltd", + "customer_facing_business_name": "Acme", + "legal_info": { + "pan": "AAACL1234C", + "gst": "18AABCU9603R1ZM" + }, + "apps": { + "websites": [ + "https://www.acme.org" + ], + "android": [ + { + "url": "playstore.acme.org", + "name": "Acme" + } + ], + "ios": [ + { + "url": "appstore.acme.org", + "name": "Acme" + } + ] + }, + "brand": { + "color": "#FFFFFF" + }, + "contact_name": "Gaurav Kumar", + "contact_info": { + "chargeback": { + "email": "cb@acme.org", + "phone": "9000090000", + "policy_url": "https://www.google.com" + }, + "refund": { + "email": "cb@acme.org", + "phone": "9898989898", + "policy_url": "https://www.google.com" + }, + "support": { + "email": "support@acme.org", + "phone": "9898989898", + "policy_url": "https://www.google.com" + } + } +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch an account +```js +accountId = "acc_GP4lfNA0iIMn5B"; + +instance.accounts.fetch(accountId); +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. | + +**Response:** +```json +{ + "id": "acc_GP4lfNA0iIMn5B", + "type": "standard", + "status": "created", + "email": "gauri@example.org", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "addresses": { + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road-1", + "city": "Bengalore", + "state": "KARNATAKA", + "postal_code": "560034", + "country": "IN" + } + } + }, + "notes": [], + "created_at": 1610603081, + "phone": "9000090000", + "reference_id": "randomId", + "business_type": "partnership", + "legal_business_name": "Acme Corp", + "customer_facing_business_name": "Example Pvt. Ltd." +} +``` + +------------------------------------------------------------------------------------------------------- + +### Upload account documents +```js +var formData ={ + 'file': { + 'value': fs.createReadStream('/Users/your_name/Downloads/sample_uploaded.jpeg'), + 'options': { + 'filename': 'sample_uploaded.jpeg', + 'contentType': null + } + }, + 'document_type': 'business_proof_url' +} + +instance.accounts.uploadAccountDoc("acc_LryDIBIjBDbOWy",formData); +``` + +**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 +```js +instance.accounts.fetchAccountDoc("acc_LryDIBIjBDbOWy"); +``` + +**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** +
+
+**For reference click [here](https://razorpay.com/docs/api/partners/account-onboarding/)** \ No newline at end of file diff --git a/documents/card.md b/documents/card.md index dbf65185..bb30cfb2 100644 --- a/documents/card.md +++ b/documents/card.md @@ -559,8 +559,48 @@ instance.customers.deleteToken(customerId,tokenId) } ``` ------------------------------------------------------------------------------------------------------- +## Using Card Number/ Tokenised Card Number +```js +instance.cards.requestCardReference({"number":"4854980604708430"}); +``` +**Parameters:** + +| Name | Type | Description | +|-------------|---------|------------------------------------------------------------------------------| +| number* | string | The card number whose PAR or network reference id should be retrieved. | +| tokenised | string | Determines if the card is saved as a token. Possible value is `true` or `false` | + +**Response:** +```json +{ + "network": "Visa", + "payment_account_reference": "V0010013819231376539033235990", + "network_reference_id": null +} +``` +------------------------------------------------------------------------------------------------------- + +## Using Razporpay token + +```js +instance.cards.requestCardReference({"token":"token_4lsdksD31GaZ09"}); +``` +**Parameters:** + +| Name | Type | Description | +|-------------|---------|------------------------------------------------------------------------------| +| token* | string | The token whose PAR or network reference id should be retrieved.| + +**Response:** +```json +{ + "network": "Visa", + "payment_account_reference": "V0010013819231376539033235990", + "network_reference_id": null +} +``` +------------------------------------------------------------------------------------------------------- **PN: * indicates mandatory fields**

-**For reference click [here](https://razorpay.com/docs/api/recurring-payments/cards/authorization-transaction/)** \ No newline at end of file diff --git a/documents/payment.md b/documents/payment.md index 2c69010e..743df19d 100644 --- a/documents/payment.md +++ b/documents/payment.md @@ -833,7 +833,50 @@ instance.payments.fetchPaymentMethods(); please refer this [doc](https://razorpay.com/docs/payments/third-party-validation/s2s-integration/methods-api/#fetch-payment-methods) for response ------------------------------------------------------------------------------------------------------- +### Token IIN API +```js +var tokenIin = "412345"; + +instance.iins.fetch(tokenIin); +``` + +**Parameters:** + +| Name | Type | Description | +|------------|--------|-----------------------------------| +| tokenIin* | string | The token IIN. | + +**Response:** +```json +{ + "iin": "412345", + "entity": "iin", + "network": "Visa", + "type": "credit", + "sub_type": "business", + "issuer_code": "HDFC", + "issuer_name": "HDFC Bank Ltd", + "international": false, + "is_tokenized": true, + "card_iin": "411111", + "emi":{ + "available": true + }, + "recurring": { + "available": true + }, + "authentication_types": [ + { + "type":"3ds" + }, + { + "type":"otp" + } + ] +} +``` +------------------------------------------------------------------------------------------------------- **PN: * indicates mandatory fields**

diff --git a/documents/productConfiguration.md b/documents/productConfiguration.md new file mode 100644 index 00000000..1af09ad5 --- /dev/null +++ b/documents/productConfiguration.md @@ -0,0 +1,444 @@ +## Product Configuration + +### Request a Product Configuration +```js + +var accountId = "acc_GP4lfNA0iIMn5B"; + +instance.products.requestProductConfiguration(accountId, { + "product_name" : "payment_gateway", + "tnc_accepted" : true, + "ip" : "233.233.233.234" +}); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| product_name* | string | The product(s) to be configured. Possible value is `payment_gateway`, `payment_links` | +| tnc_accepted | boolean | Pass this parameter to accept terms and conditions. Send this parameter along with the ip parameter when the tnc is accepted. Possible values is `true` | +| ip | integer | The IP address of the merchant while accepting the terms and conditions. Send this parameter along with the `tnc_accepted` parameter when the `tnc` is accepted. | + +**Response:** +```json +{ + "requested_configuration": { + "payment_methods": [] + }, + "active_configuration": { + "payment_capture": { + "mode": "automatic", + "refund_speed": "normal", + "automatic_expiry_period": 7200 + }, + "settlements": { + "account_number": null, + "ifsc_code": null, + "beneficiary_name": null + }, + "checkout": { + "theme_color": "#FFFFFF", + "flash_checkout": true, + "logo": "https://example.com/your_logo" + }, + "refund": { + "default_refund_speed": "normal" + }, + "notifications": { + "whatsapp": true, + "sms": false, + "email": [ + "b963e252-1201-45b0-9c39-c53eceb0cfd6_load@gmail.com" + ] + }, + "payment_methods": { + "netbanking": { + "enabled": true, + "instrument": [ + { + "type": "retail", + "bank": [ + "hdfc", + "sbin", + "utib", + "icic", + "scbl", + "yesb" + ] + } + ] + }, + "wallet": { + "enabled": true, + "instrument": [ + "airtelmoney", + "freecharge", + "jiomoney", + "olamoney", + "payzapp", + "mobikwik" + ] + }, + "upi": { + "enabled": true, + "instrument": [ + "upi" + ] + } + } + }, + "requirements": [ + { + "field_reference": "individual_proof_of_address", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/stakeholders/{stakeholderId}/documents", + "status": "required", + "reason_code": "document_missing" + }, + { + "field_reference": "individual_proof_of_identification", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/stakeholders/{stakeholderId}/documents", + "status": "required", + "reason_code": "document_missing" + }, + { + "field_reference": "business_proof_of_identification", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/documents", + "status": "required", + "reason_code": "document_missing" + }, + { + "field_reference": "settlements.beneficiary_name", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/products/acc_prd_HEgNpywUFctQ9e", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "settlements.account_number", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/products/acc_prd_HEgNpywUFctQ9e", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "settlements.ifsc_code", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/products/acc_prd_HEgNpywUFctQ9e", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "contact_name", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "name", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/stakeholders", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "customer_facing_business_name", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "kyc.pan", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/stakeholders", + "status": "required", + "reason_code": "field_missing" + } + ], + "tnc":{ + "id": "tnc_IgohZaDBHRGjPv", + "accepted": true, + "accepted_at": 1641550798 + }, + "id": "acc_prd_HEgNpywUFctQ9e", + "account_id": "acc_HQVlm3bnPmccC0", + "product_name": "payment_gateway", + "activation_status": "needs_clarification", + "requested_at": 162547884 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Edit a Product Configuration +```js +var accountId = "acc_GP4lfNA0iIMn5B"; +var productId = "acc_prd_HEgNpywUFctQ9e"; + +instance.products.edit(accountId, productId, { + "notifications": { + "email": [ + "gaurav.kumar@example.com", + "acd@gmail.com" + ] + }, + "checkout": { + "theme_color": "#528FFF" + }, + "refund": { + "default_refund_speed": "optimum" + }, + "settlements": { + "account_number": "1234567890", + "ifsc_code": "HDFC0000317", + "beneficiary_name": "Gaurav Kumar" + }, + "tnc_accepted": true, + "ip": "233.233.233.234" +}); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| notifications | object | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | +| checkout | object | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | +| refund | object | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | +| settlements | object | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | +| tnc_accepted | boolean | Pass this parameter to accept terms and conditions. Send this parameter along with the ip parameter when the tnc is accepted. Possible value is `true` | +| ip | string | The IP address of the merchant while accepting the terms and conditions. Send this parameter along with the tnc_accepted parameter when the `tnc` is accepted. | +| payment_methods | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | +| type | string | Possible value is `domestic` | +| issuer | string | The card issuer. Possible values for issuer are `amex`, `dicl`, `maestro`, `mastercard`, `rupay`, `visa`. | +| wallet | object | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | +| instrument(wallet) | string | The wallet issuer. Possible values are `airtelmoney`, `amazonpay`, `freecharge`, `jiomoney`, `mobiwik`, `mpesa`, `olamoney`, `paytm`, `payzapp`, `payumoney`, `phonepe`, `phonepeswitch`, `sbibuddy` | +| instrument(wallet) | string | The wallet issuer. Possible values are `airtelmoney`, `amazonpay`, `freecharge`, `jiomoney`, `mobiwik`, `mpesa`, `olamoney`, `paytm`, `payzapp`, `payumoney`, `phonepe`, `phonepeswitch`, `sbibuddy` | +| upi | object | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | +| instrument(upi) | string | The UPI service provider. Possible values are `google_pay`, `upi`| +| paylater | object | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | +| instrument(emi) | string | The Paylater service provider. Possible values are `epaylater`, `getsimpl`| +| emi | object | All keys listed [here](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) are supported | + +**Response:** +```json +{ + "id": "acc_GP4lfNA0iIMn5B", + "type": "standard", + "status": "created", + "email": "gauri@example.org", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "addresses": { + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road-1", + "city": "Bengalore", + "state": "KARNATAKA", + "postal_code": "560034", + "country": "IN" + } + } + }, + "notes": [], + "created_at": 1610603081, + "phone": "9000090000", + "reference_id": "randomId", + "business_type": "partnership", + "legal_business_name": "Acme Corp", + "customer_facing_business_name": "ABCD Ltd" +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch a product configuration +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +var productId = "acc_prd_HEgNpywUFctQ9e"; + +instance.products.fetch(accountId, productId); +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. | +| productId* | string | The unique identifier of a product generated by Razorpay. | + +**Response:** +```json +{ + "requested_configuration": { + "payment_methods": [] + }, + "active_configuration": { + "payment_capture": { + "mode": "automatic", + "refund_speed": "normal", + "automatic_expiry_period": 7200 + }, + "settlements": { + "account_number": null, + "ifsc_code": null, + "beneficiary_name": null + }, + "checkout": { + "theme_color": "#FFFFFF", + "flash_checkout": true + }, + "refund": { + "default_refund_speed": "normal" + }, + "notifications": { + "whatsapp": true, + "sms": false, + "email": [ + "b963e252-1201-45b0-9c39-c53eceb0cfd6_load@gmail.com" + ] + }, + "payment_methods": { + "netbanking": { + "enabled": true, + "instrument": [ + { + "type": "retail", + "bank": [ + "hdfc", + "sbin", + "utib", + "icic", + "scbl", + "yesb" + ] + } + ] + }, + "wallet": { + "enabled": true, + "instrument": [ + "airtelmoney", + "freecharge", + "jiomoney", + "olamoney", + "payzapp", + "mobikwik" + ] + }, + "upi": { + "enabled": true, + "instrument": [ + "upi" + ] + } + } + }, + "requirements": [ + { + "field_reference": "individual_proof_of_address", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/stakeholders/{stakeholderId}/documents", + "status": "required", + "reason_code": "document_missing" + }, + { + "field_reference": "individual_proof_of_identification", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/stakeholders/{stakeholderId}/documents", + "status": "required", + "reason_code": "document_missing" + }, + { + "field_reference": "business_proof_of_identification", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/documents", + "status": "required", + "reason_code": "document_missing" + }, + { + "field_reference": "settlements.beneficiary_name", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/products/acc_prd_HEgNpywUFctQ9e", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "settlements.account_number", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/products/acc_prd_HEgNpywUFctQ9e", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "settlements.ifsc_code", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/products/acc_prd_HEgNpywUFctQ9e", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "contact_name", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "name", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/stakeholders", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "customer_facing_business_name", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0", + "status": "required", + "reason_code": "field_missing" + }, + { + "field_reference": "kyc.pan", + "resolution_url": "/accounts/acc_HQVlm3bnPmccC0/stakeholders", + "status": "required", + "reason_code": "field_missing" + } + ], + "tnc":{ + "id": "tnc_IgohZaDBHRGjPv", + "accepted": true, + "accepted_at": 1641550798 + }, + "id": "acc_prd_HEgNpywUFctQ9e", + "account_id": "acc_HQVlm3bnPmccC0", + "product_name": "payment_gateway", + "activation_status": "needs_clarification", + "requested_at": 1625478849 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch Terms and Conditions for a Sub-Merchant +```js + +var productName = "payments"; + +instance.products.fetchTnc(productName); +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|-------------|---------------------------------------------| +| productName* | string | The product family for which the relevant product to be requested for the sub-merchant. Possible value is `payments` | + +**Response:** +```json +{ + "entity": "tnc_map", + "product_name": "payments", + "id": "tnc_map_HjOVhIdpVDZ0FB", + "tnc": { + "terms": "https://razorpay.com/terms", + "privacy": "https://razorpay.com/privacy", + "agreement": "https://razorpay.com/agreement" + }, + "last_published_at": 1640589653 +} +``` + +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/partners/product-configuration/)** \ No newline at end of file diff --git a/documents/stakeholders.md b/documents/stakeholders.md new file mode 100644 index 00000000..b426bbd1 --- /dev/null +++ b/documents/stakeholders.md @@ -0,0 +1,336 @@ +## Stakeholders + +### Create an Stakeholder +```js + +var accountId = "acc_GP4lfNA0iIMn5B"; + +instance.stakeholders.create(accountId, { + "percentage_ownership": 10, + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "relationship": { + "director": true, + "executive": false + }, + "phone": { + "primary": "7474747474", + "secondary": "7474747474" + }, + "addresses": { + "residential": { + "street": "506, Koramangala 1st block", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": "560034", + "country": "IN" + } + }, + "kyc": { + "pan": "AVOPB1111K" + }, + "notes": { + "random_key_by_partner": "random_value" + } +}); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| email | string | The sub-merchant's business email address. | +| name* | string | The stakeholder's name as per the PAN card. The maximum length is 255 characters. | +| percentage_ownership | float | The stakeholder's ownership of the business in percentage. Only two decimal places are allowed. For example, `87.55`. The maximum length is 100 characters. | +| relationship | boolean | The stakeholder's relationship with the account’s business. | +| phone | object | All keys listed [here](https://razorpay.com/docs/api/partners/stakeholder/#create-a-stakeholder) are supported | +| addresses | object | All keys listed [here](https://razorpay.com/docs/api/partners/stakeholder/#create-a-stakeholder) are supported | +| kyc | object | All keys listed [here](https://razorpay.com/docs/api/partners/stakeholder/#create-a-stakeholder) are supported | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "entity": "stakeholder", + "relationship": { + "director": true + }, + "phone": { + "primary": "7474747474", + "secondary": "7474747474" + }, + "notes": { + "random_key_by_partner": "random_value" + }, + "kyc": { + "pan": "AVOPB1111K" + }, + "id": "sth_GLGgm8fFCKc92m", + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "percentage_ownership": 10, + "addresses": { + "residential": { + "street": "506, Koramangala 1st block", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": "560034", + "country": "IN" + } + } +} +``` + +------------------------------------------------------------------------------------------------------- + +### Edit Stakeholder +```js +var accountId = "acc_GP4lfNA0iIMn5B"; +var stakeholderId = "sth_GOQ4Eftlz62TSL"; + +instance.stakeholders.edit(accountId, stakeholderId, { + "percentage_ownership": 20, + "name": "Gauri Kumar", + "relationship": { + "director": false, + "executive": true + }, + "phone": { + "primary": "9898989898", + "secondary": "9898989898" + }, + "addresses": { + "residential": { + "street": "507, Koramangala 1st block", + "city": "Bangalore", + "state": "Karnataka", + "postal_code": "560035", + "country": "IN" + } + }, + "kyc": { + "pan": "AVOPB1111J" + }, + "notes": { + "random_key_by_partner": "random_value2" + } +}); +``` + +**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. | +| name | string | The stakeholder's name as per the PAN card. The maximum length is 255 characters. | +| percentage_ownership | float | The stakeholder's ownership of the business in percentage. Only two decimal places are allowed. For example, `87.55`. The maximum length is 100 characters. | +| relationship | boolean | The stakeholder's relationship with the account’s business. | +| phone | object | All keys listed [here](https://razorpay.com/docs/api/partners/stakeholder/#update-a-stakeholder) are supported | +| addresses | object | All keys listed [here](https://razorpay.com/docs/api/partners/stakeholder/#update-a-stakeholder) are supported | +| kyc | object | All keys listed [here](https://razorpay.com/docs/api/partners/stakeholder/#update-a-stakeholder) are supported | +| notes | object | A key-value pair | + +**Response:** +```json +{ + "id": "acc_GP4lfNA0iIMn5B", + "type": "standard", + "status": "created", + "email": "gauri@example.org", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "addresses": { + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road-1", + "city": "Bengalore", + "state": "KARNATAKA", + "postal_code": "560034", + "country": "IN" + } + } + }, + "notes": [], + "created_at": 1610603081, + "phone": "9000090000", + "reference_id": "randomId", + "business_type": "partnership", + "legal_business_name": "Acme Corp", + "customer_facing_business_name": "ABCD Ltd" +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch all accounts +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +instance.stakeholders.all(accountId); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. | + +**Response:** +```json +{ + "entity": "collection", + "items": [ + { + "id": "GZ13yPHLJof9IE", + "entity": "stakeholder", + "relationship": { + "director": true + }, + "phone": { + "primary": "9000090000", + "secondary": "9000090000" + }, + "notes": { + "random_key_by_partner": "random_value" + }, + "kyc": { + "pan": "AVOPB1111K" + }, + "name": "Gaurav Kumar", + "email": "gaurav.kumar@acme.org", + "percentage_ownership": 10, + "addresses": { + "residential": { + "street": "506, Koramangala 1st block", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": "560034", + "country": "in" + } + } + } + ], + "count": 1 +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch an stakeholder +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +var stakeholderId = "sth_GOQ4Eftlz62TSL"; + +instance.stakeholders.fetch(accountId, 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 +{ + "entity": "stakeholder", + "relationship": { + "director": true + }, + "phone": { + "primary": "9000090000", + "secondary": "9000090000" + }, + "notes": { + "random_key_by_partner": "random_value2" + }, + "kyc": { + "pan": "AVOPB1111J" + }, + "id": "sth_GOQ4Eftlz62TSL", + "name": "Gauri Kumar", + "email": "gauri@example.com", + "percentage_ownership": 20, + "addresses": { + "residential": { + "street": "507, Koramangala 1st block", + "city": "Bangalore", + "state": "Karnataka", + "postal_code": "560035", + "country": "in" + } + } +} +``` + +------------------------------------------------------------------------------------------------------- +------------------------------------------------------------------------------------------------------- + +### Upload stakeholders documents +```js +const formData ={ + 'file': { + 'value': fs.createReadStream('/Users/your_name/Downloads/sample_uploaded.jpeg'), + 'options': { + 'filename': 'sample_uploaded.jpeg', + 'contentType': null + } + }, + 'document_type': 'aadhar_front' +} + +instance.stakeholders.uploadStakeholderDoc("acc_M0zieyllPeEvsi","sth_M0zjeiVOLRJRPW", formData) +``` + +**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 +```js +instance.stakeholders.fetchStakeholderDoc("acc_LryDIBIjBDbOWy", "sth_M0zjeiVOLRJRPW"); +``` + +**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** +
+
+**For reference click [here](https://razorpay.com/docs/api/partners/stakeholder)** \ No newline at end of file diff --git a/documents/token.md b/documents/token.md index 1ab1ac7c..34ba1f04 100644 --- a/documents/token.md +++ b/documents/token.md @@ -238,6 +238,152 @@ instance.customers.fetchTokens(customerId) } ``` ------------------------------------------------------------------------------------------------------- + +### Create a token + +```js + +instance.tokens.create({ + "customer_id": "cust_1Aa00000000001", + "method": "card", + "card": { + "number": "4111111111111111", + "cvv": "123", + "expiry_month": "12", + "expiry_year": "21", + "name": "Gaurav Kumar" + }, + "authentication": { + "provider": "razorpay", + "provider_reference_id": "pay_123wkejnsakd", + "authentication_reference_number": "100222021120200000000742753928" + }, + "notes": [] +}); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| customerId* | string | The id of the customer to be fetched | +| method* | string | The type of object that needs to be tokenised. Currently, `card` is the only supported value. | +| card* | object | All keys listed [here](https://razorpay.com/docs/partners/aggregators/partner-auth/token-sharing/#create-token-on-behalf-of-a-sub-merchant) are supported +| +| authentication | object | All keys listed [here](https://razorpay.com/docs/partners/aggregators/partner-auth/token-sharing/#create-token-on-behalf-of-a-sub-merchant) are supported | + +**Response:** +```json +{ + "id": "token_IJmat4GwYATMtx", + "entity": "token", + "method": "card", + "card": { + "last4": "1111", + "network": "Visa", + "type": "credit", + "issuer": "IDFB", + "international": false, + "emi": false, + "sub_type": "consumer" + }, + "customer": { + "id": "cust_1Aa00000000001", + "entity": "customer", + "name": "Bob", + "email": "bob@gmail.com", + "contact": "9000090000", + "gstin": null, + "notes": { + "notes_key_1": "Tea, Earl Grey, Hot", + "notes_key_2": "Tea, Earl Grey… decaf." + }, + "created_at": 1658390470 + }, + "expired_at": 1701368999, + "customer_id": "cust_1Aa00000000001", + "compliant_with_tokenisation_guidelines": true, + "status": "active", + "notes": [] +} +``` +------------------------------------------------------------------------------------------------------- + +### Fetch token +```js +instance.tokens.fetch({"id": "token_4lsdksD31GaZ09"}); +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|-------------|---------------------------------------------| +| id* | string | The unique identifier of a sub-merchant account generated by Razorpay. | + +**Response:** +```json +{ + "id": "token_4lsdksD31GaZ09", + "entity": "token", + "customer_id": "cust_1Aa00000000001", + "method": "card", + "card": { + "last4": "3335", + "network": "Visa", + "type": "debit", + "issuer": "HDFC", + "international": false, + "emi": true, + "sub_type": "consumer", + "token_iin": "453335" + }, + "compliant_with_tokenisation_guidelines": true, + "expired_at": 1748716199, + "status": "active", + "status_reason": null, + "notes": [] +} +``` +------------------------------------------------------------------------------------------------------- +### Delete a token +```js +instance.tokens.delete({"id": "token_4lsdksD31GaZ09"}); +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|-------------|---------------------------------------------| +| id* | string | The unique identifier of a sub-merchant account generated by Razorpay. | + +**Response:** +```json +[] +``` +------------------------------------------------------------------------------------------------------- + +### Process a Payment on another PA/PG with Token +```js +instance.tokens.processPaymentOnAlternatePAorPG({"id":"spt_4lsdksD31GaZ09"}); +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|-------------|---------------------------------------------| +| id* | string | The unique identifier of the token whose details are to be fetched. | + +**Response:** +```json +{ + "card": { + "number": "4016981500100002", + "expiry_month" : "12", + "expiry_year" : 2021 + } +} +``` +------------------------------------------------------------------------------------------------------- **PN: * indicates mandatory fields**

diff --git a/documents/webhook.md b/documents/webhook.md new file mode 100644 index 00000000..0c7ec522 --- /dev/null +++ b/documents/webhook.md @@ -0,0 +1,224 @@ +## Webhook + +### Create a Webhook +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +instance.webhooks.create({ + "url": "https://google.com", + "alert_email": "gaurav.kumar@example.com", + "secret": "12345", + "events": [ + "payment.authorized", + "payment.failed", + "payment.captured", + "payment.dispute.created", + "refund.failed", + "refund.created" + ] +}, accountId); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. | +| url* | string | The URL where you receive the webhook payload when an event is triggered. The maximum length is 255 characters. | +| alert_email | string | This is the email address to which notifications must be sent in case of webhook failure. | +| secret | string | A secret for the webhook endpoint that is used to validate that the webhook is from Razorpay. | +| events | string | The required events from the list of Active Events. For example `payment.authorized`, `payment.captured`, `payment.failed`, `payment.dispute.created`, `refund.failed`, `refund.created` and so on. | + +**Response:** +```json +{ + "id": "JebiXkKGYwua5L", + "created_at": 1654605478, + "updated_at": 1654605478, + "service": "beta-api-live", + "owner_id": "JOGUdtKu3dB03d", + "owner_type": "merchant", + "context": [], + "disabled_at": 0, + "url": "https://google.com", + "alert_email": "gaurav.kumar@example.com", + "secret_exists": true, + "entity": "webhook", + "active": true, + "events": [ + "payment.authorized", + "payment.failed", + "payment.captured", + "payment.dispute.created", + "refund.failed", + "refund.created" + ] +} +``` + +------------------------------------------------------------------------------------------------------- + +### Edit Webhook +```js +var webhookId = "HK890egfiItP3H"; + +var accountId = "acc_GP4lfNA0iIMn5B"; + +instance.webhooks.edit({ + "url": "https://www.linkedin.com", + "events": [ + "refund.created" + ] +}, webhookId, accountId); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. | +| webhookId* | string | The unique identifier of the webhook whose details are to be updated | +| url | string | The URL where you receive the webhook payload when an event is triggered. The maximum length is 255 characters. | +| events | string | The required events from the list of Active Events. For example `payment.authorized`, `payment.captured`, `payment.failed`, `payment.dispute.created`, `refund.failed`, `refund.created` and so on. | + +**Response:** +```json +{ + "id": "HK890egfiItP3H", + "created_at": 1623060358, + "updated_at": 1623067148, + "service": "beta-api-test", + "owner_id": "H3kYHQ635sBwXG", + "owner_type": "merchant", + "context": [], + "disabled_at": 0, + "url": "https://www.linkedin.com", + "alert_email": "gaurav.kumar@example.com", + "secret_exists": true, + "entity": "webhook", + "active": true, + "events": [ + "refund.created" + ] +} +``` +------------------------------------------------------------------------------------------------------- + +### Delete an account +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +var webhookId = "HK890egfiItP3H"; + +instance.webhooks.delete(webhookId, accountId); +``` + +**Parameters:** + +| Name | Type | Description | +|---------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account that must be deleted. | +| webhookId* | string | The unique identifier of the webhook whose details are to be updated | + +**Response:** +```json +[] +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch a webhook +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +var webhookId = "HK890egfiItP3H"; + +instance.webhooks.fetch(webhookId, accountId); +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. | +| webhookId* | string | The unique identifier of the webhook whose details are to be updated | + +**Response:** +```json +{ + "id": "HK890egfiItP3H", + "created_at": 1623060358, + "updated_at": 1623060358, + "owner_id": "H3kYHQ635sBwXG", + "owner_type": "merchant", + "context": [], + "disabled_at": 0, + "url": "https://en1mwkqo5ioct.x.pipedream.net", + "alert_email": "gaurav.kumar@example.com", + "secret_exists": true, + "entity": "webhook", + "active": true, + "events": [ + "payment.authorized", + "payment.failed", + "payment.captured", + "payment.dispute.created", + "refund.failed", + "refund.created" + ] +} +``` + +------------------------------------------------------------------------------------------------------- + +### Fetch all Webhooks +```js +var accountId = "acc_GP4lfNA0iIMn5B"; + +instance.webhooks.all({ + "count": 3 +}, accountId); +``` + +**Parameters:** + +| Name | Type | Description | +|-------------|-------------|---------------------------------------------| +| accountId* | string | The unique identifier of a sub-merchant account generated by Razorpay. | +| from | integer | Timestamp, in seconds, from when the webhooks are to be fetched. | +| to | integer | Timestamp, in seconds, till when the webhooks are to be fetched. | +| count | integer | Number of webhooks to be fetched. The default value is `10` and the maximum value is `100`. This can be used for pagination, in combination with `skip`. | +| skip | integer | Number of records to be skipped while fetching the webhooks. This can be used for pagination, in combination with `count`. | + +**Response:** +```json +{ + "id": "HK890egfiItP3H", + "created_at": 1623060358, + "updated_at": 1623060358, + "owner_id": "H3kYHQ635sBwXG", + "owner_type": "merchant", + "context": [], + "disabled_at": 0, + "url": "https://en1mwkqo5ioct.x.pipedream.net", + "alert_email": "gaurav.kumar@example.com", + "secret_exists": true, + "entity": "webhook", + "active": true, + "events": [ + "payment.authorized", + "payment.failed", + "payment.captured", + "payment.dispute.created", + "refund.failed", + "refund.created" + ] +} +``` + +------------------------------------------------------------------------------------------------------- + +**PN: * indicates mandatory fields** +
+
+**For reference click [here](https://razorpay.com/docs/api/partners/webhooks)** \ No newline at end of file diff --git a/lib/api.js b/lib/api.js index 845fc7d2..1d027fb4 100644 --- a/lib/api.js +++ b/lib/api.js @@ -54,37 +54,43 @@ class API { }) } + version = 'v1'; + + getEntityUrl(params){ + return params.hasOwnProperty('version') ? `/${params.version}${params.url}` : `/${this.version}${params.url}` ; + } + get(params, cb) { return nodeify(this.rq.get({ - url: params.url, + url: this.getEntityUrl(params), qs: params.data, }).catch(normalizeError), cb) } - post(params, cb, isNotForm = false) { + post(params, cb) { let request = { - url: params.url, + url: this.getEntityUrl(params), form: params.data }; - if(isNotForm) { + if(params.hasOwnProperty('formData')){ delete request['form']; - request.body = params.data; + request.formData = params.formData; } - + return nodeify(this.rq.post(request).catch(normalizeError), cb); } put(params, cb) { return nodeify(this.rq.put({ - url: params.url, + url: this.getEntityUrl(params), form: params.data }).catch(normalizeError), cb) } patch(params, cb) { let request = { - url: params.url, + url: this.getEntityUrl(params), form: params.data }; @@ -98,7 +104,7 @@ class API { delete(params, cb) { return nodeify(this.rq.delete({ - url: params.url + url: this.getEntityUrl(params) }).catch(normalizeError), cb) } } diff --git a/lib/razorpay.d.ts b/lib/razorpay.d.ts index b1a6428f..83d06394 100644 --- a/lib/razorpay.d.ts +++ b/lib/razorpay.d.ts @@ -16,6 +16,12 @@ import paymentLink from './types/paymentLink' import cards from './types/cards' import { validateWebhookSignature } from "./utils/razorpay-utils" import customers from './types/customers' +import accounts from './types/accounts' +import stakeholders from './types/stakeholders' +import webhooks from './types/webhooks' +import products from './types/products' +import tokens from './types/tokens' +import iins from './types/iins' interface IRazorpayConfig { key_id: string; @@ -29,6 +35,11 @@ declare class Razorpay { constructor(config: IRazorpayConfig) api: API + /** + * Accounts Entity + * @see https://razorpay.com/docs/api/partners/account-onboarding/ + */ + accounts: ReturnType /** * Customers Entity * @see https://razorpay.com/docs/api/customers/ @@ -50,19 +61,19 @@ declare class Razorpay { */ orders: ReturnType /** - * Orders Entity + * Payments Entity * @see https://razorpay.com/docs/api/payments */ payments: ReturnType /** - * Payments Entity + * Transfers Entity * @see https://razorpay.com/docs/api/payments/route/transfers */ transfers: ReturnType /** - * Transfers Entity + * Refunds Entity * @see https://razorpay.com/docs/api/refunds - */ + */ refunds: ReturnType /** * Cards Entity @@ -83,6 +94,11 @@ declare class Razorpay { * @see https://razorpay.com/docs/payments/payment-links/apis */ paymentLink: ReturnType + /** + * Products Entity + * @see https://razorpay.com/docs/payments/payment-links/apis + */ + products: ReturnType /** * Invoices Entity * @see https://razorpay.com/docs/payments/invoices/apis/ @@ -98,6 +114,11 @@ declare class Razorpay { * @see https://razorpay.com/docs/api/payments/subscriptions/#subscriptions */ subscriptions: ReturnType + /** + * Stakeholders Entity + * @see https://razorpay.com/docs/api/partners/stakeholder#stakeholders-entity + */ + stakeholders: ReturnType /** * Settlements Entity * @see https://razorpay.com/docs/api/settlements @@ -108,6 +129,21 @@ declare class Razorpay { * @see https://razorpay.com/docs/api/payments/smart-collect/ */ virtualAccounts: ReturnType + /** + * Webhook Entity + * @see https://razorpay.com/docs/api/partners/webhooks/#webhook-entity + */ + webhooks: ReturnType + /** + * Tokens Entity + * @see https://razorpay.com/docs/payments/payment-methods/cards/token-hq/merchant-requestor-with-network-tokens/apis/#1-tokenise-cards + */ + tokens: ReturnType + /** + * Iins Entity + * @see https://razorpay.com/docs/api/payments/cards/iin-api/#iin-entity + */ + iins: ReturnType } export = Razorpay diff --git a/lib/razorpay.js b/lib/razorpay.js index ed6babc1..dbbd1d86 100644 --- a/lib/razorpay.js +++ b/lib/razorpay.js @@ -25,7 +25,7 @@ class Razorpay { this.key_secret = key_secret this.api = new API({ - hostUrl: 'https://api.razorpay.com/v1/', + hostUrl: 'https://api.razorpay.com', ua: `razorpay-node@${Razorpay.VERSION}`, key_id, key_secret, @@ -36,22 +36,28 @@ class Razorpay { addResources() { Object.assign(this, { + accounts : require('./resources/accounts')(this.api), + stakeholders : require('./resources/stakeholders')(this.api), payments : require('./resources/payments')(this.api), refunds : require('./resources/refunds')(this.api), orders : require('./resources/orders')(this.api), customers : require('./resources/customers')(this.api), transfers : require('./resources/transfers')(this.api), + tokens : require('./resources/tokens')(this.api), virtualAccounts: require('./resources/virtualAccounts')(this.api), invoices : require('./resources/invoices')(this.api), + iins : require('./resources/iins')(this.api), paymentLink : require('./resources/paymentLink')(this.api), plans : require('./resources/plans')(this.api), + products : require('./resources/products')(this.api), subscriptions : require('./resources/subscriptions')(this.api), addons : require('./resources/addons')(this.api), settlements : require('./resources/settlements')(this.api), qrCode : require('./resources/qrCode')(this.api), fundAccount : require('./resources/fundAccount')(this.api), items : require('./resources/items')(this.api), - cards : require('./resources/cards')(this.api) + cards : require('./resources/cards')(this.api), + webhooks : require('./resources/webhooks')(this.api) }) } } diff --git a/lib/resources/accounts.js b/lib/resources/accounts.js new file mode 100644 index 00000000..95d3076b --- /dev/null +++ b/lib/resources/accounts.js @@ -0,0 +1,61 @@ +'use strict'; + +const { normalizeNotes } = require('../utils/razorpay-utils') + +module.exports = function (api) { + + const BASE_URL = "/accounts"; + + return { + create(params, callback) { + let { notes, ...rest } = params + let data = Object.assign(rest, normalizeNotes(notes)); + + return api.post({ + version: 'v2', + url: `${BASE_URL}`, + data: data + }, callback); + }, + + edit(accountId, params, callback) { + let { notes, ...rest } = params + let data = Object.assign(rest, normalizeNotes(notes)); + + return api.patch({ + version: 'v2', + url: `${BASE_URL}/${accountId}`, + data: data + }, callback); + }, + + fetch(accountId, callback) { + return api.get({ + version: 'v2', + url: `${BASE_URL}/${accountId}`, + }, callback); + }, + + delete(accountId, callback) { + return api.delete({ + version: 'v2', + url: `${BASE_URL}/${accountId}`, + }, callback); + }, + + uploadAccountDoc(accountId, params, callback) { + return api.post({ + version: 'v2', + url: `${BASE_URL}/${accountId}/documents`, + formData: params + }, callback); + }, + + fetchAccountDoc(accountId, callback) { + return api.get({ + version: 'v2', + url: `${BASE_URL}/${accountId}/documents`, + }, callback); + } + } +} \ No newline at end of file diff --git a/lib/resources/cards.js b/lib/resources/cards.js index aeafb278..37c08ad6 100644 --- a/lib/resources/cards.js +++ b/lib/resources/cards.js @@ -12,5 +12,12 @@ module.exports = function (api) { url: `/cards/${itemId}` }, callback) }, + + requestCardReference(params, callback) { + return api.post({ + url: `/cards/fingerprints`, + data: params + }, callback) + } } } diff --git a/lib/resources/iins.js b/lib/resources/iins.js new file mode 100644 index 00000000..a6dc7a9c --- /dev/null +++ b/lib/resources/iins.js @@ -0,0 +1,14 @@ +'use strict'; + +module.exports = function (api) { + + const BASE_URL = "/iins"; + + return { + fetch(tokenIin, callback) { + return api.get({ + url: `${BASE_URL}/${tokenIin}`, + }, callback); + }, + } +} \ No newline at end of file diff --git a/lib/resources/orders.js b/lib/resources/orders.js index f06930df..f6e00b8f 100644 --- a/lib/resources/orders.js +++ b/lib/resources/orders.js @@ -49,15 +49,10 @@ module.exports = function (api) { }, create(params = {}, callback) { - let isNotForm = false let { amount, currency, receipt, partial_payment,payment_capture, notes, method, ...otherParams } = params currency = currency || 'INR' - if(params.hasOwnProperty("first_payment_min_amount")){ - isNotForm = true - } - let data = Object.assign({ amount, currency, @@ -71,7 +66,7 @@ module.exports = function (api) { return api.post({ url: '/orders', data - }, callback, isNotForm) + }, callback) }, edit(orderId, params = {}, callback) { diff --git a/lib/resources/payments.js b/lib/resources/payments.js index 5959a90d..9a7d29eb 100644 --- a/lib/resources/payments.js +++ b/lib/resources/payments.js @@ -4,7 +4,8 @@ const Promise = require("promise"); const { normalizeDate, normalizeBoolean, normalizeNotes } = require('../utils/razorpay-utils') -const ID_REQUIRED_MSG = '`payment_id` is mandatory'; +const ID_REQUIRED_MSG = '`payment_id` is mandatory', + BASE_URL = '/payments'; module.exports = function (api) { return { @@ -29,7 +30,7 @@ module.exports = function (api) { skip = Number(skip) || 0 return api.get({ - url: '/payments', + url: `${BASE_URL}`, data: { from, to, @@ -52,7 +53,7 @@ module.exports = function (api) { } return api.get({ - url: `/payments/${paymentId}`, + url: `${BASE_URL}/${paymentId}`, data: { expand } @@ -86,13 +87,13 @@ module.exports = function (api) { } return api.post({ - url: `/payments/${paymentId}/capture`, + url: `${BASE_URL}/${paymentId}/capture`, data: payload }, callback) }, createPaymentJson(params, callback) { - let url = `payments/create/json`, + let url = `${BASE_URL}/create/json`, {...rest} = params, data = Object.assign(rest); return api.post({ @@ -105,7 +106,7 @@ module.exports = function (api) { let data = Object.assign(rest, normalizeNotes(notes)) return api.post({ - url: '/payments/create/recurring', + url: `${BASE_URL}/create/recurring`, data }, callback) }, @@ -119,7 +120,7 @@ module.exports = function (api) { let data = Object.assign(normalizeNotes(notes)) return api.patch({ - url: `/payments/${paymentId}`, + url: `${BASE_URL}/${paymentId}`, data }, callback) }, @@ -133,7 +134,7 @@ module.exports = function (api) { let data = Object.assign(otherParams, normalizeNotes(notes)) return api.post({ - url: `/payments/${paymentId}/refund`, + url: `${BASE_URL}/${paymentId}/refund`, data }, callback) }, @@ -151,7 +152,7 @@ module.exports = function (api) { */ let { from, to, count, skip } = params, - url = `/payments/${paymentId}/refunds`; + url = `${BASE_URL}/${paymentId}/refunds`; return api.get({ url, @@ -176,7 +177,7 @@ module.exports = function (api) { } return api.get({ - url: `/payments/${paymentId}/refunds/${refundId}` + url: `${BASE_URL}/${paymentId}/refunds/${refundId}` }, callback) }, @@ -196,7 +197,7 @@ module.exports = function (api) { } return api.get({ - url: '/payments/' + paymentId + '/transfers' + url: `${BASE_URL}/${paymentId}/transfers` }, callback); }, transfer(paymentId, params = {}, callback) { @@ -215,7 +216,7 @@ module.exports = function (api) { }) } return api.post({ - url: `/payments/${paymentId}/transfers`, + url: `${BASE_URL}/${paymentId}/transfers`, data }, callback) }, @@ -228,7 +229,7 @@ module.exports = function (api) { } return api.get({ - url: `/payments/${paymentId}/bank_transfer` + url: `${BASE_URL}/${paymentId}/bank_transfer` }, callback); }, fetchCardDetails(paymentId, callback) { @@ -239,13 +240,13 @@ module.exports = function (api) { } return api.get({ - url: `/payments/${paymentId}/card` + url: `${BASE_URL}/${paymentId}/card` }, callback); }, fetchPaymentDowntime(callback) { return api.get({ - url: `/payments/downtimes` + url: `${BASE_URL}/downtimes` }, callback); }, fetchPaymentDowntimeById(downtimeId, callback) { @@ -265,7 +266,7 @@ module.exports = function (api) { } return api.get({ - url: '/payments/downtimes/'+ downtimeId + url: `${BASE_URL}/downtimes/${downtimeId}` }, callback); }, otpGenerate(paymentId, callback){ @@ -285,7 +286,7 @@ module.exports = function (api) { } return api.post({ - url: `/payments/${paymentId}/otp_generate` + url: `${BASE_URL}/${paymentId}/otp_generate` }, callback); }, otpSubmit(paymentId, params={}, callback){ @@ -306,7 +307,7 @@ module.exports = function (api) { } return api.post({ - url: `/payments/${paymentId}/otp/submit`, + url: `${BASE_URL}/${paymentId}/otp/submit`, data : params }, callback); }, @@ -328,7 +329,7 @@ module.exports = function (api) { } return api.post({ - url: `/payments/${paymentId}/otp/resend` + url: `${BASE_URL}/${paymentId}/otp/resend` }, callback); }, @@ -343,7 +344,7 @@ module.exports = function (api) { * @return {Promise} */ - let url = `payments/create/upi`, + let url = `${BASE_URL}/create/upi`, {...rest} = params, data = Object.assign(rest); return api.post({ @@ -363,7 +364,7 @@ module.exports = function (api) { * @return {Promise} */ - let url = `payments/validate/vpa`, + let url = `${BASE_URL}/validate/vpa`, {...rest} = params, data = Object.assign(rest); return api.post({ @@ -381,7 +382,7 @@ module.exports = function (api) { * @return {Promise} */ - let url = `methods`; + let url = `/methods`; return api.get({ url }, callback); diff --git a/lib/resources/products.js b/lib/resources/products.js new file mode 100644 index 00000000..9e5327ff --- /dev/null +++ b/lib/resources/products.js @@ -0,0 +1,48 @@ +'use strict'; + +const { normalizeBoolean } = require('../utils/razorpay-utils') + +module.exports = function (api) { + + const BASE_URL = "/accounts"; + + return { + requestProductConfiguration(accountId, params, callback) { + + let { tnc_accepted, ...rest } = params + let data = Object.assign({tnc_accepted: normalizeBoolean(tnc_accepted), ...rest}) + + return api.post({ + version: 'v2', + url: `${BASE_URL}/${accountId}/products`, + data: data + }, callback); + }, + + edit(accountId, productId, params, callback) { + + let { tnc_accepted, ...rest } = params + let data = Object.assign({tnc_accepted: normalizeBoolean(tnc_accepted), ...rest}) + + return api.patch({ + version: 'v2', + url: `${BASE_URL}/${accountId}/products/${productId}`, + data: data + }, callback); + }, + + fetch(accountId, productId, callback) { + return api.get({ + version: 'v2', + url: `${BASE_URL}/${accountId}/products/${productId}` + }, callback); + }, + + fetchTnc(productName, callback) { + return api.get({ + version: 'v2', + url: `/products/${productName}/tnc` + }, callback); + } + } +} \ No newline at end of file diff --git a/lib/resources/stakeholders.js b/lib/resources/stakeholders.js new file mode 100644 index 00000000..d75649bc --- /dev/null +++ b/lib/resources/stakeholders.js @@ -0,0 +1,84 @@ +'use strict'; + +const { normalizeNotes, normalizeBoolean } = require('../utils/razorpay-utils') + +module.exports = function (api) { + + const BASE_URL = "/accounts"; + + return { + create(accountId, params, callback) { + + let { relationship, notes, ...rest } = params + + if(params.hasOwnProperty('relationship')){ + if(params.relationship.hasOwnProperty('executive')){ + relationship.executive = normalizeBoolean(params.relationship.executive) + } + + if(params.relationship.hasOwnProperty('director')){ + relationship.director = normalizeBoolean(params.relationship.director) + } + } + + let data = Object.assign({relationship: relationship}, normalizeNotes(notes), rest); + + return api.post({ + version: 'v2', + url: `${BASE_URL}/${accountId}/stakeholders`, + data: data + }, callback); + }, + + edit(accountId, stakeholderId, params, callback) { + let { notes, relationship, ...rest } = params + + if(params.hasOwnProperty('relationship')){ + if(params.relationship.hasOwnProperty('executive')){ + relationship.executive = normalizeBoolean(params.relationship.executive) + } + + if(params.relationship.hasOwnProperty('director')){ + relationship.director = normalizeBoolean(params.relationship.director) + } + } + + let data = Object.assign({relationship: relationship}, normalizeNotes(notes), rest); + + return api.patch({ + version: 'v2', + url: `${BASE_URL}/${accountId}/stakeholders/${stakeholderId}`, + data: data + }, callback); + }, + + fetch(accountId, stakeholderId, callback) { + return api.get({ + version: 'v2', + url: `${BASE_URL}/${accountId}/stakeholders/${stakeholderId}`, + }, callback); + }, + + all(accountId, callback) { + return api.get({ + version: 'v2', + url: `${BASE_URL}/${accountId}/stakeholders`, + }, callback) + }, + + uploadStakeholderDoc(accountId, stakeholderId, params, callback) { + return api.post({ + version: 'v2', + url: `${BASE_URL}/${accountId}/stakeholders/${stakeholderId}/documents`, + formData: params + }, callback); + }, + + fetchStakeholderDoc(accountId, stakeholderId, callback) { + return api.get({ + version: 'v2', + url: `${BASE_URL}/${accountId}/stakeholders/${stakeholderId}/documents`, + }, callback); + } + } +} \ No newline at end of file diff --git a/lib/resources/subscriptions.js b/lib/resources/subscriptions.js index 3bc39491..affbf318 100644 --- a/lib/resources/subscriptions.js +++ b/lib/resources/subscriptions.js @@ -305,7 +305,7 @@ module.exports = function subscriptionsApi (api) { }, normalizeNotes(notes)) return api.post({ - url: 'subscription_registration/auth_links', + url: '/subscription_registration/auth_links', data }, callback) } diff --git a/lib/resources/tokens.js b/lib/resources/tokens.js new file mode 100644 index 00000000..28e939b7 --- /dev/null +++ b/lib/resources/tokens.js @@ -0,0 +1,41 @@ +'use strict'; + +const { normalizeNotes } = require('../utils/razorpay-utils') + +module.exports = function (api) { + + const BASE_URL = "/tokens"; + + return { + create(params, callback) { + let { notes, ...rest } = params + let data = Object.assign(rest, normalizeNotes(notes)); + + return api.post({ + url: `${BASE_URL}`, + data: data + }, callback); + }, + + fetch(params, callback) { + return api.post({ + url: `${BASE_URL}/fetch`, + data: params + }, callback); + }, + + delete(params, callback) { + return api.post({ + url: `${BASE_URL}/delete`, + data: params + }, callback); + }, + + processPaymentOnAlternatePAorPG(params, callback) { + return api.post({ + url: `${BASE_URL}/service_provider_tokens/token_transactional_data`, + data: params + }, callback); + } + } +} \ No newline at end of file diff --git a/lib/resources/transfers.js b/lib/resources/transfers.js index 61c826e3..69c363ff 100644 --- a/lib/resources/transfers.js +++ b/lib/resources/transfers.js @@ -93,7 +93,7 @@ module.exports = function (api) { fetchSettlements(callback) { return api.get({ - url: `transfers?expand[]=recipient_settlement` + url: `/transfers?expand[]=recipient_settlement` }, callback) } } diff --git a/lib/resources/webhooks.js b/lib/resources/webhooks.js new file mode 100644 index 00000000..41b66f46 --- /dev/null +++ b/lib/resources/webhooks.js @@ -0,0 +1,84 @@ +'use strict'; + +const { normalizeDate } = require('../utils/razorpay-utils') + +module.exports = function (api) { + + const BASE_URL = "/accounts"; + + return { + create(params, accountId, callback) { + + let payload = { url: '/webhooks', data: params } + + if (accountId) { + payload = { + version: 'v2', + url: `${BASE_URL}/${accountId}/webhooks`, + data: params + } + } + return api.post(payload, callback); + }, + + edit(params, webhookId, accountId, callback) { + + if (accountId && webhookId) { + return api.patch({ + version: 'v2', + url: `${BASE_URL}/${accountId}/webhooks/${webhookId}`, + data: params + }, callback); + } + + return api.put({ + url: `/webhooks/${webhookId}`, + data: params + }, callback); + }, + + all(params={}, accountId, callback) { + let { from, to, count, skip } = params; + + if (from) { + from = normalizeDate(from) + } + + if (to) { + to = normalizeDate(to) + } + + count = Number(count) || 10 + skip = Number(skip) || 0 + + let data = {...params, from, to, count, skip } + + if (accountId) { + return api.get({ + version: 'v2', + url: `${BASE_URL}/${accountId}/webhooks/`, + data: data + }, callback); + } + + return api.get({ + url: `/webhooks`, + data: data + }, callback); + }, + + fetch(webhookId, accountId, callback) { + return api.get({ + version: 'v2', + url: `${BASE_URL}/${accountId}/webhooks/${webhookId}` + }, callback); + }, + + delete(webhookId, accountId, callback) { + return api.delete({ + version: 'v2', + url: `${BASE_URL}/${accountId}/webhooks/${webhookId}` + }, callback); + }, + } +} \ No newline at end of file diff --git a/lib/types/accounts.d.ts b/lib/types/accounts.d.ts new file mode 100644 index 00000000..2d7a0063 --- /dev/null +++ b/lib/types/accounts.d.ts @@ -0,0 +1,295 @@ +import { IMap, INormalizeError, PartialOptional, RazorpayPaginationOptions } from "./api"; +import * as fs from 'fs'; + +export declare namespace Accounts { + interface RazorpayAccountBaseRequestBody { + /** + * The sub-merchant's business email address. + */ + email: string; + /** + * The business details of the sub-merchant's account + */ + profile: Profile; + /** + * The sub-merchant's business phone number. The minimum length is 8 characters and the maximum length is 15. + */ + phone: string | number; + /** + * The account type. Possible value is standard + */ + type?: string; + /** + * The type of business operated by the sub-merchant. + */ + business_type: string; + /** + * Partner's external account reference id. The minimum length is 1 character and the maximum length is 512. + */ + reference_id?: string; + /** + * The name of the sub-merchant's business. For example, Acme Corp. The minimum length is 4 characters and the maximum length is 200. + */ + legal_business_name: string; + /** + * The sub-merchant billing label as it appears on the Razorpay Dashboard. The minimum length is 1 character and the maximum length is 255. + */ + customer_facing_business_name?: string; + /** + * The legal details about the sub-merchant's business. + */ + legal_info?: { + /** + * Valid PAN number details of the sub-merchant's business. + */ + pan?: string; + /** + * Valid GSTIN number details of the sub-merchant. + */ + gst?: string; + /** + * CIN is for Private Limited and Public Limited, whereas LLPIN is for LLP business type. + */ + cin?: string; + } + /** + * The website/app details of the sub-merchant's business. + */ + apps?: { + /** + * The websites for the sub-merchant's business. A minimum of 1 website is required. + */ + websites: string[]; + /** + * Android app details + */ + android: AppDetails[]; + /** + * iOS app details + */ + ios: AppDetails[]; + } + /** + * The branding details of the sub-merchant's business. + */ + brand?: { + /** + * The color code of sub-merchant's business brand. This is a 6-character hex code (Regex: [a-fA-F0-9]{6}). + */ + color?: string; + } + /** + * The name of the contact. The minimum length is 4 and the maximum length is 255 characters. + */ + contact_name: string; + /** + * Options available for contact support + */ + contact_info?: ContactInfoSupport; + /** + * Contains user-defined fields stored by the partner for reference purposes. + */ + notes?: IMap; + } + + type AppDetails = { + url: string; + name: string; + } + + interface Profile { + /** + * The business category of the sub-merchant. + */ + category?: string; + /** + * The business sub-category of the sub-merchant. + */ + subcategory?: string; + /** + * This parameter has been deprecated. Pass the description using the `business_model` parameter. + */ + description?: string; + /** + * Details of sub-merchant's address. + */ + addresses?: { + /** + * Details of the sub-merchant's registered address. + */ + registered?: ProfileAddresses; + /** + * Details of the sub-merchant's operational address. + */ + operation?: ProfileAddresses; + } + /** + * The business description. The character limit between 1-255 characters. + */ + business_model?: string; + } + + interface ProfileAddresses { + /** + * Address, line 1. The maximum length is 100 characters. + */ + street1: string; + /** + * Address, line 2. The maximum length is 100 characters. + */ + street2: string; + /** + * The city. The maximum length is 100 characters. + */ + city: string; + /** + * The state. The minimum length is 2 and the maximum length is 32. + */ + state: string; + /** + * The postal code. This should be exactly 6 characters. + */ + postal_code: number | string; + /** + * he country. The minimum length is 2 and the maximum length is 64. This can either be a country + * code in capital letters or the full name of the country in lower case letters. + */ + country: string; + } + + interface ContactInfoSupport { + /** + * The type of contact support. + */ + chargeback?: SupportType; + /** + * The type of contact support. + */ + refund?: SupportType; + /** + * The type of contact support. + */ + support?: SupportType; + } + + type SupportType = { + /** + * The email id of chargeback POC. + */ + email?: string; + /** + * The phone number of chargeback POC + */ + phone?: string; + /** + * The URL of chargeback policy. + */ + policy_url?: string; + } + + interface RazorpayAccountCreateRequestBody extends RazorpayAccountBaseRequestBody { } + + interface RazorpayAccountUpdateRequestBody extends Partial> { } + + interface RazorpayAccount extends RazorpayAccountBaseRequestBody { + /** + * The unique identifier of the account. + */ + id: string; + /** + * Unix timestamp that indicates when the merchant account was activated. This parameter has null value till the account is activated. + */ + activated_at: number; + /** + * Indicates the payments acceptance status of the merchant account. + */ + live: boolean; + /** + * Indicates the settlements status of the merchant account. + */ + hold_funds: boolean; + /** + * The status of the account. + */ + status: string; + /** + * Unix timestamp, when the account was created. + */ + created_at: number; + } + + interface FileCreateParams { + file: { + value: fs.ReadStream; + options: { + filename: string; + contentType: string | null; + }; + }; + document_type: string; + } + + interface RazorpayAccountDocuments { + business_proof_of_identification: [ + { + type: string; + url: string; + } + ] + } +} + +declare function accounts(api: any): { + /** + * Creates a account + * + * @param params - Check [doc](https://razorpay.com/docs/api/partners/account-onboarding#create-an-account) for required params + * + */ + create(params: Accounts.RazorpayAccountCreateRequestBody): Promise + create(params: Accounts.RazorpayAccountCreateRequestBody, callback: (err: INormalizeError | null, data: Accounts.RazorpayAccount) => void): void; + /** + * Fetches a account given Account ID + * + * @param accountId - The unique identifier of the account. + * + */ + fetch(accountId: string): Promise + fetch(accountId: string, callback: (err: INormalizeError | null, data: Accounts.RazorpayAccount) => void): void; + /** + * Update an account + * + * @param accountId - The unique identifier of the account. + * @param params - Check [doc](https://razorpay.com/docs/api/partners/account-onboarding#update-an-account) for required params + * + */ + edit(accountId: string, params: Accounts.RazorpayAccountUpdateRequestBody): Promise + edit(accountId: string, params: Accounts.RazorpayAccountUpdateRequestBody, callback: (err: INormalizeError | null, data: Accounts.RazorpayAccount) => void): void; + /** + * Delete an account + * + * @param accountId - The unique identifier of the account. + * + */ + delete(accountId: string): Promise + delete(accountId: string, callback: (err: INormalizeError | null, data: Promise) => void): void; + /** + * Upload account documents + * + * @param accountId - The unique identifier of the account. + * @param params - Check [doc](https://razorpay.com/docs/api/partners/upload-document#request-parameters) for required params + * + */ + uploadAccountDoc(accountId: string, params: Accounts.FileCreateParams): Promise + uploadAccountDoc(accountId: string, params: Accounts.FileCreateParams, callback: (err: INormalizeError | null, data: Accounts.RazorpayAccountDocuments) => void): void; + /** + * Fetches account documents + * + * @param accountId - The unique identifier of the account. + * + */ + fetchAccountDoc(accountId: string): Promise + fetchAccountDoc(accountId: string, callback: (err: INormalizeError | null, data: Accounts.RazorpayAccountDocuments) => void): void; +} + +export default accounts \ No newline at end of file diff --git a/lib/types/api.d.ts b/lib/types/api.d.ts index fa5c8078..1a7e4619 100644 --- a/lib/types/api.d.ts +++ b/lib/types/api.d.ts @@ -10,7 +10,8 @@ interface IOption { interface IPayload { url: string; - data: T; + data?: T; + formData?: T; } export type INotify = 'email' | 'sms' diff --git a/lib/types/cards.d.ts b/lib/types/cards.d.ts index e28e3a0a..f49cfa1d 100644 --- a/lib/types/cards.d.ts +++ b/lib/types/cards.d.ts @@ -1,6 +1,42 @@ import { Payments } from "./payments"; import { INormalizeError } from "./api"; +export declare namespace Cards { + interface RazorpayCardReferenceNumberBaseRequest { + /** + * The tokenised card number whose PAR or network reference id should be retrieved. + */ + number: string; + /** + * Determines if the card is saved as a token. possible value is `true` or `false` + */ + tokenised?: boolean; + } + + interface RazorpayCardReferenceTokenBaseRequest { + /** + * The token whose PAR or network reference id should be retrieved. + */ + token: string; + } + + interface RazorpayCardReference { + /** + * The card network. + */ + network?: Network; + payment_account_reference: string | null; + network_reference_id: string | null; + card_reference_number?: string | null; + provider: string; + } + + type Network = + | 'Mastercard' + | 'RuPay' + | 'Visa' +} + declare function cards(api: any): { /** * Fetch a card given a Card ID @@ -10,6 +46,14 @@ declare function cards(api: any): { */ fetch(cardId: string): Promise fetch(cardId: string, callback: (err: INormalizeError | null, data: Payments.RazorpayCard) => void): void + /** + * Retrieve the card reference number for a specific card: + * + * @param params - The card/token number whose PAR or network reference id should be retrieved. + * + */ + requestCardReference(params: Cards.RazorpayCardReferenceNumberBaseRequest | Cards.RazorpayCardReferenceTokenBaseRequest): Promise + requestCardReference(params: Cards.RazorpayCardReferenceNumberBaseRequest | Cards.RazorpayCardReferenceTokenBaseRequest, callback: (err: INormalizeError | null, data: Cards.RazorpayCardReference) => void): void } diff --git a/lib/types/iins.d.ts b/lib/types/iins.d.ts new file mode 100644 index 00000000..f19cae9e --- /dev/null +++ b/lib/types/iins.d.ts @@ -0,0 +1,109 @@ +import { INormalizeError } from "./api"; + +export declare namespace Iins { + interface RazorpayIin { + /** + * The Issuer Identification Number (IIN). The starting 6 digits of credit or debit card number. + */ + iin: string; + /** + * The name of the entity + */ + entity: string; + /** + * The card network + */ + network: Network | null; + /** + * The card type for the given IIN. The card payment pricing may differ based on the card type. + */ + type: CardType | null; + /** + * The card sub-type for the given IIN. The card payment pricing may differ based on the card sub-type. + */ + sub_type: subType | null; + /** + * The 4-character issuer code unique to each issuing bank in India. For example, `SBIN`. + */ + issuer_code: string; + /** + * The name of the issuing bank. Available for cards issued in India only. For example, `State Bank of India`. + */ + issuer_name: string; + /** + * Determines whether the card is international (issued outside India) or domestic. + * + * `true`: Card issued outside India. + * + * `false`: Card issued within India. + */ + international: boolean; + is_tokenized: boolean; + card_iin: string | null; + /** + * A JSON object which provides information about the applicability of EMI on the IIN. + */ + emi: { + /** + * Determines whether the card is eligible for EMI payments or not. Possible values `true` or `false` + */ + available: boolean; + } + /** + * A JSON object which provides information about the applicability of recurring payments on the IIN. + */ + recurring: { + /** + * Determines whether the card is eligible for recurring payments or not. Possible values `true` or `false` + */ + available: boolean; + } + /** + * Array which lists the possible authentication types for which the IIN is eligible + * + * `type: 3ds`: Indicates that the card IIN supports normal 3ds payments. + * + * `type: otp`: Indicates that the card IIN supports native OTP payments. Native OTP gives you flexibility to + * accept the OTP entered by the cardholder on your screen. + */ + authentication_types: { + type: string; + }[] + } + + type Network = + | 'Visa' + | 'RuPay' + | 'MasterCard' + | 'American Express' + | 'Diners Club' + | 'Bajaj Finserv' + | 'Maestro' + | 'JCB' + | 'Union Pay' + | 'Unknown' + + type CardType = + | 'credit' + | 'debit' + | 'prepaid' + | 'unknown' + + type subType = + | 'consumer' + | 'business' + | 'unknown' +} + +declare function iins(api: any): { + /** + * Fetch the properties of the card using token IIN + * + * @param accountId - The token IIN. + * + */ + fetch(tokenIin: string): Promise + fetch(tokenIin: string, callback: (err: INormalizeError | null, data: Iins.RazorpayIin) => void): void; +} + +export default iins \ No newline at end of file diff --git a/lib/types/payments.d.ts b/lib/types/payments.d.ts index 754a18dd..608893c0 100644 --- a/lib/types/payments.d.ts +++ b/lib/types/payments.d.ts @@ -205,15 +205,31 @@ export declare namespace Payments { /** * Expiry month for card in MM format. */ - expiry_month: number; + expiry_month: string | number; /** * Expiry year for card in YY format. */ - expiry_year: number; + expiry_year: string | number; /** * CVV printed on the back of card. */ - cvv: number; + cvv: string | number; + /** + * The cryptogram value for the token. + */ + cryptogram_value?: string; + /** + * Indicates if the payment is made using tokenised card or actual card. Possible values are `true` or `false` + */ + tokenised?: boolean; + /** + * The name of the aggregator that provided the token + */ + token_provider?: string; + /** + * The last 4 digits of the tokenised card. + */ + last4?: string; } interface RazorpayCardCreateRequest extends RazorpayCardBaseRequestBody { } @@ -478,7 +494,16 @@ export declare namespace Payments { } interface RazorpayPaymentS2SCreateRequestBody extends RazorpayPaymentBaseRequestBody { - card: RazorpayCardS2SMethod; + save:boolean | number; + /** + * Pass the unique token id created when the customer made the first payment. + */ + token?:string; + /** + * Pass the sub-merchant's unique identifier. + */ + account_id?: string; + card: Partial; /** * The customer's IP address. */ @@ -486,7 +511,7 @@ export declare namespace Payments { /** * Referrer header passed by the client's browser. */ - referer: string; + referer?: string; /** * The User-Agent header of the user's browser. * Default value will be passed by Razorpay if not provided by merchant. diff --git a/lib/types/products.d.ts b/lib/types/products.d.ts new file mode 100644 index 00000000..77ac2a9a --- /dev/null +++ b/lib/types/products.d.ts @@ -0,0 +1,268 @@ +import { Orders } from "../../dist/types/orders"; +import { IMap, INormalizeError, PartialOptional, RazorpayPaginationOptions } from "./api"; + +export declare namespace Products { + interface RazorpayProductBaseRequestBody { + /** + * The product(s) to be configured. Possible values: `payment_gateway` or `payment_links` + */ + product_name: string; + /** + * Pass this parameter to accept terms and conditions. Send this parameter along with the ip parameter when the tnc is accepted. + */ + tnc_accepted: boolean; + /** + * he IP address of the merchant while accepting the terms and conditions. Send this parameter along with the `tnc_accepted` parameter when the `tnc` is accepted. + */ + ip: string; + } + + interface RazorpayProductCreateRequestBody extends RazorpayProductBaseRequestBody { } + + interface RazorpayProductUpdateRequestBody extends PartialOptional, 'tnc_accepted' | 'ip'> { + /** + * This denotes the notifications settings + */ + notifications?: Notifications; + /** + * The checkout form of the payment capture + */ + checkout?: Checkout; + /** + * This denotes the payment refund settings + */ + refund?: { + /** + * Speed at which the refund is to be processed + */ + default_refund_speed: string; + } + /** + * The Settlement settings object. + */ + settlements?: Omit; + /** + * Details of the payment method you want to enable for the product. + */ + payment_methods?: PaymentMethods; + } + + interface PaymentMethods { + /** + * The payment method to be enabled. + */ + netbanking: Netbanking; + cards: Cards; + wallet: Wallet; + paylater: Paylater; + upi: Upi; + emi: Emi; + } + + interface Netbanking { + enabled: boolean; + instrument: Instrument[]; + } + + interface Instrument { + type: string; + bank: string[]; + } + + interface Cards { + enabled: boolean; + instrument: InstrumentCard[]; + } + + interface InstrumentCard { + issuer: string; + type: string[]; + } + + interface Wallet { + enabled: boolean; + instrument: string[]; + } + + interface Paylater { + enabled: boolean; + instrument: string[]; + } + + interface Upi { + enabled: boolean; + instrument: string[]; + } + + interface Emi { + enabled: boolean; + instrument: InstrumentEmi[]; + } + + interface InstrumentEmi { + type: string; + partner: string[]; + } + + interface RazorpayProduct extends RazorpayProductBaseRequestBody { + /** + * The configuration of the product requested by the user that is yet to be set as active. + */ + requested_configuration: { + payment_methods: PaymentMethods[]; + } + /** + * The configuration of the product that has been set as active. + */ + active_configuration: ActiveConfiguration; + /** + * The list of requirements to be enabled for this product or some of the configurations under this product. + */ + requirements: Requirement[] + tnc: Tnc; + id: string; + activation_status: string; + account_id: string; + /** + * The Unix timestamp at which the product configuration is requested. + */ + requested_at: number; + } + + interface ActiveConfiguration { + payment_capture: PaymentCapture; + settlements: Settlements; + checkout: Checkout; + refund: { + default_refund_speed: string; + } + notifications: Notifications; + payment_methods: PaymentMethods; + } + + interface PaymentCapture { + mode: string; + refund_speed: string; + automatic_expiry_period: number; + } + + interface Settlements { + account_number: string; + ifsc_code: string; + beneficiary_name: string; + } + + interface Checkout { + theme_color?: string; + flash_checkout?: boolean; + } + + interface Notifications { + /** + * The WhatsApp notifications you receive regarding payments, settlements, daily payment reports, webhooks, etc. + */ + whatsapp?: boolean; + /** + * The SMS notifications you receive regarding payments, settlements, daily payment reports, webhooks, + */ + sms?: boolean; + /** + * he email addresses that will receive notifications regarding + * payments, settlements, daily payment reports, webhooks, and so on. + */ + email?: string[]; + } + + interface Requirement { + /** + * The field which is in issue or missing. The JSON key path in resolution URL. + */ + field_reference: string; + /** + * The URL to address the requirement. The API endpoint to be used for updating missing fields or documents. + */ + resolution_url: string; + /** + * The status of the requirement. + */ + status: string; + /** + * The reason code for showing in the requirement + */ + reason_code: string; + } + + interface Tnc { + id: string; + accepted: boolean; + accepted_at: number; + } + + interface RazorpayProductTnc { + /** + * The name of the entity. + */ + entity: string; + /** + * Determines what business unit the terms and conditions belong to. + */ + product_name: string; + /** + * Unique identifier of the terms and conditions belonging to a specific business unit. + */ + id: string; + /** + * The terms and conditions content. + */ + tnc: ProductsTnc; + /** + * The timestamp in Unix format, when the terms and conditions were created/last updated. + */ + last_published_at: number; + } + + interface ProductsTnc { + terms: string; + privacy: string; + agreement: string; + } +} + +declare function products(api: any): { + /** + * Request a Product Configuration + * + * @param params - Check [doc](https://razorpay.com/docs/api/partners/product-configuration/#request-parameter) for required params + * @param accountId - The unique identifier of the account. + */ + requestProductConfiguration(accountId: string, params: Products.RazorpayProductCreateRequestBody): Promise + requestProductConfiguration(accountId: string, params: Products.RazorpayProductCreateRequestBody, callback: (err: INormalizeError | null, data: Products.RazorpayProduct) => void): void; + /** + * Fetch a Product Configuration + * + * @param accountId - The unique identifier of the account. + * @param productId - The unique identifier of a product. + * + */ + fetch(accountId: string, productId: string): Promise + fetch(accountId: string, productId: string, callback: (err: INormalizeError | null, data: Products.RazorpayProduct) => void): void; + /** + * Update a Product Configuration + * + * @param accountId - The unique identifier of the account. + * @param productId - The unique identifier of a product. + * @param params - Check [doc](https://razorpay.com/docs/api/partners/product-configuration/#update-a-product-configuration) for required params + */ + edit(accountId: string, productId: string, params: Products.RazorpayProductUpdateRequestBody): Promise + edit(accountId: string, productId: string, params: Products.RazorpayProductUpdateRequestBody, callback: (err: INormalizeError | null, data: Products.RazorpayProduct) => void): void; + /** + * Fetch Terms and Conditions for a Sub-Merchant + * + * @param productName - The product family for which the relevant product to be requested for the sub-merchant. Possible value is `payments`. + * + */ + fetchTnc(productName: string): Promise + fetchTnc(productName: string, callback: (err: INormalizeError | null, data: Products.RazorpayProductTnc) => void): void; +} + +export default products \ No newline at end of file diff --git a/lib/types/stakeholders.d.ts b/lib/types/stakeholders.d.ts new file mode 100644 index 00000000..73496708 --- /dev/null +++ b/lib/types/stakeholders.d.ts @@ -0,0 +1,174 @@ +import { Accounts } from "./accounts"; +import { IMap, INormalizeError, PartialOptional, RazorpayPaginationOptions } from "./api"; +import * as fs from "fs"; + +export declare namespace Stakeholders { + interface RazorpayStakeholderBaseRequestBody { + /** + * The stakeholder's relationship with the account’s business. + */ + relationship?: RelationShip; + /** + * The stakeholder's phone number. + */ + phone: Phone; + /** + * The type of document required to establish the stakeholder's identity. + */ + kyc: { + /** + * The PAN number of the stakeholder. + */ + pan: string; + } + /** + * The stakeholder's name as per the PAN card. + */ + name: string; + /** + * The stakeholder's email address. + */ + email: string; + /** + * The stakeholder's ownership of the business in percentage. + */ + percentage_ownership?: number; + /** + * Details of stakeholder's address. + */ + addresses?: { + residential: Partial
; + } + /** + * Contains user-defined fields stored by the partner for reference purposes. + */ + notes?: IMap; + } + + + interface RazorpayStakeholderCreateRequestBody extends RazorpayStakeholderBaseRequestBody { } + + interface RazorpayStakeholderUpdateRequestBody extends Partial> { } + + interface RazorpayStakeholder extends RazorpayStakeholderBaseRequestBody { + /** + * The unique identifier of the stakeholder whose details are created. + */ + id: string; + /** + * Indicates the type of entity. + */ + entity: string; + } + + interface Address extends Omit { + street: string; + } + + type Phone = { + /** + * The primary contact number of the stakeholder. The minimum length is 8 characters and the maximum length is 11. + */ + primary?: string; + /** + * The secondary contact number of the stakeholder. The minimum length is 8 characters and the maximum length is 11. + */ + secondary?: string; + } + + type RelationShip = { + /** + * This attribute is set to `true` if the stakeholder is a director of the account's legal entity + */ + executive?: boolean; + /** + * This attribute is set to `true` if the stakeholder is an executive of the account's legal entity. + */ + director?: boolean; + } + + interface FileCreateParams { + file: { + value: fs.ReadStream; + options: { + filename: string; + contentType: string | null; + }; + }; + document_type: string; + } + + interface RazorpayStakeholderDocuments { + individual_proof_of_address: [ + { + type: string; + url: string; + } + ] + } +} + +declare function stakeholders(api: any): { + /** + * Creates a stakeholder + * + * @param accountId - The unique identifier of the account. + * @param params - Check [doc](https://razorpay.com/docs/api/partners/stakeholder#create-a-stakeholder) for required params + * + */ + create(accountId: string, params: Stakeholders.RazorpayStakeholderCreateRequestBody): Promise + create(accountId: string, params: Stakeholders.RazorpayStakeholderCreateRequestBody, callback: (err: INormalizeError | null, data: Stakeholders.RazorpayStakeholder) => void): void; + /** + * Fetches a account given Account ID + * + * @param accountId - The unique identifier of the account. + * @param stakeholderId - The unique identifier of the stakeholder id. + * + */ + fetch(accountId: string, stakeholderId: string): Promise + fetch(accountId: string, stakeholderId: string, callback: (err: INormalizeError | null, data: Stakeholders.RazorpayStakeholder) => void): void; + /** + * Update an stakeholder + * + * @param accountId - The unique identifier of the account. + * @param params - Check [doc](https://razorpay.com/docs/api/partners/stakeholder#update-a-stakeholder) for required params + * + */ + edit(accountId: string, stakeholderId: string, params: Stakeholders.RazorpayStakeholderUpdateRequestBody): Promise + edit(accountId: string, stakeholderId: string, params: Stakeholders.RazorpayStakeholderUpdateRequestBody, callback: (err: INormalizeError | null, data: Stakeholders.RazorpayStakeholder) => void): void; + /** + * Fetch all Stakeholders + * + * @param accountId - The unique identifier of the account. + * + */ + all(accountId: string): Promise<{ + entity: string, + items: Array + }> + all(accountId: string, callback: (err: INormalizeError | null, data: { + entity: string, + count: number, + items: Array + }) => void): void; + /** + * Upload stakeholder documents + * + * @param accountId - The unique identifier of the account. + * @param stakeholderId - The unique identifier of the stakeholder id. + * + */ + uploadStakeholderDoc(accountId: string, stakeholderId: string, params: Stakeholders.FileCreateParams): Promise + uploadStakeholderDoc(accountId: string, stakeholderId: string, params: Stakeholders.FileCreateParams, callback: (err: INormalizeError | null, data: Stakeholders.RazorpayStakeholderDocuments) => void): void; + /** + * Fetches stakeholder documents + * + * @param accountId - The unique identifier of the account. + * @param stakeholderId - The unique identifier of the stakeholder id. + * + */ + fetchStakeholderDoc(accountId: string, stakeholderId: string): Promise + fetchStakeholderDoc(accountId: string, stakeholderId: string, callback: (err: INormalizeError | null, data: Stakeholders.RazorpayStakeholderDocuments) => void): void; +} + +export default stakeholders \ No newline at end of file diff --git a/lib/types/tokens.d.ts b/lib/types/tokens.d.ts index 6a84ed9f..1a8a228a 100644 --- a/lib/types/tokens.d.ts +++ b/lib/types/tokens.d.ts @@ -1,4 +1,5 @@ -import { IMap } from "./api"; +import { IMap, INormalizeError } from "./api"; +import { Customers } from "./customers"; import { Invoices } from "./invoices"; import { Orders } from "./orders"; import { Payments } from "./payments"; @@ -23,7 +24,7 @@ export declare namespace Tokens { */ frequency: string } - + interface RazorpayTokenEmandate { /** * Emandate type used to make the authorization payment @@ -55,7 +56,7 @@ export declare namespace Tokens { first_payment_amount?: number; } - interface RazorpayTokenNach extends RazorpayTokenEmandate{ + interface RazorpayTokenNach extends RazorpayTokenEmandate { /** * Additional information to be printed on the NACH form that your customer will sign. */ @@ -109,7 +110,39 @@ export declare namespace Tokens { } } - interface RazorpayBankAccount extends Orders.RazorpayBankAccount, Orders.RazorpayBankAccountBaseRequestBody {} + interface RazorpayBankAccount extends Orders.RazorpayBankAccount, Orders.RazorpayBankAccountBaseRequestBody { } + + interface RazorpayTokenBaseRequestBody { + customer_id?: string + /** + * The type of object that needs to be tokenised. Currently, card is the only supported value. + */ + method: string + /** + * The card details. + */ + card: Payments.RazorpayCardBaseRequestBody + /** + * Token authentication details. + */ + authentication: Authentication + notes?: IMap | []; + } + + interface Authentication { + /** + * The platform through which authentication was processed + */ + provider: Provider + /** + * The unique payment identifier of the payment used to collect AFA on any PA/PG. + */ + provider_reference_id: string + /** + * A unique reference number generated when authentication is initiated. + */ + authentication_reference_number: string + } interface RazorpayToken { /** @@ -197,16 +230,119 @@ export declare namespace Tokens { * The minimum value is 100 (₹1 ), and the maximum value is 1500000 (₹15,000). */ max_amount?: number; - status?:string; + /** + * The overall status for the token. + */ + status?: Status; + error_code?: string; error_description?: string | null; internal_error_code?: string | null; source: string | null; notes?: IMap; compliant_with_tokenisation_guidelines?: boolean; + customer_id?: string; + customer: Customers.RazorpayCustomer; /** * Details of the customer's billing address. */ billing_address: Invoices.RazorpayInvoiceAddress; } - -} \ No newline at end of file + + interface RazorpyProcessPayment { + token_number: string + /** + * The token cryptogram value. + */ + cryptogram_value: string + /** + * A dynamic 4-digit number printed on the front of the Amex card. This cvv should + * be passed in the CVV field to your PA/PG for processing the payment. + */ + cvv: string + /** + * The token expiry month in `mm` format. + */ + token_expiry_month: number + /** + * The token expiry year in `yyyy` format. + */ + token_expiry_year: number + /** + * The details of the card + */ + card: { + /** + * The card number. + */ + number: string + /** + * The expiry month of the card in `mm` format. + */ + expiry_month: string + /** + * The expiry year of the card in `yyyy` format. + */ + expiry_year: number + } + } + + type Status = + | 'initiated' + | 'active' + | 'suspended' + | 'deactivated' + + type Provider = + | 'amex' + | 'axis_migs' + | 'cashfree' + | 'ccavenue' + | 'cybersource' + | 'first_data' + | 'fss' + | 'hdfc' + | 'mpgs' + | 'paysecure' + | 'paytm' + | 'payu' + | 'zakpay' + | 'razorpay' + +} + +declare function tokens(api: any): { + /** + * Create a token + * + * @param params - Check [doc](https://razorpay.com/docs/payments/payment-methods/cards/token-hq/merchant-requestor/apis/#11-create-a-token) for required params + * + */ + create(params: Tokens.RazorpayTokenBaseRequestBody): Promise + create(params: Tokens.RazorpayTokenBaseRequestBody, callback: (err: INormalizeError | null, data: Tokens.RazorpayToken) => void): void; + /** + * Fetch card properties of an existing token + * + * @param params - Check [doc](https://razorpay.com/docs/payments/payment-methods/cards/token-hq/merchant-requestor/apis/#12-fetch-card-properties-of-an-existing-token) for required params + * + */ + fetch(params: { id: string}): Promise + fetch(params: { id: string}, callback: (err: INormalizeError | null, data: Tokens.RazorpayToken) => void): void; + /** + * Delete a token + * + * @param params - Check [doc](https://razorpay.com/docs/payments/payment-methods/cards/token-hq/merchant-requestor/apis/#13-delete-a-token) for required params + * + */ + delete(params: { id: string}): Promise<[]> + delete(params: { id: string}, callback: (err: INormalizeError | null, data: []) => void): void; + /** + * Process a payment on another PA/PG with token created on razorpay + * + * @param params - Check [doc](https://razorpay.com/docs/payments/payment-methods/cards/token-hq/merchant-requestor-with-network-tokens/apis/#3-process-a-payment-on-another-pa-pg) for required params + * + */ + processPaymentOnAlternatePAorPG(params: { id: string}): Promise + processPaymentOnAlternatePAorPG(params: { id: string}, callback: (err: INormalizeError | null, data: Tokens.RazorpyProcessPayment) => void): void; +} + +export default tokens \ No newline at end of file diff --git a/lib/types/transfers.d.ts b/lib/types/transfers.d.ts index 3da4b77b..b21a07a7 100644 --- a/lib/types/transfers.d.ts +++ b/lib/types/transfers.d.ts @@ -33,7 +33,7 @@ export declare namespace Transfers { * `1` - Put the transfer settlement on hold * `0` - Releases the settlement. */ - on_hold: boolean | 0 | 1; + on_hold?: boolean | 0 | 1; /** * Timestamp, in Unix, that indicates until when the settlement of the transfer must be put on hold. * If no value is passed, the settlement is put on hold indefinitely. diff --git a/lib/types/webhooks.d.ts b/lib/types/webhooks.d.ts new file mode 100644 index 00000000..8fef4f3d --- /dev/null +++ b/lib/types/webhooks.d.ts @@ -0,0 +1,113 @@ +import { IMap, INormalizeError, PartialOptional, RazorpayPaginationOptions } from "./api"; + +export declare namespace Webhooks { + interface RazorpayWebhookBaseRequestBody { + /** + * The URL where you receive the webhook payload when an event is triggered. + */ + url: string; + /** + * This is the email address to which notifications must be sent in case of webhook failure. + */ + alert_email?: string; + /** + * A secret for the webhook endpoint that is used to validate that the webhook is from Razorpay. + */ + secret?: string; + /** + * The required events from the list of Active Events. + */ + events: any; + /** + * Indicates the status of webhook. + */ + active?: string; + } + + interface RazorpayWebhookCreateRequestBody extends RazorpayWebhookBaseRequestBody { } + + interface RazorpayWebhookUpdateRequestBody extends RazorpayWebhookBaseRequestBody { } + + interface RazorpayWebhook extends RazorpayWebhookBaseRequestBody { + /** + * The unique identifier of the created webhook. + */ + id: string; + /** + * Indicates the type of entity + */ + entity: string; + /** + * The unique identifier generated by Razorpay for the sub-merchant who will receive the webhooks. For example, in this case, it will be `account_id` passed in the API URL. + */ + owner_id: string; + owner_type: string; + context: string[]; + disabled_at: number; + service: boolean; + /** + * This attribute is set to `true` if a secret password has been set for the webhook endpoint. If no secret is sent in the request, this parameter does not appear in the response code. + */ + secret_exists: boolean; + /** + * Unix timestamp, when the webhook was created. + */ + created_at: number; + updated_at: number; + } +} + +declare function webhooks(api: any): { + /** + * Creates a webhook + * + * @param params - Check [doc](https://razorpay.com/docs/api/partners/webhooks/#create-a-webhook) for required params + * @param accountId - The unique identifier of the account. + */ + create(params: Webhooks.RazorpayWebhookCreateRequestBody, accountId?: string): Promise + create(params: Webhooks.RazorpayWebhookCreateRequestBody, accountId: string | null, callback: (err: INormalizeError | null, data: Webhooks.RazorpayWebhook) => void): void; + /** + * Fetches a webhook + * + * @param webhookId - The unique identifier of the webhook whose details are to be retrieved. + * @param accountId - The unique identifier of the account. + * + */ + fetch(webhookId:string, accountId: string): Promise + fetch(webhookId:string, accountId: string, callback: (err: INormalizeError | null, data: Webhooks.RazorpayWebhook) => void): void; + /** + * Fetch all webhooks + * + * @param accountId - The unique identifier of the account. + * + */ + all(params?: RazorpayPaginationOptions, accountId?: string, ): Promise<{ + entity: string, + items: Array + }> + all(params: RazorpayPaginationOptions, accountId: string | null, callback: (err: INormalizeError | null, data: { + entity: string, + count: number, + items: Array + }) => void): void; + /** + * Update an account + * + * @param params - Check [doc](https://razorpay.com/docs/api/partners/webhooks/#update-a-webhook) for required params + * @param webhookId - The unique identifier of the webhook whose details are to be retrieved. + * @param accountId - The unique identifier of the account. + */ + edit(params: Webhooks.RazorpayWebhookUpdateRequestBody, webhookId: string, accountId?: string, ): Promise + edit(params: Webhooks.RazorpayWebhookUpdateRequestBody, webhookId: string, accountId: string | null, callback: (err: INormalizeError | null, data: Webhooks.RazorpayWebhook) => void): void; + /** + * Delete an webhook + * + * @param webhookId - The unique identifier of the webhook whose details are to be retrieved. + * @param accountId - The unique identifier of the account. + * + */ + delete(webhookId: string, accountId: string): Promise<[]> + delete(webhookId: string, accountId: string, callback: (err: INormalizeError | null, data: []) => void): void; +} + +export default webhooks \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e5f6d1d3..b62383e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "razorpay", - "version": "2.8.5", + "version": "2.8.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "razorpay", - "version": "2.8.5", + "version": "2.8.6", "license": "MIT", "dependencies": { "@types/request-promise": "^4.1.48", diff --git a/test/mocker.js b/test/mocker.js index 042575f0..ed578baf 100644 --- a/test/mocker.js +++ b/test/mocker.js @@ -22,9 +22,9 @@ Mocker.prototype.mock = function(params) { let { url, method = 'GET', requestBody, replyWithError, ignoreParseBody } = params let status = replyWithError ? 400 : 200 let requestQueryParams - + let version = params.hasOwnProperty('version')? params.version : this.version nock(this.host) - .intercept(normalizeUrl(`/${this.version}/${url}`), method) + .intercept(normalizeUrl(`/${version}/${url}`), method) .query((qp) => { requestQueryParams = qp return true diff --git a/test/resources/accounts.spec.js b/test/resources/accounts.spec.js new file mode 100644 index 00000000..d95d7621 --- /dev/null +++ b/test/resources/accounts.spec.js @@ -0,0 +1,187 @@ +'use strict' + +const chai = require('chai') +const { assert } = chai +const rzpInstance = require('../razorpay') +const mocker = require('../mocker') +const equal = require('deep-equal') + +let mockRequest = { + "email": "gauriagain.kumar@example.org", + "phone": "9000090000", + "legal_business_name": "Acme Corp", + "business_type": "partnership", + "customer_facing_business_name": "Example", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "description": "Healthcare E-commerce platform", + "addresses": { + "operation": { + "street1": "507, Koramangala 6th block", + "street2": "Kormanagala", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560047, + "country": "IN" + }, + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560034, + "country": "IN" + } + }, + "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." + }, + "legal_info": { + "pan": "AAACL1234C", + "gst": "18AABCU9603R1ZM" + }, + "brand": { + "color": "FFFFFF" + }, + "notes": { + "internal_ref_id": "123123" + }, + "contact_name": "Gaurav Kumar", + "contact_info": { + "chargeback": { + "email": "cb@example.org" + }, + "refund": { + "email": "cb@example.org" + }, + "support": { + "email": "support@example.org", + "phone": "9999999998", + "policy_url": "https://www.google.com" + } + }, + "apps": { + "websites": [ + "https://www.example.org" + ], + "android": [ + { + "url": "playstore.example.org", + "name": "Example" + } + ], + "ios": [ + { + "url": "appstore.example.org", + "name": "Example" + } + ] + } +} + +const BASE_URL = '/accounts', + API_VERSION = 'v2', + TEST_ACCOUNT_ID = 'acc_GRWKk7qQsLnDjX'; + +describe('ACCOUNTS', () => { + it('Create an account', (done) => { + + mocker.mock({ + version: API_VERSION, + url: `${BASE_URL}`, + method: 'POST' + }) + + rzpInstance.accounts.create(mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts`, + 'Create account request url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.email, + mockRequest.email + ), + 'param are passed in request body' + ) + done() + }) + }) + + it('Edit Account', (done) => { + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}`, + method: 'PATCH' + }) + + rzpInstance.accounts.edit(TEST_ACCOUNT_ID, mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}`, + 'Edit account request url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.email, + mockRequest.email + ), + 'All params are passed in request body' + ) + done() + }) + }) + + it('Account fetch', (done) => { + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}` + }) + + rzpInstance.accounts.fetch(TEST_ACCOUNT_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}`, + 'Fetch account url formed correctly' + ) + done() + }) + }) + + it('Delete an account ', (done) => { + + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}`, + method: 'DELETE' + }) + + rzpInstance.accounts.delete(TEST_ACCOUNT_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}`, + 'Delete account url formed correctly' + ) + done() + }) + }) + + it('fetch account document ', (done) => { + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}/documents`, + }) + + rzpInstance.accounts.fetchAccountDoc(TEST_ACCOUNT_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/documents`, + 'Delete account url formed correctly' + ) + done() + }) + }) +}) diff --git a/test/resources/iins.spec.js b/test/resources/iins.spec.js new file mode 100644 index 00000000..b42e997b --- /dev/null +++ b/test/resources/iins.spec.js @@ -0,0 +1,100 @@ +'use strict' + +const chai = require('chai') +const { assert } = chai +const rzpInstance = require('../razorpay') +const mocker = require('../mocker') +const equal = require('deep-equal') + +let mockRequest = { + "email": "gauriagain.kumar@example.org", + "phone": "9000090000", + "legal_business_name": "Acme Corp", + "business_type": "partnership", + "customer_facing_business_name": "Example", + "profile": { + "category": "healthcare", + "subcategory": "clinic", + "description": "Healthcare E-commerce platform", + "addresses": { + "operation": { + "street1": "507, Koramangala 6th block", + "street2": "Kormanagala", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560047, + "country": "IN" + }, + "registered": { + "street1": "507, Koramangala 1st block", + "street2": "MG Road", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": 560034, + "country": "IN" + } + }, + "business_model": "Online Clothing ( men, women, ethnic, modern ) fashion and lifestyle, accessories, t-shirt, shirt, track pant, shoes." + }, + "legal_info": { + "pan": "AAACL1234C", + "gst": "18AABCU9603R1ZM" + }, + "brand": { + "color": "FFFFFF" + }, + "notes": { + "internal_ref_id": "123123" + }, + "contact_name": "Gaurav Kumar", + "contact_info": { + "chargeback": { + "email": "cb@example.org" + }, + "refund": { + "email": "cb@example.org" + }, + "support": { + "email": "support@example.org", + "phone": "9999999998", + "policy_url": "https://www.google.com" + } + }, + "apps": { + "websites": [ + "https://www.example.org" + ], + "android": [ + { + "url": "playstore.example.org", + "name": "Example" + } + ], + "ios": [ + { + "url": "appstore.example.org", + "name": "Example" + } + ] + } +} + +const BASE_URL = '/iins', + TEST_TOKEN_IIN = '412345'; + +describe('IINS', () => { + it('fetch the properties of the card using token IIN', (done) => { + mocker.mock({ + url: `/${BASE_URL}/${TEST_TOKEN_IIN}`, + }) + + rzpInstance.iins.fetch(TEST_TOKEN_IIN).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v1/iins/${TEST_TOKEN_IIN}`, + 'fetch card url formed correctly' + ) + done() + }) + }) +}) diff --git a/test/resources/paymentLink.spec.js b/test/resources/paymentLink.spec.js index b4154d85..cb3a73d0 100644 --- a/test/resources/paymentLink.spec.js +++ b/test/resources/paymentLink.spec.js @@ -51,8 +51,7 @@ describe("PAYMENTLINK", () => { }; mocker.mock({ url: `/payment_links`, - method: 'POST', - ignoreParseBody: true + method: 'POST' }) rzpInstance.paymentLink.create(params).then((response) => { diff --git a/test/resources/products.spec.js b/test/resources/products.spec.js new file mode 100644 index 00000000..715e16ac --- /dev/null +++ b/test/resources/products.spec.js @@ -0,0 +1,109 @@ +'use strict' + +const chai = require('chai') +const { assert } = chai +const rzpInstance = require('../razorpay') +const mocker = require('../mocker') +const equal = require('deep-equal') + +const BASE_URL = '/accounts', + API_VERSION = 'v2', + TEST_ACCOUNT_ID = 'acc_GRWKk7qQsLnDjX', + TEST_PRODUCT_ID = 'acc_prd_HEgNpywUFctQ9f', + PRODUCT_NAME = 'payments'; + +describe('PRODUCTS', () => { + it('Create an account', (done) => { + const mockRequest = { + "product_name": "payment_gateway", + "tnc_accepted": true, + "ip": "233.233.233.234" + } + + mocker.mock({ + version: API_VERSION, + url: `${BASE_URL}/${TEST_ACCOUNT_ID}/products`, + method: 'POST' + }) + + rzpInstance.products.requestProductConfiguration(TEST_ACCOUNT_ID, mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/products`, + 'Request a Product Configuration url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.product_name, + mockRequest.product_name + ), + 'param are passed in request body' + ) + done() + }) + }) + + it('Update a Product Configuration', (done) => { + const mockRequest = { + "notifications": { + "email": [ + "gaurav.kumar@example.com", + "acd@gmail.com" + ] + }, + "checkout": { + "theme_color": "#528FFF" + }, + "refund": { + "default_refund_speed": "optimum" + }, + "settlements": { + "account_number": "1234567890", + "ifsc_code": "HDFC0000317", + "beneficiary_name": "Gaurav Kumar" + }, + "tnc_accepted": true, + "ip": "233.233.233.234" + } + + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}/products/${TEST_PRODUCT_ID}`, + method: 'PATCH' + }) + + rzpInstance.products.edit(TEST_ACCOUNT_ID, TEST_PRODUCT_ID, mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/products/${TEST_PRODUCT_ID}`, + 'update product configuration request url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.tnc_accepted, + mockRequest.tnc_accepted + ), + 'All params are passed in request body' + ) + done() + }) + }) + + it('fetch terms & condition', (done) => { + mocker.mock({ + version: API_VERSION, + url: `/products/${PRODUCT_NAME}/tnc` + }) + + rzpInstance.products.fetchTnc(PRODUCT_NAME).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/products/${PRODUCT_NAME}/tnc`, + 'Fetch account url formed correctly' + ) + done() + }) + }) +}) diff --git a/test/resources/stakeholders.spec.js b/test/resources/stakeholders.spec.js new file mode 100644 index 00000000..c2f3a972 --- /dev/null +++ b/test/resources/stakeholders.spec.js @@ -0,0 +1,143 @@ +'use strict' + +const chai = require('chai') +const { assert } = chai +const rzpInstance = require('../razorpay') +const mocker = require('../mocker') +const equal = require('deep-equal') + +let mockRequest = { + "percentage_ownership": 10, + "name": "Gaurav Kumar", + "email": "gaurav.kumar@example.com", + "relationship": { + "director": true, + "executive": false + }, + "phone": { + "primary": "7474747474", + "secondary": "7474747474" + }, + "addresses": { + "residential": { + "street": "506, Koramangala 1st block", + "city": "Bengaluru", + "state": "Karnataka", + "postal_code": "560034", + "country": "IN" + } + }, + "kyc": { + "pan": "AVOPB1111K" + }, + "notes": { + "random_key_by_partner": "random_value" + } +} + +const BASE_URL = '/accounts', + API_VERSION = 'v2', + TEST_ACCOUNT_ID = 'acc_GRWKk7qQsLnDjX', + TEST_STAKEHOLDER_ID = 'sth_GOQ4Eftlz62TSL'; + +describe('STAKEHOLDERS', () => { + it('Create an stakeholder', (done) => { + + mocker.mock({ + version: API_VERSION, + url: `${BASE_URL}/${TEST_ACCOUNT_ID}/stakeholders`, + method: 'POST' + }) + + rzpInstance.stakeholders.create(TEST_ACCOUNT_ID, mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/stakeholders`, + 'Create stakeholder request url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.email, + mockRequest.email + ), + 'param are passed in request body' + ) + done() + }) + }) + + it('Edit Stakerholder', (done) => { + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}/stakeholders/${TEST_STAKEHOLDER_ID}`, + method: 'PATCH' + }) + + rzpInstance.stakeholders.edit(TEST_ACCOUNT_ID, TEST_STAKEHOLDER_ID, mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/stakeholders/${TEST_STAKEHOLDER_ID}`, + 'Edit stakeholder request url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.email, + mockRequest.email + ), + 'All params are passed in request body' + ) + done() + }) + }) + + it('Stakeholder fetch', (done) => { + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}/stakeholders/${TEST_STAKEHOLDER_ID}` + }) + + rzpInstance.stakeholders.fetch(TEST_ACCOUNT_ID, TEST_STAKEHOLDER_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/stakeholders/${TEST_STAKEHOLDER_ID}`, + 'Fetch stakeholder url formed correctly' + ) + done() + }) + }) + + it('Get all stakeholders ', (done) => { + + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}/stakeholders` + }) + + rzpInstance.stakeholders.all(TEST_ACCOUNT_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/stakeholders`, + 'Fetch all stakeholder url formed correctly' + ) + done() + }) + }) + + it('fetch stakeholder document ', (done) => { + mocker.mock({ + version: API_VERSION, + url: `/${BASE_URL}/${TEST_ACCOUNT_ID}/stakeholders/${TEST_STAKEHOLDER_ID}/documents`, + }) + + rzpInstance.stakeholders.fetchStakeholderDoc(TEST_ACCOUNT_ID, TEST_STAKEHOLDER_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/stakeholders/${TEST_STAKEHOLDER_ID}/documents`, + 'Delete account url formed correctly' + ) + done() + }) + }) +}) diff --git a/test/resources/token.spec.js b/test/resources/token.spec.js new file mode 100644 index 00000000..a1621c6c --- /dev/null +++ b/test/resources/token.spec.js @@ -0,0 +1,97 @@ +'use strict' + +const chai = require('chai') +const { assert } = chai +const rzpInstance = require('../razorpay') +const mocker = require('../mocker') +const equal = require('deep-equal') + +let mockRequest = { + "customer_id": "cust_1Aa00000000001", + "method": "card", + "card": { + "number": "4111111111111111", + "cvv": "123", + "expiry_month": "12", + "expiry_year": "21", + "name": "Gaurav Kumar" + }, + "authentication": { + "provider": "razorpay", + "provider_reference_id": "pay_123wkejnsakd", + "authentication_reference_number": "100222021120200000000742753928" + }, + "notes": [] + } + +const BASE_URL = '/tokens', + API_VERSION = 'v2'; + +describe('TOKENS', () => { + it('Create an token', (done) => { + + mocker.mock({ + url: `${BASE_URL}`, + method: 'POST' + }) + + rzpInstance.tokens.create(mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v1/tokens`, + 'Create token request url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.customer_id, + mockRequest.customer_id + ), + 'param are passed in request body' + ) + done() + }) + }) + + it('fetch card properties', (done) => { + + const mockRequest = { + id: 'token_4lsdksD31GaZ09' + } + + mocker.mock({ + url: `/${BASE_URL}/fetch`, + method: 'POST' + }) + + rzpInstance.tokens.fetch(mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v1/tokens/fetch`, + 'Fetch account url formed correctly' + ) + done() + }) + }) + + it('delete token', (done) => { + + const mockRequest = { + id: 'token_4lsdksD31GaZ09' + } + + mocker.mock({ + url: `/${BASE_URL}/delete`, + method: 'POST' + }) + + rzpInstance.tokens.delete(mockRequest).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v1/tokens/delete`, + 'Fetch account url formed correctly' + ) + done() + }) + }) +}) diff --git a/test/resources/webhooks.spec.js b/test/resources/webhooks.spec.js new file mode 100644 index 00000000..3e582d51 --- /dev/null +++ b/test/resources/webhooks.spec.js @@ -0,0 +1,141 @@ +'use strict' + +const chai = require('chai') +const { assert } = chai +const rzpInstance = require('../razorpay') +const mocker = require('../mocker') +const equal = require('deep-equal') +const { getDateInSecs } = require('../../dist/utils/razorpay-utils') + +let mockRequest = { + "url": "https://google.com", + "alert_email": "gaurav.kumar@example.com", + "secret": "12345", + "events": [ + "payment.authorized", + "payment.failed", + "payment.captured", + "payment.dispute.created", + "refund.failed", + "refund.created" + ] + } + +const BASE_URL = '/accounts', + API_VERSION = 'v2', + TEST_ACCOUNT_ID = 'acc_GRWKk7qQsLnDjX', + TEST_WEBHOOK_ID = 'HK890egfiItP3H' + +describe('WEBHOOKS', () => { + it('Create an webhook', (done) => { + + mocker.mock({ + version: API_VERSION, + url: `${BASE_URL}/${TEST_ACCOUNT_ID}/webhooks`, + method: 'POST' + }) + + rzpInstance.webhooks.create(mockRequest, TEST_ACCOUNT_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/webhooks`, + 'Create webhook request url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.url, + mockRequest.url + ), + 'param are passed in request body' + ) + done() + }) + }) + + it('Edit webhook', (done) => { + + const mockParam = { + "url": "https://www.linkedin.com", + "events": [ + "refund.created" + ] + } + + mocker.mock({ + version: API_VERSION, + url: `${BASE_URL}/${TEST_ACCOUNT_ID}/webhooks/${TEST_WEBHOOK_ID}`, + method: 'PATCH' + }) + + rzpInstance.webhooks.edit(mockParam, TEST_WEBHOOK_ID, TEST_ACCOUNT_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/webhooks/${TEST_WEBHOOK_ID}`, + 'Edit webhook request url formed' + ) + + assert.ok( + equal( + response.__JUST_FOR_TESTS__.requestBody.url, + mockParam.url + ), + 'All params are passed in request body' + ) + done() + }) + }) + + it('Webhook fetch', (done) => { + mocker.mock({ + version: API_VERSION, + url: `${BASE_URL}/${TEST_ACCOUNT_ID}/webhooks/${TEST_WEBHOOK_ID}` + }) + + rzpInstance.webhooks.fetch(TEST_WEBHOOK_ID, TEST_ACCOUNT_ID).then((response) => { + assert.equal( + response.__JUST_FOR_TESTS__.url, + `/v2/accounts/${TEST_ACCOUNT_ID}/webhooks/${TEST_WEBHOOK_ID}`, + 'Fetch webhooks url formed correctly' + ) + done() + }) + }) + + // it('Fetch all webhooks', (done) => { + // let fromDate = 'Aug 25, 2016' + // let toDate = 'Aug 30, 2016' + // let fromDateInSecs = getDateInSecs(fromDate) + // let toDateInSecs = getDateInSecs(toDate) + // let expectedParams = { + // from: fromDateInSecs, + // to: toDateInSecs, + // count: 25, + // skip: 5 + // } + + // mocker.mock({ + // version: API_VERSION, + // url: `${BASE_URL}/${TEST_WEBHOOK_ID}/webhooks?count=1` + // }) + + // rzpInstance.webhooks.all({ + // from: fromDate, + // to: toDate, + // count: 25, + // skip: 5 + // },TEST_ACCOUNT_ID).then((response) => { + // assert.ok(equal( + // response.__JUST_FOR_TESTS__.requestQueryParams, + // expectedParams + // ), 'from & to dates are converted to ms & authorized to binary') + + // // assert.equal( + // // response.__JUST_FOR_TESTS__.url, + // // `/v2/orders?from=${fromDateInSecs}&to=${toDateInSecs}&count=25&skip=5&authorized=1&receipt=testreceiptid`, + // // 'Params are appended as part of request' + // // ) + // done() + // }) + // }) +})