Introduction

PayOnRamp payment gateway facilitates payments between end users and merchants. We provide users and merchants with payment methods: UPI, Bank Transfer, INR to crypto, and Crypto to Crypto. With a simple configuration/toggle capability, it can serve different options for different merchants based on their business needs, operating country/local region laws, compliances, etc.

Our payment gateway provides merchants with two types of integration options:

  1. Web-SDK Integration
  2. API Integration

These integration methods offer flexibility and convenience for merchants to seamlessly integrate our payment gateway into their applications, catering to their specific needs and preferences. Whether you prefer a ready-to-use user interface or want to build a custom solution, we have you covered.

Web-SDK Integration

Web-SDK Integration provides a user-friendly and streamlined approach for merchants to incorporate our payment gateway functionality into their web-based applications.

Upon integrating our web-SDK-based solution, you can launch the CPGModal, a user-friendly interface that empowers users to perform transactions quickly and efficiently. The CPGModal provides a seamless and intuitive experience, ensuring a user-friendly interface for users to complete their transactions securely.

Using the CPGModal, merchants can seamlessly allow their users to initiate deposits or withdraw requests.

BUY Flow

To provide flexibility and customization, our Web-SDK-based solution enables merchants to launch the CPGModal in two different ways. Merchants can choose the method that best suits their requirements and integration preferences.

  1. Launch CPGModal with Options:

    Merchants can directly launch the CPGModal with all the desired options and configurations. This method allows for a quick and straightforward integration process. By specifying the necessary parameters and options, merchants can customize the behavior and appearance of the modal to align with their application's design and user experience.

  2. Launch CPGModal with Reference ID (Backend API):

    Alternatively, merchants can call our backend API to obtain a reference ID and then launch the CPGModal using that reference ID. This method provides additional control and security feature for merchants to manage transactions and integrate with their backend systems.

Launch CPGModal with Options

The Launch CPGModal with Options feature allows merchants to initiate the CPGModal directly with specific customization options and configurations. By leveraging this functionality, you can provide a tailored payment experience for your users within your application.

With the direct launch approach, you can specify various options such as payment amount, currency, reference id, and additional transaction details. This enables you to pre-fill specific fields, set default values, or customize the behavior of the CPGModal according to your particular requirements.

This section will guide you through the steps required to launch the CPGModal with options.

Step 1: Add the SDK File

Start by including the CPGModal SDK file in the `<head>` tag of your HTML page. Make sure to specify the correct file path.

<script src="${SDK_URL}"></script>

Step 2: Create an Instance of the CPGModal

Next, create an instance of the CPGModal by passing a config object. The config object should contain the mandatory parameter applicationId, which represents the ID of the application created in the merchant site.

Parameter Type Mandatory Description
applicationId STRING Yes Id of the application created in the merchant site

To create an instance of the CPGModal, you have two options: either include the code in a separate JavaScript file or directly within a `<script>` tag of your HTML file.

Option 1: Separate JavaScript file

Create a new JavaScript file (e.g., `cpgmodal.js`) and add the following code:


  // cpgmodal.js

  // Create an instance of CPGModal
  const config = {
    applicationId: "your_application_id",
  };
  const cpgInstance = new cpg.Instance(config); 
                  

Then in your HTML file, include the JavaScript file using a `<script>` tag:

Option 2: Inline within HTML file

Alternatively, you can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
      // Create an instance of CPGModal
      const config = {
        applicationId: "your_application_id",
      };
      const cpgInstance = new cpg.Instance(config); 
    </script>
  </head>
                  

Choose the option that suits your project structure and preferences.

Remember to replace 'your_application_id' with the actual ID of the application you created on the merchant site.

Step 3: Implement a Response Callback Function

Implement a response callback function that will handle the transaction response. This function will be called when the transaction is completed, failed, or canceled.

As step2, Add the following code to implement the response callback function in the same JavaScript file `cpgmodal.js`.


  // cpgmodal.js

  // ...previous code here

  // Implement the response callback function
  const callback = (response) => {
    switch(response.status) {
      case "USER_CLOSE":
          // user closed the session
        break;
      case "ERROR":
        // error in the sdk/application
        break;
      case "SUCCESS":
        // transaction success
        break;
      case "PENDING":
        // transaction pending (UTR/Transaction Id submitted) 
        break;
      case "FAILURE":
        // transaction got rejected
        break;
    }
  }
                  

Or, You can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
    // ...previous code here

    // Implement the response callback function
    const callback = (response) => {
      switch(response.status) {
        case "USER_CLOSE":
            // user closed the session
          break;
        case "ERROR":
          // error in the sdk/application
          break;
        case "SUCCESS":
          // transaction success
          break;
        case "PENDING":
          // transaction pending (UTR/Transaction Id submitted) 
          break;
        case "FAILURE":
          // transaction got rejected
          break;
      }
    }
    </script>
  </head>
                  

Make sure to handle all the cases for a better user experience.

Step 4: Launching the CPGModal

Launch the CPGModal by calling the `launch()` method on the CPGModal instance. Pass the callback function and the desired options as parameters to customize the modal behavior.

Available options are:

Parameter Type Mandatory Description
phoneNumber STRING Yes Mobile number of the user
referenceId STRING Yes Id generated by Merchant for merchant reference.
amount NUMBER Optional Transaction amount
currency STRING Optional Type of currency INR/USDT/MATIC
blockchain STRING Optional blockchain of selected token
transfer type STRING Optional BUY/SELL
application id STRING Mandatory Your Application Id
walletAddress STRING Optional User wallet Address (mandatory only when the crypto-to-user payment method is selected)

Similar to step2, step3, Add the following code to launch the CPGModal with options in the same JavaScript file `cpgmodal.js`.


  // cpgmodal.js

  // ...previous code here

  // Launch the CPGModal with options
  const options = {
   applicationId,
  };
  cpgInstance.launch(callback, options); 
                  

Or, You can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
      // ...previous code here

      // Launch the CPGModal with options
      const options = {
        applicationId
      };
      cpgInstance.launch(callback, options); 
    </script>
  </head>
                  

That's it. You have successfully integrated buy flow into your application.

Launch CPGModal with Reference ID (Backend API):

Launching the CPGModal with a Reference ID allows merchants to retrieve the reference ID from our backend API and use it to initiate the payment transaction. This method provides flexibility and control over the transaction process.

This section will guide you through the steps required to launch the CPGModal with options.

