هر سیستمی، هر فرمتی
فروشگاهِ وردپرسی، نرمافزارِ قدیمیِ SOAP یا اپِ تازه با GraphQL؛ همه به یک API وصل میشوند. محیطِ آزمایشی رایگان است و با دادهٔ نمونه پر شده.
# اولین درخواست، در محیطِ آزمایشی curl https://sandbox.radmand.example/v1/ping \ -H "Authorization: Bearer rd_test_••••" { "ok": true, "env": "sandbox", "company": "شرکت نمونه" }
شروعِ سریع
سه آدرس، یک کلید. هر چیزی که در محیطِ آزمایشی بسازی، روی دادهٔ واقعی اثر ندارد.
- در پنل، از «تنظیمات ← API» یک کلیدِ آزمایشی بساز.
- درخواستِ /ping را بفرست تا اتصال تأیید شود.
- وقتی آماده بودی، کلیدِ اصلی بگیر و آدرس را به api عوض کن.
احرازِ هویت
کلید را در سرآیندِ Authorization بفرست. کلیدهای آزمایشی با rd_test_ و کلیدهای اصلی با rd_live_ شروع میشوند. برای اپهایی که از طرفِ کاربر کار میکنند، OAuth 2.0 با دامنهٔ دسترسیِ محدود هست.
| دامنه | اجازه |
|---|---|
| invoices:read | خواندنِ فاکتورها |
| invoices:write | ساختن و ویرایشِ فاکتور |
| ledger:read | خواندنِ سندها و گزارشها |
| webhooks | ثبتِ Webhook |
یک درخواست، چهار فرمت
ساختنِ فاکتورِ فروش با همان دادهها. فرمت را انتخاب کن.
POST /v1/invoices Content-Type: application/json { "customer": { "name": "فروشگاه بهار", "economic_code": "041118993227" }, "items": [ { "sku": "HOCO-X88", "qty": 2, "unit_price": 4500000 } ], "currency": "IRR", "send_to": ["moadian", "sepidar"] } // 201 Created { "id": "inv_8F3k2", "number": "1405-231", "total": 9900000, "status": "queued" }
POST /v1/invoices Content-Type: application/xml <invoice> <customer economic_code="041118993227">فروشگاه بهار</customer> <item sku="HOCO-X88" qty="2" unit_price="4500000"/> <currency>IRR</currency> <send_to>moadian sepidar</send_to> </invoice> <!-- 201 Created --> <invoice id="inv_8F3k2" number="1405-231" total="9900000" status="queued"/>
POST /soap/v1 (WSDL: /soap/v1?wsdl) SOAPAction: "CreateInvoice" <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rd="urn:radmand:v1"> <soap:Header><rd:ApiKey>rd_test_••••</rd:ApiKey></soap:Header> <soap:Body> <rd:CreateInvoice> <rd:CustomerName>فروشگاه بهار</rd:CustomerName> <rd:EconomicCode>041118993227</rd:EconomicCode> <rd:Item><rd:Sku>HOCO-X88</rd:Sku><rd:Qty>2</rd:Qty><rd:UnitPrice>4500000</rd:UnitPrice></rd:Item> </rd:CreateInvoice> </soap:Body> </soap:Envelope>
mutation { createInvoice(input: { customer: { name: "فروشگاه بهار", economicCode: "041118993227" } items: [{ sku: "HOCO-X88", qty: 2, unitPrice: 4500000 }] sendTo: [MOADIAN, SEPIDAR] }) { id number total status customer { name balance } # ماندهحسابِ مشتری، در همان درخواست } }
نمونهکد و SDK
SDKهای رسمی برای JavaScript، Python، PHP، C#، Java و Go. همه متنباز و با نمونهٔ کامل.
curl -X POST https://sandbox.radmand.example/v1/invoices \ -H "Authorization: Bearer $RADMAND_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: order-1043" \ -d '{"customer":{"name":"فروشگاه بهار"},"items":[{"sku":"HOCO-X88","qty":2}]}'
import { Radmand } from "@radmand/sdk"; const rd = new Radmand(process.env.RADMAND_KEY, { sandbox: true }); const inv = await rd.invoices.create({ customer: { name: "فروشگاه بهار" }, items: [{ sku: "HOCO-X88", qty: 2 }], }, { idempotencyKey: "order-1043" }); console.log(inv.number);
from radmand import Radmand rd = Radmand(os.environ["RADMAND_KEY"], sandbox=True) inv = rd.invoices.create( customer={"name": "فروشگاه بهار"}, items=[{"sku": "HOCO-X88", "qty": 2}], idempotency_key="order-1043", ) print(inv.number)
$rd = new \Radmand\Client(getenv('RADMAND_KEY'), ['sandbox' => true]); $inv = $rd->invoices->create([ 'customer' => ['name' => 'فروشگاه بهار'], 'items' => [['sku' => 'HOCO-X88', 'qty' => 2]], ], ['idempotency_key' => 'order-1043']); echo $inv->number;
var rd = new RadmandClient(Environment.GetEnvironmentVariable("RADMAND_KEY"), sandbox: true); var inv = await rd.Invoices.CreateAsync(new InvoiceInput { Customer = new() { Name = "فروشگاه بهار" }, Items = { new() { Sku = "HOCO-X88", Qty = 2 } }, }, idempotencyKey: "order-1043"); Console.WriteLine(inv.Number);
Radmand rd = Radmand.builder().apiKey(System.getenv("RADMAND_KEY")).sandbox(true).build(); Invoice inv = rd.invoices().create(InvoiceInput.builder() .customer(Customer.named("فروشگاه بهار")) .addItem("HOCO-X88", 2) .build(), RequestOptions.idempotencyKey("order-1043")); System.out.println(inv.getNumber());
rd := radmand.New(os.Getenv("RADMAND_KEY"), radmand.Sandbox()) inv, err := rd.Invoices.Create(ctx, &radmand.InvoiceInput{ Customer: radmand.Customer{Name: "فروشگاه بهار"}, Items: []radmand.Item{{SKU: "HOCO-X88", Qty: 2}}, }, radmand.IdempotencyKey("order-1043")) if err != nil { log.Fatal(err) } fmt.Println(inv.Number)
سرآیندِ Idempotency-Key جلوی فاکتورِ تکراری را میگیرد؛ اگر درخواست دو بار برسد، فقط یک فاکتور ساخته میشود.
Webhook
وقتی چیزی عوض شد، رادمند به آدرسِ تو خبر میدهد. هر درخواست امضا دارد و تا ۲۴ ساعت دوباره فرستاده میشود تا جوابِ 2xx بگیرد.
| رویداد | کِی |
|---|---|
| invoice.created | فاکتورِ تازه ساخته شد |
| invoice.moadian.accepted | سامانهٔ مودیان فاکتور را پذیرفت |
| receipt.parsed | رسیدِ ارسالی خوانده شد |
| sepidar.synced | همگامسازی با سپیدار تمام شد |
| rule.triggered | یکی از قانونهایت اجرا شد |
// بررسیِ امضا (Node.js) const sig = crypto.createHmac("sha256", process.env.RADMAND_WEBHOOK_SECRET) .update(req.rawBody).digest("hex"); if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(req.headers["radmand-signature"]))) return res.status(401).end();
وردپرس و ووکامرس
افزونهٔ رادمند هر سفارشِ ووکامرس را فاکتور میکند و موجودیِ کالا را از رادمند یا سپیدار میخواند.
از «افزونهها ← افزودن»، فایلِ افزونهٔ رادمند را بارگذاری کن.
کلیدِ API را در «ووکامرس ← تنظیمات ← رادمند» بگذار.
شناسهٔ کالای ووکامرس را به کدِ کالای رادمند وصل کن.
سیستمهای اختصاصی
نرمافزارِ داخلیِ شرکت، صندوقِ فروشگاهی یا سیستمی که فقط فایل خروجی میدهد هم وصل میشود.
- ورودِ فایلِ Excel و CSV با نگاشتِ ستونها
- پوشهٔ مشترک یا SFTP: هر فایلِ تازه خودکار خوانده میشود
- SOAP با WSDL برای سیستمهایی که REST ندارند
- ایجنتِ محلی برای پایگاهدادههایی که از بیرون در دسترس نیستند
محدودیتها و خطاها
| پلن | درخواست در دقیقه |
|---|---|
| همراهِ سپیدار | ۶۰، فقط خواندن |
| رشد | ۶۰۰ |
| سازمانی | قابلِ تنظیم |
کدهای خطا
| کد | معنی |
|---|---|
| 400 invalid_economic_code | کدِ اقتصادی باید ۱۲ رقم باشد |
| 401 invalid_key | کلید نامعتبر یا باطل شده |
| 409 duplicate | همین Idempotency-Key قبلاً استفاده شده |
| 429 rate_limited | از سقفِ درخواست رد شدی؛ سرآیندِ Retry-After را ببین |