Skip to content

Collect LRS remittances from India

This guide uses the Glomo Unified SDK — the Order Checkout journey auto-detects the LRS flow. Make sure the order is created as an LRS order: an order lacking a checkout_type defaults to the standard checkout. See the Unified SDK reference for the full set of journeys and options. To open checkout inside a native mobile app, see Web Checkout in a Mobile App (WebView). If you integrated earlier with the older lrs-checkout-sdk, it continues to work — switch the import to the Unified SDK when convenient.

The sequence diagram below represents the interactions between the investor, broker, Glomo API and Glomo Web SDK.

Workflow for merchants


Integration steps

Below are the steps to integrate the Glomo APIs and Web SDK to enable remittance of funds from investors

Fetch supported banks (optional)

getLrsBanks · GET /v1/lrs/banks · API reference

Fetch the list of banks supported on the remittance flow using this API. Only the banks enabled for your account are listed, so the list can be empty.

API Endpoint

GET https://api.glomopay.com/api/v1/lrs/banks

Request

curl -i -X GET \
  https://api.glomopay.com/api/v1/lrs/banks \
  -H 'Authorization: Bearer <YOUR_JWT_HERE>' \
  -H 'Content-Type: application/json'

Response

[
    { "bank_code": "hdfc", "bank_name": "HDFC bank" },
    { "bank_code": "axis", "bank_name": "Axis bank" }
]

Create a customer

createCustomer · POST /v1/customer · API reference

Create a customer entity in Glomo’s system by adding the customer details such as contact details, name and address.

Note: Call this API when the investor adds funds for the first time. Store the customer_id received in the response and reuse it for the investor’s return journey.

By default, customer uniqueness is enforced on email. On request, this can instead be enforced on PAN (kyc.pan_number) in place of email, so investors are de-duplicated by PAN even if they use different emails. This is off by default — to enable PAN-based uniqueness for your account, reach out to support@glomopay.com.

Customer field restrictions

When you create a customer (POST /customer), Glomo checks the address, city and state fields:

FieldLengthAllowed characters
city2–100 charactersLetters A-Z a-z, digits 0-9, space, and - ' , . & : ( )
state2–100 charactersLetters A-Z a-z, digits 0-9, space, and - ' , . & : (brackets are not allowed)
address2–255 charactersLetters A-Z a-z, digits 0-9, space, and - , . # / ( ) ' [ ] & : \
  • city and state must not start or end with -, ' or ,.
  • Any other character is rejected. Common examples: accented letters such as é or ū, letters from other scripts, the curly apostrophe ’, the long dash –, the non-breaking space (often added by copy and paste), and the symbols _ @ ; " + !.
  • A customer is a duplicate when its email and country match a customer that already exists in your account. Letter case in the email does not matter. Don't create the customer again; find the existing one with GET /customer?email_address=<email> (exact match, case-insensitive) and reuse its id.
  • A request that breaks any of these rules is rejected with 400, and the message field gives the reason. Nothing is created, so you can send the request again once the data is corrected.
  • Don't retry a 400 unchanged; it will be rejected again. Retry only after a 5xx error or a timeout. Where possible, check the data against these rules before you send it.

API Endpoint

POST https://api.glomopay.com/api/v1/customer

Request

curl -i -X POST \
  https://api.glomopay.com/api/v1/customer \
  -H 'Authorization: Bearer <YOUR_JWT_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "John Doe",
    "customer_type": "individual",
    "email": "investor@example.com",
    "phone": "+91-9876543210",
    "dob": "1990-01-01",
    "address": "123 Main St",
    "city": "Anytown",
    "state": "Anystate",
    "country": "IND",
    "pincode": "560048",
    "kyc": {
        "pan_number": "BFQPG7654R"
    }
  }'

Response