Step 1: Add the SDK File

Start by including the CPGModal SDK file in the `<head>` tag of your HTML page. Make sure to specify the correct file path.

<script src="${SDK_URL}"></script>

Step 2: Create an Instance of the CPGModal

Next, create an instance of the CPGModal by passing a config object. The config object should contain the mandatory parameter applicationId, which represents the ID of the application created in the merchant site.

Parameter Type Mandatory Description
applicationId STRING Yes Id of the application created in the merchant site

To create an instance of the CPGModal, you have two options: either include the code in a separate JavaScript file or directly within a `<script>` tag of your HTML file.

Option 1: Separate JavaScript file

Create a new JavaScript file (e.g., `cpgmodal.js`) and add the following code:


  // cpgmodal.js

  // Create an instance of CPGModal
  const config = {
    applicationId: "your_application_id",
  };
  const cpgInstance = new cpg.Instance(config); 
                  

Then in your HTML file, include the JavaScript file using a `<script>` tag:

Option 2: Inline within HTML file

Alternatively, you can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
      // Create an instance of CPGModal
      const config = {
        applicationId: "your_application_id",
      };
      const cpgInstance = new cpg.Instance(config); 
    </script>
  </head>
                  

Choose the option that suits your project structure and preferences.

Remember to replace 'your_application_id' with the actual ID of the application you created on the merchant site.

Step 3: Implement a Response Callback Function

Implement a response callback function that will handle the transaction response. This function will be called when the transaction is completed, failed, or canceled.

As step 2, Add the following code to implement the response callback function in the same JavaScript file `cpgmodal.js`.


  // cpgmodal.js

  // ...previous code here

  // Implement the response callback function
  const callback = (response) => {
    switch(response.status) {
      case "USER_CLOSE":
          // user closed the session
        break;
      case "ERROR":
        // error in the sdk/application
        break;
      case "SUCCESS":
        // transaction success
        break;
      case "PENDING":
        // transaction pending (UTR/Transaction Id submitted) 
        break;
      case "FAILURE":
        // transaction got rejected
        break;
    }
  }
                  

Or, You can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
    // ...previous code here

    // Implement the response callback function
    const callback = (response) => {
      switch(response.status) {
        case "USER_CLOSE":
            // user closed the session
          break;
        case "ERROR":
          // error in the sdk/application
          break;
        case "SUCCESS":
          // transaction success
          break;
        case "PENDING":
          // transaction pending (UTR/Transaction Id submitted) 
          break;
        case "FAILURE":
          // transaction got rejected
          break;
      }
    }
    </script>
  </head>
                  

Make sure to handle all the cases for a better user experience.

Step 4: Generate transferReferenceId from Backend

The transferReferenceId, required to initiate the buy transaction, can be generated by calling our Initiate Buy API from your backend with the necessary parameters. Once the transferReferenceId is generated, it should be sent to your front end for launching the CPGModal.

Warning

It is recommended to call the Initiate Buy API from the backend rather than directly from the front end to ensure the security of sensitive information. By performing the API call from the backend, such as a server-side script or application, you prevent the exposure of private keys or authentication credentials to the client-side environment. This helps maintain the integrity of your application and protects sensitive data from unauthorized access or misuse.

Step 5: Launch the CPGModal with the transferReferenceId

Upon receiving the transferReferenceId from the backend, From the frontend, you can launch the CPGModal using the transferReferenceId.

Similar to step2, step3, Add the following code to launch the CPGModal with options in the same JavaScript file `cpgmodal.js`.


  // cpgmodal.js

  // ...previous code here

  // Retrieve the transferReferenceId from the backend
  const transferReferenceId = 'your_transfer_reference_id';

  // Launch the CPGModal using the callback function and transferReferenceId
  cpgInstance.launch(callback, transferReferenceId); 
                  

Or, You can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
      // ...previous code here

      // Retrieve the transferReferenceId from the backend
      const transferReferenceId = 'your_transfer_reference_id';
    
      // Launch the CPGModal using the callback function and transferReferenceId
      cpgInstance.launch(callback, transferReferenceId);
    </script>
  </head>
                  

Congratulations! You have now successfully integrated the buy flow in your application, adding an extra layer of security.

SELL Flow

You can leverage the same CPGModal for integrating the sell flow into your application. By utilizing CPGModal, you can provide a seamless and user-friendly interface for users to perform withdrawal transactions securely. The sell flow integration follows a similar process as the buy flow, ensuring consistency and familiarity for users.

You can effectively track and manage withdrawal requests by leveraging the unique referenceId generated by our backend API for each withdrawal transaction. This referenceId serves as a vital identifier, allowing you to maintain secure and transparent withdrawals for your users.

The following section will guide you through the steps required to integrate sell flow into your application using the CPGModal.

Step 1: Add the SDK File

Start by including the CPGModal SDK file in the `<head>` tag of your HTML page. Make sure to specify the correct file path.

<script src="${SDK_URL}"></script>

Note

If you have already integrated the Buy Flow using the CPGModal and added the SDK file to your application, you can skip this step for adding the SDK file and next step, creating an instance of the CPGModal.

Note

The SDK file and the instance of the CPGModal are required for initializing the payment gateway and launching the modal. However, if you have already completed this step during the integration of the deposit flow, there is no need to repeat it for the withdrawal integration. Proceed with the remaining steps specific to the withdrawal flow integration.

Step 2: Create an Instance of the CPGModal

Next, create an instance of the CPGModal by passing a config object. The config object should contain the mandatory parameter applicationId, which represents the ID of the application created in the merchant site.

Parameter Type Mandatory Description
applicationId STRING Yes Id of the application created in the merchant site

To create an instance of the CPGModal, you have two options: either include the code in a separate JavaScript file or directly within a `<script>` tag of your HTML file.

Option 1: Separate JavaScript file

Create a new JavaScript file (e.g., `cpgmodal.js`) and add the following code:


  // cpgmodal.js

  // Create an instance of CPGModal
  const config = {
    applicationId: "your_application_id",
  };
  const cpgInstance = new cpg.Instance(config); 
                  

Then in your HTML file, include the JavaScript file using a `<script>` tag:

Option 2: Inline within HTML file

Alternatively, you can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
      // Create an instance of CPGModal
      const config = {
        applicationId: "your_application_id",
      };
      const cpgInstance = new cpg.Instance(config); 
    </script>
  </head>
                  

