Coins Integration (Partner Managed)
Do You Need Coins Integration?
The Hubble SDK works in two modes:
-
Plain SDK (no coins): If your app does not have any in-app currency (coins, points, rewards, cashback, etc.), you are using the plain SDK. Gift card purchases are paid entirely through the payment gateway. You can skip this entire section.
-
SDK with Coins: If your app has its own in-app currency that users should be able to spend on gift card purchases, read on. You will need to build three API endpoints on your backend.
If you don't currently have a coin or rewards system in your app but want to offer one, Hubble provides a managed currency engine. With Currency Engine, Hubble manages the coin infrastructure for you - you don't need to build balance, debit, or reverse APIs. Contact the Hubble support team to learn more about this option.
Full Reference: Hubble Currency Engine
Technical Requirements
- HTTPS required: All three coin endpoints must be served over HTTPS with TLS 1.2 or higher.
- Content-Type: All requests and responses must use
application/json. - Base URL: The base URL for coin APIs depends on your SSO method:
- Classic SSO: The coin APIs use the same integration base URL you provided for SSO. You do not need to register a separate URL. If your SSO is at
https://api.yourapp.com/hubble/sso, your coin endpoints must be athttps://api.yourapp.com/hubble/balance,/debit, and/reverse. - JWT_PUSH: The
/ssoendpoint is not invoked. Only the Coins API endpoints will be called using the separately configured Coin Base URL in the integration portal.
- Classic SSO: The coin APIs use the same integration base URL you provided for SSO. You do not need to register a separate URL. If your SSO is at
Authentication
All requests from Hubble include the X-Hubble-Secret header with the same pre-shared secret used for SSO. Validate this header on every request to ensure the call is genuinely from Hubble.
How Coins Work
If your app has its own rewards currency (coins, points, cashback, etc.), you can integrate it with Hubble so that users can spend their balance for discounts on gift card purchases directly within the SDK. Hubble calls your coin APIs during the purchase flow - you maintain full control of your coin ledger.
If you do not have a coin system, skip this page entirely.
Hubble supports three models for how coins interact with the purchase. The model is configured on Hubble's side during onboarding - you choose one model, and it applies to all transactions for your integration.
Model 1: Coins as Additional Discount
Coins give the user extra savings on top of the brand's existing discount. The brand discount applies regardless of whether the user spends coins.
Example: A user buys a ₹1,000 Amazon voucher that already has a 5% discount (₹50 off). If the user has 100 coins (at 1 coin = ₹1), they can use them to get an additional ₹100 off. Their total savings become ₹150.
| Component | Amount |
|---|---|
| Gift Card Value | ₹1,000 |
| Brand Discount (5%) | −₹50 |
| Coins Used (100 coins @ ₹1 each) | −₹100 |
| User Pays | ₹850 |
The user gets ₹50 from the brand discount and ₹100 from coins, saving ₹150 total. If the user had zero coins, they would still get the ₹50 brand discount and pay ₹950.
Model 2: Coins to Fund the Discount
Coins are required to unlock the discount. The user must spend coins to receive the discount. Without enough coins, the user pays full price with no discount. In this model, the payment gateway (PG) step is optional - if the coin value fully covers the discount, no PG transaction is needed.
Example: A user buys a ₹1,000 Amazon voucher with a ₹20 discount. To get this discount, the user must have and spend at least 20 coins. If they have 0 coins, they pay the full ₹1,000.
| Component | Amount |
|---|---|
| Gift Card Value | ₹1,000 |
| Discount Available | ₹20 |
| Coins Required to Unlock | 20 coins minimum |
| User Pays (with 20+ coins) | ₹980 |
| User Pays (with 0 coins) | ₹1,000 |
In this model, the discount exists but is gated behind coin spending. This is useful when you want to incentivize users to earn and hold coins in your app before they can access gift card discounts.
Model 3: Coins-Only Payment
The entire purchase is paid using coins. Here, the discount availability is optional with no payment gateway involved - the user's coin balance is debited for the full gift card value. This model is typically used when your coins have a direct monetary value and you want to offer gift cards as a redemption option for your rewards program.
| Component | Amount |
|---|---|
| Gift Card Value | ₹5,000 |
| Coins Debited (500 coins @ ₹1 each) | 500 coins |
| User Pays via Gateway | ₹0 |
The coin burn model, conversion ratio (e.g., 1 coin = ₹1), and usage limits are configured on Hubble's side. Discuss your preferred model with the Hubble team during onboarding and add the conversion ratio to the integration portal.
What You Need to Build
You need to build three API endpoints on your backend. Hubble will call these endpoints during the gift card purchase flow.
For Classic SSO: All three endpoints use the same integrationBaseUrl you provided for SSO. For example, if your integrationBaseUrl is https://api.yourapp.com/hubble, Hubble will call:
GET https://api.yourapp.com/hubble/balancePOST https://api.yourapp.com/hubble/debitPOST https://api.yourapp.com/hubble/reverse
For JWT_PUSH: The /sso endpoint is not invoked. Only the Coins API endpoints will be called using the separately configured Coin Base URL in the integration portal.
1. Get Coin Balance
Hubble calls this endpoint to display the user's current coin balance in the SDK.
/balance?userId={partnerUserId}Headers:
X-Hubble-Secret(required)
Query Parameters:
userId(string, required) — Partner's user ID
Response (200 OK):
{
"userId": "partner_user_123",
"totalCoins": 1500.0
}
Response Fields:
userId— The user identifier (echo back what was sent)totalCoins— The user's available coin balance
Error Responses
Your balance API should handle these error cases:
| Scenario | HTTP Status | Response Body |
|---|---|---|
| User not found | 404 | { "error": "USER_NOT_FOUND", "message": "No user with this ID" } |
| Invalid/missing secret | 401 | { "error": "UNAUTHORIZED", "message": "Invalid X-Hubble-Secret" } |
| Internal error | 500 | { "error": "INTERNAL_ERROR", "message": "..." } |
The SDK displays this balance to the user. If your balance API returns incorrect values, users will see a wrong coin balance and may attempt transactions that fail at the debit step. Always return the real-time balance.
2. Debit Coins
Hubble calls this endpoint to deduct coins from a user when they use coins in a gift card purchase.
/debitHeaders:
X-Hubble-Secret(required)Content-Type: application/json
Request Body
{
"userId": "partner_user_123",
"coins": 500.0,
"referenceId": "hubble_txn_abc123",
"note": "Redemption for Amazon Gift Card"
}
Request Body Fields:
userId(string, required) — The user to debit coins fromcoins(number, required) — Number of coins to debitreferenceId(string, required) — Unique transaction identifier from Hubble (used for idempotency)note(string, optional) — Description of the transaction
Response (200 OK):
{
"status": "SUCCESS",
"transactionId": "partner_txn_789",
"balance": 1000.0,
"referenceId": "hubble_txn_abc123"
}
Error Responses
Your debit API should return appropriate error responses:
| Scenario | HTTP Status | Response Body |
|---|---|---|
| Insufficient balance | 400 | { "status": "INSUFFICIENT_BALANCE", "balance": 200.0 } |
| User not found | 404 | { "status": "USER_NOT_FOUND", "message": "No user with this ID" } |
| Invalid/missing secret | 401 | { "status": "UNAUTHORIZED" } |
| Internal error | 500 | { "status": "INTERNAL_ERROR", "message": "..." } |
Idempotency Rules (Critical)
The referenceId is the idempotency key. You must implement idempotency correctly:
- First request with a
referenceId: Process the debit normally, deduct coins, return the response. - Duplicate request with the same
referenceId: Do NOT debit coins again. Return the original response from the first request.
Network issues can cause Hubble to retry a debit request. Without idempotency, a retry would deduct coins a second time, double-charging the user. This causes real money loss and support escalations.
The simplest implementation: store the referenceId and response for each successful debit. On subsequent requests with the same referenceId, look up and return the stored response without processing.
3. Reverse Debit
Hubble calls this endpoint to refund coins when a gift card purchase fails or is cancelled after coins were already debited.
/reverseHeaders:
X-Hubble-Secret(required)Content-Type: application/json
Request Body
{
"userId": "partner_user_123",
"referenceId": "hubble_txn_abc123",
"note": "Redemption cancelled by user"
}
The referenceId in the reverse request matches the referenceId of the original debit transaction. This tells you which debit to reverse.
Successful Response (200 OK)
{
"status": "SUCCESS",
"transactionId": "partner_txn_rev_456",
"balance": 1500.0,
"referenceId": "hubble_txn_abc123"
}
Error Responses
Your reverse API should handle these error cases:
| Scenario | HTTP Status | Response Body |
|---|---|---|
referenceId not found | 404 | { "status": "TRANSACTION_NOT_FOUND", "message": "No debit found for this referenceId" } |
| Already reversed | 200 | { "status": "SUCCESS", "message": "Already reversed" } (idempotent) |
| Invalid/missing secret | 401 | { "status": "UNAUTHORIZED" } |
| Internal error | 500 | { "status": "INTERNAL_ERROR", "message": "..." } |
Reversal requests must also be idempotent. If Hubble sends the same reverse request twice (same referenceId), you should return the original response and NOT credit the coins again. The logic is identical to debit idempotency: store the referenceId and response, and return the stored response for duplicates.
Advanced Features
Controlling Coin Consumption Eligibility
Some partners need to restrict certain users from spending coins even when they have a non-zero balance — for example, until a KYC check is complete, a cooling period has passed, or some other condition is met on the partner's system.
To support this, the /balance response accepts an optional consumptionEligibility object. When present, Hubble uses it to decide whether to allow the user to apply coins at checkout.
Extended Response (200 OK):
{
"userId": "partner_user_123",
"totalCoins": 1500.0,
"consumptionEligibility": {
"allowed": false,
"message": "Complete your KYC to start redeeming coins"
}
}
consumptionEligibility Fields:
| Field | Type | Required | Description |
|---|---|---|---|
allowed | boolean | Yes | Whether the user can spend coins right now |
message | string | No | Human-readable reason shown to the user when allowed is false |
Behaviour:
- If
consumptionEligibilityis omitted, Hubble treats the user as eligible — existing integrations are unaffected. - If
allowedistrue, the user can apply coins normally. - If
allowedisfalse, Hubble hides the coin redemption option and, ifmessageis provided, surfaces it to the user as the reason.
When allowed is true:
{
"userId": "partner_user_123",
"totalCoins": 1500.0,
"consumptionEligibility": {
"allowed": true
}
}
Example reasons partners have used:
| Scenario | message |
|---|---|
| KYC not completed | "Complete your KYC to start redeeming coins" |
| Account under review | "Your account is under review. Coin redemption is temporarily unavailable" |
| Cooling period active | "Coins unlock after your first repayment" |
| Subscription inactive | "Renew your subscription to redeem coins" |
| Minimum activity not met | "Make your first purchase to unlock coin redemption" |
Eligibility is enforced at checkout display time. Hubble's debit endpoint still performs its own server-side validation — never rely solely on the balance response to gate redemptions.