أتمتة ملخص Stripe Payouts إلى Slack بدون فتح Dashboard
هتكسب من المقال ده ملخص أسبوعي واضح لمدفوعات Stripe في Slack، بدل ما تفتح Dashboard وتراجع نفس الأرقام يدويًا كل مرة.
مستوى القارئ: متوسط
المشكلة باختصار
لو عندك متجر صغير أو SaaS بيستقبل مدفوعات يومية، غالبًا حد في الفريق بيفتح Stripe Dashboard كل أسبوع ويراجع الـ payouts: إيه اللي اتحول، إيه اللي فشل، وإيه المتوقع يوصل البنك. الطريقة دي بتفشل لما الشخص المسؤول يسافر، أو لما عدد الحسابات يزيد، أو لما payout فاشل يعدي يومين من غير ما حد يشوفه.
الافتراض إن عندك حساب Stripe واحد، وقناة Slack داخلية للمالية أو العمليات، ومحتاج قراءة فقط من Stripe API. الأوتوميشن هنا لا ينشئ payout، ولا يلغي payout، ولا ينفذ أي حركة مالية. هو يقرأ آخر النتائج ويرسل ملخص.
الفكرة العملية بمثال بسيط
ركز في المثال ده: عندك 30 payout في الأسبوع. المراجعة اليدوية بتاخد 45 دقيقة بين فتح Stripe، فلترة الحالات، نسخ الأرقام، وبعت رسالة للفريق. السكربت التالي يطلب آخر payouts من Stripe، يلخص الإجمالي حسب الحالة، ويبعته إلى Slack خلال 6 دقائق إعداد وتشغيل أسبوعي شبه صفر.
Stripe API يدعم endpoint لعرض payouts بترتيب الأحدث أولًا، مع معاملات مثل limit وstatus. Slack Incoming Webhooks تستقبل طلب POST JSON فيه نص الرسالة. بالظبط ده اللي هنستخدمه.
import os
import requests
from collections import defaultdict
STRIPE_KEY = os.environ["STRIPE_SECRET_KEY"]
SLACK_WEBHOOK_URL = os.environ["SLACK_WEBHOOK_URL"]
def fetch_payouts(limit=25):
response = requests.get(
"https://api.stripe.com/v1/payouts",
auth=(STRIPE_KEY, ""),
params={"limit": limit},
timeout=15,
)
response.raise_for_status()
return response.json()["data"]
def build_summary(payouts):
totals = defaultdict(int)
counts = defaultdict(int)
failed = []
for payout in payouts:
status = payout["status"]
currency = payout["currency"].upper()
amount = payout["amount"] / 100
key = f"{status}_{currency}"
totals[key] += amount
counts[key] += 1
if status == "failed":
failed.append(f"{payout['id']} - {amount:.2f} {currency}")
lines = ["*Stripe payouts weekly summary*"]
for key in sorted(totals):
lines.append(f"- {key}: {counts[key]} payouts / {totals[key]:.2f}")
if failed:
lines.append("*Failed payouts need review:*")
lines.extend(f"- {item}" for item in failed[:5])
else:
lines.append("No failed payouts in the latest batch.")
return "\n".join(lines)
def post_to_slack(text):
response = requests.post(
SLACK_WEBHOOK_URL,
json={"text": text},
timeout=10,
)
response.raise_for_status()
if __name__ == "__main__":
payouts = fetch_payouts(limit=25)
post_to_slack(build_summary(payouts))
إعداد التشغيل الآمن
- أنشئ Stripe restricted key بصلاحية قراءة للـ payouts فقط، بدل ما تستخدم secret key عام في سكربت صغير.
- أنشئ Slack app وفعل Incoming Webhooks لقناة محددة، مثل
#finance-ops. - احفظ الأسرار في متغيرات بيئة، وليس داخل الملف.
- شغل السكربت يدويًا مرة، ثم ضعه على cron أو أي scheduler داخلي.
export STRIPE_SECRET_KEY="sk_live_or_restricted_key"
export SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
python stripe_payouts_summary.py
# تشغيل أسبوعي كل يوم أحد 9 صباحًا
0 9 * * 0 /usr/bin/python3 /opt/jobs/stripe_payouts_summary.py
لو عايزها تدعم أكثر من حساب Stripe، اعمل قائمة accounts وشغل نفس الدالة لكل حساب، ثم ضيف اسم الحساب في الرسالة. لكن لا تجمع المفاتيح في ملف واحد مكشوف؛ استخدم secret manager لو البيئة إنتاجية.
الـ trade-off هنا
المكسب واضح: مراجعة أسبوعية ممكن تنزل من 45 دقيقة إلى 6 دقائق، ومعها تنبيه أسرع للحالات الفاشلة. الخسارة إنك أضفت تكامل جديد يحتاج مراقبة. لو Slack webhook اتسرب، أي شخص يقدر يبعت رسائل للقناة. عشان كده تعامل معه كسر، وخزنه في مكان آمن، ودوّر المفتاح لو ظهر في logs أو Git.
فيه trade-off تاني: الملخص السريع لا يغني عن reconciliation كامل مع البنك أو المحاسبة. هو طبقة تنبيه وتشغيل، مش نظام محاسبي. لو الأرقام حساسة جدًا، ابعت نطاقات أو totals فقط، وخلي التفاصيل داخل Stripe.
متى لا تستخدم هذه الطريقة
لا تستخدمها لو فريقك يحتاج اعتماد مالي رسمي قبل أي مراجعة؛ Slack مش مكان اعتماد محاسبي. لا تستخدمها لو عندك متطلبات امتثال تمنع إرسال مبالغ أو معرفات payout في قنوات محادثة. ولا تستخدمها كبديل عن webhook حقيقي لو محتاج رد فعل لحظي خلال ثواني. في الحالة دي استخدم Stripe events وendpoint داخلي بدل job أسبوعي.
مصادر موثوقة
- Stripe API: List all payouts
- Slack API: Sending messages using incoming webhooks
- Requests documentation: timeouts
الخطوة التالية
الخطوة التالية: شغل السكربت على بيئة test أو Stripe test mode، وخلي الرسالة تروح لقناة خاصة. لو ظهر failed payout في الملخص، افتح Dashboard وراجع السبب يدويًا قبل أي قرار مالي.