Choose the option that suits your project structure and preferences.

Remember to replace 'your_application_id' with the actual ID of the application you created on the merchant site.

Step 3: Implement a Response Callback Function

Implement a response callback function that will handle the transaction response. This function will be called when the transaction is completed, failed, or canceled.

As step2, Add the following code to implement the response callback function in the same JavaScript file `cpgmodal.js`.


  // cpgmodal.js

  // ...previous code here

  // Implement the response callback function
  const callback = (response) => {
    switch(response.status) {
      case "USER_CLOSE":
          // user closed the session
        break;
      case "ERROR":
        // error in the sdk/application
        break;
      case "SUCCESS":
        // transaction success
        break;
      case "PENDING":
        // transaction pending (UTR/Transaction Id submitted) 
        break;
      case "FAILURE":
        // transaction got rejected
        break;
    }
  }
                  

Or, You can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
    // ...previous code here

    // Implement the response callback function
    const callback = (response) => {
      switch(response.status) {
        case "USER_CLOSE":
            // user closed the session
          break;
        case "ERROR":
          // error in the sdk/application
          break;
        case "SUCCESS":
          // transaction success
          break;
        case "PENDING":
          // transaction pending (UTR/Transaction Id submitted) 
          break;
        case "FAILURE":
          // transaction got rejected
          break;
      }
    }
    </script>
  </head>
                  

Make sure to handle all the cases for a better user experience.

Step 4: Generate referenceId from Backend

The unique referenceId, which is required to initiate the withdrawal transaction, can be generated by calling our Initiate Withdrawal API from the your backend with necessary parameters. Once the referenceId is generated, it should be sent to your frontend for launching the CPGModal.

Warning

It is recommended to call the Initiate Sell API from the backend rather than directly from the front end to ensure the security of sensitive information. By performing the API call from the backend, such as a server-side script or application, you prevent the exposure of private keys or authentication credentials to the client-side environment. This helps maintain the integrity of your application and protects sensitive data from unauthorized access or misuse.

Step 5: Launch the CPGModal with the referenceId

Upon receiving the referenceId from the backend, From the frontend, you can launch the CPGModal using the referenceId and the callback function.

Similar to step2, step3, Add the following code to launch the CPGModal with options in the same JavaScript file `cpgmodal.js`.


  // cpgmodal.js

  // ...previous code here

  // Retrieve the transferReferenceId from the backend
  const referenceId = 'your_transfer_reference_id';

  // Launch the CPGModal using the callback function and referenceId
  cpgInstance.withdraw(callback, referenceId); 
                  

Or, You can directly include the code within a `<script>` tag of your HTML file:


  <head>
    <script>
      // ...previous code here

      // Retrieve the transferReferenceId from the backend
      const transferReferenceId = 'your_transfer_reference_id';
    
      // Launch the CPGModal using the callback function and transferReferenceId
      cpgInstance.launch(callback, transferReferenceId);
    </script>
  </head>
                  

Congratulations! You have now successfully integrated the sell flow in your application, with an extra layer of security.

Signature

To ensure secure communication between your system and our backend APIs, you must generate a Signature for each API request. The Signature is used to verify the authenticity and integrity of the request.

Steps to Generate Signature

  1. Add Current Timestamp: Include the current timestamp in the request body. The timestamp should accurately represent the time of the request.
  2. Sort Request Body: Sort the key-value pairs in the request body in ascending order based on the keys. This ensures consistent ordering of the data for generating the hash.
  3. Generate Hash with HMAC Algorithm: Use the HMAC (Hash-based Message Authentication Code) algorithm to generate the hash. Encode the secret key using hex encoding before passing it to the HMAC algorithm. Ensure that the data is serialized to JSON with UTF-8 encoding before updating the hash. Convert the resulting hash to bytes.
  4. Convert Hash to Hex Signature: Convert the hash, which is now in bytes, to a hexadecimal signature. This is the final format in which the signature will be included in the request headers.
  5. Include Signature in Request Headers: Add the generated Signature to the request headers as a field (e.g., "signature"). This allows our backend APIs to verify the integrity of the request.

Note

During signature generation, careful consideration should be given to string encoding. As our APIs consume JSON bodies, it's essential to note that the default character set for serialized JSON is UTF-8, a widely supported encoding in most libraries.

Note

For accurate and secure signature generation for your API requests, please carefully follow the steps outlined above. Accurate implementation of each step is crucial to maintain request integrity and authenticity. If you encounter difficulties or have questions, refer to this documentation or contact our support team for assistance.

Example (Node.js):

const crypto = require('crypto');

// Step 1: Add current timestamp to the request body
const timestamp = new Date();

// Step 2: Sort the request body based on keys
const requestBody = {
  timestamp,
  // ...other request parameters
};
const sortedBody = Object.keys(requestBody)
  .sort()
  .reduce((sorted, key) => {
    sorted[key] = requestBody[key];
    return sorted;
  }, {});

// Step 3: Generate the hash using HMAC algorithm
const secret = 'YOUR_SECRET_KEY';
const keyBytes = Buffer.from(secret, 'hex'); // Key encoded as hex encoded binary bytes
const hmac = crypto
  .createHmac('sha256', keyBytes)
  .update(JSON.stringify(sortedBody)) // Encode the sorted body using UTF-8
  .digest('hex'); // Convert the hash to a hexadecimal string

// Step 4: Include the Signature in the request headers
const headers = {
  'signature': hmac,
  // ...other headers
};
                
Example (using `CryptoJS` library):

  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
  <script>
    // Step 1: Add a current timestamp to the request body
    const timestamp = new Date();

    // Step 2: Sort the request body based on keys
    const requestBody = {
      timestamp,
      // ...other request parameters
    };
    const sortedBody = Object.keys(requestBody)
      .sort()
      .reduce((sorted, key) => {
        sorted[key] = requestBody[key];
        return sorted;
      }, {});

    // Step 3: Generate the hash using HMAC algorithm
    const secret = "YOUR_SECRET_KEY";
    // Create an HMAC instance with CryptoJS using the secret key (key encoding: hex)
    const keyBytes = CryptoJS.enc.Hex.parse(secret); // Key encoded as hex binary bytes
    const hmac = CryptoJS.HmacSHA256(JSON.stringify(sortedBody), keyBytes);
    // Convert the hash to a hexadecimal string (data/body encoding: utf-8)
    const hash = hmac.toString(CryptoJS.enc.Hex);

    // Step 4: Include the Signature in the request headers
    const headers = {
      signature: hash,
      // ...other headers
    };
  </script>
                
