← الأساسيات / حزم تطوير البرمجيات (SDK)
استيراد الحسابات المصرفية والمدفوعات
كشوفات camt.053، ملفات CSV من Stripe، تسويات مدفوعات مزودي خدمات الدفع (PSP)، وتدفقات JSON المخصصة.
تصل جميع العمليات المستوردة بصفتها معاملات مصرفية في حساب مصرفي (bank/accounts/create). تحمي المعاملات معرف externalId، مما يجعله آمناً لإعادة استيراد نفس الملف - حيث يتم تخطي الصفوف التي يتطابق فيها الزوج (bankAccountId, externalId) مسبقاً والإبلاغ عنها في عداد التخطي (skipped). تبدأ المعاملات المستوردة بالحالة new (جديدة) ولا يتم ترحيلها إلى دفتر الأستاذ (ledger) إلا عند مطابقتها (bank/transactions/match، مع استخدام bank/transactions/suggest-matches لاقتراح المرشحين للمطابقة).
يعرض تطبيق الويب نفس عمليات الاستيراد ضمن البنك ← استيراد ملف (تحميل الملفات، وتحديد القوالب).
يمكن التراجع عن المطابقة الخاطئة باستخدام bank/transactions/unmatch (خيار إلغاء المطابقة في البنك ← المعاملات). لا يتم تعديل أو حذف القيود المرحلة إطلاقاً: فالدفعة المطابقة لفاتورة، أو السطر الذي مرحله قالب الاستيراد إلى حساب ما، يتلقى معاملة يومية عكسية (reversing journal transaction) تتضمن كل قيد في الجانب المعاكس، ومؤرخة بتاريخ date (الافتراضي: اليوم، ولا يجوز أن يسبق تاريخ الترحيل الأصلي أبداً). يعود المبلغ المدفوع للفاتورة وحالة الدفع إلى الوراء بمقدار قيمة ذلك السطر المصرفي. أما السطر المرتبط بتسوية مقدم خدمة الدفع، فيتم إلغاء ربطه فقط لأن قيد التسوية ينتمي إلى دفعة التسوية (batch). يعود السطر إلى الحالة new ويمكن مطابقتها مرة أخرى. يجب أن يقع تاريخ العكس (reversal date) ضمن فترة محاسبية مفتوحة.
قوالب الاستيراد
يحدد قالب الاستيراد مصدراً للبيانات، ويسرد الحقول التي يوفرها المصدر، ويربط الحقول المالية بحسابات دفتر الأستاذ. تتم إدارة القوالب ضمن البنك ← قوالب الاستيراد وعبر نقاط النهاية bank/import-templates/create|update|delete|get|list.
POST /v1/bank/import-templates/create
{
"name": "Stripe payments export",
"type": "stripe",
"fields": [
{ "name": "id" },
{ "name": "Created date (UTC)" },
{ "name": "Amount" },
{ "name": "Fee", "accountCode": "6800" },
{ "name": "Amount Refunded" }
],
"metaFields": ["order_id"]
}
- القيمة
typeهي أحد الأنواع التالية:stripeأوiso20022أوbank_connectionأوrevolut. - يحتوي كل حقل على
name(اسم) وaccountCode(رمز حساب) اختياري. الحقول المالية وحدها هي التي تقبل تعيين حساب: حقول Stripe مثلAmountوFeeوAmount Refunded؛ وحقل camt.053 مثلNtry/Amt؛ وتدفق البيانات المصرفي مثلtransaction_amount.amount. يجب أن يكون الحساب موجوداً في شجرة الحسابات (يمكن إنشاؤه عبرledger/accounts/create). - يمكن تخطي حقل
fields؛ وفي هذه الحالة يتم الرجوع تلقائياً إلى قائمة الحقول القياسية لهذا النوع: أسماء الأعمدة في ملف المدفوعات ← التصدير من Stripe (باستثناء أعمدةCard …الـ 19 التي يتركها النموذج غير محددة أيضاً بشكل افتراضي)، أو عناصر camt.053 التي يحملها كل كشف (Stmt/Id،Stmt/Acct/Id/IBAN،Stmt/Bal/…،Ntry/Amt،Ntry/CdtDbtInd،Ntry/Sts،Ntry/BookgDt)، أو السمات التي يعيدها تدفق الخدمات المصرفية المفتوحة PSD2 لكل معاملة. يمكنك إضافة أو حذف إدخالات لتتناسب مع ملفك: يقرأ المستورد أيضاً عناصر camt.053 الاختيارية وهيNtry/ValDt،Ntry/NtryRef،Ntry/AcctSvcrRef،Ntry/AddtlNtryInf،TxDtls/Refs/EndToEndId،TxDtls/Refs/TxId،TxDtls/RltdPties/Dbtr/Nm،TxDtls/RltdPties/DbtrAcct/Id/IBAN،TxDtls/RltdPties/Cdtr/Nm،TxDtls/RltdPties/CdtrAcct/Id/IBAN،TxDtls/RmtInf/Ustrd، وTxDtls/AddtlTxInf. - يمكن لحقل البريد الإلكتروني للعميل في Stripe (
Customer Email) أن يحمل القيمة"createPartner": true. في هذه الحالة، ينشئ الاستيراد عميلاً (شريكاً من نوع فرد، مصنفاً كعميل) لكل بريد إلكتروني في الملف لا يملكه أي شريك حالي، مستخدماً وصف العميلCustomer Descriptionكاسم له (أو البريد الإلكتروني في حال كان الوصف فارغاً) وأعمدة عنوان البطاقةCard Address …كعنوان في حال تضمن الملف ذلك. تتم مطابقة الشركاء الحاليين بواسطة البريد الإلكتروني مع تجاهل حالة الأحرف (case-insensitively). يعيد الرد العدد الإجمالي فيcustomersCreated. - تسرد حقول
metaFields(خاصة بـ Stripe فقط) مفاتيح البيانات الوصفية (metadata) التي تحملها مدفوعاتك. تصدر Stripe كل مفتاح كعمود بصيغة<key> (metadata)؛ وهذه القائمة حرة الشكل ويمكن أن تكون طويلة. - حقل
invoiceItemId(خاص بـ Stripe فقط، اختياري) هو عنصر من كتالوج الصنف. عند تعيينه، تشير كل فاتورة وسطر إشعار دائن ينشئه الاستيراد إلى هذا الصنف (ترحيله، ومعدل ضريبة القيمة المضافة الخاص به عندما يكون حقلinvoiceVatRatePercentفارغاً)؛ بينما يستمر جلب نص السطر من المعاملة نفسها. - يحدد حقل
companyMetaField(خاص بـ Stripe فقط) أحد تلك المفاتيح ليكون بمثابة مؤشر للشركات. عندما يحمل الشحن قيمةtrueأو1أوyesأوcompanyأوbusinessأوb2bفي هذا العمود، فإن العميل المنشأ له يُعامل كشريك من نوع شركة بدلاً من فرد. - يحدد حقل
invoiceMetaField(خاص بـ Stripe فقط) أحد تلك المفاتيح، وليكن مثلاً رقم الطلب، بينما يحدد حقلinvoiceVatRatePercentمعدل ضريبة القيمة المضافة للفواتير المنشأة منه. عند الاستيراد، يتم تجميع كل صف دفع واسترداد بناءً على قيمة هذا المفتاح:- القيمة التي تتطابق مع فاتورة مبيعات موجودة - أي أمر مبيعات يكون مرجعه الخارجي
externalRefمساوياً لتلك القيمة عبر (ecommerce/orders/create، لأي قناة) أو فاتورة يكون رقمها الكاملfullNumberمساوياً لتلك القيمة - تقوم بربط المجموعة بتلك الفاتورة؛ - القيمة التي ليس لها فاتورة تنشئ فاتورة جديدة: الشريك يُستمد من
Customer Email(يتم إنشاؤه عند عدم وجوده، تماماً كما هو الحال فيcreatePartner)، مع سطر واحد لكل عملية دفع (باستخدام ملخص عناصر الدفعCheckout Line Item Summaryأو الوصفDescriptionكنص، ومبلغ الدفع كجعر شامل للضريبة بالنسبة المئوية فيinvoiceVatRatePercent)، وتاريخ الإصدار = تاريخ الدفع الأول، ومعالجة ضريبة القيمة المضافة تُستمد من الشركة وبلد البطاقة. يتم إصدار الفاتورة وترحيلها دفعة واحدة، ويتم تسجيل أمر مبيعات بقناةstripeوتلك القيمة كمرجع خارجيexternalRefلكي تقوم عمليات الاستيراد اللاحقة بالربط بدلاً من الإنشاء؛ - بعد ذلك، تتم مطابقة كل عملية دفع في المجموعة مع الفاتورة كعملية تحصيل (مع ترحيل التحصيل)؛ وكل عملية استرداد تنشئ إشعاراً داحناً صادراً مقابل الفاتورة بالمبلغ المسترد وتطابق الاسترداد معها.
- القيمة التي تتطابق مع فاتورة مبيعات موجودة - أي أمر مبيعات يكون مرجعه الخارجي
- تعود الأعداد في الاستجابة تحت مسميات
invoicesCreatedوinvoicesLinkedوcreditNotesCreatedوpaymentsMatched؛ أما المجموعات التي تعذر معالجتها (مثل غياب البريد الإلكتروني للعميل، أو اختلاف العملات، أو فاتورة مرتبطة لا تزال في حالة مسودة أو مدفوعة بالكامل مسبقاً) فيتم إدراجها فيwarnings(التحذيرات) وتُترك كمعاملات مصرفية بالحالةnew. احذر من تعيين الحقلAmountلحساب في دفتر الأستاذ في نفس القالب: فالدفعات المطابقة لفاتورة لا تُرحل مرة أخرى، بينما الدفعات غير المطابقة سيتم ترحيلها. - أسماء القوالب فريدة لكل شركة.
- تحمل قوالب camt.053 والاتصالات المصرفية نفس الخيارات، مقروءة من الكشف بدلاً من أعمدة Stripe:
- إنشاء الشركاء المفقودين (Create missing partners): يؤدي تفعيل
createPartnerفي صف اسم المدين (TxDtls/RltdPties/Dbtr/Nm، أو تدفق البياناتdebtor.name) إلى إنشاء عميل لكل دافع مجهول للأموال الواردة؛ وفي صف اسم الدائن (TxDtls/RltdPties/Cdtr/Nm، أو تدفق البياناتcreditor.name) إلى إنشاء مورد لكل مستلم مجهول للأموال الصادرة. يتم التعرف على الشركاء بواسطة رقم الحساب المصرفي الدولي IBAN (المخزن فيpartner_bank_accounts)، ثم بواسطة الاسم المطابق تماماً؛ ويُعتبر الشريك الجديد شركة إذا حمل الاسم شكلاً قانونياً (مثل UAB، MB، SIA، GmbH، Ltd، …)، وإلا فيُعتبر فرداً. تعود الأعداد في الاستجابة على هيئةcustomersCreated(استيراد الملفات) أوpartnersCreated(مزامنة تدفق البيانات). - ربط الفواتير عن طريق المرجع (Link invoices by reference): عندما يتم تعيين
invoiceMetaFieldإلى صف الحوالة أو المرجع (TxDtls/RmtInf/Ustrd،TxDtls/RmtInf/Strd/CdtrRefInf/Ref،TxDtls/Refs/EndToEndId؛ أو تدفق البياناتremittance_information،reference_number)، فإن ذلك يطابق كل سطر مصرفي جديد يحتوي مرجعه أو وصفه على رقم فاتورة مبيعات صادرة مفتوحة (أموال واردة) أو فاتورة شراء مسجلة (أموال صادرة)، ويقوم بترحيل الدفعة. عندما يكون رقم الIBAN الخاص بالدافع مخزناً لدى شريك ما، أو عندما يساوي اسم الدافع اسم شريك أو رمزه، يجب أن ينتمي الفاتورة لذلك الشريك. لا يتم ربط الدفعة الواردة من دافع مجهول إلا عندما تساوي الرصيد المتبقي للفاتورة ويحمل رقم الفاتورة بادئة سلسلته، بحيث لا يُتخذ الرقم المجرد مثل المبلغ كمرجع أبداً. لا يتم ربط الدفعة التي تتجاوز الرصيد المتبقي إطلاقاً. تبقى السطور التي تفشل في هذه الفحوصات في حالة "جديدة" للمطابقة اليدوية ويتم إدراجها في التحذيرات. وعند تفعيلadvanceInvoices: true، فإن الدفعة الواردة غير المطابقة من شريك معروف تنشئ فاتورة دفع مقدم صادرة (من نوعadvance) للمبلغ بالمعدل المئويinvoiceVatRatePercentأو معدلinvoiceItemIdوتطابق الدفعة معها؛ ويجب أن يكون الشريك معروفاً، لذا يجب تفعيل صف المدين أيضاً. - قواعد الترحيل حسب رمز المعاملة المصرفية (Posting rules by transaction code): بالإضافة إلى
Ntry/Amt/transaction_amount.amount، تحتوي قائمة الحقول على صفوف قواعد مثلNtry/BkTxCd=CHRG،=INTR،=TAXE، وNtry/CdtDbtInd=DBIT،=CRDT(تدفق البيانات:bank_transaction_code=…،credit_debit_indicator=…). يُرحل السطر إلى حساب القاعدة الأولى التي تتطابق معه: عائلة رمز المعاملة المصرفية أولاً، ثم اتجاهها، ثم صف المبلغ العادي. لا يتم التحقق من صفوف القواعد ضد الملف. - شريك الرسوم المصرفية (Bank charges partner): يؤدي تفعيل
createPartnerفي صف القاعدة…=CHRGإلى إنشاء مورد يُسمى باسم البنك (كشفStmt/Acct/Svcr/FinInstnId/Nm، أو بنك الاتصال، أو اسم الحساب المصرفي في دفتر الأستاذ) ويقيد كل رسوم مع ذلك الشريك. - يتم اختيار قوالب الاتصال المصرفي لكل حساب تدفق عبر
bank/feeds/accounts/configure(قسم البنك ← الاتصالات في التطبيق)، والذي يحدد أيضاً جدول المزامنةsyncSchedule(manual،daily،weekly،monthly): حيث تقوم واجهة برمجة التطبيقات بمزامنة الحسابات ذات الجدول الزمني تلقائياً بمجرد انقضاء فترتها. تُطبق القوالب عند كل عملية مزامنةbank/feeds/sync؛ وتبلغ استجابة المزامنة بعد ذلك عن الأعداد التالية:posted، وpartnersCreated، وinvoicesLinked، وinvoicesCreated، وpaymentsMatched، وwarnings.
- إنشاء الشركاء المفقودين (Create missing partners): يؤدي تفعيل
مرر templateId إلى bank/statements/import بدلاً من format: حيث يحدد نوع القالب المحلل المطلوب، ويجب أن يحتوي الملف على كل حقل مدرج في القالب - أي ملف يفتقر لأي منها يتم رفضه بالرمز HTTP 422 مع ذكر أسماء الأعمدة أو العناصر المفقودة. لا يُشترط وجود حقول البيانات الوصفية. تصف قوالب الاتصال المصرفي تدفق PSD2 المباشر ولا يمكن استخدامها لاستيراد الملفات.
يقرأ قالب ISO 20022 أيضاً ملفات MT940: الملف الذي يبدأ بـ {1: أو :20: (أو يتم إرساله مع القيمة "format": "mt940") يتم تحليله كملف MT940 وتُطبق قواعد مطابقة المراجع والترحيل الخاصة بالقالب على سطوره. يتم تخطي التحقق من العناصر في ملفات MT940، ولا تُطبق قواعد Ntry/BkTxCd=… أبداً على سطور MT940 نظراً لعدم احتواء ملفات MT940 على رموز معاملات مصرفية خاصة بمعيار ISO 20022؛ وعوضاً عن ذلك، استخدم قواعد Ntry/CdtDbtInd=….
يحمل الحساب المصرفي عملة واحدة. يُرفض الكشف الوارد بعملة أخرى بالرمز HTTP 422 (في ملف camt.053 الذي يحتوي على كشوفات بعمولات متعددة لنفس الـ IBAN، يتم استيراد الكشف المتوافق مع عملة الحساب فقط)، وكذلك الحال بالنسبة للسطر المرسل إلى نقاط النهاية bank/transactions/import بعملة تخالف عملة الحساب.
تُرحل كل حركة ناتجة عن حقل يحتوي على accountCode وقت الاستيراد كمعاملة يومية واحدة: فالأموال الواردة تجعل حساب البنك في دفتر الأستاذ مديناً والحساب المعين دائناً؛ والأموال الصادرة تجعل الحساب المعين مديناً وحساب البنك في دفتر الأستاذ دائناً. يتم تحويل المبالغ إلى العملة الأساسية في تاريخ الحركة. تصبح المعاملة المصرفية بعد ذلك "مطابقة" (matched) لتلك المعاملة اليومية (بحيث يكون matchedDocumentType = journal_transaction) ولم تعد مطروحة للمطابقة مع الفواتير. تبلغ الاستجابة عن العدد في posted. أما الحركات الناتجة عن الحقول غير المعينة فتبقى في حالة new وتتم مطابقتها مع الفواتير كالسابق - على سبيل المثال، قم بتعيين الحقل Fee لحساب مصروفات رسوم مزود خدمة الدفع واترك حقل Amount بدون تعيين لكي تظل الدفعات مطابقة لفواتير المبيعات.
POST /v1/bank/statements/import
{
"bankAccountId": "…",
"templateId": "…",
"content": "id,Created date (UTC),Amount,…"
}
معيار ISO 20022 camt.053 (فتح الخدمات المصرفية عبر XML)
تتيح لك البنوك اللتوانية (Swedbank، SEB، Luminor، Šiaulių bankas، …) تنزيل كشوفات الحسابات بصيغة ISO 20022 camt.053 XML من خدماتها المصرفية عبر الإنترنت - وعادة ما يكون ذلك تحت خيار تصدير/تنزيل الكشوفات، بالصيغة "ISO XML" أو "camt.053". يتم إرجاع نفس التنسيق بواسطة واجهات برمجة تطبيقات معلومات الحساب PSD2.
POST /v1/bank/statements/import
{
"bankAccountId": "…",
"format": "camt053",
"content": "<?xml version=\"1.0\"…>…"
}
- قد يحتوي الملف على عدة كشوفات؛ يجب أن يتطابق رقم الـ IBAN لكل كشف مع الـ IBAN الخاص بالحساب المصرفي (الكشوفات التي لا تحتوي على IBAN، أو الحسابات التي لا تملك واحداً، يتم قبولها كما هي).
- تتحول مراجع القيود (
AcctSvcrRef/NtryRef، مع العودة إلى استخدام تجزئة المحتوى كبديل) إلى معرفexternalId. - تعكس الاستجابة البيانات الوصفية لكل كشف: معرف الكشف، والفترة، والأرصدة الافتتاحية/الختامية، وعدد المعاملات.
- يتم استخراج اسم الطرف المقابل، ورقم الـ IBAN، وغرض الدفع لكل إدخال لأغراض المطابقة.
تُصدر المدفوعات في الاتجاه المعاكس بصيغة pain.001 عبر bank/payments/export.
ملفات Revolut Business CSV
قم بتنزيل كشف المعاملات الخاص بحساب Revolut Business بصيغة CSV واستورده باستخدام القالب المدمج Revolut Business (القيمة templateId: "builtin-revolut"). تمتلك كل شركة هذا القالب دون الحاجة لإنشائه: يقوم أمر bank/import-templates/list-builtin بإدراجه، وbank/import-templates/get بإرجاعه، بينما يرفض أمرا bank/import-templates/update وbank/import-templates/delete التعامل معه مرجعين الرمز HTTP 400. يظهر هذا القالب في التطبيق أولاً ضمن البنك ← قوالب الاستيراد؛ وعند فتحه تظهر إعداداته، ويؤدي حفظه إلى إنشاء قالب شركة خاص بك يمكنك تعديله.
POST /v1/bank/statements/import
{
"bankAccountId": "…",
"templateId": "builtin-revolut",
"content": "Date started (UTC),Date completed (UTC),ID,Type,State,…"
}
- يتم استيراد الصفوف التي تكون فيها حالة
Stateمساوية لـCOMPLETEDفقط. أما الصفوف الأخرى (مثلPENDOUNGأوPENDING) فيتم استبعادها وعدها في التحذيراتwarnings؛ ليتم استيرادها لاحقاً عند استيراد ملف تصبح فيه مكتملة. - يتحول كل صف إلى معاملة مصرفية بالتاريخ المستمد من
Date completed (UTC)، والمبلغ منTotal amount، والعملة منPayment currency، ومعرفIDكـexternalId، وDescriptionكالوصف. - الطرف المقابل للأموال الصادرة هو
Beneficiary nameوBeneficiary IBAN؛ وفي حالة المدفوعات بالبطاقة بدون مستفيد، يكون التاجر هو الوارد في حقلDescription. بينما الطرف المقابل للأموال الواردة هوSender nameوSender account. - يتم تجميع الصفوف حسب الحساب والعملة. يجب أن يتطابق رقم الحساب الدولي
International account numberمع الـ IBAN الخاص بالحساب المصرفي، ويتم استيراد الصفوف التي تحمل عملة الحساب المصرفي فقط. - يتحقق المستورد لكل صف من أن رصيد الصف السابق مضافاً إليه
Total amountيساوي الحقلBalance، ويقوم بإدراج أي صف لا يحقق ذلك في التحذيراتwarnings. - يجب أن يحتوي الملف على الأعمدة التالية:
Date completed (UTC)، وID، وType، وState، وDescription، وPayment currency، وTotal amount، وReference، وSender name، وBeneficiary name.
عند كل عملية استيراد، يقوم القالب المدمج بما يلي:
إنشاء عميل لكل مرسل مجهول للأموال الواردة، ومورد لكل مستفيد مجهول أو تاجر بطاقات للأموال الصادرة، تماماً كما هو موضح في قسم إنشاء الشركاء المفقودين أعلاه؛
مطابقة كل صف يحتوي مرجعه
Referenceأو وصفهDescriptionعلى رقم فاتورة مبيعات أو شراء مفتوحة، وترحيل الدفعة وفقاً لضوابط قسم ربط الفواتير عن طريق المرجع أعلاه؛ترحيل الصفوف التي لم تطابقها أي فاتورة بناءً على نوعها
Type، إلى حساب قاعدة الترحيل المناسبة:Typeقاعدة الترحيل (Posting rule) الحساب الافتراضي شجرة الحسابات الرومانية عملية الترحيل FEEbank.fees6800 627 جعل حساب القاعدة مديناً، وحساب البنك في دفتر الأستاذ دائناً؛ والشريك: مورد مسجى باسم الحساب المصرفي CARD_PAYMENTbank.cardPayments6209 628 جعل حساب القاعدة مديناً، وحساب البنك في دفتر الأستاذ دائناً، بدون ضريبة قِيمة مضافة TOPUPbank.topUps3010 1012 جعل حساب البنك في دفتر الأستاذ مديناً، وحساب القاعدة دائناً تبقى صفوف الأنواع الأخرى، مثل
TRANSFER، بحالةnewللمطابقة.
يمكنك تغيير الحسابات باستخدام ledger/posting-rules/update؛ وسوف يست استخدم القالب المدمج الحسابات الجديدة بدءاً من الاستيراد التالي. لا يمكن إيقاف تشغيل قاعدة الترحيل: لاستيراد مدفوعات البطاقات أو عمليات الشحن دون ترحيلها، أنشئ قالب شركة من نوع revolut بدون صفوف النوع Type=CARD_PAYMENT أو Type=TOPUP واستخدمه في الاستيراد. عملية دفع البطاقة المرحلة بهذه الطريقة لا تتم مطابقتها مع فاتورة المورد إذا تم تسجيل تلك الفاتورة لاحقاً؛ لذا قم بترحيل أحد الإجراءين فقط وليس كلييهما.
يستخدم قالب الشركة من نوع revolut نفس الأعمدة ويمكنه ترحيل الصفوف حسب النوع باستخدام صفوف القواعد Type=FEE وType=CARD_PAYMENT وType=TRANSFER وType=TOPUP. أما الاستيراد باستخدام الخيار "format": "revolut-csv" بدون تحديد قالب فيقوم باستيراد الصفوف دون أي من هذه الخطوات.
ملفات Stripe CSV
قم بالتصدير من لوحة تحكم Stripe - حيث يعمل أي من التقرير التاليين:
- التقارير ← الرصيد ← التغيير المفصل للرصيد من النشاط (Reports → Balance → Itemized balance change from activity) (موصى به): الأعمدة هي
balance_transaction_id, created_utc, currency, gross, fee, net, reporting_category, description. - المدفوعات ← التصدير (Payments → Export): الأعمدة هي
id, Created (UTC), Amount, Fee, Currency, Description, Customer Description.
POST /v1/bank/statements/import
{
"bankAccountId": "…",
"format": "stripe-csv",
"content": "balance_transaction_id,created_utc,currency,gross,fee,net,…"
}
أنشئ حساباً مصرفياً مخصصاً لـ Stripe (مثلاً باسم "Stripe"، وحساب الأستاذ العام 2710 أو حساباً فرعياً خاصاً به) - حيث يتصرف رصيد Stripe تماماً مثل الحساب المصرفي: تتدفق الشحنات للداخل، وتُخصم الرسوم، وتعمل المدفوعات على تحويل الرصيد إلى حسابك المصرفي الحقيقي.
سلوك الاستيراد:
- تتحول كل معاملة رصيد إلى معاملة مصرفية واحدة للمبلغ الإجمالي (gross) (حيث
externalId= معرف معاملة الرصيد). - تتحول الرسوم (fee) غير الصفرية إلى معاملة ثانية بعلامة معاكسة (بحيث
externalId=<id>:fee، والطرف المقابل هو "Stripe") - لكي يمكن مطابقة/ترحيل الرسوم كمصروفات بشكل منفصل عن الإيرادات. أما الرسوم المُستردة على عمليات الاسترداد فتأتي كمبالغ موجبة. - تُستورد صفوف عمليات الدفع (Payout) كمعاملات سالبة منفردة؛ قم بمطابقتها مقابل المعاملة الواردة المقابلة في كشف حسابك المصرفي الحقيقي.
- تُتخطي الصفوف ذات المبلغ الصفري؛ ويُستمد التاريخ من الحقل
created_utc(بتوقيت UTC). - تُتخطي صفوف تصدير المدفوعات التي لم تحرك أموالاً: أي الحالات التي يكون فيها
Captured = false(عمليات التفويض/الالتقاط المؤجل) والحالاتStatusالتي تكون Failed (فاشلة) أو Canceled (ملغاة). - يتحول المبلغ المسترد (Amount Refunded) غير الصفر إلى معاملة ثالثة سالبة (حيث
externalId=<id>:refund) مؤرخة بتاريخRefunded date (UTC)- لكي لا تضيع المبالغ المستردة الجزئية والكاملة المضمنة في صفوف المدفوعات.
تسوية تسوية مزودي خدمات الدفع (تقارير مدفوعات Stripe)
لتقسيم المدفوعات الإجمالية (lump-sum payout) إلى طلباتها الأساسية، ومبالغ الاسترداد، والرسوم، والمبالغ المستردة القسرية (chargebacks)، استخدم نقاط نهاية التسويات بدلاً من استيراد الكشوفات البسيطة. يتم قبول نوعين من تصديرات Stripe (ويتم اكتشافهما تلقائياً):
- التقارير ← المدفوعات ← تسوية المدفوعات، مفصلة (Reports → Payouts → Payout reconciliation, itemized) (أنواع التقارير
payout_reconciliation.itemized.*أوpayout_reconciliation.by_id.itemized.*) - دقيقة، صف واحد لكل معاملة رصيد؛ وهي المفضلة في الحسابات الحية. - المدفوعات ← التصدير (المفصلة) (Payments → Export (unified payments)) - تصدير على مستوى الشحنة؛ يعمل في وضع الاختبار/البيئة التجريبية (sandbox) حيث لا تتوفر تسوية المدفوعات. يتم تجميع الشحنات الملتقطة بواسطة معرف الدفع في عمود
Transfer؛ بينما يتم تخطي الصفوف غير الملتقطة/الفاشلة (skippedNotSettled)؛ ويتحولAmount Refundedغير الصفر إلى سطر استرداد اصطناعي في دفعة دفع الشحنة - وهو تقريب، نظراً لأن الاسترداد قد يكون قد استقر حقاً في دفعة لاحقة. تأتي مراجع المطابقة من معرف الشحنة، وPaymentIntent ID، وInvoice Number، وClient Reference ID، وكل عمود بصيغة… (metadata)(مثل رقم الطلب في البيانات الوصفية).
يمكن لملف CSV واحد أن يمتد ليشمل العديد من المدفوعات. تقوم Stripe بتنزيل التقرير المفصل ملفاً واحداً لكل قسم (…_charge_…، …_refund_…، …_fee_…)؛ قم باستيرادها جميعاً - فالصفوف الخاصة بدفعة تم استيرادها مسبقاً تندمج في الدفعة الحالية (ويتم الإبلاغ عنها في العداد updated) طالما لم يتم ترحيلها بعد، ويتم إعادة حساب إجماليات الدفعة.
POST /v1/bank/settlements/import
{
"bankAccountId": "…",
"provider": "stripe",
"content": "balance_transaction_id,created_utc,…,reporting_category,…,automatic_payout_id,…"
}
سلوك الاستيراد:
- يتم تجميع الصفوف حسب
automatic_payout_idفي دفعات تسوية (settlement batches) - دفعة واحدة لكل عملية دفع، مع إجماليات الإجمالي/الرسوم/الصافي (مجموع حقلnetللصفوف = المبلغ الذي يدخل حسابك المصرفي). يتم تخطي إعادة استيراد الدفعة (العدادskipped). أما الصفوف التي لم تُسند بعد إلى دفعة وصفوفpayoutنفسها فيتم تخطيها وعدها بشكل منفصل. - يتم مطابقة كل صف شحنة/استرداد/نزاع تلقائياً مع فاتورة مبيعات باستخدام العناصر التالية بالترتيب: المرجع الخارجي لأمر التجارة الإلكترونية
externalRef(أي قيمة منorder_id، أوpayment_intent_id، أوsource_id، أوcharge_id، أو أي عمود بصيغة*_metadata[...])، أو رقم الفاتورة الكاملfullNumberالذي يظهر في تلك الأعمدة، وفي حالات الاسترداد والنزاعات - معرف الشحنةcharge_idلشحنة تمت مطابقتها مسبقاً (من نفس الملف أو عمليات الاستيراد السابقة). - المراجعة تتم عبر
bank/settlements/list/bank/settlements/get؛ وإصلاح البقايا المتبقية يتم عبرbank/settlements/match { lineId, invoiceId }(أو استخدامinvoiceId: nullلإلغاء المطابقة).
يؤدي تنفيذ طلب POST /v1/bank/settlements/post { id, date?, commissionPercent? } إلى ترحيل الدفعة بأكملها كمعاملة يومية متوازنة واحدة وتسوية الفواتير المطابقة (تحديث paidAmount/paymentStatus، وإطلاق إشعارات الويب sale_invoice.paid):
- جعل حساب الأستاذ العام للبنك مديناً بصافي الدفعة؛ وجعل رسوم مزود خدمة الدفع (
settlements.fees، الافتراضي 6800) مدينَة للرسوم المقتطعة وصفوف الرسوم. - جعل الحسابات المدينة (accounts receivable) دائنة لكل شحنة مطابقة؛ وتعمل عمليات الاسترداد والنزاعات على عكس ذلك. يُحدد تطبيق المبلغ بحد أقصى يعادل الرصيد المتبقي لكل فاتورة - فأي زيادة تستقر في حساب التعليق مع إصدار تحذير.
- الشحنات غير المطابقة: عند تعيين
commissionPercentيتم تقسيمها إلى إيرادات عمولة (settlements.commissionRevenue، الافتراضي 5001) والتزام تجاه البائع (settlements.sellerPayable، الافتراضي 4499) - وهو تدفق السوق الذي تنتمي فيه الأموال المحصلة في الغالب إلى البائعين. وبدون ذلك، يتم ركنها في حسابsettlements.suspense(الافتراضي 4440، الدفعات المقدمة المستلمة). - ترحيل صفوف
platform_earning(رسوم تطبيق Stripe Connect) إلى إيرادات العمولة؛ وتعمل صفوفtransfer(المدفوعات للبائعين المتصلين) على تخفيض الالتزام تجاه البائع. - جميع الحسابات الأربعة قابلة للتجاوز لكل شركة عبر قواعد الترحيل (
ledger/posting-rules). - السطر الذي تم استيراد شحنته أو رسومه أو استرداده مسبقاً إلى حساب مصرفي آخر من تصدير مدفوعات Stripe (
bank/statements/import) لا يتم تقييده على الرسوم أو الحسابات المدينة أو حساب التعليق. بدلاً من ذلك، يُقيد صافي مبلغهnetفي حساب الأستاذ العام لذلك الحساب المصرفي، لكي تتم تصفية الحساب المصرفي لـ Stripe دفعة بعد دفعة. يمثلsummary.clearedAmountإجمالي المبلغ المحول بهذه الطريقة؛ والسطر الذي يختلف مبلغه عما يحتفظ به ذلك الحساب يتم ذكره بالاسم في التحذيراتwarnings. وإذا لم يبق شيء للتقييد، تُرحل الدفعة مع جعلjournalTransactionIdبالقيمة فارغة (null).
تعيد نقاط النهاية bank/settlements/list و/get لكل دفعة القيم التالية: clearedNet، وclearingDifference (خطوط الدفع ناقص المبالغ التي يحتفظ بها الحساب المصرفي الآخر لها؛ وتكون صفراً عندما تتطابق)، وclearingOpenCount (الخطوط التي بها فرق أو حركة غير مرحلة)؛ بينما تعيد نقطة النهاية /get نفس القيم لكل سطر تحت أسماء clearingBankAccountId، وclearingBooked، وclearingDifference، وclearingUnposted. يتم مقارنة خطوط الاسترداد للشحنة الواحدة معاً، نظراً لأن تصدير المدفوعات لا يحتوي إلا على إجمالي المبلغ المسترد. تصدير مدفوعات Stripe الذي يتم استيراده بعد ترحيل دفعته يتخطى حركات تلك الدفعة ويذكرها بالاسم في التحذيرات warnings.
تتم فوترة ضريبة القيمة المضافة على العمولة نفسها بشكل منفصل (عبر إصدار فاتورة عمولة للبائع)؛ فالتقسيم يخصص النقد المحصل فقط.
المدفوعات بعملة أخرى
تُكتب قيود اليومية دائماً بالعملة الأساسية للشركة، ولكن الدفع بعملة مختلفة يتم ترحيله تلقائياً - دون الحاجة لأي إدخال يدوي:
- يتم تحويل الدفعة بالعر سعر الصرف لتاريخ الترحيل (
date، مع الرجوع لتاريخ الدفعة، ثم تاريخ اليوم). سعر الصرف هو سعر الشركة الخاص لتلك العملة (reference/exchange-rates/set) عندما يكون حديثاً على الأقل مثل السعر الرسمي، وإلا فيتم استخدام أحدث سعر صرف رسمي في أو قبل هذا التاريخ. وفي حال عدم وجود سعر صرف في أو قبل التاريخ، يفشل الطلب مع الرمز 422 ويشير إلىreference/exchange-rates/sync. - يتم تحويل كل حساب بسعر صرف تلك الدفعة باستثناء الحسابات المدينة (accounts receivable)، والتي يتم إبراء ذمتها بسعر الصرف
fxRateالذي صدرت به كل فاتورة. يُرحل الفارق بين السعرين إلى حسابbank.fxGain(الافتراضي 5803) أوbank.fxLoss(الافتراضي 6803) كفارق صرف محقق، لكي يظل قيد اليومية متوازناً. - يعيد الملخص في الاستجابة
summaryقيمة سعر الصرف المستخدمfxRateوفارق الصرف الناتجexchangeDifference، وتحتفظ الدفعة بسعر الصرف الذي رُحلت به. الفاتورة المطابقة التي تختلف عملتها عن عملة الدفعة لا تتم تسويتها: بل يذهب مبلغها إلى حساب التعليق مع إصدار تحذير. - يبقى حد استيراد واحد قائماً: تُرفض الدفعة المفردة التي تختلط صفوفها بعدة عملات بالرمز 422، وكذلك الحال بالنسبة لإعادة الاستيراد التي تختلف عملتها عن الدفعة المخزنة مسبقاً لتلك الدفعة.
التدفقات اليدوية / المخصصة
يمكن دفع أي شيء آخر كبيانات JSON عادية:
POST /v1/bank/transactions/import
{
"bankAccountId": "…",
"transactions": [
{ "date": "2026-07-01", "amount": "-25.00", "currency": "EUR",
"counterpartyName": "…", "description": "…", "externalId": "unique-ref-1" }
]
}
احرص على توفير معرف externalId مستقر لكل معاملة للحفاظ على خاصية التكرار الآمن (idempotent) لعمليات إعادة الاستيراد.