← सभी ट्यूटोरियल

ट्यूटोरियल 11 / 12

अपना क्रिप्टो मार्केटप्लेस बनाएँ।

साझा कार्ट से विक्रेताओं को भुगतान तक, $300 के व्यावहारिक उदाहरण और सर्वर-साइड कोड के साथ।

आपके पास क्या होगा

ऐसा भुगतान इंटीग्रेशन जिसे ग्राहक भुगतान और विक्रेता पेआउट मिलाए बिना जाँच, मिलान और स्वचालित कर सकते हैं।

1. तय करें कौन क्या सँभालेगा

आपकी दुकान कैटलॉग, विक्रेता खाते, कार्ट, शिपिंग और ऑर्डर पूरा करना सँभालती है। Wholly Crypto चेकआउट, भुगतान सत्यापन, विक्रेता आवंटन और मंज़ूर पेआउट सँभालता है। विक्रेता रिकॉर्ड विक्रेता लॉगिन नहीं है; मौजूदा शॉप प्लगइन बहु-विक्रेता कार्ट अपने आप नहीं बाँटते।

  1. एक साझा कार्ट
  2. एक ग्राहक इनवॉइस
  3. सत्यापित विक्रेता हिस्से
  4. मंज़ूर पेआउट

ग्राहक पहले प्रोजेक्ट वॉलेट में भुगतान करते हैं। कुंजियाँ आपके नियंत्रण में हैं और विक्रेताओं को देय फ़ंड आपके पास रहता है। यह सीधे ग्राहक-से-विक्रेता बँटवारा या विक्रेताओं के लिए नॉन-कस्टोडियल सेवा नहीं है।

मार्केटप्लेस में Bitcoin मेननेट, समर्थित EVM कॉइन और मानक ERC-20 टोकन समर्थित हैं। विक्रेताओं को ग्राहक द्वारा इस्तेमाल किए एसेट और नेटवर्क में भुगतान मिलता है, अपने आप फ़िएट रूपांतरण नहीं। सभी 30 प्राप्ति चेन मार्केटप्लेस पेआउट के लिए समर्थित नहीं हैं।

2. राशियों का हिसाब करें

तीन विक्रेता $100 का सामान प्रति व्यक्ति बेचते हैं। इस उदाहरण में कोई स्टोर या विक्रेता ओवरराइड रखे बिना प्रोजेक्ट कमीशन 4% करें।

हिस्सासकलआपका कमीशनविक्रेता को मिलता है
हर विक्रेता$100$4$96
तीनों का कुल$300$12$288

ये इनवॉइस के लॉक किए कोट पर समतुल्य राशियाँ हैं, जिनका भुगतान क्रिप्टो में होता है। भविष्य में डॉलर मूल्य की गारंटी नहीं है। सामान्य 1% प्रोसेसिंग फ़ीस इस $300 इनवॉइस पर प्रीपेड क्रेडिट के $3 एक बार लेती है, हर विक्रेता के लिए अलग नहीं। वह शुल्क लागू होने पर आपका $12 सकल कमीशन नेटवर्क खर्च से पहले $9 बचाता है।

Bitcoin शुल्क या EVM गैस के लिए अलग उपलब्ध नेटिव कॉइन रखें। शुल्क विक्रेताओं की सुरक्षित मूल राशि नहीं खर्च कर सकता। सामान्य स्वीप मार्केटप्लेस प्राप्ति पतों का फ़ंड खर्च नहीं कर सकते।

3. वॉलेट और विक्रेता तैयार करें

  1. प्रोजेक्ट → मार्केटप्लेस → सेटिंग्स में मार्केटप्लेस चालू करें, स्टोर चुनें और कमीशन तय करें। सेटअप के दौरान पेआउट रोके रखें और ऑटोमैटिक नीतियाँ बंद रखें।
  2. प्रोजेक्ट वॉलेट और डेटाबेस का बैकअप लें। स्टोर में इच्छित BTC/EVM विधियाँ चालू करें, स्कैनर की तैयारी जाँचें और प्रोसेसिंग क्रेडिट के साथ अलग नेटिव शुल्क का फ़ंड रखें।
  3. हर विक्रेता जोड़ें। उसकी UUID को दुकान की विक्रेता ID से जोड़कर सहेजें; external_id में वह विक्रेता संदर्भ रह सकता है। सटीक चेन और नेटवर्क पर हर पेआउट पता स्वतंत्र रूप से सत्यापित और मंज़ूर करें।