Example (JAVA Spring Boot Framework):

package com.payonramp.signature.sample.controller;

import java.util.TreeMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.payonramp.signature.sample.dto.SignatureDto;
import com.payonramp.signature.sample.service.SignerService;

@RestController
@RequestMapping("/sign")
public class SignerController {
    
    @Autowired
    SignerService signerService;

    String key = "27d1b6e12fa9c48da476f29cc92fd7c57270058f89a8a357ff0afa68c01b5d24f2d540ed94a39d0d679fcb3ab3d7c4b137797ac82ab8e5c5290dea4e1e5650cd";
    
    @GetMapping("/generate")
    public SignatureDto generate() {
        TreeMap<String, String> requestObject = new TreeMap<String, String>();
        requestObject.put("amount", "100");
        requestObject.put("application_id", "6980E5F4-EB4F-4DC0-84E7-53C897115D9D");
        requestObject.put("currency", "INR");
        requestObject.put("email", "[email protected]");
        requestObject.put("mobile_number", "9988776655");
        requestObject.put("reference_id", "6E430071-F173-4F49-A499-BA30D252B007");
        requestObject.put("timestamp", "2023-08-08T08:08:08.808Z");
        requestObject.put("username", "payonrampCustomer");
        return signerService.getSignature(key, requestObject);
    }

    @GetMapping("/verify")
    public SignatureDto verify() {
        String hash = "7e4a33aca6bb49b3b6ab9e52066f87e5666543bba43eb280f321ccb94f3763b";
        // The request json can be in any order the `TreeMap` will sort the data and creates the hash for it
        String jsonData = "{\"currency\":\"INR\",\"email\":\"[email protected]\"," + 
                        "\"amount\":\"100\",\"reference_id\":\"6E430071-F173-4F49-A499-BA30D252B007\"," + 
                        "\"mobile_number\":\"9988776655\",\"timestamp\":\"2023-08-08T08:08:08.808Z\"," + 
                        "\"application_id\":\"6980E5F4-EB4F-4DC0-84E7-53C897115D9D\",\"username\":\"payonrampCustomer\"}";
        System.out.println(jsonData);
        return signerService.verifySignature(key, jsonData, hash);        
    }
}
                

package com.payonramp.signature.sample.service;


import com.payonramp.signature.sample.dto.SignatureDto;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.log4j.Log4j2;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HexFormat;
import java.util.TreeMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Log4j2
@Service
public class SignerService {    

    @Autowired
    ObjectMapper objectMapper;

  /**
   * Gets signature hash.
   *
   * @param key secret key
   * @param obj value to be encrypted
   * @return SignatureDto
   */
  public SignatureDto getSignature(String key, TreeMap<String, String> obj) {
    try {
      String requestString = objectMapper.writeValueAsString(obj);
      log.info("Request body for signature generation : {} key : {}", requestString, key);
      
      Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
      SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(), "HmacSHA256");
      sha256_HMAC.init(secret_key);
      String signature = new String(HexFormat.of().formatHex(sha256_HMAC.doFinal(requestString.getBytes())));
      
      SignatureDto signResponse = new SignatureDto();
      signResponse.setJsonData(requestString);
      signResponse.setSignature(signature);
      signResponse.setOperation("CREATE");
      
      return signResponse;
    } catch (NoSuchAlgorithmException ex) {
      throw new RuntimeException("No such algorithm exception.", ex);
    } catch (InvalidKeyException e) {
      throw new RuntimeException("Invalid secret key.", e);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("Unable to parse json.", e);
    }
  }

  public SignatureDto verifySignature(String key, String data, String hash) {
      TreeMap<String, String> requestObject;
      SignatureDto signResponse;
      try {
        requestObject = (TreeMap<String, String>)objectMapper.readValue(data, TreeMap.class);
        signResponse = getSignature(key, requestObject);
        if (!signResponse.getSignature().equals(hash)) {
          // Signature Verification failed
          throw new RuntimeException("Hash mismatch " + signResponse.getSignature() + " != " + hash);
        }
      } catch (JsonProcessingException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
      signResponse.setOperation("VERIFY");
      return signResponse;
  }

}

                

package com.payonramp.signature.sample.dto;

import lombok.Data;

@Data
public class SignatureDto {
    public String jsonData;
    public String signature;
    public String operation;
}
                

Secret Key

The secret key required for generating the Signature can be found in the application details we provided. It is essential to keep this secret key confidential and securely store it in your system.

Signature Generator

This is a sample signature genrator which ca be used to test and verify signatures.

Frequently Asked Questions (FAQ)

Welcome to our Frequently Asked Questions (FAQ) section, where we provide answers to common queries and concerns about our payment gateway integration. Whether you're seeking information about API endpoints, SDK usage, callback handling, or other integration-related topics, you'll find comprehensive answers here. These FAQs are designed to streamline your integration process and ensure a seamless experience while using our services. If you can't find the answer you're looking for, please don't hesitate to reach out to our support team for further assistance.

Where can we find Application ID and Application Secret?

You can locate the Application ID and Application Secret within the application settings of your merchant account.

What is the API Base URL?

The API Base URL is the primary endpoint for accessing our API services. You can obtain this URL from our support team.

Where can I find the SDK Source URL?

You can obtain the SDK Source URL by reaching out to our support team.

How can I launch the SDK with the reference ID?

You can launch the SDK with the reference ID by calling our backend API to generate the reference ID and then initiating the SDK with this ID.

Is there a PHP Library available for integration?

No, at present, we do not offer a PHP library for integration.

Is there an NPM package available for the SDK?

No, currently, we do not provide an NPM package for the SDK.

Is there a way to skip the OTP during integration testing on stage?

Yes, you have the flexibility to skip OTP verification for both stage and live environments by disabling the OTP verification option in the application settings.

What is the purpose of the 'payonramp.umd.js' file?

'payonramp.umd.js' is a JavaScript file designed for integrating the CPGModal into your application, enabling the initiation of deposit and withdrawal transactions. When integrated, it opens an iframe within your web application, facilitating seamless payment processing.

Can I use dummy bank account details for integration testing on the stage environment?

