To join the ONDC network, Network Participants (NPs) must be registered in the ONDC registry. Follow these prerequisites and steps to complete your onboarding for Staging, Pre-Production, and Production environments:
-
Domain Name: Ensure your Network Participant (NP) has a valid Fully Qualified Domain Name (FQDN/DNS) that will be included in your subscriber ID (subscriber_id).
e.g., prod.ondcapp.com
-
SSL Certificate: Obtain a valid SSL certificate for your domain. This certificate is used for Online Certificate Status Protocol (OCSP) validation.
-
Whitelisting: Get approval for your Staging, Pre-Production, and Production subscriber_id by submitting a request on the Network Participant Portal:
- Sign up on the Network Participant Portal here and submit your request.
- Complete your profile 100% after signing up.
- From the home menu, find and raise a request for whitelisting under "environment access request." Approval may take 6 to 48 hours.
-
System Configuration: Configure your system with the domain name and SSL certificate. All communications with the ONDC Network must occur through this domain.
You can use the utility here to perform these steps. Choose from the following technologies for generating key pairs:
-
Generate Signing Key Pair: Create a Signing Key Pair using the Ed25519 Algorithm. This will include a
signing_public_key
and asigning_private_key
(both base64 encoded). -
Generate Encryption Key Pair: Create an Encryption Key Pair using the X25519 Algorithm. This includes an
encryption_public_key
(in ASN.1 DER format -> base64 encoded) and anencryption_private_key
(base64 encoded).- Note: Use the Libsodium library for key pair generation. For NodeJS, use the inbuilt Crypto library instead of Libsodium. Ensure the encryption public key is in ASN.1 DER format. Refer to the key format and generation documentation here.
You can perform these steps using the utility here. If a utility is not available for your tech stack, you may create one following the outlined steps.
-
Generate Unique Request ID: Create a unique Request ID (
request_id
). This ID must be unique for each network participant and can be any format (e.g., UUID, number, or alphanumeric). -
Generate SIGNED_UNIQUE_REQ_ID: Sign the
request_id
using thesigning_private_key
from Step 1. The signature should be created using the Ed25519 algorithm without hashing. The on_subscribe utility can help with this. -
Create
ondc-site-verification.html
: Place this file at the subscriber_id path and include theSIGNED_UNIQUE_REQ_ID
generated in Step 4. The registry will check for this file at:https://<subscriber_id>/ondc-site-verification.html
<!-- Contents of ondc-site-verification.html --> <!-- Replace SIGNED_UNIQUE_REQ_ID with the actual value --> <html> <head> <meta name='ondc-site-verification' content='SIGNED_UNIQUE_REQ_ID' /> </head> <body> ONDC Site Verification Page </body> </html>
-
Configure
/on_subscribe
Endpoint: Create the encryption shared key using theencryption_private_key
(from Step 2) and the ONDC public key to decrypt thechallenge_string
received in the/on_subscribe
call using the AES algorithm.ONDC public key (prod) = "MCowBQYDK2VuAyEAvVEyZY91O2yV8w8/CAwVDAnqIZDJJUPdLUUKwLo3K0M=" ONDC public key (pre-prod) = "MCowBQYDK2VuAyEAa9Wbpvd9SsrpOZFcynyt/TO3x0Yrqyys4NUGIvyxX2Q=" ONDC public key (staging) = "MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM="
-
Host
/on_subscribe
Post Endpoint: Deploy the/on_subscribe
endpoint at:https://<subscriber_id>/<callback_url>/on_subscribe
Use the (Node.JS, JAVA, Node, PHP) utility to implement this endpoint.
8. Refer to the SwaggerHub document and FAQs for /subscribe
API
- SwaggerHub Documentation: Request Body and Response
- FAQs for Subscribe Payload: FAQs Document
- ops_no : 1 - Buyer App Registration
- ops_no : 2 - Seller App Registration
- ops_no : 4 - Buyer & Seller App Registration
Note: ops_no 3 & 5 is deprecated as feature of Seller On Record (SOR) in registry is obsolete.
- Create /subscribe request as follows:
1.subscriber_id= YOUR SUBSCRIBER ID (abc.ondcapp.com)
2.callback_url= Relative path to on_subscribe implementation
3.subscriber_url = Relative path to the subscriber_id
4.signing_public_key= <value of sign_public_key generated in step 1>
5.encryption_public_key= <value of enc_dec_public_key generated in step 2>
6.unique_key_id= <generate a unique number for tracking key pairs>
7.For other fields, please refer below swaggerhub link and examples mentioned under heading as ops_no_1, ops_no_2, ops_no_3, ops_no_4 and ops_no_5
https://app.swaggerhub.com/apis-docs/ONDC/ONDC-Registry-Onboarding/2.0.5
- Send created request to URL for /subscribe as below
# For Staging Onboarding
https://staging.registry.ondc.org/subscribe
# For PreProd Onboarding
https://preprod.registry.ondc.org/ondc/subscribe
# For Prod Onboarding
https://prod.registry.ondc.org/subscribe
- The call is received by the respective registry and following operations are performed:
- /subscribe payload schema is verified
- OCSP Check: SSL Certificate is verified
- Domain Verification: ondc-site-verification.html is verified;
- should be hosted on
https://<subscriber_id>/ondc-site-verification.html
- request_id should be signed using the signing private key (without hashing)
- /on_susbcribe is called by the registry with a challenge string hosted on the callback_url
https://<subscriber_id>/<callback_url>/on_subscribe
{ "subscriber_id": "abc.com", "challenge": "encrypted_challenge_string" }
- The challenge string should be decrypted using the shared key (generated in step 6) and answer should be provided as a sync response.
{ "answer": "decrypted_challange_string" }
- Verify whether you have received a successful response. If a success response is not received, refer to the section listing possible errors. If the issue persists, kindly reach out to our support desk using the details provided in step 14 below.
{
"message": {
"ack": {
"status": "ACK"
}
},
"error": {
"type": null,
"code": null,
"path": null,
"message": null
}
}
- Check your record in registry lookup
- /lookup
# For Staging
https://staging.registry.ondc.org/lookup
# For Pre-prod
https://preprod.registry.ondc.org/ondc/lookup
# For PROD
https://prod.registry.ondc.org/lookup
curl --location --request POST 'https://preprod.registry.ondc.org/ondc/lookup' \
--header 'Content-Type: application/json' \
--data-raw '{
"country": "IND",
"domain":"ONDC:RET10"
}'
- /vlookup
# For Staging
https://staging.registry.ondc.org/vlookup
# For Pre-prod
https://preprod.registry.ondc.org/ondc/vlookup
# For PROD
https://prod.registry.ondc.org/vlookup
curl --location 'https://preprod.registry.ondc.org/ondc/vlookup' \
--header 'Content-Type: application/json' \
--data '{
"sender_subscriber_id": "your_sub_id",
"request_id": "27baa06d-f90a-486c-85e5-cc621b787f04",
"timestamp": "2022-09-13T20:45:07.060Z",
"signature": "UNC7Wy8WZ5iQYNBUnHu1wsCtRhZ0P+I4NO5CpP03cNZ+jYuVtXyeMKQs1coU9Q9fpXIJupB8uRVJ5KPbl/x3Bg==",
"search_parameters": {
"country": "IND",
"domain": "ONDC:RET10",
"type": "sellerApp",
"city":"std:080",
"subscriber_id": "counter_party_sub_id"
}
}'
- sender_subscriber_id: subscriber id of request initiator
- request_id: unique identifier for request
- timestamp: current timestamp in RFC3339 format
- signature: search_parameters signed using private key of request initiator: sign(country|domain|type|city|subscriber_id) => - sign(IND|ONDC:RET10|sellerApp|std:080|ondc.org)
- type: enums are "buyerApp", "sellerApp", "gateway"
- In case you are not able to find your record in lookup and vlookup, please report to [email protected]
Please mention below details in email:
# Name : XXXXXXX
# Contact Number : XXXXXXXXXXX
# Subscriber ID : XXX.XX
# Error occurred : Error Code
# Error Description : Error Description received after calling subscriber id.
# Issue or clarification at which step # : Prerequisites or Steps ?
# Issue / Clarification required : XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{
"message": {
"ack": {
"status": "NACK"
}
},
"error": {
"type": "POLICY-ERROR",
"code": "132",
"path": null,
"message": "Subscriber Id is not whitelisted"
}
}
Resolution:
Please connect with ONDC ([email protected]) and get your subscriber ID whitelisted
{
"message": {
"ack": {
"status": "NACK"
}
},
"error": {
"type": "POLICY-ERROR",
"code": "132",
"path": null,
"message": "Timestamp is invalid"
}
}
Resolution:
Need to put timestamp within the stipulated timegap defined by ONDC.
{
"message": {
"ack": {
"status": "NACK"
}
},
"error": {
"type": "POLICY-ERROR",
"code": "132",
"path": null,
"message": "Domain verification is failed"
}
}
Resolution:
The signature generated with signing private key and request id should be put into ondc-site-verification.html (signed using ed25519 algorithm without hashing)
{
"message": {
"ack": {
"status": "NACK"
}
},
"error": {
"type": "POLICY-ERROR",
"code": "132",
"path": null,
"message": "Subscriber id already exists"
}
}
Resolution:
If the subscriber ID is already registered with ONDC, this error will be thrown.
{
"message": {
"ack": {
"status": "NACK"
}
},
"error": {
"type": "POLICY-ERROR",
"code": "132",
"path": null,
"message": "OCSP failed"
}
}
Resolution:
Need to get a valid SSL certificate for the purchased domain.
{
"message": {
"ack": {
"status": "NACK"
}
},
"error": {
"type": "POLICY-ERROR",
"code": "132",
"path": null,
"message": "https://pilot-gateway-1.beckn.nsdl.co.in/option1/test/on_subscribe : Encryption verification is failed"
}
}
Resolution:
Utilize the encrypted private key and ONDC public key, then process the challenge received in the on_subscribe callback. Respond synchronously by providing the decrypted value.
{
"message": {
"ack": {
"status": "NACK"
}
},
"error": {
"type": "POLICY-ERROR",
"code": "132",
"path": null,
"message": " Please provide valid Network Participant [0] Type "
}
}
Resolution:
Incorrect JSON Type Specification: For example, in Option 1, if the Network Participant is registering and the type is set to sellerApp, the aforementioned error will occur. The value should align with the specified options. Option 3 Flag Misalignment: Instead of setting MSN to true, it has been incorrectly set as false, and vice versa for non-MSN cases where the flag is inaccurately set to true.
{
"message": {
"ack": {
"status": "NACK"
}
},
"error": {
"type": "DOMAIN-ERROR",
"code": "129",
"path": null,
"message": "https://{{netowrk_participant_subsctiber_id}} : Domain verification is failed "
}
}
Resolution:
Utilize Plain Request_ID: Network Participants are advised to use the request_id as is, without applying any hashing, when generating the signature. Maintain Consistent Request_ID: Network Participants should ensure the request_id in the request body matches the one used during signature generation to guarantee successful validation. Verify Signing Public Key: Network Participants should include the same signing public key in the request body that corresponds to the signing private key used during the signing process.