تخطَّ إلى المحتوى

إضافة تكامل Stripe

Stripe هي منصة لمعالجة المدفوعات عبر الإنترنت مصممة للأعمال التجارية على الإنترنت. يتيح تكامل Stripe لتطبيقك معالجة المعاملات والاشتراكات والبيانات المالية بشكل آمن.

بعد اختيار Stripe من قائمة عمليات التكامل، ستظهر نافذة تكوين. يجب عليك تقديم بيانات الاعتماد التالية من لوحة تحكم Stripe الخاصة بك لإنشاء الاتصال:

  • الإدخال: أدخل المفتاح السري الخاص بك في Stripe (يبدأ عادةً بـ sk_) في حقل Secret Key. يتيح هذا المفتاح للواجهة الخلفية مصادقة الطلبات الآمنة.

2. المفتاح القابل للنشر (Publishable Key)

Section titled “2. المفتاح القابل للنشر (Publishable Key)”
  • الإدخال: أدخل المفتاح القابل للنشر العام الخاص بك في Stripe (يبدأ عادةً بـ pk_) في حقل Publishable Key. يستخدم هذا المفتاح لتنفيذ الواجهة الأمامية.
  • الإدخال: حدد سياق البيئة المناسب من القائمة المنسدلة (على سبيل المثال، Test لوضع التطوير/صندوق الحماية أو Production للمعالجة المباشرة).

بمجرد تكوين المفاتيح والبيئة:

  1. تحقق من شريط الحالة (يظهر حاليًا Not Connected).
  2. انقر فوق الزر الأسود Add في أسفل اليمين لحفظ بيانات الاعتماد وتمكين تكامل الدفع.

تكوين Stripe

تكامل Stripe

مرجع واجهة برمجة تطبيقات تكامل Stripe

Section titled “مرجع واجهة برمجة تطبيقات تكامل Stripe”

إنشاء تكوين Stripe جديد للمشروع والبيئة.

Mutation:

mutation ConfigureStripe (
$input: ConfigureStripeInput!
) {
configureStripe (
input: $input
) {
id
publishableKey
webhookUrl
}
}

Input:

input ConfigureStripeInput {
secretKey: String! # Stripe secret key (sk_test_... or sk_live_...)
publishableKey: String! # Stripe publishable key (pk_test_... or pk_live_...)
environment: StripeEnvironment! # TEST or LIVE
webhookSecret: String # Webhook signing secret (optional)
}

Response:

type ConfigureStripePayload {
id: ID! # Configuration ID
publishableKey: String! # Publishable key
webhookUrl: String! # Generated webhook URL
}

Example:

{
"input": {
"secretKey": "sk_test_...",
"publishableKey": "pk_test_...",
"environment": "TEST",
"webhookSecret": "whsec_..."
}
}

ملاحظات:

  • يتم تشفير المفتاح السري باستخدام AES-256-GCM قبل التخزين
  • تكوين واحد فقط لكل مجموعة مشروع/بيئة
  • إرجاع خطأ إذا كان التكوين موجودًا بالفعل

تحديث تكوين Stripe الحالي.

Mutation:

mutation UpdateStripeConfig (
$input: UpdateStripeConfigInput!
) {
updateStripeConfig (
input: $input
) {
id
publishableKey
webhookUrl
}
}

Input:

input UpdateStripeConfigInput {
secretKey: String # Optional
publishableKey: String # Optional
environment: StripeEnvironment # Optional
webhookSecret: String # Optional
}

Response:

type UpdateStripeConfigPayload {
id: ID!
publishableKey: String!
webhookUrl: String!
}

ملاحظات:

  • جميع الحقول اختيارية
  • يتم تحديث الحقول المقدمة فقط
  • يتم تشفير المفتاح السري إذا تم توفيره

استرداد عميل واحد بواسطة المعرف.

Query:

query stripe_customer{
stripe_customer(
id: "cus_Ts..."
)
{
id
name
email
phone
description
metadata
object
createdAt
}
}

سرد العملاء مع ترقيم الصفحات والتصفية الاختيارية.

Query:

query stripe_customers (
$first: Int,
$after: String,
$customerId: String
) {
stripe_customers (
first: $first,
after: $after,
customerId: $customerId
) {
edges {
node {
id
name
email
phone
description
createdAt
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
}
}

Parameters:

  • first: عدد العناصر التي سيتم إرجاعها (الافتراضي: 10)
  • after: مؤشر لترقيم الصفحات
  • customerId: تصفية حسب معرف العميل (اختياري)

إنشاء عميل جديد.

Mutation:

mutation stripe_createCustomer {
stripe_createCustomer (
input: {
name: "Customer",
email: "example@archie.com",
phone: "+573001230001",
description: "Description Example"
metadata: {
data1: "Example data1",
data2: "Example data2"
}
}
)
{
id
name
email
phone
description
metadata
object
createdAt
}
}

تحديث عميل حالي.

Mutation:

mutation stripe_updateCustomer {
stripe_updateCustomer(
id: "cus_Ts...",
input: {
name: "Customer",
email: "example@archie.com",
phone: "+573001230001",
description:"Description Example",
metadata: {
data1: "Example data1 updated",
data2: "Example data2 updated"
}
}
)
{
id
name
email
phone
description
metadata
object
createdAt
}
}

ملاحظات:

  • جميع الحقول اختيارية
  • يتم تحديث الحقول المقدمة فقط

حذف عميل.

Mutation:

mutation stripe_deleteCustomer {
stripe_deleteCustomer (
id: "cus_Ts...")
}

Response:

  • إرجاع true عند النجاح
  • إرجاع خطأ إذا لم يتم العثور على العميل

استرداد نية دفع واحدة بواسطة المعرف.

Query:

query stripe_paymentIntent {
stripe_paymentIntent (
id: "pi_3Su..."
)
{
id
customerId
paymentMethodId
currency
amount
status
metadata
object
clientSecret
createdAt
}
}

سرد نوايا الدفع مع ترقيم الصفحات والتصفية الاختيارية.

Query:

query stripe_paymentIntents (
$first: Int,
$after: String,
$customerId: String
) {
stripe_paymentIntents (
first: $first,
after: $after,
customerId: $customerId
) {
edges {
node {
id
customerId
paymentMethodId
currency
amount
status
metadata
object
clientSecret
createdAt
}
cursor
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}

Parameters:

  • first: عدد العناصر التي سيتم إرجاعها (الافتراضي: 10)
  • after: مؤشر لترقيم الصفحات
  • customerId: تصفية حسب معرف العميل (اختياري)

إنشاء نية دفع جديدة.

Mutation:

mutation stripe_createPaymentIntent {
stripe_createPaymentIntent (
input: {
amount: 12.35,
currency: "usd",
customerId: "cus_Ts...",
paymentMethodId: "pm_1Su...",
automaticPaymentMethods: true
}
)
{
id
customerId
paymentMethodId
currency
amount
status
metadata
object
clientSecret
createdAt
}
}

ملاحظات:

  • يتم إرجاع clientSecret لتأكيد الواجهة الأمامية
  • استخدم automaticPaymentMethods: true للتكامل مع Stripe.js

تحديث نية الدفع قبل التأكيد.

Mutation:

mutation stripe_updatePaymentIntent{
stripe_updatePaymentIntent(
id: "pi_3S...",
input: {
amount: 36.92,
currency: "usd",
paymentMethodId: "pm_1Su..."
metadata:{
data1: "Example data1"
}
}
) {
id
customerId
paymentMethodId
currency
amount
status
metadata
object
clientSecret
createdAt
}
}

ملاحظات:

  • يمكن التحديث فقط قبل التأكيد
  • جميع الحقول اختيارية

تأكيد نية الدفع.

Mutation:

mutation stripe_confirmPaymentIntent{
stripe_confirmPaymentIntent(
id: "pi_3Su..."
input: {
paymentMethodId: "pm_1Su...",
returnUrl: "http://localhost:3000/successful-payment"
}
) {
id
customerId
paymentMethodId
currency
amount
status
metadata
object
clientSecret
createdAt
}
}

ملاحظات:

  • مطلوب لإكمال الدفع
  • قد يتطلب مصادقة 3D Secure
  • إرجاع الحالة المحدثة (succeeded, requires_action, إلخ)

إلغاء نية الدفع.

Mutation:

mutation stripe_cancelPaymentIntent {
stripe_cancelPaymentIntent(
id: "pi_3Su..."
) {
id
customerId
paymentMethodId
currency
amount
status
metadata
object
clientSecret
createdAt
}
}

ملاحظات:

  • يمكن إلغاء نوايا الدفع التي لم تنجح أو لم يتم إلغاؤها فقط
  • تتغير الحالة إلى “canceled”

استرداد اشتراك واحد بواسطة المعرف.

Query:

query stripe_subscription {
stripe_subscription(id: "sub_1Su...") {
id
customerId
status
currentPeriodStart
currentPeriodEnd
createdAt
cancelAtPeriodEnd
metadata
object
items {
data {
id
priceId
quantity
}
}
}
}

سرد الاشتراكات مع ترقيم الصفحات والتصفية الاختيارية.

Query:

query stripe_subscriptions (
$first: Int,
$after: String,
$customerId: String
) {
stripe_subscriptions (
first: $first,
after: $after,
customerId: $customerId
) {
edges {
node {
id
customerId
status
currentPeriodStart
currentPeriodEnd
createdAt
cancelAtPeriodEnd
metadata
object
items {
data {
id
priceId
quantity
}
}
}
cursor
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}

Parameters:

  • first: عدد العناصر التي سيتم إرجاعها (الافتراضي: 10)
  • after: مؤشر لترقيم الصفحات
  • customerId: تصفية حسب معرف العميل (اختياري)
  • status: تصفية حسب الحالة (اختياري)

إنشاء اشتراك جديد.

Mutation:

mutation stripe_createSubscription {
stripe_createSubscription (
input: {
customerId: "cus_TsQ...",
items: {
priceId: "price_1Su...",
quantity: 1
},
metadata: {
data1: "Example data1"
},
trialPeriodDays: 0
}
) {
id
customerId
status
currentPeriodStart
currentPeriodEnd
createdAt
cancelAtPeriodEnd
metadata
object
items {
data {
id
priceId
quantity
}
}
}
}

ملاحظات:

  • يمكن أن يكون paymentBehavior “default_incomplete” للاشتراكات التي تتطلب طريقة دفع
  • يتم تحديد فترة التجربة بالأيام
  • يتم توسيع أحدث فاتورة ونية دفع تلقائيًا

تحديث اشتراك حالي.

Mutation:

mutation stripe_updateSubscription {
stripe_updateSubscription(
id: "sub_1Sv..."
input: {
cancelAtPeriodEnd: false
metadata: {
data2: "Example data2"
}
}
) {
id
customerId
status
currentPeriodStart
currentPeriodEnd
createdAt
cancelAtPeriodEnd
metadata
object
items {
data {
id
priceId
quantity
}
}
}
}

إلغاء اشتراك.

Mutation:

mutation stripe_cancelSubscription {
stripe_cancelSubscription (
cancelAtPeriodEnd: true,
id: "sub_1Sv..."
) {
id
customerId
status
currentPeriodStart
currentPeriodEnd
createdAt
cancelAtPeriodEnd
metadata
object
items {
data {
id
priceId
quantity
}
}
}
}

Parameters:

  • id: معرف الاشتراك (مطلوب)
  • cancelAtPeriodEnd: إذا كان صحيحًا، يتم الإلغاء في نهاية الفترة؛ إذا كان خطأ، يتم الإلغاء فورًا (الافتراضي: خطأ)

ملاحظات:

  • الإلغاء الفوري: ينتهي الاشتراك الآن
  • الإلغاء في نهاية الفترة: يستمر الاشتراك حتى نهاية الفترة الحالية

سرد المنتجات مع ترقيم الصفحات.

Query:

query stripe_products (
$first: Int,
$after: String
) {
stripe_products (
first: $first,
after: $after
) {
edges {
node {
id
name
description
active
metadata
object
createdAt
}
cursor
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}

إنشاء منتج جديد.

Mutation:

mutation stripe_createProduct {
stripe_createProduct (
input: {
name: "Product 01",
description: "Description product 01",
metadata: {
data1: "Example data1"
}
}
) {
id
name
description
active
metadata
object
createdAt
}
}

سرد الأسعار مع ترقيم الصفحات والتصفية الاختيارية.

Query:

query stripe_prices (
$first: Int,
$after: String,
$productId: String
) {
stripe_prices (
first: $first,
after: $after,
productId: $productId
) {
edges {
node {
id
productId
active
currency
unitAmount
object
metadata
createdAt
recurring {
interval
intervalCount
}
}
cursor
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}

Parameters:

  • first: عدد العناصر التي سيتم إرجاعها (الافتراضي: 10)
  • after: مؤشر لترقيم الصفحات
  • productId: تصفية حسب معرف المنتج (اختياري)

إنشاء سعر جديد.

Mutation:

mutation stripe_createPrice {
stripe_createPrice (
input: {
productId: "prod_Tst...",
unitAmount: 25.85,
currency: "usd",
recurring: {
interval: "month",
intervalCount: 1
},
metadata: {
data1: "Example data1"
}
}
) {
id
productId
currency
unitAmount
active
object
createdAt
metadata
recurring {
interval
intervalCount
}
}
}

ملاحظات:

  • اترك recurring للمبالغ المدفوعة لمرة واحدة
  • يجب أن يكون interval واحدًا من: “day”, “week”, “month”, “year”

استرداد فاتورة واحدة بواسطة المعرف.

Query:

query stripe_invoice {
stripe_invoice (
id: "in_1Su..."
) {
id
customerId
subscriptionId
currency
amountPaid
amountDue
status
object
metadata
createdAt
lineItems {
data {
id
description
currency
amount
quantity
}
}
}
}

ملاحظات:

  • يتم تعبئة معرف الاشتراك عن طريق توسيع API عند توفره

سرد الفواتير مع ترقيم الصفحات والتصفية الاختيارية.

Query:

query stripe_invoices (
$first: Int,
$after: String,
$customerId: String,
$status: String
) {
stripe_invoices (
first: $first,
after: $after,
customerId: $customerId,
status: $status
) {
edges {
node {
id
customerId
subscriptionId
currency
amountPaid
amountDue
status
object
metadata
createdAt
lineItems {
data {
id
description
currency
amount
quantity
}
}
}
cursor
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}

Parameters:

  • first: عدد العناصر التي سيتم إرجاعها (الافتراضي: 10)
  • after: مؤشر لترقيم الصفحات
  • customerId: تصفية حسب معرف العميل (اختياري)
  • status: تصفية حسب الحالة (اختياري)

دفع فاتورة برمجياً.

Mutation:

mutation stripe_payInvoice {
stripe_payInvoice (
id: "in_1Sv..."
) {
id
customerId
subscriptionId
currency
amountPaid
amountDue
status
object
metadata
createdAt
lineItems {
data {
id
description
currency
amount
quantity
}
}
}
}

ملاحظات:

  • محاولات لدفع الفاتورة باستخدام طريقة الدفع الافتراضية للعميل
  • إرجاع خطأ إذا فشل الدفع
  • تحديث حالة الفاتورة إلى “paid” عند النجاح

سرد المبالغ المستردة مع ترقيم الصفحات والتصفية الاختيارية.

Query:

query stripe_refunds (
$first: Int,
$after: String,
$paymentIntentId: String
) {
stripe_refunds (
first: $first,
after: $after,
paymentIntentId: $paymentIntentId
) {
edges {
node {
id
paymentIntentId
reason
status
currency
amount
metadata
object
createdAt
}
cursor
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}

Parameters:

  • first: عدد العناصر التي سيتم إرجاعها (الافتراضي: 10)
  • after: مؤشر لترقيم الصفحات
  • paymentIntentId: تصفية حسب معرف نية الدفع (اختياري)

إنشاء استرداد لنية الدفع.

Mutation:

mutation stripe_createRefund {
stripe_createRefund (
input: {
paymentIntentId: "pi_3Sv...",
amount: 200,
reason: "requested_by_customer"
}
) {
id
reason
paymentIntentId
status
currency
amount
object
metadata
createdAt
}
}

ملاحظات:

  • اترك amount لاسترداد المبلغ بالكامل
  • يمكن أن يكون reason: “duplicate”, “fraudulent”, “requested_by_customer”
  • تبدأ حالة الاسترداد بـ “pending” ويتم تحديثها إلى “succeeded” أو “failed”

سرد طرق الدفع مع ترقيم الصفحات والتصفية الاختيارية.

Query:

query stripe_paymentMethods (
$first: Int,
$after: String,
$customerId: String
) {
stripe_paymentMethods(
first: $first,
after: $after,
customerId: $customerId
) {
edges {
node {
id
customerId
type
object
metadata
createdAt
card {
brand
expMonth
expYear
last4
}
}
cursor
}
pageInfo {
hasPreviousPage
hasNextPage
startCursor
endCursor
}
}
}

Parameters:

  • first: عدد العناصر التي سيتم إرجاعها (الافتراضي: 10)
  • after: مؤشر لترقيم الصفحات
  • customerId: تصفية حسب معرف العميل (اختياري)

ملاحظات:

  • يتم إرجاع معلومات البطاقة الآمنة فقط (آخر 4 أرقام، العلامة التجارية، انتهاء الصلاحية)
  • لا يتم كشف أرقام البطاقات الكاملة أبدًا

إرفاق طريقة دفع بعميل.

Mutation:

mutation stripe_attachPaymentMethod {
stripe_attachPaymentMethod (
id: "pm_1Sv...",
input: {
customerId: "cus_Ts4..."
}
) {
id
customerId
type
card {
brand
expMonth
expYear
last4
}
metadata
object
createdAt
}
}

ملاحظات:

  • يجب إنشاء طريقة الدفع أولاً (عادة عبر Stripe.js)
  • يمكن استخدام طرق الدفع المرفقة للاشتراكات والمدفوعات

فصل طريقة دفع عن عميل.

Mutation:

mutation stripe_detachPaymentMethod {
stripe_detachPaymentMethod (
id: "pm_1Sv..."
) {
id
customerId
type
card {
brand
expYear
expMonth
last4
}
metadata
object
createdAt
}
}

ملاحظات:

  • لا يمكن استخدام طرق الدفع المفصولة للمدفوعات بعد الآن
  • إرجاع طريقة الدفع مع تعيين customerId إلى null

سرد أحداث webhook التي تتلقاها الخدمة.

Query:

query ListWebhookEvents (
$first: Int,
$after: String
) {
stripe_webhookEvents (
first: $first,
after: $after
) {
edges {
node {
id
type
data
processed
createdAt
}
cursor
}
pageInfo {
hasNextPage
hasPreviousPage
endCursor
}
}
}

Response:

type StripeWebhookEvent {
id: ID!
type: String! # Event type (e.g., "payment_intent.succeeded")
data: String! # JSON string of event data
processed: Boolean! # Whether event has been processed
createdAt: Time!
}

Parameters:

  • first: عدد العناصر التي سيتم إرجاعها (الافتراضي: 10)
  • after: مؤشر لترقيم الصفحات

ملاحظات:

  • يتم تلقي الأحداث تلقائيًا عبر نقطة نهاية webhook
  • يتم تخزين الأحداث بعد التحقق من التوقيع
  • يحتوي الحقل data على حمولة الحدث الكاملة كسلسلة JSON

تدعم جميع استعلامات القائمة ترقيم الصفحات المستند إلى المؤشر باستخدام نمط اتصال Relay.

type PageInfo {
hasNextPage: Boolean!
hasPreviousPage: Boolean!
startCursor: String
endCursor: String
}
query ListCustomers (
$first: Int,
$after: String
) {
stripe_customers (
first: $first,
after: $after
) {
edges {
node {
id
email
}
cursor
}
pageInfo {
hasNextPage
endCursor
}
}
}

تدفق ترقيم الصفحات:

  1. الطلب الأولي: first: 10, after: null
  2. استخدم pageInfo.endCursor من الاستجابة كـ after في الطلب التالي
  3. تحقق من hasNextPage لتحديد ما إذا كانت هناك صفحات أخرى

القيم الافتراضية:

  • first: الافتراضي إلى 10 إذا لم يتم توفيره
  • after: يبدأ من البداية إذا لم يتم توفيره

تُرجع جميع العمليات أخطاء GraphQL برسائل سهلة القراءة. يتم تعيين الأخطاء من أخطاء Stripe API لتقديم ملاحظات واضحة.

سيناريوهات الخطأ الشائعة

Section titled “سيناريوهات الخطأ الشائعة”

أخطاء التكوين:

  • 400: تنسيق مفتاح Stripe غير صالح
  • 404: المشروع أو التكوين غير موجود
  • 400: التكوين موجود بالفعل

أخطاء العميل:

  • 404: العميل غير موجود
  • 400: بيانات العميل غير صالحة

أخطاء خيار الدفع:

  • 404: نية الدفع غير موجودة
  • 400: مبلغ أو عملة غير صالحة
  • 402: فشل الدفع (تم رفض البطاقة، رصيد غير كافٍ، إلخ)

أخطاء الاشتراك:

  • 404: الاشتراك غير موجود
  • 400: معلمات الاشتراك غير صالحة
  • 400: لا يمكن تحديث اشتراك ملغى

رموز خطأ Stripe: يتم تعيين رموز خطأ Stripe الشائعة إلى رسائل سهلة القراءة:

  • card_declined: “تم رفض بطاقتك”
  • insufficient_funds: “رصيد غير كافٍ”
  • invalid_number: “رقم البطاقة غير صالح”
  • expired_card: “انتهت صلاحية البطاقة”
  • incorrect_cvc: “رمز CVC غير صحيح”
{
"errors": [
{
"message": "Customer not found",
"extensions": {
"code": "NOT_FOUND",
"stripeErrorCode": "resource_missing"
}
}
],
"data": null
}

enum StripeEnvironment {
TEST # Test mode
LIVE # Live/production mode
}

يمثل النوع القياسي Map تعيين مفتاح بقيمة حيث:

  • المفاتيح عبارة عن سلاسل
  • يمكن أن تكون القيم سلاسل أو أرقامًا أو منطقية أو خرائط متداخلة
  • تستخدم لحقول البيانات الوصفية

مثال:

{
"metadata": {
"order_id": "12345",
"user_id": "67890",
"premium": true
}
}

يمثل النوع القياسي Time الطوابع الزمنية بتنسيق ISO 8601.

مثال: "2025-11-16T00:28:48.081Z"