चेकआउट विधि के लिए हर भाग लेने वाले विक्रेता का मेल खाता मंज़ूर गंतव्य चाहिए। बाद में विक्रेता पता बदलने से मौजूदा देनदारियाँ चुपचाप दूसरी जगह नहीं भेजी जातीं।

पेआउट सत्यापन के लिए शून्य से अधिक पुष्टियाँ और दो स्वतंत्र संगत प्रदाता चाहिए, भले ही चेकआउट शून्य पुष्टि या एक स्कैनर की अनुमति दे।

कंसोल सेटअप का चरण-दर-चरण विवरण · बैकअप और बहाली

4. साझा कार्ट जोड़ें

सेटिंग्स → API ऐक्सेस में प्रोजेक्ट तक सीमित मार्केटप्लेस क्रेडेंशियल बनाएँ। चेकआउट बैकएंड को marketplace.read और invoices.write दें, जहाँ उचित हो उसे उसके स्टोर तक सीमित रखें। उस कुंजी में पता मंज़ूरी और पेआउट मंज़ूरी की अनुमतियाँ न रखें।

कीमत, छूट, टैक्स और शिपिंग अपने सर्वर पर गणना करें, फिर विक्रेता हिस्सों में आवंटित करें। शून्य से अधिक दशमलव स्ट्रिंग के साथ 1–100 अलग विक्रेता भेजें; उनकी सकल राशियों का जोड़ बिल्कुल इनवॉइस के बराबर होना चाहिए। ब्राउज़र से आए बँटवारे पर भरोसा न करें और पैसों के लिए फ़्लोटिंग-पॉइंट गणना कभी न करें।

नीचे API होस्टनेम और UUID प्लेसहोल्डर बदलें। WHOLLY_TOKEN अपने सर्वर वातावरण से लोड करें। अनुरोध कॉन्फ़िगर किया 4% कमीशन अपनाता है; इसे कमीशन ओवरराइड करने की अनुमति नहीं चाहिए।

