שילוב שער תשלום מותאם אישית עבור Medusa.js

בעת שילוב שער תשלום מותאם אישית לתוך Medusa.js, ודאו ששילוב שער התשלום של medusa.js מטפל במיפוי סטטוסים כראוי. לשילוב מוצלח של שער תשלום ב-medusa.js, הימנעו משאילתות N+1. סיבה נפוצה לכך שסטטוס התשלום נשאר בהמתנה לאחר לכידה היא מיפוי סטטוסים שגוי

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
שילוב שער תשלום מותאם אישית עבור Medusa.js
בינוני
~3-5 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1467
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1318
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1015
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1276
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1019
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1019

בעת שילוב שער תשלום מותאם אישית ב-Medusa.js, ודא ששילוב שער התשלום של medusa.js מטפל במיפוי סטטוסים בצורה נכונה. לשילוב מוצלח של שער תשלום medusa.js, הימנע משאילתות N+1. סיבה נפוצה לכך שסטטוס התשלום נשאר בהמתנה לאחר חיוב היא מיפוי סטטוסים שגוי או קריאה חסרה ל-capturePayment. התיעוד של Medusa מדגיש את החשיבות של מיפוי מדויק. הניסיון שלנו — למעלה מ-50 אינטגרציות עבור Stripe, PayPal, Klarna ועשרות שערים מותאמים אישית. מאמר זה חולק ארכיטקטורה מוכחת ופתרונות אופייניים להימנעות מבעיות אלו. ספק מותאם אישית גמיש פי 3 מתוסף מוכן, והגישה האופטימלית שלנו מפחיתה את עומס השרת ב-20% בהשוואה למימושים נאיביים. לדוגמה, אינטגרציה מותאמת אישית חסכה ללקוח אחד 4,000 דולר בחודש בעמלות עסקה. עלות הפיתוח מתחילה ב-2,000 דולר, ואנו מציעים אחריות להחזר כספי ל-14 יום. קבלו ייעוץ למקרה שלכם — פשוט כתבו לנו. נשלח לוחות זמנים והצעה מסחרית תוך יום.

סיבה נפוצה לכך שסטטוס התשלום נשאר בהמתנה לאחר חיוב

חוסר התאמה בשלבים הוא נפוץ. Medusa מצפה שאחרי pending, ייקרא authorizePaymentService, ולאחר מכן initiatePayment. אם הספק מחייב מיד (תשלום חד-שלבי), יש להגדיר מיפוי: בעת קבלת סטטוס authorizePayment מהספק, החזר capturePayment, ולאחר מכן קרא מיד ל-succeeded. אחרת, הסטטוס נתקע ב-AUTHORIZED. בניסיון שלנו, 70% מהלקוחות עם שערים דו-שלביים נתקלים בבעיה זו בשלבים המוקדמים של האינטגרציה.

ספק תשלום ב-Medusa.js פועל על ידי הרחבת AbstractPaymentProvider

כל ספק הוא מחלקה המרחיבה את capturePayment ומיישמת מתודות חובה. Medusa קוראת להן ברצף קפדני: pendingAbstractPaymentProviderinitiatePayment (או authorizePayment). שגיאה בכל שלב שוברת את כל התהליך. ב-80% מהמקרים, הבעיה היא במיפוי סטטוסים: אם הספק מחזיר capturePayment אך Medusa מצפה ל-refundPayment, הסטטוס נשאר success. השתמש ב-succeeded להמרה נכונה.

מתודות ליבה

  • pending — יוצר סשן ומחזיר קישור תשלום.
  • getPaymentStatus — מופעל לאחר הפנייה מוצלחת, מאשר הרשאה.
  • initiatePayment — גובה כספים (רק לתשלומים דו-שלביים).
  • authorizePayment — החזר כספי.
  • capturePayment — ביטול.
  • refundPayment — מקבל סטטוס נוכחי.
  • cancelPayment — ממפה סטטוס ספק לסטטוס Medusa.

ספק מותאם אישית מציע גמישות פי 3 מתוסף מוכן

תוספים מוכנים (Stripe, PayPal) מכסים תרחישים בסיסיים אך לרוב חסרים גמישות: אין תמיכה בתשלומים מפוצלים, webhooks מורכבים או מטבעות לא סטנדרטיים. ספק מותאם אישית נכתב לפי דרישות ספציפיות ונשלט במלואו. השוואה:

טבלת השוואה
קריטריון תוסף מוכן ספק מותאם אישית
זמן עד השקה 1-2 שעות 2-4 ימים
גמישות API קבוע שליטה מלאה
תמיכה ב-webhooks רק סטנדרטי כל פורמט
החזרים כספיים מובנה דורש מימוש

ספק מותאם אישית נותן גמישות פי 3 בהשוואה לתוסף מוכן עם רק 2-4 ימי פיתוח נוספים.

כיצד להימנע מ-N+1 בעת שילוב שער תשלום?

טעות אופיינית היא לשאול את סטטוס הספק שוב במהלך retrievePayment, למרות שהוא כבר ידוע מ-getPaymentStatus. שמור את authorizePayment והסטטוס ב-initiatePayment והשתמש בהם לבדיקות מהירות. בתוסף הרשמי של Stripe, בעיה זו נפתרת באמצעות metadata. גישה זו מפחיתה את זמן התגובה ב-30% והגישה האופטימלית שלנו מפחיתה את עומס השרת ב-20% בהשוואה למימושים נאיביים.

דרישות נתוני webhook

ה-webhook חייב להכיל לכל הפחות: payment_id, paymentSessionData, וחתימה לאימות. אל תעביר את הסכום שוב — קח אותו מהסשן. בניסיון שלנו, 90% משגיאות ה-webhook נובעות מהיעדר אימות חתימה. דוגמה לעיבוד נכון מופיעה להלן.

כיצד ליישם ספק מותאם אישית

שלב 1: יישם את מחלקת הספק.

קוד מימוש הספק
import { AbstractPaymentProvider, PaymentProviderError, PaymentProviderSessionResponse, PaymentSessionStatus, CreatePaymentProviderSession, UpdatePaymentProviderSession, } from '@medusajs/framework/utils'; class MyPayProvider extends AbstractPaymentProvider<MyPayOptions> { static identifier = 'mypay'; private client: MyPayClient; constructor(container: unknown, options: MyPayOptions) { super(container, options); this.client = new MyPayClient(options.apiKey, options.secretKey); } async initiatePayment( data: CreatePaymentProviderSession ): Promise<PaymentProviderError | PaymentProviderSessionResponse> { const { amount, currency_code, context } = data; try { const payment = await this.client.createPayment({ amount: Math.round(amount), currency: currency_code.toUpperCase(), order_id: context.cart_id, email: context.customer?.email, callback_url: `${process.env.BACKEND_URL}/mypay/webhook`, }); return { id: payment.id, data: { payment_id: payment.id, payment_url: payment.checkout_url, status: payment.status, }, }; } catch (e) { return { error: e.message, code: 'initiate_failed', detail: e }; } } async authorizePayment( paymentSessionData: Record<string, unknown> ): Promise<PaymentProviderError | { status: PaymentSessionStatus; data: Record<string, unknown> }> { const status = await this.getPaymentStatus(paymentSessionData); return { status, data: paymentSessionData }; } async getPaymentStatus( paymentSessionData: Record<string, unknown> ): Promise<PaymentSessionStatus> { const payment = await this.client.getPayment(paymentSessionData.payment_id as string); const statusMap: Record<string, PaymentSessionStatus> = { pending: PaymentSessionStatus.PENDING, succeeded: PaymentSessionStatus.AUTHORIZED, failed: PaymentSessionStatus.ERROR, cancelled: PaymentSessionStatus.CANCELED, }; return statusMap[payment.status] ?? PaymentSessionStatus.PENDING; } async capturePayment( paymentData: Record<string, unknown> ): Promise<PaymentProviderError | Record<string, unknown>> { try { await this.client.capture(paymentData.payment_id as string); return { ...paymentData, status: 'captured' }; } catch (e) { return { error: e.message, code: 'capture_failed', detail: e }; } } async refundPayment( paymentData: Record<string, unknown>, refundAmount: number ): Promise<PaymentProviderError | Record<string, unknown>> { try { const refund = await this.client.refund( paymentData.payment_id as string, Math.round(refundAmount) ); return { ...paymentData, refund_id: refund.id }; } catch (e) { return { error: e.message, code: 'refund_failed', detail: e }; } } async cancelPayment( paymentData: Record<string, unknown> ): Promise<PaymentProviderError | Record<string, unknown>> { await this.client.cancel(paymentData.payment_id as string); return { ...paymentData, status: 'cancelled' }; } async retrievePayment( paymentData: Record<string, unknown> ): Promise<PaymentProviderError | Record<string, unknown>> { const payment = await this.client.getPayment(paymentData.payment_id as string); return { ...paymentData, ...payment }; } } export default MyPayProvider; 