{
    "id": "cust_68468bfcxaGo2",
    "name": "John Doe",
    "customer_type": "individual",
    "email": "investor@example.com",
    "phone": "+91-9876543210",
    "address": "123 Main St",
    "city": "Anytown",
    "state": "Anystate",
    "country": "IND",
    "pincode": "560048",
    "status": "active",
    "created_at": "2025-06-09T07:23:40.598Z",
    "updated_at": "2025-06-09T07:23:40.598Z",
    "kyc": {
        "pan_number": "BFQPG7654R"
    }
}

Create a bank account

createLrsCustomerBankAccount · POST /v1/customer/{id}/bank_account · API reference

Create a bank account entity in Glomo’s system by adding the bank account information of the remitter.

Note: Call this API when the investor adds funds for the first time. Store the acclrs_id received in the response and reuse it for the investor’s return journey.

The id returned in the API response should be passed as a value of bank_account_id in the Create an Order API request.

bank_customer_id is the investor's customer ID at their bank. It is optional for every bank. It is checked only for HDFC and Kotak, where it must contain only digits and have a length that bank accepts, or the call returns 400. For other banks the value is stored as sent. For HDFC and Kotak, if not provided, the checkout will prompt the customer to enter this value during the payment flow.

Account number restrictions

When you add a customer's bank account (POST /customer/{id}/bank_account), Glomo checks that the account_number is digits only and that its length is within the range the bank accepts:

BankAccepted length
HDFC14–15 digits
IDFC9–11 digits
ICICI12–15 digits
Axis10–15 digits
Kotak10–14 digits
  • Send the account number exactly as the bank issued it: digits only, with no spaces, hyphens or other characters. Keep any leading zeros.
  • A number outside the range is rejected with 400. The error message names the bank and the length it expects. Nothing is created or changed, so you can retry once the number is corrected.
  • Don't retry the same number unchanged; it will be rejected again. Check the number with the customer first.
  • These ranges are confirmed with each bank. Some older accounts may not follow a bank's current format. If you have a valid account number that falls outside its range, contact Glomo support and we will check it with the bank.

API Endpoint

POST https://api.glomopay.com/api/v1/customer/{customer_id}/bank_account

Request

curl -i -X POST \
  https://api.glomopay.com/api/v1/customer/cust_68468bfcxaGo2/bank_account \
  -H 'Authorization: Bearer <YOUR_JWT_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "bank_code": "hdfc",
    "account_number": "12345678901234",
    "bank_customer_id": "12345678"
  }'

Response

{
    "id": "acclrs_68468c03g9xt7",
    "bank_code": "hdfc",
    "account_number": "12345678901234",
    "bank_customer_id": "12345678"
}

Update Bank Customer ID

updateLrsCustomerBankAccount · PATCH /v1/customer/{id}/bank_account/{bank_account_id} · API reference

Use Case: In case the customer has provided an incorrect Bank Customer ID in the Create a Bank Account API, call this API endpoint to update the Bank Customer ID in Glomo.

API Endpoint

PATCH https://api.glomopay.com/api/v1/customer/{customer_id}/bank_account/{bank_account_id}

Request

curl --location --request PATCH 'https://api.glomopay.com/api/v1/customer/cust_68468bfcxaGo2/bank_account/acclrs_68468c03g9xt7' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <YOUR_JWT_HERE>' \
  --data '{
    "bank_customer_id": "87654321"
  }'

Response

{
    "id": "acclrs_68468c03g9xt7",
    "bank_code": "hdfc",
    "account_number": "12345678901234",
    "bank_customer_id": "87654321"
}

Create a Beneficiary (optional)

createBeneficiaryV2 · POST /v2/beneficiaries · API reference

Create a Beneficiary entity in Glomo by providing the receiver’s bank account details. This entity is required when beneficiaries are dynamic (i.e., a different beneficiary per end-user of the broker/fund, or per transaction) and should be created via API.

If there is one fixed beneficiary shared across all users, you do not need to create a Beneficiary per user in Glomo. In this scenario, the beneficiary can be configured once in Glomo’s backend system and reused for all transactions.