अनुरोध cURL, JavaScript, PHP या Python में खोलें
cURL
: "${WHOLLY_TOKEN:?Set WHOLLY_TOKEN to your server-side API token}"
# Keep this key and the exact body for retries; use a new key for each new operation.
curl --fail-with-body --max-time 30 \
  --request POST \
  --url "https://api.example.com/v1/marketplace/invoices" \
  --header "Authorization: Bearer $WHOLLY_TOKEN" \
  --header 'Idempotency-Key: cart-1042-marketplace-v1' \
  --header 'Content-Type: application/json' \
  --data-raw '{
  "project_id": "YOUR_PROJECT_ID",
  "store_id": "YOUR_STORE_ID",
  "amount": "300.00",
  "currency": "USD",
  "order_id": "cart-1042",
  "description": "One order from three vendors",
  "ipn_url": "https://shop.example.com/payments/wholly-ipn",
  "metadata": {
    "cart_id": "cart-1042"
  },
  "allocations": [
    {
      "vendor_id": "VENDOR_A_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_B_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_C_UUID",
      "gross_amount": "100.00"
    }
  ]
}'
JavaScript
// Node.js 18+ · run on your server, never in browser code.
const token = process.env.WHOLLY_TOKEN;
if (!token) throw new Error("Set WHOLLY_TOKEN");
// Keep this key and the exact body for retries; use a new key for each new operation.
const body = `{
  "project_id": "YOUR_PROJECT_ID",
  "store_id": "YOUR_STORE_ID",
  "amount": "300.00",
  "currency": "USD",
  "order_id": "cart-1042",
  "description": "One order from three vendors",
  "ipn_url": "https://shop.example.com/payments/wholly-ipn",
  "metadata": {
    "cart_id": "cart-1042"
  },
  "allocations": [
    {
      "vendor_id": "VENDOR_A_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_B_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_C_UUID",
      "gross_amount": "100.00"
    }
  ]
}`;
const response = await fetch("https://api.example.com/v1/marketplace/invoices", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${token}`,
    "Idempotency-Key": "cart-1042-marketplace-v1",
    "Content-Type": "application/json"
  },
  body,
  redirect: "error",
  signal: AbortSignal.timeout(30000)
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
console.log(await response.json());
PHP
<?php
// PHP 8+ with the cURL extension; run on your server.
$token = getenv('WHOLLY_TOKEN');
if (!$token) { throw new RuntimeException('Set WHOLLY_TOKEN'); }
// Keep this key and the exact body for retries; use a new key for each new operation.
$body = <<<'JSON'
{
  "project_id": "YOUR_PROJECT_ID",
  "store_id": "YOUR_STORE_ID",
  "amount": "300.00",
  "currency": "USD",
  "order_id": "cart-1042",
  "description": "One order from three vendors",
  "ipn_url": "https://shop.example.com/payments/wholly-ipn",
  "metadata": {
    "cart_id": "cart-1042"
  },
  "allocations": [
    {
      "vendor_id": "VENDOR_A_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_B_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_C_UUID",
      "gross_amount": "100.00"
    }
  ]
}
JSON;
$ch = curl_init("https://api.example.com/v1/marketplace/invoices");
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token, "Idempotency-Key: cart-1042-marketplace-v1", "Content-Type: application/json"],
    CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
if ($status < 200 || $status >= 300) { throw new RuntimeException("HTTP $status: $response"); }
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));
Python
# Python 3 · standard library; run on your server.
import json
import os
from urllib.request import Request, build_opener, HTTPRedirectHandler

class NoRedirect(HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None

# Keep this key and the exact body for retries; use a new key for each new operation.
headers = {
    "Idempotency-Key": "cart-1042-marketplace-v1",
    "Content-Type": "application/json"
}
headers["Authorization"] = "Bearer " + os.environ["WHOLLY_TOKEN"]
body = """{
  "project_id": "YOUR_PROJECT_ID",
  "store_id": "YOUR_STORE_ID",
  "amount": "300.00",
  "currency": "USD",
  "order_id": "cart-1042",
  "description": "One order from three vendors",
  "ipn_url": "https://shop.example.com/payments/wholly-ipn",
  "metadata": {
    "cart_id": "cart-1042"
  },
  "allocations": [
    {
      "vendor_id": "VENDOR_A_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_B_UUID",
      "gross_amount": "100.00"
    },
    {
      "vendor_id": "VENDOR_C_UUID",
      "gross_amount": "100.00"
    }
  ]
}""".encode("utf-8")
request = Request("https://api.example.com/v1/marketplace/invoices",
                  method="POST", headers=headers, data=body)
# Non-2xx responses raise HTTPError. Do not retry writes with a new key.
with build_opener(NoRedirect()).open(request, timeout=30) as response:
    print(json.load(response))

भेजने से पहले अनुरोध बॉडी और Idempotency-Key स्थायी रूप से सहेजें। टाइमआउट के बाद उसी कुंजी से वही बॉडी फिर भेजें। data.invoice_id को ऑर्डर के साथ सहेजें और शीर्ष-स्तर के links.checkout पर रीडायरेक्ट करें। ग्राहक के ब्राउज़र में API कुंजियाँ कभी न रखें।

प्रोजेक्ट और स्टोर UUID कहाँ मिलेंगी →

SDK पसंद है? मार्केटप्लेस उदाहरणों से शुरू करें:

5. भुगतान और पेआउट अलग ट्रैक करें

चेकआउट वापसी URL भुगतान का प्रमाण नहीं है। रॉ बॉडी पर कॉलबैक हस्ताक्षर सत्यापित करें, टाइमस्टैम्प और अपेक्षित प्रोजेक्ट जाँचें, और प्राप्ति स्वीकार करने से पहले event_id अनोखे रूप में सहेजें। अलग ऑर्डर-स्तरीय सुरक्षा रखें ताकि पुनः प्रयास से ऑर्डर दो बार पूरा न हो।

इवेंटइससे क्या पता चलता है
invoice.settledग्राहक इनवॉइस का निपटान हो गया। ऑर्डर पूरा करने से पहले समीक्षा संकेत और मार्केटप्लेस रोक जाँचें।
marketplace.allocations.availableसत्यापित हिस्से पेआउट के लिए उपलब्ध हैं। इसका मतलब किसी विक्रेता को भुगतान हो चुका है, यह ज़रूरी नहीं।
marketplace.payout.confirmedपेआउट की पुष्टि जाँच पूरी हो गई।

इनवॉइस IPN स्टोर का IPN सीक्रेट इस्तेमाल करता है। मार्केटप्लेस जीवनचक्र webhook अपने एंडपॉइंट का साइनिंग सीक्रेट इस्तेमाल करते हैं। दोनों रिसीवर अलग रखें। छूटे या क्रम से बाहर आए इवेंट का मिलान करते समय API से मौजूदा इनवॉइस या पेआउट पढ़ें।

इनवॉइस कॉलबैक और हस्ताक्षर सत्यापन · मार्केटप्लेस इवेंट और API संदर्भ

6. पहले समीक्षा करें, बाद में स्वचालित करें

सत्यापित हिस्से उपलब्ध होने पर पेआउट का विराम हटाएँ, लेकिन ऑटोमैटिक नीतियाँ बंद रखें। मार्केटप्लेस → पेआउट में आवंटन तैयार करें, प्राप्तकर्ता और नेटिव शुल्क/गैस सीमाएँ देखें, फिर सटीक योजना एक बार मंज़ूर करें। केवल प्रसारित नहीं, भुगतान हो गया तक उसका अनुसरण करें।

Bitcoin चुने इनवॉइस के सभी अवैतनिक हिस्से एक बैच में रखता है। EVM टोकन पेआउट को टोकन ट्रांसफ़र से पहले गैस फ़ंडिंग चाहिए हो सकती है। ये कई लेनदेन हैं, एक परमाणु सब-या-कुछ-नहीं बँटवारा नहीं।

छोटे सफल परीक्षण के बाद हर एसेट की एक ऑटोमैटिक नीति बनाएँ: न्यूनतम पेआउट, हर पेआउट और दैनिक मूल राशि सीमा, नेटिव शुल्क/गैस बजट, अंतराल और पुष्टियाँ। इसे चालू करने से बिना और क्लिक के भेजने की मंज़ूरी मिलती है। कम क्रेडिट या बंद सर्वर ट्रांसफ़र नियंत्रण फिर भी खर्च रोक सकता है।

7. पेचीदा मामले सँभालें

कम, देर से, मिले-जुले या चेन पुनर्गठन वाले भुगतान

चेकआउट निपट जाने से पूरी तरह फ़ंड वाले विक्रेता बँटवारे की गारंटी नहीं होती। सहनशीलता गायब फ़ंड नहीं बना सकती। रोके आवंटन देखें, भुगतान का इंतज़ार करें, रिफ़ंड करें या पूरी तरह फ़ंड वाले छोटे बँटवारे को स्पष्ट मंज़ूरी दें। अतिरिक्त भुगतान अपने आप मार्केटप्लेस की अतिरिक्त आय नहीं है।

अधिक भुगतान Bitcoin, EVM कॉइन या समर्थित ERC-20 टोकन पर कोट किया विक्रेता भुगतान नहीं रोकता। विक्रेता हिस्से नहीं बदलते और अतिरिक्त राशि मिलान के लिए अलग रहती है।

पेआउट अटक जाए या अनुरोध टाइमआउट हो जाए

उसके सहेजे लेनदेन हैश, स्रोत बैलेंस, गैस और समीक्षा कारण जाँचें। मौजूदा पेआउट फिर चलाएँ या मिलान करें; रिस्पॉन्स खो जाने पर दूसरा ट्रांसफ़र न बनाएँ। बैकअप बहाल करने के बाद ऑन-चेन परिणाम और लेजर मेल खाने तक पेआउट रोके रखें।

फिर शुरू करने पर विफल EVM ट्रांसफ़र तभी बदला जा सकता है जब दो स्वतंत्र प्रदाता पुष्ट ऑन-चेन रिवर्ट साबित करें। अज्ञात परिणाम आरक्षित रहते हैं और विफल प्रयास का शुल्क मूल बजट में फिर भी गिना जाता है।

ग्राहक को रिफ़ंड चाहिए

ग्राहक के नियंत्रण वाला रिफ़ंड पता सत्यापित करें। समर्थित रिफ़ंड पूरे और उसी एसेट में होते हैं। सभी विक्रेताओं को भुगतान के बाद मुख्य वॉलेट में अलग फ़ंड डालें; Wholly Crypto उनसे वापस नहीं काट सकता। आंशिक भुगतान वाले विक्रेता बैच में मैन्युअल मिलान चाहिए, आंशिक-रिफ़ंड बटन होने की धारणा नहीं।

8. खोलने से पहले जाँचें

  • छोटा BTC और/या EVM भुगतान पुष्ट विक्रेता पेआउट तक चलाकर जाँचें। चेन, टोकन कॉन्ट्रैक्ट, गंतव्य, कमीशन और अलग शुल्क की पुष्टि करें।
  • दोहराया कॉलबैक, टाइमआउट API रिस्पॉन्स, कम भुगतान और रोका पेआउट जाँचें। सत्यापित करें कि किसी से दोहरा ऑर्डर पूरा होना या दोबारा भेजना नहीं होता।
  • निजी बैकअप सर्वर से बाहर रखें, पेआउट विफलताओं की निगरानी करें और विक्रेता देनदारियों का नियमित रूप से ऑन-चेन फ़ंड से मिलान करें।

समीक्षा किए पेआउट और कम विक्रेताओं से शुरू करें। केवल जाँचे एसेट, बजट और गंतव्य स्वचालित करें।