Orders
This is the core of the integration — converting brand selections into actual gift card vouchers. This page covers the order lifecycle from placement to handling all response states.
The Order Object
id string
Unique identifier for the order.
referenceId string
Idempotency key from source system.
status string
Order status. Values: SUCCESS, FAILED, PROCESSING, CANCELLED, REVERSED
vouchers Voucher[] nullable
List of vouchers. See Voucher object.
failureReason string nullable
Error message. Only populated when order status is FAILED.
The Voucher Object
id string
Unique identifier for the voucher.
cardType string
Type of card. Values: CARD_NUMBER_SECURED, PIN_NO_SECURED, CARD_AND_PIN_NO_SECURED
cardPin string
PIN for the voucher.
cardNumber string
Card number for the voucher.
validTill date nullable
Expiry date of the voucher. Format: YYYY-MM-DD
amount number
Voucher amount.
Place an Order
/v1/partners/ordersGenerate vouchers for a brand.
- If vouchers are successfully generated, the status will be
SUCCESSand the vouchers list will contain voucher data. - If status is
PROCESSING, voucher generation is taking time. Poll the status or listen for webhooks. - In case of
PROCESSING, the voucher list will be empty.
Request Body Fields
| Field | Type | Required | Description |
|---|---|---|---|
productId | string | Required | Brand/product ID from the catalog |
referenceId | string | Required | Your idempotency key (max 40 chars, globally unique) |
amount | number | Required | Total order amount (must = sum of denomination × qty) |
denominationDetails[] | array | Required | List of {denomination, quantity} pairs |
customerDetails | object | Conditional | Required for B2C, nullable for B2B |
deliveryDetails | object | Optional | Only if Hubble handles voucher delivery for you |
customerDetails child attributes
- customerDetails.name
string— Customer name. - customerDetails.phoneNumber
string— Customer phone number. - customerDetails.email
string— Customer email address.
deliveryDetails child attributes
- deliveryDetails.recipientName
stringoptional — Name of the recipient. - deliveryDetails.recipientType
string— Recipient type. Values:SELF,OTHER - deliveryDetails.recipientPhoneNumber
string— Recipient phone number. - deliveryDetails.senderName
stringoptional — Name of the sender. - deliveryDetails.wishMessage
stringoptional — Personalized message for the recipient.
referenceIdmust be globally unique, max 40 chars, cannot reuse even for failed ordersdenominationDetailsmust match brand's allowed denominationsamountmust equal sum of all (denomination × quantity)
Example Request
curl -X POST "https://api.dev.myhubble.money/v1/partners/orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-H "X-REQUEST-ID: 239774a8-f59c-496c-bb52-ceb683d60af3" \
-d '{
"productId": "01GMAW822RPDJ5C50XK24QC2C4",
"referenceId": "ORD-2026-001",
"amount": 1000,
"denominationDetails": [
{ "denomination": 500, "quantity": 2 }
],
"customerDetails": {
"name": "John Doe",
"phoneNumber": "9876543212",
"email": "john@example.com"
}
}'
Example Response
{
"id": "01KJA7HBZAPKDN0VVXTVN6R41H",
"referenceId": "ORD-2026-001",
"status": "SUCCESS",
"vouchers": [
{
"id": "voucher_id",
"cardType": "CARD_AND_PIN_NO_SECURED",
"cardPin": "112233",
"cardNumber": "2359481287412",
"validTill": "2027-02-25",
"amount": 500
},
{
"id": "voucher_id",
"cardType": "CARD_AND_PIN_NO_SECURED",
"cardPin": "445566",
"cardNumber": "2359481287413",
"validTill": "2027-02-25",
"amount": 500
}
],
"failureReason": null
}
B2B: customerDetails is nullable — may be omitted if end recipient is unknown at order time.
B2C: customerDetails is mandatory. phoneNumber is required. If you don't have the user's email, use a fallback (e.g., noreply@yourcompany.com).
phoneNumber must look realistic — use a valid 10-digit number (e.g., 9999999999). Avoid obviously invalid formats.
Order Response States
| Status | Meaning | Your Action |
|---|---|---|
| SUCCESS | Vouchers generated — data in vouchers[] | Display vouchers to user |
| PROCESSING | Generation in progress — vouchers[] is empty | Listen for webhook OR poll |
| FAILED | Generation failed — see failureReason | Show error, allow retry with new referenceId |
| CANCELLED | Cancelled by client request | Confirm cancellation to user |
| REVERSED | Reversed by client request | Process refund if applicable |
Let us walk through the three primary states with real examples.
Handling SUCCESS Orders
When an order completes successfully, the response includes a vouchers[] array with the generated gift card details. Here is a complete example using Flipkart as the brand.
Example: Placing a Flipkart Order (Staging)
Brand: Flipkart | Product ID: 01GMMNJECTDZAG2YS61K58HVG8 | Amount: Rs 500
Request
curl -X POST "https://api.dev.myhubble.money/v1/partners/orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-H "X-REQUEST-ID: 239774a8-f59c-496c-bb52-ceb683d60af3" \
-d '{
"productId": "01GMMNJECTDZAG2YS61K58HVG8",
"referenceId": "ref_1772006406973_tfrkrtu",
"amount": 500,
"denominationDetails": [
{ "denomination": 500, "quantity": 1 }
],
"customerDetails": {
"name": "Test User",
"phoneNumber": "9876543212",
"email": "test@example.com"
}
}'
SUCCESS Response (HTTP 200)
{
"id": "01KJA7HBZAPKDN0VVXTVN6R41H",
"referenceId": "ref_1772006406973_tfrkrtu",
"status": "SUCCESS",
"vouchers": [
{
"id": "01KJA7HF412HR53Z21GCX68XMD",
"cardType": "CARD_AND_PIN_NO_SECURED",
"cardPin": "215744",
"cardNumber": "8090920011768104",
"validTill": "2027-02-25",
"amount": 500
}
],
"failureReason": null
}
What to Do on SUCCESS
- Extract the
vouchers[]array — each object contains the gift card credentials. - Check the
cardTypefield to determine what to display to the end user. In this Flipkart example,CARD_AND_PIN_NO_SECUREDmeans the customer needs both the card number and PIN to redeem. - Display credentials: Show the
cardNumberandcardPinto the customer. - Show the expiry date: The
validTillfield tells the customer when the voucher expires. - Store the order: Save the Hubble
idand yourreferenceIdfor reconciliation.
CARD_AND_PIN_NO_SECURED— Show both cardNumber and cardPin (like this Flipkart example)CARD_NUMBER_SECURED— Show only the cardNumber (cardPin will be null)PIN_NO_SECURED— Show only the cardPin (cardNumber will be null)
Always check the brand's cardType before building your display logic. Handle null values gracefully.
Handling FAILED Orders
When an order fails, the response includes an empty vouchers[] array and a failureReason explaining what went wrong. Here is an example using Jiomart as the brand. (Brands like Jiomart and Myntra are configured to fail in staging.)
Example: Placing a Jiomart Order (Staging)
Brand: Jiomart | Product ID: 01J1W4D2KRHMJZKPAQWXCEMF4M | Amount: Rs 500
Request
curl -X POST "https://api.dev.myhubble.money/v1/partners/orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-H "X-REQUEST-ID: 239774a8-f59c-496c-bb52-ceb683d60af3" \
-d '{
"productId": "01J1W4D2KRHMJZKPAQWXCEMF4M",
"referenceId": "ref_1772017611584_94lcjp8",
"amount": 500,
"denominationDetails": [
{ "denomination": 500, "quantity": 1 }
],
"customerDetails": {
"name": "Test User",
"phoneNumber": "9876543212",
"email": "test@example.com"
}
}'
FAILED Response (HTTP 200)
The HTTP status is still 200. The failure is indicated by the status field in the response body.
{
"id": "01KJA7NYJHHRPQ47VMN4ZN3JFT",
"referenceId": "ref_1772017611584_94lcjp8",
"status": "FAILED",
"vouchers": [],
"failureReason": "Brand not available"
}
What to Do on FAILED
- Read the
failureReason— in this case, "Brand not available" means Jiomart is not currently active or has no available providers. - Do NOT reuse the
referenceId— even though the order failed, the referenceIdref_1772017611584_94lcjp8is now consumed. You must generate a new one for any retry. - Check the brand status — call
GET /v1/partners/products/:productIdto verify if the brand is ACTIVE before retrying. - Inform the user — show a meaningful error message. Do not expose raw error strings to end users.
- Log everything — save the Hubble
id, yourreferenceId, and thefailureReasonfor debugging.
E200— Voucher generation failed. This is a provider-side failure. Retry after 1–2 minutes. If persistent, contact Hubble support with X-REQUEST-ID.E201— Provider polling failed. Same resolution as E200.cardNumber TypeError— Partners have reported TypeErrors when reading the cardNumber field. Handle cases where cardNumber may be null (for PIN_NO_SECURED brands).
Common Failure Reasons
| Reason | Resolution |
|---|---|
| "Brand not available" | The brand is INACTIVE or has no active providers. Try a different brand or wait. |
| "Voucher generation failed" | Provider-side failure (E200). Retry after 1–2 minutes. |
| "Insufficient balance" | Wallet balance too low (E300). Top up before retrying. |
| "Denomination not available" | The denomination is not in the brand's allowed list (E150). Refresh your catalog. |
Error messages (reasons) are derived from the corresponding error codes. You must validate the error code and message before displaying it on the UI, as not all errors are meant for end customers and some should be handled internally.
Handling PROCESSING Orders
Some orders do not resolve immediately. When voucher generation takes time (e.g., for large orders or certain providers), the API returns a PROCESSING status. The vouchers[] array will be empty, and you need to wait for the final state.
If an order is returned with the status PROCESSING, follow this protocol:
- Begin polling the Get Order endpoint — start polling 1 minute after order placement.
- Limit polling to a maximum of 5 attempts at reasonable intervals.
- Optionally, set up the Order Reached Terminal State webhook (recommended).
- You may configure your system to listen for the webhook to receive the final order status automatically instead of relying only on polling.
If the order remains in PROCESSING status after 15 minutes, mark it as FAILED on your side and contact Hubble support for further assistance.
In staging, all Myntra and Flipkart orders go into PROCESSING state initially. This allows you to test your webhook or polling logic:
- Myntra orders terminate to
FAILEDstate - Flipkart orders terminate to
SUCCESSstate
Example 1: Myntra Order (Terminates to FAILED)
Brand: Myntra | Product ID: 01GMAW9HTBB70C8WQQTHW6R8SR | Amount: Rs 500
Use this example to test how your system handles orders that go through PROCESSING and eventually fail.
Request
curl -X POST "https://api.dev.myhubble.money/v1/partners/orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-H "X-REQUEST-ID: 239774a8-f59c-496c-bb52-ceb683d60af3" \
-d '{
"productId": "01GMAW9HTBB70C8WQQTHW6R8SR",
"referenceId": "ref_myntra_processing_test",
"amount": 500,
"denominationDetails": [
{ "denomination": 500, "quantity": 1 }
],
"customerDetails": {
"name": "Test User",
"phoneNumber": "9876543212",
"email": "test@example.com"
}
}'
Initial PROCESSING Response (HTTP 200)
{
"id": "01KRE5EBMP5ZN5EMDHTPJY9RCF",
"referenceId": "ref_myntra_processing_test",
"status": "PROCESSING",
"vouchers": [],
"failureReason": null
}
Key observations: The status is PROCESSING, vouchers[] is empty (no gift cards yet), and failureReason is null (it has not failed yet — it is still in progress).
Terminal State: FAILED
After polling or receiving the webhook, call GET /v1/partners/orders/01KRE5EBMP5ZN5EMDHTPJY9RCF to get the final state:
{
"id": "01KRE5EBMP5ZN5EMDHTPJY9RCF",
"referenceId": "ref_myntra_processing_test",
"status": "FAILED",
"vouchers": [],
"failureReason": "Voucher generation failed"
}
Example 2: Flipkart Order (Terminates to SUCCESS)
Brand: Flipkart | Product ID: 01GMMNJECTDZAG2YS61K58HVG8 | Amount: Rs 50
Use this example to test how your system handles orders that go through PROCESSING and eventually succeed.
Request
curl -X POST "https://api.dev.myhubble.money/v1/partners/orders" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <access_token>" \
-H "X-REQUEST-ID: 339774a8-f59c-496c-bb52-ceb683d60af4" \
-d '{
"productId": "01GMMNJECTDZAG2YS61K58HVG8",
"referenceId": "ref_flipkart_processing_test",
"amount": 50,
"denominationDetails": [
{ "denomination": 50, "quantity": 1 }
],
"customerDetails": {
"name": "Test User",
"phoneNumber": "9876543212",
"email": "test@example.com"
}
}'
Initial PROCESSING Response (HTTP 200)
{
"id": "01KRE64AH1YV85B97KZ4JWJGBC",
"referenceId": "ref_flipkart_processing_test",
"status": "PROCESSING",
"vouchers": [],
"failureReason": null
}
Key observations: The status is PROCESSING, vouchers[] is empty, and failureReason is null — the order is still being processed.
Terminal State: SUCCESS
After polling or receiving the webhook, call GET /v1/partners/orders/01KRE64AH1YV85B97KZ4JWJGBC to get the final state:
{
"id": "01KRE64AH1YV85B97KZ4JWJGBC",
"referenceId": "ref_flipkart_processing_test",
"status": "SUCCESS",
"vouchers": [
{
"id": "01KRE64VOUCHER001",
"cardType": "CARD_AND_PIN_NO_SECURED",
"cardPin": "834291",
"cardNumber": "5012340098761234",
"validTill": "2027-02-25",
"amount": 50
}
],
"failureReason": null
}
What to Do Next: Wait for Resolution
You have two options to know when the order resolves:
Option A: Polling
If webhooks are not set up, poll the Get Order endpoint:
- Wait at least 1 minute after order placement before the first poll.
- Poll
GET /v1/partners/orders/:orderIdat reasonable intervals (e.g., every 2 minutes). - Limit polling to a maximum of 5 attempts.
- If the order remains PROCESSING after 15 minutes, mark it as FAILED on your side and contact Hubble support.
Option B: Webhook (Recommended)
If you have the Order Reached Terminal State webhook configured, Hubble will push a notification to your endpoint when the order resolves to SUCCESS or FAILED.
// Webhook payload you will receive:
{
"orderId": "01KRE64AH1YV85B97KZ4JWJGBC",
"status": "SUCCESS"
}
On receiving this webhook, call GET /v1/partners/orders/:orderId to fetch the full order details including the vouchers[] array.
Handling Timeouts
If your HTTP request to the Place Order API times out (no response received at all):
- Call
GET /v1/partners/orders/by-reference/:referenceIdto check if the order was created. - A 404 response means the order was NOT created — you may safely retry with the same
referenceId. - Any other response means the order exists — process based on the returned status (SUCCESS, FAILED, or PROCESSING).
Get an Order
/v1/partners/orders/:orderIdor
/v1/partners/orders/by-reference/:referenceIdGet the order details based on Hubble order ID or your reference ID.
Response Body
Returns The Order Object.
Example:
{
"id": "order_id",
"referenceId" : "idempotency key from source system",
"status": "SUCCESS/FAILED/PROCESSING/REVERSED",
"vouchers": [
{
"id": "voucher_id",
"cardType" : "CARD_NUMBER_SECURED/PIN_NO_SECURED/CARD_AND_PIN_NO_SECURED",
"cardPin": "112233",
"cardNumber": "2359481287412",
"validTill": "2022-11-22",
"amount": "100"
},
{
"id": "voucher_id",
"cardType" : "CARD_NUMBER_SECURED/PIN_NO_SECURED/CARD_AND_PIN_NO_SECURED",
"cardPin": "112233",
"cardNumber": "2359481287412",
"validTill": "2022-11-22",
"amount": "100"
}
]
"failureReason": "Error message", //Optional
}
Get a Voucher
/v1/partners/orders/vouchers/:idGet details of an individual voucher.
Response Body
Returns The Voucher Object.
{
"id": "voucher_id",
"cardType": "CARD_NUMBER_SECURED",
"cardPin": "112233",
"cardNumber": "2359481287412",
"validTill": "2022-11-22",
"amount": 100
}