Note: For LRS beneficiaries, the intermediate_bank.swift_code field is required. This is the SWIFT/BIC code of the correspondent/intermediary bank used to route the remittance.

API Endpoint

POST https://api.glomopay.com/api/v2/beneficiaries

Request

curl -i -X POST \
  https://api.glomopay.com/api/v2/beneficiaries \
  -H 'Authorization: Bearer <YOUR_JWT_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "category": "lrs",
    "beneficiary": {
      "name": "ACME Corporation",
      "type": "business",
      "email": "finance@acme.com",
      "phone": "+1-555-123-4567",
      "nickname": "ACME Primary Account",
      "address": {
        "address_line1": "123 Business Park",
        "address_line2": "Suite 100",
        "city": "New York",
        "state": "NY",
        "country_code": "USA",
        "postal_code": "10001"
      }
    },
    "bank_account": {
      "account_number": "1234567890",
      "name": "Citibank NA",
      "swift_code": "CITIUS33",
      "local_routing_number": "021000089",
      "currency": "USD",
      "address": {
        "address_line1": "388 Greenwich Street",
        "city": "New York",
        "state": "NY",
        "country_code": "USA",
        "postal_code": "10013"
      },
      "intermediate_bank": {
        "name": "JPMorgan Chase Bank",
        "country": "USA",
        "swift_code": "CHASUS33",
        "account_number": "123456789"
      }
    }
  }'

Response

{
  "id": "bene_5JU9yv0lGSUP",
  "name": "ACME Corporation",
  "type": "business",
  "category": "lrs",
  "email": "finance@acme.com",
  "phone": "+1-555-123-4567",
  "nickname": "ACME Primary Account",
  "created_at": "2025-01-15T10:00:00Z",
  "updated_at": "2025-01-15T10:00:00Z",
  "address": {
    "address_line1": "123 Business Park",
    "address_line2": "Suite 100",
    "city": "New York",
    "state": "NY",
    "country_code": "USA",
    "postal_code": "10001"
  },
  "bank_account": {
    "account_number": "1234567890",
    "name": "Citibank NA",
    "swift_code": "CITIUS33",
    "local_routing_number": "021000089",
    "currency": "USD",
    "address": {
      "address_line1": "388 Greenwich Street",
      "city": "New York",
      "state": "NY",
      "country_code": "USA",
      "postal_code": "10013"
    },
    "intermediate_bank": {
      "name": "JPMorgan Chase Bank",
      "country": "USA",
      "swift_code": "CHASUS33",
      "account_number": "123456789"
    }
  }
}

Create a quote

createLrsQuote · POST /v1/lrs/quotes · API reference

Create a quote from the server by passing the amount to be remitted and the bank of the customer. Using this API you can display FX rate, tax and net USD to your user before proceeding. Please note that all currency fields are represented in minor units (e.g., cents, paisa, or equivalent subunits).

In the response:

  • fx_rate is always INR per 1 USD, whichever direction you quote in. "84.85" means ₹84.85 to $1.
  • total_tax is the GST, an integer in paisa. 7906 is ₹79.06.
  • For an INR-to-USD quote, to.amount is the USD remitted after the GST is deducted from the INR amount. Pass it as the order's amount.
  • expires_at is when the quote expires. An order created from the quote expires at the same time.

Note: The quote_id generated from this API is valid for 30 minutes from the time of creation; expires_at gives the exact time. The displayed exchange rate is indicative. Actual exchange rate and final INR debit (incl. GST & TCS) are set by the banking partner.

API Endpoint

POST https://api.glomopay.com/api/v1/lrs/quotes

Request

curl -i -X POST \
  https://api.glomopay.com/api/v1/lrs/quotes \
  -H 'Authorization: Bearer <YOUR_JWT_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "bank_code": "hdfc",
    "source_amount": 4400000,
    "source_currency": "INR",
    "target_currency": "USD"
  }'

