# Webhook URL

## अवलोकन

यह सुविधा भुगतान हो चुके इनवॉइस का डेटा व्यापारी के सर्वर तक पहुँचाती है। यह इसलिए है, ताकि व्यापारी का स्टोर भुगतान को अपने-आप प्रोसेस कर सके और आपके ग्राहक को उत्पाद या सेवा दे सके।

Webhook URL हर प्रोजेक्ट के लिए अलग सेट होता है और व्यापारी के स्टोर के भीतर भुगतान हैंडलर स्क्रिप्ट की ओर इशारा करता है। पते में HTTPS और डोमेन नाम होना चाहिए: IP एड्रेस स्वीकार नहीं होते, और हर डिलीवरी पर सर्टिफ़िकेट की जाँच होती है।

जब भी इनवॉइस की स्थिति भुगतान हुआ (Paid) में बदलती है, सेवा इस URL पर इस फ़ॉर्मैट में POST अनुरोध भेजती है:

```json
{
   "wallet":{
      "id":"47aa71e2-07a0-482e-9172-7114d7376ba0",
      "name":"usdt-tron",
      "blockchain":"tron",
      "cryptocurrency":"usdt",
      "address":"TKbstUwMzLrfTAGL4erYb7gc7ghmHQ9zG7"
   },
   "project":{
      "id":"9deea1e2-0c08-41a3-bdc2-a34eada3892d",
      "name":"My project",
      "commissionPayer":"seller",
      "commissionRate":1
   },
   "invoice":{
      "id":"a4c9e2ee-9a03-43e5-a1a1-00caf679d16a",
      "uid":"AFhygKX21ecd",
      "createDatetime":"2024-02-26 13:29:24",
      "timeToPayDatetime":"2024-02-27 01:29:24",
      "commissionFiatUSD":0.05,
      "amountFiatUSD":5.02,
      "amountFiat":5,
      "calcAmountFiat":5.02,
      "currencyFiat":"USD",
      "description":null,
      "serviceData":null,
      "status":"paid"
   },
   "payment":{
      "id":"f986ad8d-2298-473d-982a-efbc817b975d",
      "amount":5.02,
      "hash":"74763b65e43bcc9492a6ce9a7f26fbfdbd7635aecd3454420b5e9534cba50ee6",
      "transactionDatetime":"2024-02-26 13:32:57"
   }
}
```

सूचना भुगतान हुआ स्थिति में हर बदलाव पर भेजी जाती है — तब भी, जब सेवा ने भुगतान अपने-आप खोजा, और तब भी, जब व्यापारी ने भुगतान को इनवॉइस से मैन्युअल रूप से जोड़ा।

## अनुरोध पैरामीटर

| पैरामीटर | विवरण |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `wallet.id` | UUID फ़ॉर्मैट में वॉलेट ID |
| `wallet.name` | वॉलेट का नाम |
| `wallet.blockchain` | क्रिप्टो वॉलेट का ब्लॉकचेन |
| `wallet.cryptocurrency` | वॉलेट की क्रिप्टोकरेंसी |
| `wallet.address` | क्रिप्टो वॉलेट का एड्रेस |
| `project.id` | UUID फ़ॉर्मैट में प्रोजेक्ट ID |
| `project.name` | प्रोजेक्ट का नाम |
| `project.commissionPayer` | सेवा शुल्क कौन चुकाता है |
| `project.commissionRate` | % में शुल्क दर |
| `invoice.id` | UUID फ़ॉर्मैट में इनवॉइस ID |
| `invoice.uid` | इनवॉइस ID (ग्राहक के लिए) |
| `invoice.createDatetime` | इनवॉइस बनने की तारीख़ और समय (UTC) |
| `invoice.timeToPayDatetime` | वह तारीख़ और समय, जब तक इनवॉइस ग्राहक के लिए मान्य है (UTC)। भुगतान की खोज इस निशान के बाद 1 और घंटे चलती रहती है — धीमे नेटवर्क के लिए। इसलिए सूचना ऐसे इनवॉइस की भी आ सकती है, जो पहले ही समाप्त दिखाया जा चुका था |
| `invoice.commissionFiatUSD` | सेवा शुल्क की राशि। इसकी गणना `invoice.amountFiatUSD` राशि से होती है |
| `invoice.amountFiatUSD` | USD में राशि। इनवॉइस बनाते समय इसकी गणना `invoice.amountFiat` से मौजूदा विनिमय दर पर होती है। **भुगतान के समय इसमें असल में मिली राशि लिख दी जाती है**, जो उस पल की विनिमय दर पर USD में बदली जाती है। `invoice.commissionFiatUSD` का शुल्क भी इसी से दोबारा गिना जाता है |
| `invoice.amountFiat` | फ़िएट मुद्रा में इनवॉइस की मूल राशि। नहीं बदलती |
| `invoice.calcAmountFiat` | भुगतान के समय के क्रिप्टो विनिमय दर पर `invoice.currencyFiat` मुद्रा में गिनी गई राशि। यह `invoice.amountFiat` से अलग हो सकती है, क्योंकि ग्राहक ने इनवॉइस का भुगतान तुरंत नहीं, बल्कि बनने के कुछ समय बाद किया हो सकता है। इस दौरान `invoice.currencyFiat` के मुकाबले क्रिप्टो की दर किसी भी दिशा में जा सकती थी |
| `invoice.currencyFiat` | फ़िएट मुद्रा |
| `invoice.description` | इनवॉइस बनाते समय सेट किया गया विवरण |
| `invoice.serviceData` | इनवॉइस बनाते समय सेट किया गया सर्विस डेटा |
| `invoice.status` | इनवॉइस की स्थिति |
| `payment.id` | UUID फ़ॉर्मैट में भुगतान ID |
| `payment.amount` | क्रिप्टोकरेंसी में भुगतान की राशि |
| `payment.hash` | ऑन-चेन ट्रांज़ैक्शन का hash |
| `payment.transactionDatetime` | ऑन-चेन ट्रांज़ैक्शन की तारीख़ और समय (UTC) |