Yes, you can utilize dummy account details for integration testing on the stage environment, allowing you to simulate transactions without providing actual bank accounts. Additionally, you have the capability to manually approve or reject these transactions from the merchant portal for testing purposes.

What kind of signature errors might occur during integration?

Signature errors can occur due to various reasons, including:

  1. Incorrect Parameter Sorting: If the parameters in your API requests are not sorted correctly, it can result in signature errors.
  2. Encoding Mismatch: The encoded string must match our encoding format (UTF-8). Any mismatch can lead to signature verification issues.
  3. Expired Timestamp: If the timestamp in your request expires before processing, it can trigger signature errors. Ensure that the timestamp is current and within the acceptable time frame i.e 5 min.
How can I address a 'Forbidden' error in API requests?

A 'Forbidden' error typically occurs due to a signature mismatch. To resolve this, you can verify the signature by generating a signature using the same request body with our signature generator. Ensure that the generated signature matches the one sent in the request headers to rectify the 'Forbidden' error.

Do I need to request access from specific IPs for API access?

In the stage environment, there is no need for IP whitelisting. However, for the live environment, it is mandatory to whitelist specific IPs to ensure secure API access.

Regarding the mobile number in API requests, should I include the country code?

No, you should provide the ten-digit mobile number without the country code in all API requests. Please note that currently, we only support Indian mobile numbers for OTP purposes.

What are the types of callbacks available?

There are two types of callbacks available: one for deposit transactions and the other for withdrawal transactions.

What happens if a transaction times out?

If a user doesn't take any action after initiating the transaction, the transaction will be automatically cancelled upon the completion of the timeout period. This timeout period can be configured from the merchant portal for your convenience.

What data is included in a status callback?

For complete information on the data included in a status callback, please refer to our callback section for detailed documentation.

Can you provide a list of dummy phone numbers for testing purposes?

Here is a list of dummy phone numbers for testing purposes, including '9999999999' and '9999988888,' with a default OTP of '123456.'

What is the maximum UTR length supported?

The maximum UTR (Unique Transaction Reference) length can vary based on the transfer type, ranging from 12 to 22 alphanumeric characters.

API Integration with KYC

In addition to web-SDK integration , REST-API integration, we also offer REST API-based integration including KYC, allowing merchants to build their own custom user interface (UI) while leveraging our API endpoints for seamless transaction processing with KYC.

By utilizing our REST API, merchants can access a comprehensive set of endpoints that enable them to perform various transaction-related operations, including initiating deposits, processing withdrawals, and retrieving transaction history. These APIs offer secure and reliable communication channels for transmitting transaction data between the merchant's application and our payment gateway.

Crypto Tokens, Rates and Fee

Crypto Tokens Supported:

You can access the Cryptotokens supported based on your app id. You'll receive your app id on registration

Method: GET

Endpoint: ${BASE_URL}/crypto/market/api/v1/<app-id>/currencies

Response type: application/json

Example response data:

{
  "error": false,
  "data": {
    "currencies": [
      {
        "currency": "USDT",
        "blockchain": "TRON",
        "chainId": null,
        "tokenAddress": "TRxxxxxxxxxxxxxxxxxxxxxj6t",
        "aliasName": "USDT-TRON",
        "tokenType": "TRC-20",
        "minimumBuyLimit": 10,
        "maximumBuyLimit": 0,
        "minimumSellLimit": 0,
        "maximumSellLimit": 0,
        "networkFee": 3,
        "source": "cryptoforce",
        "tokenName": "TETHER"
      },
      // ... (other currencies)
    ]
    "indpay": true,
    "markup": : "0.01",
    "sellMarkup": "0.02",
    "sellCurrecies": [
        {
            "currency": "USDT",
            "blockchain": "TRON",
            "chainId": null,
            "tokenAddress": "TRxxxxxxxxxxxxxxxxxxxxxj6t",
            "aliasName": "USDT-TRON",
            "tokenType": "TRC-20",
            "minimumBuyLimit": 10,
            "maximumBuyLimit": 0,
            "minimumSellLimit": 0,
            "maximumSellLimit": 0,
            "networkFee": 3,
            "source": "cryptoforce",
            "tokenName": "TETHER"
        }
        // ... (other currencies)
    ]
  }
}
            

Platform Fee

Platform Fee issued by Payonramp. You need to have app-id to access this Api

Method: GET

Endpoint: ${BASE_URL}/crypto/market/api/v1/<app-id>/fee

Response type: application/json

Example response data:

{
  "error": false,
  "data": {
    "tdsPercent": 1,
    "buyFeePercent": 0.236,
    "sellFeePercent": 0.236,
    "gstPercent": 18
  }
}
            

Exchange Rate

Method: GET

Endpoint: ${BASE_URL}/crypto/market/api/v1/exchangeRate?currency=<string>&source=<string>&blockchain=<string>&quantity=<number&applicationId=<string>

Query Parameters: currency=USDT, source=cryptoforce, blockChain=BSC, quantity=10, applicationId=xxxx-xxxx-xxx

Response type: application/json

Example response data:

{
  "error": false,
  "data": {
    "buy": "88.73129857",
    "sell": "87.2318211"
  }
}
            
Note: In addition to the exchange rate, the final value applied to the user will include platform fees, network fees, and a markup

User Authentication

To authenticate a user before sending transaction. We have two ways to authenticate User. OTP Authentication based and Secret Key based . Access token is required for further consumation of transaction api's.

User Login using OTP

Method: POST

Endpoint: ${BASE_URL}/user/portal/login/otp

Request:

Request body:

{
  "phonenumber": "+91XXXXXXXXXX"
}
                                      

Response type: application/json

Example response data:

{
  "error": false,
  "message": "OTP sent successfully",
  "data": {
      "otpReferenceKey": "dead418e-57ec-4318-9790-a3a20796f505"
  }
}
                                      

Verify User Mobile

Method: POST

Endpoint: ${BASE_URL}/user/portal/login/otp/verify

Request:

Request body:

{
"otpReferenceKey": "5c688191-5411-4118-b29f-48f4e3b19f21",
"otp": "980592",
"phonenumber": "+91XXXXXXXXXX"
}
          

Response type: application/json

Example response data:

{
"error": false,
"data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.",
    "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9",
    "kycApproved": true,
    "kycStatus": "BASIC_KYC_SUCCESS",
    "expiry": 1718644624,
    "existingUser": true
}
}
          

if result.data.kycApproved == false , then you have to follow kyc verification process as follows, else skip to Transaction Initiate

