Guide

Advanced embed configuration

Two switches for partners whose users are already verified in the partner's own app: skip OroPocket's OTP, and hand over the user's KYC so they never repeat it.

By default, the first time a user opens the hosted embed through your app, OroPocket sends them an OTP, and buying beyond the basics needs our KYC. If your app has already verified the mobile number and done KYC (for example through DigiLocker or an Aadhaar OKYC provider), you can skip both.

Both switches are off by default and set per account by OroPocket. Ask your OroPocket contact for Skip OTP on embed login, Accept partner KYC at user init, or both. Your integration does not change until they are on, and requests that don't use them are never affected.

1. Skip the OTP

With Skip OTP on embed login on, the embed_url you get from /partner/users/init opens straight into the user's account. There is no OTP screen, and nothing changes in your call.

  • New users get an OroPocket account created on that first open, linked to you.
  • People who already use OroPocket are logged in too. Inside your embed they see only what they hold through you (their sub-wallet), never what they hold elsewhere.
  • Use a fresh link every time. Each embed_url works once and for 10 minutes. If you build the URL yourself from a user's permanent user_code, the user is still asked for an OTP: a permanent code can leak through browser history or logs, so it is never treated as a login.
  • Suspended accounts are refused exactly as before.
  • Sandbox. With an oro_test_ key the OTP is skipped too, so you can test the flow end to end.
Skipping the OTP means OroPocket relies on your verification of the mobile number. Only send numbers your app has verified for the person holding the phone, and keep your API key on your server.

2. Send the user's KYC

POST/partner/users/initembed

With Accept partner KYC at user init on, add a kyc object to the same call. We check it on our side (no second verification for the user) and, if it passes, their OroPocket KYC is approved before they open the embed. Their name, date of birth and email are taken from it, so they also skip the profile screen.

FieldTypeDescription
kycobjectoptionalThe user's KYC, as verified in your app. Only on the embed flow (flow "embed").
kyc.panstringrequiredIndividual PAN, e.g. ABCPK1234Z (the 4th character must be P). Case doesn't matter.
kyc.aadhaarstringrequiredThe full 12-digit Aadhaar number, or the masked form "XXXXXXXX1234" (X, x or *; spaces and dashes are ignored). Send masked if that is all you are allowed to keep.
kyc.aadhaar_dataobjectrequiredThe Aadhaar record your OKYC / DigiLocker provider returned, as JSON. Keys we read are listed below; others are ignored. Leave out the photo and the XML (64 KB limit).
kyc.dobstringrequiredDate of birth as YYYY-MM-DD. Must match the record, and the user must be 18 or older.
kyc.emailstringoptionalThe user's email. Falls back to the top-level email; one of the two is required.
kyc.pan_namestringoptionalThe name on the PAN, if you have it. It must share a word with the Aadhaar name.

Keys we read from aadhaar_data (the usual OKYC and DigiLocker spellings both work):

KeyUse
name (required)The legal name. It becomes the user's name on OroPocket, their invoices and their holding certificate.
dob · date_of_birth · dateOfBirthDD-MM-YYYY, DD/MM/YYYY or YYYY-MM-DD. Must equal kyc.dob.
year_of_birthIf the record has only a year, it must match the year of kyc.dob.
masked_aadhaar · aadhaar_last4 · uidIf present, the last 4 digits must match kyc.aadhaar.
address (object) · split_addresshouse, street, landmark, vtc, district, state, pincode.
full_address · address (string)Kept as the full address.
gender · care_of · reference_idKept with the record.
curl -X POST https://api.oropocket.com/partner/users/init \
  -H "Authorization: Bearer oro_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "flow": "embed",
    "mobile": "9876543210",
    "name": "Asha Kumari",
    "email": "asha@example.com",
    "kyc": {
      "pan": "ABCPK1234Z",
      "aadhaar": "XXXXXXXX4321",
      "dob": "1990-08-15",
      "email": "asha@example.com",
      "aadhaar_data": {
        "name": "Asha Kumari",
        "dob": "15-08-1990",
        "gender": "F",
        "care_of": "D/O Ram Kumar",
        "masked_aadhaar": "xxxxxxxx4321",
        "reference_id": "your-okyc-reference",
        "address": {
          "house": "12", "street": "MG Road", "landmark": "Near the park",
          "vtc": "Pune", "district": "Pune", "state": "Maharashtra", "pincode": "411001"
        }
      }
    }
  }'