Response

{
    "id": "quote_6ab60de4Kx7Pq",
    "from": {
        "amount": 4400000,
        "currency": "INR"
    },
    "to": {
        "amount": 51763,
        "currency": "USD"
    },
    "fx_rate": "84.85",
    "bank_code": "hdfc",
    "total_tax": 7906,
    "expires_at": "2026-09-25T06:30:04.113Z",
    "created_at": "2026-09-25T06:00:04.113Z"
}

Create an order on the server

createOrder · POST /v1/orders · API reference

Initiate the payment process by creating an order from your server using your secret API keys and the previously created quote ID.

  1. The id returned in the API response should be passed to the web sdk. This ensures the payment is securely linked to the correct order and prevents tampering.
  2. The Order API accepts amounts in USD, with the value expressed in cents. currency must be USD, and amount must equal the USD side of the quote: to.amount for an INR-to-USD quote, from.amount for a USD-to-INR quote.
  3. remittance_information is a reference string that helps identify the purpose of the remittance. It cannot be empty, must contain only alphanumeric characters and hyphens (a–z, A–Z, 0–9, -), with no spaces or special characters, and must not exceed 20 characters in length.
  4. request_id is an optional idempotency key. Creating an order with a request_id that was already used returns a 400 error (Order already exists for this request_id).
  5. purpose_code is optional. An LRS order accepts only S0001 or S0002, and uses S0001 if you leave it out. Any other value returns a 400 error.
  6. An LRS order expires when its quote expires (see expires_at on the quote): the order's expires_at is set to the quote's. Creating an order from a quote that has already expired returns a 400 error. The order's status may not show expired straight away. It usually updates within about 5 minutes, and not until any open payment attempt on the order has resolved; an attempt already under way can still complete the order. Use the quote's expires_at, not the order's status, to decide whether the customer can start a new payment.

Note: If the quote expires while the investor has checkout open, payment creation fails with an error saying the quote or order has expired. Create a new quote and a new order, and open checkout again with the new order ID.

API Endpoint

POST https://api.glomopay.com/api/v1/orders

Request

curl -i -X POST \
  https://api.glomopay.com/api/v1/orders \
  -H 'Authorization: Bearer <YOUR_JWT_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "customer_id": "cust_68468bfcxaGo2",
    "currency": "USD",
    "amount": 51763,
    "request_id": "unique_order_request_id_123",
    "notes": {
      "key1": "some note"
    },
    "lrs": {
        "lrs_quote_id": "quote_6ab60de4Kx7Pq",
        "remittance_information": "REF12345",
        "bank_account_id": "acclrs_68468c03g9xt7",
        "beneficiary_id": "bene_5JU9yv0lGSUP"
    }
  }'

Note: LRS orders don't store invoice_number, invoice_description, invoice_amount, reference_number, document_id or product; they come back as null or are left out. A value you send is still validated (a malformed invoice_number, for example, returns 400), so leave these fields out.

Response

{
    "id": "order_6ab60f0cLm4Wz",
    "customer_id": "cust_68468bfcxaGo2",
    "document_id": null,
    "status": "active",
    "currency": "USD",
    "amount": 51763,
    "remaining_amount": 51763,
    "already_paid_amount": 0,
    "purpose_code": "S0001",
    "invoice_amount": null,
    "invoice_description": null,
    "invoice_number": null,
    "notes": {
        "key1": "some note"
    },
    "expires_at": "2026-09-25T06:30:04Z",
    "created_at": "2026-09-25T06:05:00Z",
    "updated_at": "2026-09-25T06:05:00Z",
    "reference_number": null,
    "lrs": {
        "lrs_quote_id": "quote_6ab60de4Kx7Pq",
        "remittance_information": "REF12345",
        "bank_account_id": "acclrs_68468c03g9xt7",
        "beneficiary_id": "bene_5JU9yv0lGSUP"
    }
}

Add the payment button on your website or app