Secret Key base Authentication

Method: POST

Endpoint: ${BASE_URL}/user/login

Header:

secret-key : "xxxxx-xxxx-xxxx"

Request:

Request body:

{
    "phoneNumber": "1234xxxxxxx",
    "applicationId": "xxxxx-xxxxx-xxxx-xxxx"
}
                                    

Response type: application/json

Example response data:

{
    "error": false,
    "message": "The user has not completed the KYC process or The user has not submitted their KYC details.",
    "data": {
        "kycApproved": false,
        "accessToken": "xxxxx-xxxx-xxxx-xxxx",
        "refreshToken": "xxxxx-xxxx-xxxx-xxxx",
        "existingUser": true,
        "userInfo": false,
        "status": "NOT_STARTED"
    }
}
                                      

Note: Please get secret-key and applicationId from PayOnRamp Team.

if result.data.kycApproved == false , then you have to follow kyc verification process as follows, else skip to Transaction Initiate

User Profile

User Details, Daily Monthly Limits and user availed for daily and monthly

User Profile

Method: GET

Endpoint: ${BASE_URL}/user/portal/profile

Header:


{
"authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW..."
}

Response type: application/json

Example response data:

{
    "error": false,
    "message": "Profile info fetched successfully",
    "data": {
        "kycInfo": {
            "isBasicKycVerified": true,
            "isFullKycVerified": false,
            "basicKycMonthlyLimit": 1000000,
            "basicKycTransactionLimit": 200000,
            "fullKycMonthlyLimit": 1000000,
            "fullKycTransactionLimit": 500000,
            "kycStatus": "FULL_KYC_PENDING",
            "kycApplicationStatus": "auto_approved:BASIC_KYC",
            "fullKYCDocs": {
                "video": "PENDING",
                "bankStatement": "APPROVED"
            }
        },
        "userInfo": {
            "fullName": "XXXX XXX XXX",
            "phoneNumber": "XXXXXXXXXX",
            "lastOtpVerified": "2024-06-18T01:16:17.000Z",
            "lastLoginIpAddress": "2601:985:4180:d4e0:6586:c0bb:8944:fb0b, 172.70.42.67"
        },
        "transactionInfo": {
            "monthlyLimitUsed": 4032,
            "monthlyBuyOrderSum": 2016,
            "monthlySellOrderSum": 360.5313
        }
    }
}

Possible kycStatus : [BASIC_KYC_PENDING, BASIC_KYC_SUCCESS, BASIC_KYC_REJECTED, FULL_KYC_PENDING, FULL_KYC_SUCCESS, FULL_KYC_REJECTED, NOT_YET_STARTED]

A user's ability to perform basic KYC operations remains unaffected regardless of their Full KYC status (pending or rejected).

User KYC with Hyperverge SDK

User needs to complete KYC to be able to place BUY/SELL transactions. You should integrate Hyperverge SDK, provided in the following documentation, for the KYC to completed. User should be authenticated before you can consume KYC related api's

Get Hyperverge KYC workflow id

Status: Initiated, Pending, Success

Method: POST

Endpoint: ${BASE_URL}/user/auth/kyc/token

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"kycType": "BASIC_KYC"
}
          

Response type: application/json

Example response data:

{
"data": {
    "accessToken": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.",
    "transactionId": "28197c3a-a448-47a5-bc52-734dc623361a",
    "workflowId": "workflow_uuid"
},
"error": false,
"message": "token generated successfully"
}
          

integrate Hyperverge SDK and launch KYC attempt

Add Hyperverge KYC SDK to your page using following javascript SDK.


<script type="text/javascript" src="https://hv-camera-web-sg.s3-ap-southeast-1.amazonaws.com/[email protected]/src/sdk.min.js">
  

Launch Hyperverge KYC :


const hyperKycConfig = new window.HyperKycConfig( 
  accessToken, 
  workflowId, 
  transactionId
); 
const kycStatus = window.HyperKYCModule.launch(hyperKycConfig , (kycResponse) => {
  switch(kycResponse.status){
    case "user_cancelled" : {
      break;
    }

    case "error":{
      return {status:"rejected" , kycId:result.data.transactionId}
    }
    case "auto_declined":{
      return {status:"rejected" , kycId:result.data.transactionId}
    }
    case "needs_review":{
      return {status:"need_review" , kycId:result.data.transactionId}
    }
    case "auto_approved":{
      return {status:"success" , kycId:result.data.transactionId}
    }
    default:
      break;
  }
})
    

Verify KYC status with Payonramp

Use kycStatus as payload to fetch status from Payonramp

Method: POST

Endpoint: ${BASE_URL}/user/auth/kyc/status

