API پرداخت کارت به کارت: ساخت پرداخت و دریافت وضعیت با کد
اگر سایت، اپلیکیشن یا نرمافزار اختصاصی دارید، میتوانید پرداخت کارتبهکارت را از کد خودتان بسازید و نتیجهی تأیید یا رد را با وبهوک امضاشده دریافت کنید.
API کارت پی برای چه کاری ساخته شده است؟
هر کاری که در پنل کارت پی انجام میدهید، از طریق API هم ممکن است و دادهی هر دو سمت یکی است. اگر از کد یک پرداخت بسازید، همان لحظه در فهرست تراکنشهای پنل هم میبینیدش؛ اگر از پنل یا ربات تلگرام یک رسید را تأیید کنید، سیستم شما از طریق وبهوک خبردار میشود. به این ترتیب مجبور نیستید بین «پنل برای آدمها» و «API برای کد» یکی را انتخاب کنید.
این API برای ساختن و پیگیری پرداختهای کارتبهکارت است. جایگزین درگاه بانکی نیست و پول از آن عبور نمیکند؛ مشتری هنوز مبلغ را مستقیم به کارت شما میزند و رسید میفرستد. API فقط لایهی نظم و اتصال را به نرمافزار شما میدهد. اگر هنوز با کلیات این روش آشنا نیستید، اول صفحهی درگاه پرداخت کارت به کارت را بخوانید.
چه کسانی به آن نیاز پیدا میکنند
فروشگاه اینترنتی که میخواهد کارتبهکارت را کنار روشهای دیگرش داشته باشد، سیستم رزرو یا آموزشگاه که صورتحساب و نوبت را جای دیگری نگه میدارد، نرمافزار حسابداری یا CRM که باید از پرداختها خبر بگیرد، و رباتسازهایی که فروش را داخل پیامرسان انجام میدهند.
امکانات API در یک نگاه
درخواست پرداخت
یک تراکنش با وضعیت «در انتظار پرداخت» میسازید و نشانی صفحهی پرداخت را برای هدایت مشتری میگیرید.
وضعیت و فهرست تراکنشها
وضعیت یک تراکنش یا فهرست صفحهبندیشدهی همهی تراکنشها را با فیلتر تاریخ و خدمت میخوانید.
خدمات و نوبتدهی
خدمت میسازید، ویرایش میکنید و برنامهی نوبتدهی هر خدمت را تنظیم میکنید.
فاکتور و پرداختهای آن
فاکتور میسازید، پرداخت دستی ثبت میکنید و ماندهی فاکتور را میخوانید.
کارتهای بانکی
کارتها، اولویت و سقف روزانهی هر کارت را میخوانید و جابهجا میکنید.
وبهوک امضاشده
با هر تغییر وضعیت، یک POST با امضای HMAC-SHA256 به آدرس شما میرسد.
همین حالا شروع کنید
ثبتنام با شماره موبایل و کد تأیید انجام میشود.
اولین درخواست: ساختن یک پرداخت
همهی اندپوینتها زیر مسیر /api/v1/open/ هستند و احراز هویت با کلید API در هدر X-API-KEY انجام میشود. کلید را در بخش توسعهدهندگان پنل میسازید. برای شروع، فقط چهار فیلد لازم است: مبلغ، عنوان، و نشانی بازگشت مرورگر مشتری. شمارهی موبایل و نام خریدار اختیاریاند.
curl -X POST https://kartpy.ir/api/v1/open/payment/request/ \
-H "X-API-KEY: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 450000,
"title": "سفارش شماره 1204",
"callback_url": "https://shop.example.com/orders/1204/done",
"api_callback_url": "https://shop.example.com/hooks/kartpay"
}'{
"status": 201,
"message": "درخواست پرداخت ساخته شد",
"data": [{
"transaction_id": 981,
"token": "…",
"payment_url": "https://kartpy.ir/pay/getway/…",
"status": "awaiting_payment",
"amount": 450000,
"title": "سفارش شماره 1204"
}]
}مشتری را به payment_url هدایت میکنید. او مبلغ و شماره کارت را میبیند، کارتبهکارت میکند و رسید را ثبت میکند. تا وقتی هنوز رسیدی ثبت نشده، این تراکنش فقط یک درخواست ثبتشده است و هیچ اثری روی آمار یا ظرفیت کارتها نمیگذارد.
سه قدم برای وصل کردن یک سفارش به کارت پی
کلید API بسازید
در بخش توسعهدهندگان پنل کلید را میسازید. هر حساب یک کلید دارد که یک بار ساخته میشود و باید آن را فقط سمت سرور نگه دارید.
هنگام ثبت سفارش، پرداخت بسازید
درخواست پرداخت را از بکاند بفرستید، شناسهی تراکنش را کنار سفارش ذخیره کنید و مشتری را به payment_url ببرید.
نتیجه را بگیرید
یا وبهوک را بپذیرید یا با شناسهی تراکنش وضعیت را بخوانید. وقتی وضعیت تأییدشده شد، سفارش را نهایی کنید.
نقشهی اندپوینتها
| مسیر (زیر /api/v1/open/) | کاربرد |
|---|---|
| payment/request/ | ساخت درخواست پرداخت (POST) |
| payment/status/{id}/ | بررسی وضعیت یک تراکنش |
| transactions/ | فهرست صفحهبندیشدهی تراکنشها با فیلتر |
| transactions/{id}/ | ویرایش تراکنش (وضعیت، مبلغ و توضیح) |
| services/ و services/{id}/ | ساخت، ویرایش و فهرست خدمتها |
| services/{id}/schedule/ | تنظیمات نوبتدهی یک خدمت |
| invoices/ و invoices/{id}/payments/ | فاکتورها و پرداختهای ثبتشده روی هر فاکتور |
| appointments/ | نوبتهای خدمتها و حذف گروهی نوبتهای آزاد |
| bank-cards/ و bank-cards/{id}/move/ | کارتهای بانکی، سقف روزانه و تغییر اولویت |
وبهوک: چه میرسد و چطور باید راستیآزمایی شود
اگر هنگام ساخت پرداخت api_callback_url را بدهید، با هر تغییر وضعیت یک درخواست POST به آن نشانی میرسد. بدنه همان شکل پاسخ بررسی وضعیت را دارد، بهاضافهی رویداد و وضعیت قبلی. سه هدر هم همراه آن است: X-KartPay-Event (نوع رویداد)، X-KartPay-Delivery (شناسهی ارسال) و X-KartPay-Signature (امضا).
امضا به شکل sha256 و رشتهی هگز HMAC بدنهی خام با کلید API شماست. باید همان بایتهای خام درخواست را بخوانید، نه JSON پارسشده و دوباره ساختهشده را.
import hmac, hashlib
def is_valid(raw_body: bytes, header: str, api_key: str) -> bool:
digest = hmac.new(api_key.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest("sha256=" + digest, header)اگر سرور شما پاسخ ۲۰۰ تا ۲۹۹ ندهد یا در ۱۰ ثانیه جواب ندهد، ارسال دوباره امتحان میشود: حداکثر پنج تلاش با فاصلههایی که از یک دقیقه شروع میشود و تا چند ساعت بیشتر میشود. پس هندلر وبهوک را طوری بنویسید که اگر همان رویداد دو بار آمد، دو بار سفارش را نهایی نکند.
از ثبت سفارش تا نهایی شدن؛ یک سناریوی کامل
- ثانیهی ۰
مشتری سفارش را ثبت میکند
سفارش با وضعیت «در انتظار پرداخت» در پایگاه دادهی شما ساخته میشود. اگر موجودی کالا محدود است، میتوانید برای آن یک رزرو کوتاهمدت در نظر بگیرید.
- ثانیهی ۲
درخواست پرداخت ساخته میشود
بکاند شما به کارت پی POST میکند، transaction_id را کنار سفارش مینویسد و مرورگر را به payment_url میفرستد.
- چند دقیقه بعد
مشتری پرداخت و رسید را ثبت میکند
این بخش بیرون از سیستم شماست. وضعیت تراکنش به «در انتظار بررسی» میرود.
- لحظهی تصمیم
شما یا همکارتان در پنل یا ربات تأیید میکنید
وضعیت به «تأییدشده» تغییر میکند و وبهوک ساخته و برای ارسال صف میشود.
- کمی بعد
سفارش در سیستم شما نهایی میشود
هندلر وبهوک امضا را میسنجد، سفارش را پیدا میکند و وضعیتش را به پرداختشده تغییر میدهد.
وضعیت پرداخت را چطور به وضعیت سفارش خودتان ترجمه کنید؟
بزرگترین خطای طراحی در این اتصال، ساده کردن بیش از حد وضعیتهاست. اگر فقط «پرداختشده» و «پرداختنشده» داشته باشید، مشتریای که رسید فرستاده و منتظر بررسی است همان پیام مشتری بیپرداخت را میگیرد و فکر میکند پولش گم شده. این جدول یک نقطهی شروع پیشنهادی است.
| وضعیت تراکنش در کارت پی | پیشنهاد برای سفارش شما | نکته |
|---|---|---|
| در انتظار پرداخت | سفارش در انتظار پرداخت | مشتری هنوز رسید نفرستاده؛ میتوانید پس از مدتی یادآوری بفرستید |
| در انتظار بررسی | پرداخت در حال بررسی | به مشتری نشان دهید پول در حال بررسی است، نه اینکه خرید ناموفق بوده |
| تأییدشده | پرداختشده، آمادهی پردازش | تنها وضعیتی که اجازهی نهایی کردن سفارش را میدهد |
| ردشده | پرداخت ناموفق، قابل تلاش دوباره | لینک پرداخت را دوباره نشان دهید و علت را اگر دارید بگویید |
| لغوشده | سفارش لغو | موجودی رزروشده را آزاد کنید |
| مرجوعی | سفارش مرجوع | برگشت وجه را خودتان واریز کردهاید؛ سفارش را بر همان اساس ببندید |
اگر وبهوک نرسید، مسیر پشتیبان چیست؟
هیچ سیستم توزیعشدهای اطمینان مطلق نمیدهد؛ سرور شما ممکن است در لحظهی ارسال خاموش باشد، یا فایروال راه را بسته باشد. کارت پی چند بار دوباره تلاش میکند، ولی توصیهی عملی این است که همیشه یک راه پشتیبان داشته باشید.
بررسی دورهای سفارشهای معلق
یک کار زمانبندیشده بنویسید که هر چند دقیقه سفارشهایی را که مدتی در انتظار پرداخت یا بررسی ماندهاند پیدا کند و برای هرکدام از اندپوینت بررسی وضعیت بپرسد. این کار در حالت عادی هیچ تغییری ایجاد نمیکند، ولی اگر وبهوکی گم شده بود، سفارش را خودش اصلاح میکند.
وقتی مشتری از صفحهی پرداخت برمیگردد
روی صفحهی بازگشت، پیش از نمایش پیام «پرداخت موفق»، یک بار وضعیت را از API بپرسید. اگر هنوز «در انتظار بررسی» بود، پیام درست را نشان دهید: رسید ثبت شده و منتظر بررسی هستیم. به این شکل صفحهی بازگشت هیچوقت چیزی نمیگوید که واقعیت نباشد.
اشتباههایی که هنگام اتصال زیاد دیده میشود
اعتماد به callback_url
نشانی بازگشت مرورگر فقط برای نمایش پیام به مشتری است. هر کسی میتواند آن را دستی باز کند. وضعیت واقعی را همیشه از وبهوک یا API بخوانید.
کلید API در کد کلاینت
کلید مثل رمز عبور است. در جاوااسکریپت صفحه، اپ موبایل یا مخزن عمومی نگذارید. اگر لو رفت، همان لحظه از طریق پشتیبانی پنل خبر بدهید.
پارس کردن و دوباره ساختن بدنه
امضا روی بایتهای خام محاسبه شده؛ اگر JSON را پارس و دوباره سریالایز کنید، فاصله و ترتیب کلیدها عوض میشود و امضا نمیخواند.
نهایی کردن دوبارهی سفارش
یک رویداد ممکن است بیش از یک بار برسد. شناسهی تحویل یا وضعیت فعلی سفارش را بسنجید و تکراریها را نادیده بگیرید.
فراموش کردن حداقل مبلغ
مبلغ درخواست پرداخت نمیتواند کمتر از حد مجاز باشد. در سمت خودتان قبل از فراخوانی اعتبارسنجی کنید تا خطای غیرضروری نگیرید.
ساختار پاسخها و خطاها
هر پاسخ، چه موفق و چه ناموفق، سه کلید ثابت دارد: status (همان کد وضعیت HTTP)، message (پیام فارسی قابل نمایش) و data (آرایهای که در خطا خالی است). فهرستها کلید چهارمی به نام pagination هم دارند و اندازهی پیشفرض صفحه ۲۰ و حداکثر آن ۱۰۰ است. اگر کد یک تراکنش را پارس کند، روی عضوهای فهرست هم همان کد کار میکند.
خطاهای رایج
- ۴۰۱: هدر X-API-KEY فرستاده نشده یا کلید معتبر نیست.
- ۴۰۰: ورودی ناقص یا نامعتبر است؛ message علت را به فارسی میگوید، مثلاً نامعتبر بودن شماره موبایل یا نشانی بازگشت.
- ۴۰۴: تراکنش یا موجودیت پیدا نشد. توجه کنید که شناسهی متعلق به حساب دیگر هم همین پاسخ را میگیرد.
برای دیدن دقیق فیلدها، نوعها و نمونهی پاسخ هر اندپوینت، Swagger UI و ReDoc و فایل OpenAPI در دسترساند (مسیر docs/ و redoc/ و schema/ زیر /api/v1/open/) و میتوانید هر اندپوینت را همانجا امتحان کنید.
این API مناسب چه کسی است؟
مناسب است اگر
- سیستمی دارید که سفارش یا رزرو را در پایگاه دادهی خودش ثبت میکند و باید از پرداخت خبر بگیرد.
- چند فروشگاه یا چند شعبه دارید و میخواهید تراکنشها در یک جا جمع شود.
- میخواهید فاکتور یا نوبت را از نرمافزار خودتان در کارت پی بسازید.
- مشتریهایتان به پرداخت کارتبهکارت عادت دارند و دنبال سامان دادن آن هستید.
مناسب نیست اگر
- انتظار دارید مشتری با کارت شتاب پرداخت کند و تسویهی بانکی داشته باشید؛ برای آن درگاه رسمی لازم است.
- میخواهید پرداخت بدون هیچ مرحلهی تأیید انسانی نهایی شود؛ تأیید هنوز با پذیرنده است.
- محیط آزمایشی جداگانهای با پول مجازی لازم دارید؛ برای آزمایش از مبلغهای کوچک واقعی و Swagger استفاده میشود.
چکلیست پیش از انتشار اتصال
- کلید در محیط امن: کلید را در متغیر محیطی یا مدیریت رازهای سرور نگه داشتهاید، نه در کد.
- امضا بررسی میشود: هندلر وبهوک بدنهی خام را با کلید شما مقایسه میکند و درخواست بیامضا را رد میکند.
- هندلر تکرارپذیر است: دو بار رسیدن یک رویداد نتیجهی تکراری ایجاد نمیکند.
- وضعیتها درست نگاشت شدهاند: سفارش فقط وقتی نهایی میشود که وضعیت تراکنش «تأییدشده» باشد، نه صرفاً رسیدن مشتری به callback_url.
- خطاها لاگ میشوند: پاسخهای ۴۰۰ و ۴۰۱ را با message ثبت میکنید تا اشکال سریع پیدا شود.
تأیید رسید همچنان کار انسان است
توسعهدهندگانی که با درگاه بانکی کار کردهاند، معمولاً انتظار دارند پرداخت در چند ثانیه نتیجه بدهد. در کارتبهکارت، بین ثبت رسید و تأیید یک مرحلهی انسانی هست: پذیرنده باید واریز را روی حساب ببیند. این مرحله ممکن است چند دقیقه یا چند ساعت طول بکشد و طراحی سیستم شما باید با این واقعیت سازگار باشد.
در عمل یعنی سفارش شما باید یک وضعیت میانی داشته باشد که به مشتری بگوید پرداختش دریافت و در حال بررسی است. ایمیل یا پیامک تأیید سفارش را هم بهتر است بعد از رسیدن وبهوک تأیید بفرستید، نه بعد از بازگشت مرورگر. اگر سرعت برایتان مهم است، به پذیرنده پیشنهاد کنید ربات تلگرام یا بله را وصل کند تا رسیدها در ساعت کاری ظرف چند دقیقه بررسی شوند.
این مرحلهی انسانی ضعف نیست؛ دلیلش این است که هیچ سرویسی جز خود صاحب حساب به حساب بانکی او دسترسی ندارد. کارت پی بهجای وانمود کردن به تأیید، وضعیت را صادقانه گزارش میکند.
پرسشهای متداول درباره API پرداخت کارت به کارت
احراز هویت چطور است؟
کلید API را در هدر X-API-KEY هر درخواست میفرستید. بدون آن یا با کلید نامعتبر پاسخ ۴۰۱ میگیرید.
هر حساب چند کلید دارد؟
هر حساب یک کلید API دارد که یک بار ساخته میشود و پنل جلوی ساخت دوبارهی ناخواسته را میگیرد. اگر شک دارید کلید لو رفته است، از طریق تیکت پشتیبانی پنل پیگیری کنید.
پاسخها چه ساختاری دارند؟
هر پاسخ سه کلید دارد: status، message و data. فهرستها کلید pagination هم دارند.
وبهوک چه وقت ارسال میشود؟
اگر هنگام ساخت درخواست پرداخت api_callback_url را بدهید، با هر تغییر وضعیت تراکنش، چه از پنل چه از ربات چه از API، یک POST میرسد.
چطور از اصالت وبهوک مطمئن شوم؟
هدر X-KartPay-Signature را با HMAC-SHA256 بدنهی خام و کلید API خودتان بازمحاسبه و مقایسه کنید.
اگر سرورم در لحظهی ارسال وبهوک خاموش بود؟
ارسال با فاصلههای زمانی افزایشی چند بار دوباره امتحان میشود. اگر به هر دلیل از دست دادید، وضعیت را با شناسهی تراکنش از اندپوینت بررسی وضعیت بخوانید.
Swagger دارید؟
بله. Swagger UI و ReDoc و فایل OpenAPI در دسترساند و میتوانید اندپوینتها را مستقیم امتحان کنید.
آیا مشتری باید حساب کارت پی داشته باشد؟
نه. مشتری از سایت شما به صفحهی پرداخت میآید، مبلغ را میبیند و رسید را میفرستد. حتی نام و موبایل او هم اختیاری است.
میتوانم از API برای تأیید یا رد رسید هم استفاده کنم؟
بله، وضعیت یک تراکنش از طریق اندپوینت تراکنشها قابل بهروزرسانی است و همان مسیر وبهوک را فعال میکند.
مستندات کامل اندپوینتها، نمونه درخواستها و Swagger پس از ورود به پنل پذیرنده، در بخش «توسعهدهندگان» در دسترس است.
آمادهاید شروع کنید؟
حساب بسازید، کارت بانکی را وصل کنید و اولین پرداخت را دریافت کنید.