Integrate an “Add Funds” button into your client-side interface.

  1. Add the provided code snippet to your website or app to launch Glomo’s sdk.
  2. When the user clicks the button, the checkout form will open, using the order_id created using above API.
  3. Handle payment initiation success and failure events using the provided handler functions.
  4. On payment completion, you’ll receive either a payment object (on successful authorisation by the user) or an error object (on failure).
  5. Send this information back to your server for order fulfillment or to trigger a retry if the payment failed.
<!DOCTYPE html>
<html>
<head>
    <title>Glomo checkout integration</title>
</head>
<body>
    <button id="pay-button">Pay with Glomo</button>

    <script type="module">
        import { GlomoCheckoutApi } from 'https://unified-sdk.glomopay.com/index.js';

        document.getElementById('pay-button').addEventListener('click', async () => {
            try {
                // Initialize the checkout
                const checkout = new GlomoCheckoutApi({
                    publicKey: 'your-public-key-here',
                    orderId: 'unique-order-id-123', // an LRS order — the Unified SDK auto-detects the LRS flow
                });

                // Handle payment success
                checkout.on('payment.success', (data) => {
                    console.log('Payment successful:', data);
                    // Handle successful payment
                    window.location.href = '/payment-success';
                });

                // Handle payment failure
                checkout.on('payment.failure', (data) => {
                    console.log('Payment failed:', data);
                    // Handle failed payment
                    alert('Payment failed. Please try again.');
                });

                // Handle checkout close
                checkout.on('checkout.closed', () => {
                    console.log('Checkout closed by user');
                    // Handle checkout modal close
                });

                // Open the checkout modal
                await checkout.open();

            } catch (error) {
                console.error('Checkout error:', error);
                alert('Unable to open checkout. Please try again.');
            }
        });
    </script>
</body>
</html>

Verify the SDK response and signature on the server

The process to verify the signature can be found here.

Verify payment status

Payment status can be tracked via the following ways

  1. Dashboard Monitoring: View real-time updates for all payments in the Glomo merchant dashboard.
  2. Payment API Polling: Programmatically check payment status using Glomo’s Payment APIs.
  3. Webhook Notification: Get instant notifications on payment status changes directly to your server.

Test it in sandbox

Sandbox runs the same checkout your customers see, against a simulated bank. The only change to your integration is the keys:

  • Create the customer, bank account, quote and order from your server with your test secret key.
  • Open checkout with your test public key (test_…). Glomo routes to sandbox from the key prefix, so you load the same SDK from the same hosts as in production. You can test a production build of your app this way.

An order created with live keys cannot be opened with a test key, and the other way round.

Complete the OTP step

The simulated bank does not send an OTP. Enter 123456; any other value is rejected as a wrong OTP.

Trigger the document upload step

In production, the bank asks for an ITR or a bank statement when the customer's account is less than a year old. In sandbox, checkout asks for it only for these bank accounts:

Bankbank_codeaccount_number
HDFChdfc50100117322072
Axisaxis925010000230876

Create the bank account with one of them, use its id as bank_account_id on the order, and use a quote for the same bank_code. The bank must be one that Fetch supported banks returns for your sandbox account. After the OTP, checkout shows the document step. With any other account number, it skips the step.

Upload an ITR to test the step: any readable PDF within the size limit checkout shows is accepted.

Once a payment with an uploaded ITR succeeds, later payments by the same customer reuse that ITR for 90 days and skip the step. To see the step again, create a new customer and add the same test account to them.

Mark the payment successful

There is no bank confirmation in sandbox, so a payment completed in checkout stays In Progress. To simulate the bank's confirmation:

  1. Log in to the Dashboard.
  2. Open the Payment Details page for the payment.
  3. Click Update Status on the right side of the screen.
  4. Select Success and click Confirm.

In production, Glomo updates the status automatically once the bank confirms the payment.


For answers to common integration questions, see the FAQ.