3. The kyc result

A KYC problem never stops the login. You always get the embed_url, plus a kyc block telling you what happened. If KYC was not approved, the user can complete it in the embed later, the normal way.

Response
{
  "success": true,
  "request_id": "req_xxx",
  "mode": "live",
  "data": {
    "user_code": "usr_xxx",
    "embed_url": "https://connect.oropocket.com/?u=usr_yyy",
    "expires_at": "2026-10-13T09:22:00.000Z",
    "expires_in_seconds": 600,
    "user_existed": false,
    "mode": "live",
    "kyc": { "status": "approved", "errors": [], "persisted": true }
  }
}
kyc.statusMeaning
approvedChecks passed and the user's KYC is approved. persisted is true.
already_verifiedThe user had already completed OroPocket KYC. Nothing was changed.
rejectedSomething didn't pass. errors lists every problem; nothing was saved.
validated_sandboxSandbox key: the data passed the format checks, but nothing is saved and no duplicate check runs.
A rejected result
"kyc": {
  "status": "rejected",
  "persisted": false,
  "errors": [
    { "code": "DOB_MISMATCH", "field": "kyc.dob", "message": "dob does not match aadhaar_data." }
  ]
}
Error codeMeaning
INVALID_PANNot a PAN, or not an individual's PAN.
INVALID_AADHAARNot 12 digits, fails the Aadhaar checksum, or not in the masked form.
AADHAAR_LAST4_MISMATCHThe last 4 digits differ from the ones in aadhaar_data.
INVALID_AADHAAR_DATAaadhaar_data is missing, has no name or date of birth, or is over 64 KB.
INVALID_DOBdob isn't a real YYYY-MM-DD date.
DOB_MISMATCHdob differs from the date (or year) of birth in aadhaar_data.
UNDER_18The user is under 18.
INVALID_EMAILNo email, or not a valid one.
NAME_MISMATCHpan_name and the Aadhaar name share no word.
PAN_IN_USE · AADHAAR_IN_USEAlready verified on a different OroPocket account.
EMAIL_IN_USEThe email belongs to a different OroPocket account.
USER_SUSPENDEDThe account for this mobile is suspended.
KYC_NOT_RECORDEDWe couldn't save it just now. Retry the init, or let the user complete KYC in the app.

Error messages never repeat the values you sent. You can check a user's KYC at any time with GET /partner/users/:user_code/kyc/status (see KYC).

4. Request errors

These refuse the whole request, like any other contract error. No link is issued.

CodeMeaning
403 PARTNER_KYC_NOT_ENABLEDYou sent kyc but Accept partner KYC at user init isn't on for your account. Leave kyc out, or ask OroPocket.
400 INVALID_KYC_FLOWkyc was sent on the trusted-API flow (flow "api"). It only applies to the hosted embed.

5. How we handle the data

  • The KYC is recorded as attested by you, separately from KYC we verified ourselves, with your account against it.
  • We keep the PAN, the Aadhaar number (only the last 4 digits when you send it masked), the name, date of birth, gender, address and email. Photos, XML, signatures and share codes are dropped and never stored.
  • Request bodies are never written to your request logs, and our own logs carry masked values only.
  • Send only KYC you have actually verified, with the user's consent to share it with OroPocket.

Related: Open the embed on a screen (use launch in the same call) and WebView & UPI setup.