GamesDrop.io API - Merchant Guide
[!WARNING] All offer groups in this documentation are PRODUCTION offers!
For testing purposes, please use Test Offer ID 999 only.
API Base URL:https://partner.gamesdrop.io
Welcome to the GamesDrop.io Partner API documentation! This guide provides everything you need to integrate your reseller platform with the GamesDrop network. By integrating, you gain access to our catalog of over 10,000 digital products, ranging from mobile operator top-ups to in-game currency for popular mobile games. Start here to streamline your product offerings and connect your customers to a world of digital goods.
Table of Contents
- Authorization
- Core Concepts
- API Endpoints
- API Testing
- Integration Recommendations
- FAQ & Troubleshooting
- Support
Authorization
Getting a Token
How to get it
- Log in to your merchant account
- Create a new store
- After creating the store, you will receive a unique token
- Token format:
abcdef1234567890abcdef1234567890
Authorization Methods
The system supports two authorization methods depending on the request type:
-
Shop API Token:
- Used for all product and order operations (creating orders, checking status, checking store balance).
- Passed in the header:
Authorization: <your_token> - Example:
Authorization: abcdef1234567890abcdef1234567890
-
JWT Token (for management):
- Used for the merchant dashboard and top-up operations (Bank Transfer, PayPal, etc.).
- Passed as a Bearer token:
Authorization: Bearer <jwt_token> - Note: JWT tokens have a limited lifespan.
Token Security
- π The token is confidential information
- β οΈ Do not share the token with third parties
- π The token cannot be recovered after creation
- π If necessary, you can generate a new token (the old one will become invalid)
Core Concepts
Order Statuses
| Status | Description | Actions |
|---|---|---|
SUBMITTED | Order created and awaiting processing | Wait for transition to PROCESSING |
PROCESSING | Order is being processed | Wait for completion. For top-ups, this stage can take from 1 to 60 minutes. |
COMPLETED | Order successfully completed | Receive key/product |
CANCELED | Order canceled due to an error | Check message field for details, create a new order |
FAILED | Internal system error | Automatic refund, check message, stop polling |
REFUND | Order refunded | Wait for funds return |
Possible Errors
| Error Code | Description | Solution |
|---|---|---|
INVALID_TOKEN | Invalid authorization token | Check the token or get a new one |
OFFER_NOT_FOUND | Product not found or no access | Check Product ID and access rights |
TRANSACTION_DUPLICATE | Duplicate transaction | Use a new transaction_id |
WRONG_PRICE | Incorrect product price | Update price information |
ORDER_NOT_FOUND | Order not found | Check Order ID |
ORDER_NOT_PROCESSING | Order is not yet processing | Wait for transition to PROCESSING |
ORDER_NOT_COMPLETED | Order is not yet completed | Wait for order completion |
ORDER_ALREADY_CANCELED | Order is already canceled | Create a new order |
ORDER_ALREADY_REFUNDED | Order is already refunded | Create a new order |
SERVICE_UNAVAILABLE | Service temporarily unavailable | Retry the request later |
INVALID_REQUEST_BODY | Invalid request format | Check request structure |
INSUFFICIENT_BALANCE | Insufficient account balance | Top up balance or reduce purchase amount |
BALANCE_UNAVAILABLE | Balance temporarily unavailable | Retry the request later |
Supplier Settlement Compatibility
GamesDrop works with multiple suppliers. Some suppliers settle in fiat payment rails, some settle in USDT, and some support both. To prevent currency-mismatch risk, each partner account is assigned a balance profile and each supplier offer is assigned a settlement method.
Balance profiles:
| Profile | Meaning |
|---|---|
FIAT | The partner is configured for fiat-based settlement. |
USDT | The partner is configured for USDT-based settlement. |
MIXED | The partner can use both fiat and USDT supplier offers. |
Offer settlement methods:
| Method | Meaning |
|---|---|
FIAT | The supplier offer is settled through fiat rails. |
USDT | The supplier offer is settled through USDT rails. |
MIXED | The supplier offer can be used by both fiat and USDT partners. |
Compatibility rules:
| Partner balance profile | Visible / purchasable offer methods |
|---|---|
FIAT | FIAT, MIXED |
USDT | USDT, MIXED |
MIXED | FIAT, USDT, MIXED |
Only compatible offers are returned by catalog and product endpoints. If an offer is not compatible with your account profile, it is hidden from sync and find-one, and order creation is rejected if attempted directly.
This compatibility layer is separate from product price markup and currency conversion. GamesDrop returns the final purchase price available to your account; your system should always use the latest price returned by sync or find-one when creating an order.
API Endpoints
Balance Management
Check Balance
You can check your account's current balance using your Shop API token.
HTTPGET /api/v1/offers/balance Authorization: {{token}}
[!NOTE] The
/api/v1/balanceendpoint (without/offers/) requires JWT authorization and is primarily used for the web interface. For API integration, use/api/v1/offers/balancewith your Shop Token.
Response:
JSON{
"balance": 500.25,
"draftBalance": 0.00,
"isPostpaid": false,
"balanceProfile": "USDT",
"currency": {
"id": 3,
"code": "USD"
},
"partnerId": 123
}
Response Fields:
| Key | Type | Description |
|---|---|---|
balance | number | Current available balance in USD |
draftBalance | number | Reserved funds (processing) |
isPostpaid | boolean | true: postpaid account (balance not required for orders). false: prepaid account (must top up balance). |
balanceProfile | FIAT | USDT | MIXED | Determines which supplier offer settlement methods are available to your account. |
partnerId | number | Unique ID of your partner account |
currency | object | Balance currency information (always USD) |
Transaction History
HTTPGET /api/v1/balance/transactions?page=1&limit=20 Authorization: {{passwordHash}}
Response:
JSON{
"transactions": [
{
"id": 12,
"amount": -75.00,
"type": "PURCHASE",
"description": "API Purchase - Virtual credits",
"balanceAfter": 425.00,
"createdAt": "2025-07-28T05:21:46.121Z"
},
{
"id": 11,
"amount": -50.00,
"type": "PURCHASE",
"description": "Test Purchase - Mobile game credits",
"balanceAfter": 500.00,
"createdAt": "2025-07-28T05:16:23.718Z"
}
],
"total": 25
}
Request fields description:
| Key | Value | Notes |
|---|---|---|
page | number | Page number (default: 1) |
limit | number | Records per page (default: 20) |
Response fields description:
| Key | Value | Notes |
|---|---|---|
transactions | array | List of transactions |
transactions[].id | number | Unique transaction ID |
transactions[].amount | number | Operation amount (negative for debits) |
transactions[].type | string | Operation type (DEPOSIT, PURCHASE, REFUND) |
transactions[].description | string | Operation description |
transactions[].balanceAfter | number | Balance after operation |
transactions[].createdAt | string | Operation date and time (UTC) |
total | number | Total number of transactions |
Getting Product Information
HTTPPOST /api/v1/offers/find-one Authorization: {{token}} { "offerId": 1001 }
Response:
JSON{
"offerId": 1001,
"productName": "PUBG MOBILE GIFT",
"offerName": "60 UC",
"count": 1,
"price": 560.10,
"currency": "RUB",
"settlementMethod": "USDT",
"balanceProfile": "USDT",
"isSettlementCompatible": true,
"isReturnDataForCustomer": true
}
Request fields description:
| Key | Value | Notes |
|---|---|---|
offerId | number | Important: must be a number, not a string |
Response fields description:
| Key | Value | Notes |
|---|---|---|
offerId | number | - |
productName | string | - |
offerName | string | - |
count | number | Number of product units |
price | number | - |
currency | KZT, USD, RUB, etc. | Pricing currency code |
settlementMethod | FIAT | USDT | MIXED | Settlement method of the selected supplier offer. |
balanceProfile | FIAT | USDT | MIXED | Your partner balance profile. |
isSettlementCompatible | boolean | Always true for returned offers. Incompatible offers are hidden. |
isReturnDataForCustomer | boolean | true: Key/Gift Card (will return key). false: Direct Top-up (instant credit). |
Catalog Synchronization (B2B Sync)
The Sync endpoint is specifically designed for partners who need to regularly update their local product databases. It returns a flattened, highly optimized list of available offers, current prices (with your markup applied), and stock availability in a single request.
The response includes only offers compatible with your balanceProfile. For example, a USDT partner will not receive fiat-only supplier offers in this feed.
HTTPPOST /api/v1/offers/sync Authorization: {{token}} { "limit": 1000, "page": 1, "category": "Top Up", "search": "genshin" }
Request fields description:
| limit | number | Elements per page (max 5000). Default: 1000. |
| page | number | Page number. Default: 1. |
| search | string | Optional text search by product name. |
| category | string | Optional filter by category (e.g., Top Up, Gift Cards). Legacy aliases TOP_UP and GIFT_CARD are also accepted. |
Response:
JSON{
"count": 1250,
"rows": [
{
"productId": 5,
"productName": "PUBG Mobile",
"offerGroupId": 101,
"offerGroupName": "60 UC",
"price": 0.99,
"currency": "USD",
"inStock": true
}
]
}
Response fields description:
| Key | Value | Notes |
|---|---|---|
count | number | Total number of items matching filters. |
rows[].offerGroupId | number | The ID to pass as offerId when creating an order. |
rows[].price | number | Final cost required to purchase the item (in your currency). |
rows[].inStock | boolean | true if at least one supplier is currently active. |
rows[].isRequiredGameUserId | boolean | true if the product requires a player identifier. |
rows[].isRequiredGameServerId | boolean | true if the product requires a server identifier. |
Creating an Order
HTTPPOST /api/v1/offers/create-order Authorization: {{token}} { "offerId": 1001, "price": 560.10, "transactionId": "test112321124214", "customer": { "email": "user@gmail.com", "gameUserId": "52357322414" } }
Request fields description:
| Key | Value | Notes |
|---|---|---|
offerId | number | Important: must be a number, not a string |
price | number | The latest GamesDrop purchase price returned by find-one or sync. Do not send your retail/customer-facing price. |
transactionId | string | Unique transaction identifier in your system |
customer | undefined | object |
email | undefined | string |
gameUserId | undefined | string |
Price Confirmation and Supplier Selection
The price field in create-order is a price confirmation. It must match the GamesDrop price that your system received from find-one or sync before creating the order.
Do not send the price shown to your end customer. Your storefront markup is managed on your side and is not part of the GamesDrop order request.
For products backed by multiple suppliers, GamesDrop may select the best available supplier at order time. The order will only be accepted if the confirmed price still covers the required GamesDrop purchase price. If supplier prices changed or the cheapest supplier became unavailable and the confirmed price is no longer valid, the API returns WRONG_PRICE, OFFER_NOT_FOUND, OUT_OF_STOCK, or SERVICE_UNAVAILABLE depending on the situation. In this case, refresh the offer price and ask the customer to retry the purchase.
Response:
JSON{
"orderId": 10222502,
"count": 1,
"price": 560.10,
"currency": "RUB",
"offerId": 1001,
"productName": "PUBG MOBILE GIFT",
"offerName": "60 UC",
"status": "COMPLETED",
"isReturnDataForCustomer": true,
"key": "001434249936",
"createdAt": "2024-05-28 10:08:04.296+00"
}
Response fields description:
| Key | Value | Notes |
|---|---|---|
orderId | number | - |
count | number | Number of product units |
price | number | - |
currency | KZT | USD |
offerId | number | - |
productName | string | - |
offerName | string | - |
status | string | SUBMITTED, PROCESSING, COMPLETED, CANCELED |
isReturnDataForCustomer | boolean | true: Key product. false: Direct top-up. |
isRequiredGameUserId | boolean | true if the product requires a player identifier. |
isRequiredGameServerId | boolean | true if the product requires a server identifier. |
key | string (optional) | Activation Code/PIN. Present ONLY if isReturnDataForCustomer: true AND status: "COMPLETED". |
createdAt | string | UTC +0 |
Check Order Status
HTTPPOST /api/v1/offers/order-status Authorization: {{token}} { "orderId": 10222502 // OR "transactionId": "test112321124214" }
Request fields description:
| Key | Value | Notes |
|---|---|---|
orderId | number | Optional if transactionId is provided |
transactionId | string | Optional if orderId is provided |
Response:
JSON{
"orderId": 10222502,
"count": 1,
"price": 560.10,
"currency": "RUB",
"offerId": 1001,
"productName": "PUBG MOBILE GIFT",
"offerName": "60 UC",
"status": "COMPLETED",
"isReturnDataForCustomer": true,
"key": "001434249936",
"createdAt": "2024-05-28 10:08:04.296+00"
}
Response fields description:
| Key | Value | Notes |
|---|---|---|
orderId | number | - |
count | number | Number of product units |
price | number | - |
currency | KZT | USD | EUR | RUB | - |
offerId | number | - |
productName | string | - |
offerName | string | - |
status | string | Current status: SUBMITTED, PROCESSING, COMPLETED, CANCELED, FAILED |
message | string (optional) | Detailed error message if status is CANCELED or FAILED. |
isReturnDataForCustomer | boolean | true: Key product. false: Direct top-up. |
isRequiredGameUserId | boolean | true if the product requires a player identifier. |
isRequiredGameServerId | boolean | true if the product requires a server identifier. |
key | string (optional) | Activation Code/PIN. Present ONLY if isReturnDataForCustomer: true AND status: "COMPLETED". |
createdAt | string | UTC +0 |
Server List Discovery
For products that require a server identifier (isRequiredGameServerId: true), you can fetch the list of available servers to display in your UI.
HTTPPOST /api/v1/partner/product-offer/servers Authorization: {{token}} { "offerId": 1001 }
You can also use the equivalent short path:
HTTPPOST /api/v1/offers/servers Authorization: {{token}}
Response:
JSON{
"Europe": "os_euro",
"America": "os_usa",
"Asia": "os_asia"
}
Note: Use the key (e.g., "Europe") as the display label and the value (e.g., "os_euro") as the gameServerId when creating an order.
Player Validation
HTTPPOST /api/v1/offers/check-game-data Authorization: {{token}} { "offerId": 1001, "gameUserId": "52357322414", "gameServerId": "1234" }
Request fields description:
| Key | Value | Notes |
|---|---|---|
offerId | number | Important: must be a number, not a string |
gameUserId | string | Player identifier |
gameServerId | undefined | string |
Successful response:
JSON{
"status": "VALID",
"gameUserLogin": "JJJ"
}
Successful response fields description:
| Key | Value | Notes |
|---|---|---|
status | "VALID" | Player is valid |
gameUserLogin | string | Player login |
Error response:
JSON{
"status": "INVALID"
}
Error response fields description:
| Key | Value | Notes |
|---|---|---|
status | "INVALID" | Player is invalid |
API Testing
Test Product
For testing API integration, a special test product is available:
- Product ID: 999
- Name: Steam US
- Offer Name: TEST OFFER GROUP
- Price: 23.09 KZT (important to use exact value)
- Returns Key: Yes
Example request for test product information:
HTTPPOST /api/v1/offers/find-one Authorization: {{token}} { "offerId": 999 }
Example creating test order:
HTTPPOST /api/v1/offers/create-order Authorization: {{token}} { "offerId": 999, "price": 23.09, "transactionId": "test_123456", "customer": { "email": "test@example.com", "gameUserId": "123456789" } }
Test product features:
- Always returns successful response with correct parameters
- Generates test activation key
- Creates order with COMPLETED status
- Player validation always returns VALID for test product
- Works in test mode without real fund deduction
Balance Management Examples
Check balance before purchase:
JAVASCRIPT// 1. Check current balance
const balanceResponse = await fetch('/api/v1/balance', {
headers: { 'Authorization': 'your-token-here' }
});
const { balance } = await balanceResponse.json();
// 2. Get product information
const offerResponse = await fetch('/api/v1/offers/find-one', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({ offerId: 1001 })
});
const { price } = await offerResponse.json();
// 3. Check sufficient funds
if (balance >= price) {
// Create order
console.log('Sufficient balance, creating order...');
} else {
console.log('Insufficient balance, need to top up');
}
Get transaction history:
JAVASCRIPTconst transactionsResponse = await fetch('/api/v1/balance/transactions', {
headers: { 'Authorization': 'your-token-here' }
});
const { transactions, total } = await transactionsResponse.json();
console.log(`Total transactions: ${total}`);
transactions.forEach(tx => {
console.log(`${tx.createdAt}: ${tx.type} ${tx.amount} (Balance: ${tx.balanceAfter})`);
});
Integration Recommendations
π° Balance Management
- Regularly check balance before large purchases
- Keep track of transactions for reconciliation with your system
- Notify users about need to top up when funds are insufficient
- Use pagination when requesting transaction history
π Before Creating an Order
- Get up-to-date product information
- Check balance to ensure sufficient funds
- Check player validity (for direct top-up)
π When Creating an Order
- Use a unique transactionId
- Specify the latest GamesDrop price returned by
find-oneorsync - Do not send your customer-facing retail price in the
pricefield - Specify offerId as number, not string
- Fill in all required fields for the product type
β After Creating an Order
- Save the orderId
- Check the order status
- Upon COMPLETED status, receive the key/product
β οΈ When Errors Occur
- Check the token
- Ensure data correctness and request format
- Create a new order if necessary
FAQ & Troubleshooting
Product Types (Top-up vs Keys)
Our system supports two main types of delivery. You can distinguish them using the isReturnDataForCustomer field in the Product Info response.
1. Gift Cards / Keys (isReturnDataForCustomer: true)
- What it is: The customer receives a digital code, PIN, or link to activate manually.
- Flow:
create-orderreturnsstatus: "COMPLETED"and akeyfield.- You display this
keyto your customer.
- Example: Steam Wallet Code, PUBG UC usage code.
2. Direct Top-up (isReturnDataForCustomer: false)
- What it is: Funds are credited directly to the player's game account. No code is returned.
- Flow:
- You MUST provide
gameUserId(and sometimesgameServerId) in thecreate-orderrequest. - We recommend validating the ID first using
/check-game-data. create-orderreturnsstatus: "COMPLETED". The player receives the item in-game automatically.
- You MUST provide
- Example: Mobile Legends Diamonds top-up by User ID.
Currency Conversion
- Your Partner Balance: Always maintained in USD.
- Product Prices: Can be in various currencies (RUB, KZT, EUR, etc.) depending on the region.
- How it works:
- You do not need to convert funds manually.
- When you purchase a product priced in
RUB(e.g., 500 RUB), the system calculates the equivalent inUSD(e.g., $5.50) and deducts it from your USD balance. - Ensure you have enough USD balance to cover the converted amount.
- Supplier settlement compatibility: Your catalog is filtered by your
balanceProfilebefore pricing is returned. This prevents fiat-only supplier offers from being sold to USDT-only partners, and vice versa. - No manual FX surcharge: GamesDrop does not require you to add an extra conversion-loss percentage in the API request. Use the latest price returned by
find-oneorsync. Any configured B2B markup is already included in the returned GamesDrop purchase price.
Common Questions
"I see a parameter 'it' mentioned, what is it?"
There is no parameter named it in our API. This is likely a typo for id or a misunderstanding.
- Product identifier is
offerId. - Transaction identifier is
transactionId. - User identifier is
gameUserId.
"How do I validate a Player ID?"
Use the POST /api/v1/offers/check-game-data endpoint. It will return VALID and the player's nickname if the ID is correct. This is highly recommended for Direct Top-up products to avoid errors.
Support
If you have any questions, please contact technical support:
- π§ Email: info@gamesdrop.io
- π¬ Telegram: @gigoryan34
Error Handling Recommendations
π Pre-Request Checks
- Token validation
- Product ID verification
- Price accuracy
- Uniqueness of transaction_id
- Correct data format (especially offerId as number)
π Response Handling
- Handle all error codes
- Log errors
- Implement retry mechanism
π Order Management
- Save order IDs
- Monitor statuses
- Update data
Telegram Stars
π GamesDrop has integrated Telegram Stars support! Now you can send Telegram Stars to users through the same standard API endpoints.
Available Telegram Stars Products
For the Partner API, offerId must be the numeric GamesDrop offer group ID returned by sync or find-one. The string IDs below are internal provider product identifiers and are shown only for reference.
| Internal Provider Product ID | Number of Stars | Dynamic Price |
|---|---|---|
telegram_stars_50 | 50 | Based on TON exchange rate |
telegram_stars_100 | 100 | Based on TON exchange rate |
telegram_stars_500 | 500 | Based on TON exchange rate |
telegram_stars_1000 | 1000 | Based on TON exchange rate |
How pricing works:
- A6-Gateway gets the current TON/USD rate from kernel currency API
- Price is calculated based on Fragment.com coefficients (100 Stars β 0.3 TON)
- Prices are updated in real-time with each request
Using the Same Endpoints
1. Getting Telegram Stars information:
HTTPPOST /api/v1/offers/find-one Authorization: {{token}} { "offerId": 1001 }
Response:
JSON{
"offerId": 1001,
"productName": "Telegram Stars",
"offerName": "100 Stars",
"count": 1,
"price": 0.77,
"currency": "USD",
"isReturnDataForCustomer": true
}
2. Creating an order for Telegram Stars:
HTTPPOST /api/v1/offers/create-order Authorization: {{token}} { "offerId": 1001, "price": 0.77, "transactionId": "tg_stars_12345", "customer": { "email": "user@example.com", "gameUserId": "143594291" } }
Response on successful delivery:
JSON{
"orderId": 10228901,
"count": 1,
"price": 0.78,
"currency": "USD",
"offerId": 1001,
"productName": "Telegram Stars",
"offerName": "100 Stars",
"status": "COMPLETED",
"isReturnDataForCustomer": true,
"fulfillmentData": {
"telegram_user_id": 143594291,
"stars_amount": 100,
"transaction_id": "tg_tx_abc123",
"delivery_status": "completed"
},
"createdAt": "2025-08-26T12:30:15.234Z"
}
Response on delivery failure:
JSON{
"orderId": 10228902,
"status": "CANCELED",
"message": "Failed to deliver Stars: user not found",
"fulfillmentData": {
"telegram_user_id": 123456789,
"stars_amount": 100,
"delivery_status": "failed",
"error_message": "user not found"
},
"createdAt": "2025-08-26T12:30:15.234Z"
}
π Important Telegram Stars Features
gameUserId requirements:
- gameUserId must be a numeric Telegram User ID for order creation
- Get User ID in two ways:
- π Via @userinfobot in Telegram
- π Via our API validation (see section below)
- Example:
"gameUserId": "143594291" - β NOT username (@username) for order creation
Delivery statuses:
COMPLETED- Stars successfully delivered to userCANCELED- Failed to deliver (invalid user ID, blocked bot, etc.)
Typical delivery errors:
"user not found"- invalid Telegram User ID"STARGIFT_INVALID"- user cannot receive Stars (restrictions)"bot was blocked by user"- user blocked the bot
π Telegram User Validation
π― New endpoint for validating username and getting User ID!
If your users only know their @username, use this endpoint to get User ID before creating an order.
Validation endpoint:
HTTPPOST https://gamesdrop.io/api/aggregator/a6/telegram/user-info Authorization: {{token}} Content-Type: application/json { "username": "@igoryan34" }
Response on successful validation:
JSON{
"valid": true,
"username": "igoryan34",
"userInfo": {
"id": 143594291,
"first_name": "Igor",
"username": "igoryan34",
"photo_url": "AQADAgADRKgxGzMTjwgABCAI..."
},
"message": "User account verified successfully"
}
Response when User ID cannot be obtained:
JSON{
"valid": true,
"username": "igoryan34",
"userInfo": {
"username": "igoryan34",
"first_name": "igoryan34"
},
"message": "Username format is valid, but user details are not publicly available. Full verification requires user interaction with the bot."
}
Request fields description:
| Key | Value | Notes |
|---|---|---|
username | string | Telegram username with @ or without |
Response fields description:
| Key | Value | Notes |
|---|---|---|
valid | boolean | Always true for correct usernames |
username | string | Cleaned username without @ |
userInfo.id | number | π― User ID for orders (if available) |
userInfo.first_name | string | User's first name |
userInfo.username | string | User's username |
userInfo.photo_url | string | Avatar URL (if available) |
message | string | Validation result description |
β οΈ Important features:
- Endpoint returns User ID only if user has interacted with the bot
- If
userInfo.idis missing, ask user to message @gamesdrop_api_bot - Can pass as
"@username"or"username" - Can also pass User ID to get additional information
π± Developer Integration Examples
Complete flow example with username validation in JavaScript:
JAVASCRIPT// 1. Validate username and get User ID
const validateTelegramUser = async (username) => {
const response = await fetch('https://gamesdrop.io/api/aggregator/a6/telegram/user-info', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({ username })
});
const result = await response.json();
if (result.valid && result.userInfo && result.userInfo.id) {
return {
userId: result.userInfo.id,
firstName: result.userInfo.first_name,
username: result.userInfo.username
};
} else {
throw new Error('Unable to get User ID. Please ask user to message @gamesdrop_api_bot first.');
}
};
// 2. Resolve numeric offer group ID from your synced catalog
const getTelegramStarsOfferGroupId = async (starsAmount) => {
const response = await fetch('/api/v1/offers/sync', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({ limit: 5000, page: 1, search: 'Telegram Stars' })
});
const catalog = await response.json();
const row = catalog.rows.find((item) =>
item.productName?.includes('Telegram Stars') &&
item.offerGroupName?.includes(String(starsAmount))
);
if (!row) {
throw new Error(`Telegram Stars offer group not found for ${starsAmount} Stars`);
}
return row.offerGroupId;
};
// 3. Get current price
const getStarsPrice = async (starsAmount) => {
const offerGroupId = await getTelegramStarsOfferGroupId(starsAmount); // Resolve from your synced catalog
const response = await fetch('/api/v1/offers/find-one', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
offerId: offerGroupId
})
});
return response.json();
};
// 4. Send Stars to user
const sendStarsByUsername = async (usernameOrId, starsAmount) => {
// First get User ID if username was passed
let userId;
if (isNaN(usernameOrId)) {
// This is username, need to get User ID
const userInfo = await validateTelegramUser(usernameOrId);
userId = userInfo.userId;
console.log(`β
Validated user: ${userInfo.firstName} (@${userInfo.username}) - ID: ${userId}`);
} else {
// This is already User ID
userId = parseInt(usernameOrId);
}
// Get price
const { offerId, price } = await getStarsPrice(starsAmount);
// Create order
const response = await fetch('/api/v1/offers/create-order', {
method: 'POST',
headers: {
'Authorization': 'your-token-here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
offerId: offerId,
price: price,
transactionId: `stars_${Date.now()}`,
customer: {
email: "optional@example.com",
gameUserId: userId.toString()
}
})
});
const result = await response.json();
if (result.status === 'COMPLETED') {
console.log(`β
Successfully sent ${starsAmount} Stars to User ID ${userId}`);
return result;
} else {
console.error(`β Failed to send Stars: ${result.message}`);
throw new Error(result.message);
}
};
// Usage:
// With username:
sendStarsByUsername('@igoryan34', 100)
.then(order => console.log('Order created:', order.orderId))
.catch(error => console.error('Delivery failed:', error));
// With User ID:
sendStarsByUsername('143594291', 100)
.then(order => console.log('Order created:', order.orderId))
.catch(error => console.error('Delivery failed:', error));
πΌ B2B Use Cases
1. Game rewards:
JAVASCRIPT// Reward player for achievement
await sendStars(userTelegramId, 50);
2. Promo campaigns:
JAVASCRIPT// Send Stars to all contest winners
const winners = [143594291, 987654321, 456789123];
for (const userId of winners) {
await sendStars(userId, 100);
}
3. Cashback programs:
JAVASCRIPT// Return part of purchase as Stars
const cashbackAmount = Math.floor(purchaseAmount * 0.05); // 5% cashback
const starsAmount = Math.min(cashbackAmount * 100, 1000); // convert to Stars
await sendStars(userTelegramId, starsAmount);
β‘ Performance and Limits
- Rate limiting: 30 requests per second on Telegram API
- Minimum amount: 1 Star
- Maximum amount: 2500 Stars per transaction
- Retry logic: Automatic retries on temporary errors
- Delivery time: Instant delivery (< 3 seconds)
π‘οΈ Security
- Telegram User ID validation before sending
- GamesDrop balance check before order creation
- Logging of all operations for audit
- Duplicate transaction protection via
transactionId