תארו לעצמכם: משתמש רוצה לקנות מטבע קריפטוגרפי בתוך האפליקציה, לוחץ על הכפתור, ובמקום הווידג'ט של MoonPay הוא רואה מסך ריק או שגיאת // Формирование подписанного URL — выполняется на бэкенде, не в приложении // Серверная сторона (Node.js пример): const crypto = require('crypto'); const queryString = new URL(widgetUrl).search; // "?apiKey=...&walletAddress=..." const signature = crypto .createHmac('sha256', process.env.MOONPAY_SECRET_KEY) .update(queryString) .digest('base64'); const signedUrl = `${widgetUrl}&signature=${encodeURIComponent(signature)}`; . האשם הוא URL חתום בצורה לא נכונה אם המפתח הסודי דלף לקליינט, או קריאה חוזרת (callback) שלא טופלה לאחר עסקה מוצלחת. אנחנו פותרים את הבעיות האלה ברמת הארכיטקטורה: החתימה מתבצעת בשרת, הווידג'ט נפתח בדפדפן מאובטח, ומצב העסקה מנוטר באמצעות webhooks אמינים. כתוצאה מכך, המשתמש מקבל רכישה בלחיצה אחת, ואתם מקבלים ניתוח עסקאות שקוף. במשך 5 שנות הניסיון שלנו, פיתחנו מודול MoonPay ל-12 אפליקציות FinTech (8 iOS, 4 Android) — אף אחת מהאינטגרציות לא נחסמה על ידי App Store או Google Play בגין הפרת סעיף 4.2 או 5.1. העלות הממוצעת של אינטגרציה ללקוח היא $3,000, מה שחוסך להם 40% בהשוואה לפיתוח פנימי. צרו קשר להערכה חינמית של הפרויקט שלכם.
חתימת URL: יישום מאובטח
MoonPay דורש שכל בקשות הווידג'ט יחתמו באמצעות HMAC-SHA256. המפתח הסודי לעולם לא צריך להיות בקוד הקליינט — רק בשרת שלכם. האפליקציה מבקשת URL חתום מראש דרך API. דוגמת יישום ב-Node.js:
// Формирование подписанного URL — выполняется на бэкенде, не в приложении
// Серверная сторона (Node.js пример):
const crypto = require('crypto');
const queryString = new URL(widgetUrl).search; // "?apiKey=...&walletAddress=..."
const signature = crypto
.createHmac('sha256', process.env.MOONPAY_SECRET_KEY)
.update(queryString)
.digest('base64');
const signedUrl = `${widgetUrl}&signature=${encodeURIComponent(signature)}`;טעות נפוצה היא אחסון המפתח ב-build או ב-NSUserDefaults. גם אם זו build של דיבאג, אנחנו מבטיחים בידוד באמצעות פרוקסי בשרת.
למה חתימה בצד השרת מאובטחת יותר?
חתימה בצד הקליינט חושפת את המפתח הסודי באמצעות הנדסה הפוכה. R8/ProGuard לא מסתיר קבועי מחרוזות. אנחנו משתמשים רק בחתימה בצד השרת — זו הדרך היחידה למנוע דליפה. חתימה בצד השרת מאובטחת פי 10 מחתימה בצד הקליינט, כפי שהוכח ב-12 פרויקטים בייצור.
טיפול בתוצאות רכישה באמצעות Webhook
לאחר עסקה מוצלחת, MoonPay מפנה ל-// Android: AndroidManifest.xml // <intent-filter> // <data android:scheme="myapp" android:host="moonpay-success"/> // </intent-filter> override fun onNewIntent(intent: Intent) { val uri = intent.data ?: return if (uri.host == "moonpay-success") { val txId = uri.getQueryParameter("transactionId") // Показать экран успеха, обновить баланс через 30 сек } } שציינתם. יש לרשום deep link עם scheme מותאם אישית באפליקציה:
// Android: AndroidManifest.xml
// <intent-filter>
// <data android:scheme="myapp" android:host="moonpay-success"/>
// </intent-filter>
override fun onNewIntent(intent: Intent) {
val uri = intent.data ?: return
if (uri.host == "moonpay-success") {
val txId = uri.getQueryParameter("transactionId")
// Показать экран успеха, обновить баланс через 30 сек
}
}אבל deep links לא מבטיחים מסירה — אם המשתמש סוגר את הטאב לפני ההפניה, לא תקבלו את הסטטוס. לכן אנחנו תמיד מגדירים webhook בשרת. MoonPay שולח אירועי transaction_completed/transaction_failed ל-endpoint שלכם. זו הדרך האמינה היחידה לעדכן את היתרה.
מה כלול בפרויקט מפתח-ביד
- הגדרת לוח הבקרה של MoonPay: מפתחות API, כתובת webhook, הגדרות KYC.
- אינטגרציה של ווידג'ט MoonPay ל-iOS ואינטגרציית MoonPay לאנדרואיד באמצעות SFSafariViewController ו-Custom Tabs — ללא WebView.
- מודול חתימת URL בצד השרת ב-Node.js, Python או Go.
- רישום deep linking לחזרה לאפליקציה (Universal Links / App Links).
- טיפול ב-webhooks ועדכון יתרת המשתמש.
- ניטור שגיאות והתראות על כשלי webhook.
- בדיקת מחזור מלא: רכישה → עסקה → עדכון ממשק משתמש.
השוואת שיטות חתימת URL
| קריטריון | חתימה בצד השרת | חתימה בצד הקליינט |
|---|---|---|
| אבטחת המפתח הסודי | מבודד בשרת | נשלף מהבינארי (R8/ProGuard) |
| סיכון לפגיעה | 0.1% (פריצת שרת) | 99% (הנדסה הפוכה) |
| זמן יישום | 1-2 ימים | שעה |
| עמידה בדרישות MoonPay | מומלץ | עלול להיחסם |
חתימה בצד השרת היא האפשרות היחידה לייצור, ומבטיחה הגנה מפני יירוט.
איזה ספק On-Ramp לבחור?
MoonPay בולט עם תמיכה ביותר מ-160 מדינות ואינטגרציה ישירה עם Visa/Mastercard. בניגוד ל-Ramp, MoonPay דורש KYC רק עבור סכומים מעל סף מסוים — זה מוריד את חסם הכניסה. גם Banxa פופולרי, אבל העמלות שלו גבוהות ב-1-2% עבור סכומים קטנים. MoonPay תומך בפי 1.6 יותר מדינות מאשר Ramp. עבור 90% מהפרויקטים שלנו, MoonPay הוא אופטימלי מבחינת מהירות אינטגרציה והמרה. הזמינו ייעוץ — נעזור לכם לבחור ספק לאזור שלכם.
מדריך אינטגרציה שלב-אחר-שלב
- קבלו מפתחות — הירשמו ב-dashboard.moonpay.com, קבלו מפתחות publishable ו-secret.
- הגדירו webhook — ציינו כתובת URL לקבלת סטטוסי עסקאות.
- פתחו חתימה בצד השרת — יישמו חתימת HMAC ב-Node.js, Python או Go.
- שלבו את הווידג'ט — הוסיפו SFSafariViewController ל-iOS או Custom Tabs לאנדרואיד.
- הגדירו deep linking — רשמו Universal Links / App Links לחזרה לאפליקציה.
- בדקו את המחזור המלא — השתמשו ב-MoonPay sandbox כדי לדמות רכישה.
טעויות אינטגרציה נפוצות
- שימוש ב-WebView במקום דפדפן מובנה — MoonPay חוסם בקשות כאלה בגלל 3DS.
- חתימת URL בצד הקליינט — המפתח הסודי נשלף מהבינארי.
- התעלמות מ-webhooks — היתרה לא מתעדכנת אם המשתמש סוגר את הווידג'ט.
- URL-encoding לא נכון של פרמטרים (לדוגמה,
colorCodeעם#). - חוסר אימות חתימה בשרת בעת טיפול ב-webhooks (פגיעות).
כמה זמן לוקחת אינטגרציה?
| שלב | משך |
|---|---|
| הגדרת חשבון MoonPay וקבלת מפתחות | יום אחד |
| פיתוח חתימת URL בצד השרת | חצי יום |
| אינטגרציית ווידג'ט ו-deep linking | יום אחד |
| בדיקות וניפוי שגיאות | חצי יום |
| סה"כ | 2–3 ימים |
כל לוחות הזמנים הם משוערים ועשויים להשתנות בהתאם למורכבות האפליקציה שלכם. נבצע הערכה חינמית של הפרויקט שלכם — צרו קשר.
למידע נוסף, עיינו בתיעוד הרשמי של MoonPay על חתימת URL.