## सूचना का हस्ताक्षर

हर अनुरोध पर Webhook की गुप्त कुंजी से हस्ताक्षर होता है। हस्ताक्षर `X-Timestamp` और `X-Signature` हेडर में जाता है और इससे आप पक्का कर सकते हैं कि सूचना सेवा से आई है, न कि किसी बाहरी से, जिसे आपके हैंडलर का पता मालूम हो गया।

ऑर्डर प्रोसेस करने से पहले हस्ताक्षर की जाँच करें। पूरा तरीका और तैयार उदाहरण [Webhook हस्ताक्षर की जाँच](./signature-verification.md) में हैं।

## प्रोसेसिंग की सिफ़ारिशें

**सूचना को इसलिए न ठुकराएँ कि भुगतान की समय-सीमा बीत चुकी है।** “इनवॉइस समाप्त है, इसलिए भुगतान अमान्य है” जैसी जाँच तर्कसंगत दिखती है, लेकिन असली भुगतानों का एक हिस्सा काट देती है: धीमे नेटवर्क पर ट्रांज़ैक्शन समय-सीमा के बाद कन्फ़र्म हो सकता है, और व्यापारी भुगतान को समय समाप्त इनवॉइस से मैन्युअल रूप से जोड़ सकता है। सूचना ख़ुद ही भुगतान की पुष्टि है।

**राशि की जाँच मूल फ़ील्ड** `invoice.amountFiat` **से करें।** यह इनवॉइस की वही राशि है, जिस पर वह जारी हुआ, और यह नहीं बदलती। `amountFiatUSD` फ़ील्ड असल में मिली राशि दिखाता है और जारी की गई राशि से अलग हो सकता है — विनिमय दर की चाल की वजह से भी और भुगतान के मैन्युअल जोड़ने की वजह से भी।

**राशियों को संख्या के रूप में पार्स करें।** आख़िर के शून्य हट जाते हैं: 10.00 की राशि 10 बनकर आती है; दिखाने के लिए उसे अपनी ओर से फ़ॉर्मैट करें। 0.0001 से छोटी राशियाँ exponential notation में आती हैं, जैसे 1.0e-6 — सामान्य JSON पार्सिंग सही संख्या लौटाती है; सिर्फ़ स्ट्रिंग को हाथ से पार्स करना टूटता है।

**सूचनाओं को idempotent ढंग से प्रोसेस करें।** एक ही सूचना दोबारा आ सकती है — जैसे तब, जब आपकी स्क्रिप्ट ने भुगतान तो सफलता से प्रोसेस किया, लेकिन non-2xx कोड लौटाया। ऑर्डर पूरा करने से पहले जाँचें कि यह `invoice.id` पहले प्रोसेस तो नहीं हो चुका।

**मान दिखाते समय एस्केप करें।** `invoice.description` और `invoice.serviceData` फ़ील्ड ठीक उसी रूप में लौटते हैं, जिस रूप में व्यापारी ने उन्हें भेजा था। अगर आप इन्हें HTML में दिखाते हैं, तो अपनी ओर से एस्केप करें।

## डिलीवरी का शेड्यूल

Webhook URL वाले सर्वर को 2xx HTTP कोड से जवाब देना चाहिए। कोई भी दूसरा कोड, टाइमआउट या टूटा हुआ कनेक्शन असफल डिलीवरी गिना जाता है।

रीडायरेक्ट फ़ॉलो नहीं होते: 301 या 302 जवाब असफल डिलीवरी है, नए पते पर छलाँग नहीं। हैंडलर का अंतिम पता सेट करें।

कनेक्शन के लिए 5 सेकंड हैं, पूरे अनुरोध के लिए 10 सेकंड। अगर हैंडलर इसमें नहीं समाता, तो डिलीवरी असफल गिनी जाती है।

असफल डिलीवरी के बाद सेवा इस शेड्यूल पर पुनः प्रयास करती है:

* आख़िरी असफल डिलीवरी के 5 मिनट बाद
* 15 मिनट बाद
* 30 मिनट बाद
* 1 घंटे बाद
* 3 घंटे बाद
* 6 घंटे बाद
* 12 घंटे बाद
* 24 घंटे बाद

इसके बाद डिलीवरी की कोशिशें रुक जाती हैं।

## Webhook URL बंद होना

कभी-कभी स्टोर की webhook स्क्रिप्ट भुगतान तो सही प्रोसेस करती है, लेकिन non-2xx HTTP कोड लौटाती है। इससे हमारे सर्वर से ऊपर वाले शेड्यूल पर बार-बार पुनः प्रयास होते हैं, जो हमारे और आपके, दोनों सर्वर पर बेवजह भार डालते हैं।

ऐसे मामलों से बचने के लिए हमारे पास एक तंत्र है, जो प्रोजेक्ट में Webhook URL बंद कर देता है। इससे बचने के लिए ये कदम उठाएँ:

1. अपने webhook हैंडलर का कोड बदलें, ताकि भुगतान की सफल प्रोसेसिंग पर वह 2xx कोड लौटाए, आमतौर पर 200। किसी भी एम्युलेटर से उसकी जाँच करें, जैसे Postman।
2. सेटिंग्स ठीक कराने के लिए तकनीकी सहायता से संपर्क करें।
3. प्रोजेक्ट सेटिंग्स में Webhook URL फिर से चालू करें और प्रोजेक्ट सेव करें।