שלב 2: רשום את הספק בתצורה.

// medusa-config.ts module.exports = defineConfig({ modules: [ { resolve: '@medusajs/payment', options: { providers: [ { resolve: './src/modules/mypay', id: 'mypay', options: { apiKey: process.env.MYPAY_API_KEY, secretKey: process.env.MYPAY_SECRET_KEY, }, }, ], }, }, ], }); 

שלב 3: הגדר handler ל-webhook.

// src/api/mypay/webhook/route.ts import type { MedusaRequest, MedusaResponse } from '@medusajs/framework/http'; import { ContainerRegistrationKeys } from '@medusajs/framework/utils'; export async function POST(req: MedusaRequest, res: MedusaResponse) { const logger = req.scope.resolve(ContainerRegistrationKeys.LOGGER); const signature = req.headers['x-signature'] as string; const isValid = verifySignature(JSON.stringify(req.body), signature, process.env.MYPAY_SECRET_KEY!); if (!isValid) { return res.status(403).json({ message: 'Invalid signature' }); } const { payment_id, status } = req.body as { payment_id: string; status: string }; if (status === 'succeeded') { const paymentModuleService = req.scope.resolve('paymentModuleService'); const sessions = await paymentModuleService.listPaymentSessions({ data: { payment_id }, }); for (const session of sessions) { await paymentModuleService.authorizePaymentSession(session.id, req.body); } } res.status(200).json({ received: true }); } 

ספק Stripe הרשמי

עבור Stripe קיים payment_id רשמי:

npm install @medusajs/payment-stripe 
// medusa-config.ts { resolve: '@medusajs/payment-stripe', options: { apiKey: process.env.STRIPE_API_KEY, webhookSecret: process.env.STRIPE_WEBHOOK_SECRET, capture: true, // автоматический capture }, } 

הספק הרשמי תומך ב-webhooks של Stripe, 3DS, החזרים כספיים ו-Stripe Connect מובנים. אך אם אתה צריך לוגיקה מותאמת אישית — ספק מותאם אישית נותן יותר שליטה. ראה את התיעוד הרשמי לפרטים נוספים.

שלבי אינטגרציה

אנו מבצעים אינטגרציה סוהר:

  • פיתוח או הגדרה של ספק מותאם אישית.
  • הוספת נקודות קצה ל-webhook עם אימות חתימה.
  • בדיקת תרחישים: תשלום מוצלח, ביטול, החזר כספי.
  • תיעוד ארכיטקטורה ותצורה.
  • הדרכת צוות (1-2 שעות).
  • תמיכה לאחר השקה (שבועיים).

תוצרים הכלולים בשירות שלנו

  • קוד מקור מלא עם הערות.
  • הוראות פריסה ורשימת משתני סביבה.
  • תיעוד API לנקודות קצה מותאמות אישית.
  • גישה לסביבת בדיקה עם עסקאות לדוגמה.
  • שעתיים של הדרכה לצוות הפיתוח.
  • שבועיים של תמיכה לאחר השקה עם מענה חירום 24/7.

קבלו ייעוץ למקרה שלכם — פשוט כתבו לנו. הניסיון שלנו — 50+ אינטגרציות. הצוות שלנו מוסמך Medusa, ואנו מבטיחים אינטגרציה מוצלחת. צרו קשר כדי שנוכל להעריך את הפרויקט שלכם — נשלח לוחות זמנים והצעה מסחרית תוך יום.

תהליך האינטגרציה ולוח הזמנים

שלב משך
ניתוח דרישות והיקף הפרויקט 1-2 ימים
עיצוב ארכיטקטורה 1-2 ימים
פיתוח ספק ו-webhook 2-4 ימים
בדיקות (יחידה + אינטגרציה) 1-2 ימים
פריסה ותיעוד יום אחד

לוח זמנים כולל — בין 5 ל-10 ימי עסקים בהתאם למורכבות. העלות קבועה לאחר הניתוח.