Headers:

      
{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      
  

Request:

Request body:
          
{
    "status": "approved",
    "kycID": "f76c0d7e-8d36-4e4d-b872-49573eb86e5f"
}
          
      

Add KYC with Merchant application

Merchant application can add KYC directly. If already verified the user

Method: POST

Endpoint: ${BASE_URL}/user/merchant-user-kyc

Headers:

      
{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      
  

Request:

Request body:

Request body should send as form-data. panImage, aadharFrontImage, aadharBackImage, userPhoto are image files.

          
{
    "applicationId":"1a5cc483-3869-4d56-ae84-a78eaf222baf",
    "phoneNumber":"9400663804",
    "fullname":"John Doe",
    "email":"[email protected]",
    "residenceOfCountry":"India",
    "DOB":"1985-01-25",
    "gender":"Male",
    "pan":"ABCDE1234F",
    "aadhar":"123456789018",
    "state":"Kerala",
    "address":"House No. 123, Main Street, City, Kerala, 678901",
    "panImage": "${IMAGE_PATH}/panImage.jpg",
    "aadharFrontImage": "${IMAGE_PATH}/aadharFrontImage.jpg",
    "aadharBackImage": "${IMAGE_PATH}/aadharBackImage.jpg",
    "userPhoto": "${IMAGE_PATH}/userPhoto.jpg"
}
          
      

Response type: application/json

Example response data: Success

{
  "error": false,
  "message": "kyc verification success",
  "status": "success"
}
Example response data: Failed

{
"error": false,
"message": "kyc verification failed",
"status": "rejected"
}

Full KYC API

Upon successful Basic KYC completion, the user is eligible for Full KYC. Upgrading to Full KYC increases daily and monthly transaction limits. To initiate Full KYC, the user must provide a bank statement and a live selfie video.

Note: As of now this verification process is manual and expect a delay to get approved/rejected.

Video upload

Video size should be in between 1KB and 25MB

User should prompt the following to upload video

"I, [Your Name], am completing KYC verification with [Payonramp] on [today's date] for my account identified by [Phone number/Unique ID]. "I take full responsibility for all transactions conducted on my [Payonramp account, including deposits and withdrawals involving INR and cryptocurrencies. Any liabilities or obligations arising from these transactions are exclusively my responsibility. I confirm that the funds used in these transactions are legitimately mine and have been obtained through lawful means."

Method: POST

Endpoint: ${BASE_URL}/user/full-kyc-video

Headers:

          
{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
          
      

Request:

Request body:

Request body should send as form-data. video should be lively recorded video.

              
{
    "video": "live_video.webm",
}
              
          

Response type: application/json

Example response data: Success

{
    "error":false,
    "data":"video"
}
    
Bank statement upload

User should upload last 3 months bank statement

File size should be in between 1KB and 2MB

Method: POST

Endpoint: ${BASE_URL}/user/full-kyc-bank-statement

Headers:


{
    "authorization": "Bearer ${ACCESS_TOKEN}"
}

Request:

Request body:

Request body should send as form-data. bank_statement should be image.


{
    "bank_statement": "${IMAGE_PATH}/bankStatement.jpeg",
}

Response type: application/json

Example response data: Success
                
{
    "error":false,
    "data":"kyc-bank-statement"
}

The full KYC status, including details for each submitted document, can be found in the response from ${BASE_URL}/user/portal/profile. You can resubmit rejected documents individually using the same API endpoint of upload.

KYC Status

API to check KYC status and related information of an user, registered via applications

Method: POST

Endpoint: ${BASE_URL}/user/merchant-user-status

Headers:

          

Request:

Request body:

                  
{
    "applicationId": "xxxx-xxxxx-xxx",
    "phoneNumber": "*******"
}
                  
              

Response type: application/json

Example response data: Success

{
    "error": false,
    "status": "FULL_KYC_REJECTED",
    "userId": "xxxx-xxxxxx",
    "phoneNumber": "*******",
    "fullName": "John Doe",
    "pan": "ABC56564",
    "aadhar": "XXXXXXXX0000",
    "remarks": "Invalid Video"
}
        

Reject Reason will be given in remarks (if KYC is in Rejected state).

Initiate Buy/Sell Transaction

User should be authenticated and KYC should be completed before you can initiate a BUY or SELL transaction

Initiate Buy Transaction

Method: POST

Endpoint: ${BASE_URL}/user/api/v2/transaction/initiate

Header:

      
{
  "authorization": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW..."
}
      
  

Request:

Request body:
          
{
"amount": 1455,
"currency": "USDT",
"blockchain": "TRON",
"applicationId": "application uuid",
"referenceId": "reference uuid",
"transferType": "BUY",
"phoneNumber": "+91XXXXXXXXXXX",
"walletAddress": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
"coinPrice": 90.234
}
          
      

Response type: application/json

Example response data:

{
"error": false,
"message": "Transfer request was submitted successfully",
  "data": {
      "logoUrl": "https://payonramp/logo",
      "applicationName": "PayOnRamp",
      "kycApproved": true,
      "verifyUser": false,
      "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
      "expiry": 1718648146
      "referenceId": "6e2d2626-55bb-41d5-9892-318e48a45f4b",
      "transferReferenceId": "affad017-eb12-49d0-a164-a1c028531e98",
      "otpRequired": false,
      "allowedCurrencies": ["USDT-TRON","BTC","BTC-BSC","INR","USDC-ETHEREUM","ETH","ADA-BSC","USDT-BSC","BNB","USDT-ETHEREUM","SHIB-ETHEREUM","DOGE","MATIC"],
      "amount": 1455,
      "currency": "USDT",
      "isAmountEditable": false,
      "isCurrencyEditable": false
  }
}
          

Get Allowed Transaction Type Details

Currently supports only UPI and Bank transfers.

Method: POST

Endpoint: ${BASE_URL}/transactions/auth/getAvailablePaymentMethods

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"currency": "INR",
"headers": {
  "Authorization": "Bearer ${ACCESS_TOKEN}"
}
}
          

Response type: application/json

Example response data:

{
"error": false,
"data": {
  "UPI": true,
  "BANKTRANSFER": true,
  "INTERNETBANKING": false,
  "CARDPAYMENT": false,
  "CRYPTO": false,
  "PAYPAL": false,
  "conversionPointsRatio": 1,
  "exchangeRate": 1,
  "nativeTokenName": "INR",
  "minimumTransferLimit": 0,
  "maximumTransferLimit": 0
}
}

Get UPI handle and QR code

Method: POST

Endpoint: ${BASE_URL}/user/auth/getQRCode

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"amount": 1455
}
          

Response type: application/json

Example response data:

{
"UPIQR": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMQAAADECAYAAADA....",
"bankId": "763d24a8-4ac1-4f43-82ee-76945903fe97",
"intent": "upi://pay?pa=XXXXXXXXX%40paytm&pn=Gxxxxxm%20Vxxxxa%20Cxxxxxxr&am=1455&tn=6797147333659193",
"error": false,
"message": "QR generated successfully",
"isMerchantAccount": false,
"upiId": "xxxxxxxxxx@paytm",
"isUTRRequired": true
}
          

Get Bank account details

Method: POST

Endpoint: ${BASE_URL}/user/auth/getBankDetails

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"amount": 1455
}
          

Response type: application/json

Example response data:

{
"error": false,
"bankAccount": {
  "BankId": "763d24a8-4ac1-4f43-82ee-76945903fe97",
  "accountNumber": "373xxxxxxxxx19",
  "IFSC": "IOBxxxxx32",
  "accountHolderName": "Gxxxx xxxxxxxxxxr",
  "bankName": "XXXX",
  "upiId": "XXXXXXXXX@paytm",
  "isActive": true,
  "accountName": "XXXXXX XXXXX XXXXX",
  "status": "APPROVED",
  "phoneNumber": "XXXXXXXXXXX",
  "merchantId": "92XXXXXXXXXXXXXXf36ac",
  "createdAt": "2023-09-12T06:05:13.673Z",
  "updatedAt": "2023-09-12T06:05:13.673Z",
  "merchantCode": null,
  "isUPIPaymentMerchant": false,
  "isUTRRequired": true
},
"message": "Available bank details"
}
          

Submit and Check Transaction Status

Submit transaction with UTR number, which is mandatory.

Submit UTR number to verify the transaction

Method: POST

Endpoint: ${BASE_URL}/transactions/auth/submitUTR

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

if you opt for automatic flow then UTR can be empty else user has to submit UTR, to verify Automatic flow is enabled check IndPay value in currencies api

Bank ID should be fetch from UPI/ Bank transfer api

Request body should send as form-data.


data: {
"utrNumber": "",
"bankId": "763d24a8-4ac1-4f43-82ee-76945903fe97",
"transferType": "UPI"
}
          

Response type: application/json

Example response data:

{
"error": false,
"message": "UPI transfer request created successfully."
}
          

Check the transaction status

Method: POST

Endpoint: ${BASE_URL}/transactions/auth/checkTransactionStatus

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Response type: application/json

Example response data:

{
"error": false,
"status": "PENDING"
}
          

Initiate Sell Transaction

Method: POST

Endpoint: ${BASE_URL}/user/api/v2/transaction/initiate

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"amount": 13.3165,
"blockchain": "DOGE",
"applicationId": "application uuid",
"referenceId": "6e2d2626-55bb-41d5-9892-318e48a45f4b",
"transferType": "SELL",
"currency": "DOGE",
"phoneNumber": "+91xxxxxxxxx",
"coinPrice": 90.234
}
          

