Gift Card API — code retrieval और automated delivery
Gift card हर दूसरे digital product से एक बात में अलग है — code वापस नहीं लिया जा सकता। जैसे ही वह string खरीदार तक पहुँची, आपको पता नहीं चलेगा कि वह redeem हुई या नहीं, और हर dispute आपके log से तय होता है, समझदारी से नहीं। नीचे code का पूरा सफ़र है — order से delivery तक, उन्हीं जगहों पर ज़ोर देकर जहाँ असल में पैसा डूबता है।
पाँच चरण जिन्हें अलग रखना ज़रूरी है
Code issuance की ज़्यादातर गड़बड़ियाँ इसलिए होती हैं क्योंकि developer इस पूरे काम को एक operation मान लेता है। ये पाँच अलग operations हैं और हर एक का failure mode अलग है:
| चरण | क्या होता है | State का मालिक |
|---|---|---|
| 1. Order | आप purchase request भेजते हैं | आपका DB + सप्लायर |
| 2. Issuance | सप्लायर code reserve करके issue करता है | सप्लायर |
| 3. Retrieval | आप response से code निकालते हैं | आपका DB |
| 4. Storage | Code आपके पास encrypted रहता है | आपका DB |
| 5. Delivery | खरीदार code देखता है | आपका frontend / email |
हर transition आपके database में timestamp के साथ अलग row होनी चाहिए। अगर पूरे सफ़र के लिए एक ही status column है, तो पहली ही गड़बड़ी पर आप उस सवाल का जवाब नहीं दे पाएँगे जो सबसे ज़रूरी है — code issue हुआ भी था या नहीं।
चरण 1. Order बनाना
Order product ID और quantity के साथ बनता है:
curl -X POST "https://public-api.foxreload.com/api/orders" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"itemId": "product_01krgfgww8eth9xvvysd6y7r4j",
"quantity": 1
}
],
"isMock": false
}'
Response में status active वाला order object आता है, साथ में id, price, createdAt, paymentExpiresAt और items[] array।
इस चरण के तीन नियम:
- सप्लायर को call करने से पहले अपने database में intent लिखें, बाद में नहीं। «हम ग्राहक X के लिए यह order करने जा रहे हैं» वाली row HTTP request जाने से पहले मौजूद होनी चाहिए — वरना भेजने और जवाब आने के बीच process गिरा तो कोई निशान नहीं बचेगा।
- सप्लायर का
order_idआते ही save करें। यही एकमात्र key है जिससे आप वह order दोबारा खोज पाएँगे। - Mock और production orders को बिना explicit flag के एक ही table में मत मिलाएँ। FoxReload के order object में
isMockfield आता है — उसे अपने schema में copy करें।
चरण 2. सप्लायर की तरफ़ issuance
Order बनने के बाद वह active → paid (balance debit) → processing (सप्लायर issue कर रहा है) → completed से गुज़रता है।
processing किसी और के system का हिस्सा है और card type के अनुसार कुछ सेकंड से लेकर काफ़ी लंबा चल सकता है। यहाँ आपका काम सिर्फ़ एक है: जब तक state अज्ञात है, कुछ भी विनाशकारी मत करें। «शायद fail हो गया, एक और order कर देते हैं» बिल्कुल नहीं।
चरण 3. Code retrieval
Code order का status poll करके मिलता है:
curl "https://public-api.foxreload.com/api/orders/{order_id}" \
-H "X-API-Key: YOUR_API_KEY"
जब status == "completed", तब हर items[] entry में होता है:
product— product object जिसमेंid,name,userGuide,attributesexternalData[]— issue हुए codes या PINs का arrayerror— उस item की error, अगर कोई है
userGuide field सजावट नहीं है। यह सप्लायर का activation निर्देश है और इसे code के साथ खरीदार तक पहुँचाना चाहिए — «code काम नहीं कर रहा» वाले आधे tickets का असली मतलब होता है कि खरीदार ग़लत region या account के ग़लत हिस्से में redeem कर रहा है।
Webhooks के बारे में — अपने सप्लायर से जाँचें
कुछ सप्लायर order पूरा होने पर notification भेज सकते हैं, अक्सर callback पर HMAC signature के साथ। ज़रूर जाँचें कि आपका सप्लायर वाक़ई यह देता है या नहीं। FoxReload webhooks support नहीं करता — नतीजा सिर्फ़ polling से मिलता है।
Webhooks मौजूद हों तब भी polling safety net के तौर पर रखें: delivery की गारंटी कभी नहीं होती और आपका handler ठीक ग़लत क्षण पर down हो सकता है। Webhook accelerator है, polling source of truth।
Partial fulfilment
Multi-line order में items स्वतंत्र रूप से पूरे होते हैं। एक line code दे सकती है जबकि दूसरी items[].error भरकर fail हो जाए।
सही प्रतिक्रिया:
- जो वाक़ई issue हुआ है उसे save करके खरीदार को दें। वह पैसा ख़र्च हो चुका है और code मौजूद है।
- बची हुई मात्रा के लिए या तो अलग operation में दोबारा order करें या ग्राहक को refund करें।
- जब कुछ codes जा चुके हों तो पूरे order को failed कभी न मानें। इसका अंत उस माल का refund देने में होता है जो ग्राहक पहले ही पा चुका है।
चरण 4. Double-issuance से सुरक्षा
यह इस श्रेणी की सबसे महँगी ग़लती है, और यह दो अलग जगहों पर पैदा होती है।
Order level पर duplicate
आपने order creation request भेजी, timeout मिला, दोबारा भेजी — और दो orders बन गए। दो codes ख़रीदे, एक दिया, दूसरा या तो बेकार पड़ा है या इससे भी बुरा, ग़लती से अगले खरीदार के पास चला गया।
कुछ API Idempotency-Key header स्वीकार करते हैं जो यह समस्या सप्लायर की तरफ़ हल कर देता है। ज़रूर जाँचें कि आपका सप्लायर इसे लागू करता है या नहीं — बहुत से नहीं करते। FoxReload Idempotency-Key header support नहीं करता।
इसलिए सुरक्षा आपकी तरफ़ बनती है:
- Call से पहले unique operation key अपने database में save करें।
- Timeout पर पहले सप्लायर की order list माँगें, statuses से filter करके देखें कि order मौजूद है या नहीं।
- पुष्टि हो जाए कि नहीं है, तभी retry करें।
curl "https://public-api.foxreload.com/api/orders/?statuses=active,processing&limit=20" \
-H "X-API-Key: YOUR_API_KEY"
Delivery level पर duplicate
दूसरा स्रोत आपके अपने system के अंदर की race है। ग्राहक ने «code दिखाएँ» दो बार दबाया, दो parallel requests ने order row को «code तैयार, delivered नहीं» पढ़ा और दोनों delivery करने चल पड़े।
इलाज transaction और row lock है: delivery order को delivered mark करके commit करती है, उसके बाद ही code बाहर जाता है। अगर code email से जा रहा है तो भेजना उसी transaction के अंदर queue होता है, बीच में synchronously नहीं।
Retries
सामान्य नियम: वही retry करें जिसे दोहराना सुरक्षित है।
429और5xx— jitter के साथ exponential backoff पर retry।429के अलावा बाक़ी4xx— कभी retry न करें, जवाब नहीं बदलेगा।- Order creation पर timeout — retry नहीं, पहले state check।
विस्तार से retry और backoff patterns वाले लेख में।
चरण 5. Storage — encryption और access
Gift card code एक bearer instrument है। जिसने पढ़ लिया, वही ख़र्च कर सकता है।
- Code value को application layer पर encrypt करें, secret manager की key से। Disk encryption काफ़ी नहीं: database dump, चोरी हुआ backup और SQL injection सब disk को पहले से decrypted पढ़ते हैं।
- Decryption सिर्फ़ एक service तक सीमित रखें। Analytics replica, support admin panel और debugging scripts के पास decryption का अधिकार नहीं होना चाहिए।
- Codes को logs में कभी न लिखें। न सामान्य logs में, न debug output में, न APM traces में, न support ticket के body में। Value को data-access layer से बाहर निकलते समय mask करें, हर print जगह पर अलग-अलग नहीं।
- Code का hash साथ रखें। इससे «हमने यही code दिया था» साबित होता है बिना value दोबारा दिखाए।
- Retention period तय करें। Delivery और dispute window बीत जाने के बाद encrypted value हटाई जा सकती है, hash और metadata रहने दें।
चरण 6. Delivery और audit trail
Delivery भी एक operation है जो fail हो सकती है। Email bounce होती है, tab बंद हो जाता है, खरीदार ग़लत पता लिख देता है।
काम करने वाला pattern:
- Code एक ही बार दिखाया जाता है, सुरक्षित order page पर जो सिर्फ़ authenticated खरीदार को उपलब्ध है।
- दोबारा access account area से होता है, और हर view log में लिखा जाता है।
- कोई one-time view link हो तो वह अल्पकालिक और एकल-उपयोग हो।
- पहली बार दिखाने का समय timestamp के साथ दर्ज होता है — यही तथ्य आप dispute में पेश करेंगे।
Audit trail
हर code के लिए न्यूनतम events जो लिखने चाहिए:
| Event | क्या दर्ज करें |
|---|---|
| Order बना | Internal ID, product, खरीदार, समय |
| सप्लायर ID मिला | सप्लायर का order_id |
| Code मिला | Code hash, line item, समय |
| Code खरीदार को दिखा | समय, IP, session identifier |
| Dispute खुला | Order और ticket का link |
| Dispute का फ़ैसला | Refund, इनकार, replacement |
यही log — support thread नहीं — इस सवाल का जवाब देता है कि «code delivered हुआ था या नहीं और कब»। यह सबूत असल में कैसे काम आता है, यह digital goods में chargebacks से बचाव में समझाया गया है।
वे जोख़िम भी याद रखें जो किसी code से ठीक नहीं होते: issuer की तरफ़ से code revocation, regional redemption पाबंदियाँ, और fraud के शक पर card void होना। इन परिस्थितियों का विश्लेषण code revocation और region locks में है।
Gift cards थोक में कहाँ से लें
ऊपर वाली pipeline एक बार बनाना समझदारी है, और ऐसे catalogue के सामने जो आपकी पूरी range कवर करे। FoxReload एक थोक digital-goods सप्लायर है जिसके पास 900+ SKU हैं — gift cards, game keys, top-ups, eSIM और software licences — सब एक ही REST API के पीछे, automated delivery और multi-region SKUs के साथ। हर issuer के लिए अलग integration की जगह सभी categories पर एक order model और एक response shape।