Response type: application/json

Example response data:

{
"error": false,
"message": "Transfer request was submitted successfully",
"data": {
  "logoUrl": "https://payonramp/logo",
  "applicationName": "PayOnRamp",
  "kycApproved": true,
  "verifyUser": false,
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "referenceId": "6e2d2626-55bb-41d5-9892-318e48a45f4b",
  "transferReferenceId": "1fc0e068-076c-4be0-8cc8-df285305aa31",
  "otpRequired": false,
  "allowedCurrencies": ["USDT-TRON", "BTC", ...],
  "amount": 13.3165,
  "currency": "DOGE",
  "isAmountEditable": false,
  "isCurrencyEditable": false
}
}
          

Add bank account for user

Method: POST

Endpoint: ${BASE_URL}/user/portal/add/bank

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"accountNumber": "124349898989",
"IFSC": "SBIN0070264",
"accountHolderName": "SSSS",
"bankName": "SBI",
"accountType": "Current Account",
"branchName": "RPM",
"cx": "SSSS"
}
          

Response type: application/json

Example response data:

{
"message": "Bank Details Added Successfully",
"error": false
}
          

Delete bank account for user

Method: POST

Endpoint: ${BASE_URL}/user/portal/add/inactivate

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"bankId": "168b5352-ce2d-4781-a5ac-678b2e2e86e9"
}
          

Response type: application/json

Example response data:

{
"message": "Bank removed Successfully",
"error": false
}
          

Get User Saved bank details

Get user saved bank account list. This API is to be used with SELL flow

Method: GET

Endpoint: ${BASE_URL}/user/portal/get/banks?limit=10&offset=0

Query Parameters: limit=10&offset=0

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Response type: application/json

Example response data:

{
"data": [
  {
    "bankId": "168b5352-ce2d-4781-a5ac-678b2e2e86e9",
    "accountNumber": "xxxxxxxxxxxx",
    "IFSC": "SBxxxxxx4",
    "accountHolderName": "XXX XXXXXX",
    "bankName": "XXXX",
    "userId": "user uuid",
    "phoneNumber": null,
    "accountType": "Current Account",
    "cx": "XXX XXXXXXXXX",
    "branchName": "XXXXXX",
    "createdAt": "2023-10-13T14:09:25.598Z",
    "updatedAt": "2023-10-13T14:09:25.598Z",
    "active": true
  },
  // ... Additional entries
],
"count": 10,
"error": false
}
          

Confirm user Bank details with payonramp

Method: POST

Endpoint: ${BASE_URL}/user/transaction/bank/confirm

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"bankId": "321412cc-e4cc-4fda-a7c7-8afa0efd94b3"
}
          

Response type: application/json

Example response data:

{
"error": false
}
          

Get Merchant Wallet address on selling crypto

Method: POST

Endpoint: ${BASE_URL}/transactions/auth/crypto/getMerchantWalletAddress

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"amount": 20,
"currency": "DOGE"
}
          

Response type: application/json

Example response data:

{
"error": false,
"data": {
  "address": "DJHC9Cou6z5YAAJqjKTMPVmYbzQrdgYFk2",
  "currency": "DOGE",
  "blockchain": "DOGE",
  "tokenType": "DOGE"
}
}
          

Verify Crypto Deposit

Method: POST

Endpoint: ${BASE_URL}/transactions/auth/verifyCryptoDeposit

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Request:

Request body:

{
"transactionHash": "6xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe",
"blockNumber": "8653",
"amount": 20,
"currency": "DOGE"
}
          

Response type: application/json

Example response data:

{
"error": false,
"message": "Transfer request submitted successfully"
}
          

Check the transaction status

Method: POST

Endpoint: ${BASE_URL}/transactions/auth/checkTransactionStatus

Headers:


{
  "authorization": "Bearer ${ACCESS_TOKEN}"
}
      

Response type: application/json

Example response data:

{
"error": false,
"status": "PENDING"
}
          

Transaction Status using `transactionId`

Method: POST

Endpoint: ${BASE_URL}/user/portal/transaction-status

Request:

Request body:

  {
      "transactionId": "0a5398f7-ddd7-44fd-ace7-xxxxxx"
  }
            

Response type: application/json

Example response data:

Note: `remarks` field will contain the reason for rejection if a test case fails. Otherwise, it may include additional notes or be left empty.


  {
      "error": false,
      "data": {
          "status": "CANCELLED",
          "transactionHash": "",
          "cryptoAmount": "10.082777254726667",
          "INRAmount": 900,
          "payonrampFee": 2.124,
          "networkFee": 267.1513941,
          "coinPrice": 89.0504647,
          "remarks": "Invalid Transaction: No such transaction in our bank, and invalid proof",
          "fiat": "INR",
          "createdAt": "2024-06-07T12:25:57.529Z",
          "userIdentifier": "xxxxxxxxx",
          "fullName": "John Doe"
      }
  }