תארו לעצמכם: קונה כבר בחר מוצר, הוסיף אותו לעגלה, אבל בקופה רואה רק את המחיר המלא. אם אין אפשרות לתשלום בתשלומים, הוא עלול לעזוב. אנחנו פותרים זאת על ידי שילוב Karta Pokupok, שירות תשלומים בתשלומים בלארוסי המשמש למעלה מ-500,000 בעלי כרטיסים. ערך ההזמנה הממוצע עולה ב-20–30% לאחר החיבור, ושיעור ההמרה ב-15–20%. עם ניסיון של 5 שנים ו-30+ שילובי תשלומים, אנחנו לוקחים על עצמנו גם תרחישים לא סטנדרטיים.
Karta Pokupok פועלת במודל: הקונה משלם בתשלומים שווים ללא ריבית, והחנות מקבלת את הסכום המלא מיד. שילוב באמצעות REST API ו-webhook הופך את עיבוד הבקשות לאוטומטי: 99% מההחלטות מתקבלות תוך 2 דקות. עמלת השירות היא 2–4% מסכום ההזמנה, מה שמשתלם דרך הגדלת המכירות.
למה משתלם לשלב את Karta Pokupok?
בהשוואה לכרטיסי אשראי, תשלומים בתשלומים מושכים יותר קונים: אין תשלום יתר על ריבית, והאישור אורך דקות. עבור החנות, זה אומר עלייה של 20–30% בערך ההזמנה הממוצע ופחות נטישות בקופה. שילוב באמצעות REST API מהיר ואמין יותר מעיבוד ידני—בקשות מאושרות אוטומטית. לפי דוחות הלקוחות שלנו, שיעורי ההמרה עולים ב-18–25% בתוך החודש הראשון לאחר ההפעלה.
איך אנחנו מגדירים את השילוב
הארכיטקטורה בנויה דרך REST API של לוח הבקרה של השותף. הרצף:
- החנות יוצרת בקשה דרך API → מקבלת קישור לטופס
- הקונה ממלא את הטופס ומאשר את התשלום בתשלומים (קוד SMS)
- Webhook מודיע לחנות על סטטוס הבקשה
- בסטטוס
APPROVED— משלוח
יצירת בקשה
class KartaPokupokService {
private const BASE_URL = 'https://api.kartapokupok.by/v1';
public function createApplication(Order $order, int $months): array
{
$response = Http::withHeaders([
'X-Partner-Id' => env('KP_PARTNER_ID'),
'X-Partner-Token' => env('KP_TOKEN'),
'Content-Type' => 'application/json',
])->post(self::BASE_URL . '/applications', [
'order' => [
'id' => $order->id,
'amount' => $order->total, // в BYN
'term' => $months, // 3, 6, 12, 18, 24
'purpose' => 'Заказ #' . $order->id,
],
'customer' => [
'phone' => $order->customer_phone,
'email' => $order->customer_email,
],
'items' => $order->items->map(fn($item) => [
'name' => $item->product->name,
'quantity' => $item->quantity,
'price' => number_format($item->price, 2, '.', ''),
'total' => number_format($item->price * $item->quantity, 2, '.', ''),
])->toArray(),
'callback_url' => 'https://example.com/webhook/karta-pokupok',
'success_url' => 'https://example.com/payment/success',
'fail_url' => 'https://example.com/payment/fail',
]);
// Возвращает application_id и redirect_url
return $response->json();
}
} Webhook
public function webhook(Request $request): Response {
// Проверка HMAC подписи
$body = $request->getContent();
$receivedSign = $request->header('X-Signature');
$expectedSign = hash_hmac('sha256', $body, env('KP_WEBHOOK_SECRET'));
if (!hash_equals($expectedSign, $receivedSign)) {
return response('Bad signature', 403);
}
$payload = $request->json()->all();
// Статусы: APPROVED, REJECTED, CANCELLED, EXPIRED
match ($payload['status']) {
'APPROVED' => $this->onApproved($payload),
'REJECTED' => $this->onRejected($payload),
default => null,
};
return response('OK');
}
private function onApproved(array $payload): void {
Order::where('id', $payload['order_id'])->update([
'status' => 'paid',
'payment_type' => 'karta_pokupok',
'kp_application' => $payload['application_id'],
'paid_at' => now(),
]);
} מה לעשות אם ה-webhook לא מגיע?
ה-webhook הוא מקור האמת היחיד לסטטוס הבקשה. אם הודעה אבדה, ההזמנה עלולה להיתקע. אנחנו מספקים גיבוי: כל 10 דקות דרך cron אנחנו קוראים מחדש את כל הבקשות בסטטוס class KartaPokupokService { private const BASE_URL = 'https://api.kartapokupok.by/v1'; public function createApplication(Order $order, int $months): array { $response = Http::withHeaders([ 'X-Partner-Id' => env('KP_PARTNER_ID'), 'X-Partner-Token' => env('KP_TOKEN'), 'Content-Type' => 'application/json', ])->post(self::BASE_URL . '/applications', [ 'order' => [ 'id' => $order->id, 'amount' => $order->total, // в BYN 'term' => $months, // 3, 6, 12, 18, 24 'purpose' => 'Заказ #' . $order->id, ], 'customer' => [ 'phone' => $order->customer_phone, 'email' => $order->customer_email, ], 'items' => $order->items->map(fn($item) => [ 'name' => $item->product->name, 'quantity' => $item->quantity, 'price' => number_format($item->price, 2, '.', ''), 'total' => number_format($item->price * $item->quantity, 2, '.', ''), ])->toArray(), 'callback_url' => 'https://example.com/webhook/karta-pokupok', 'success_url' => 'https://example.com/payment/success', 'fail_url' => 'https://example.com/payment/fail', ]); // Возвращает application_id и redirect_url return $response->json(); } } באמצעות public function webhook(Request $request): Response { // Проверка HMAC подписи $body = $request->getContent(); $receivedSign = $request->header('X-Signature'); $expectedSign = hash_hmac('sha256', $body, env('KP_WEBHOOK_SECRET')); if (!hash_equals($expectedSign, $receivedSign)) { return response('Bad signature', 403); } $payload = $request->json()->all(); // Статусы: APPROVED, REJECTED, CANCELLED, EXPIRED match ($payload['status']) { 'APPROVED' => $this->onApproved($payload), 'REJECTED' => $this->onRejected($payload), default => null, }; return response('OK'); } private function onApproved(array $payload): void { Order::where('id', $payload['order_id'])->update([ 'status' => 'paid', 'payment_type' => 'karta_pokupok', 'kp_application' => $payload['application_id'], 'paid_at' => now(), ]); } . אם עברו יותר מ-30 דקות והסטטוס אינו pending או GET /applications/{id}, אנחנו מחשיבים את הבקשה כבעייתית ומודיעים לתמיכה. אנחנו מבטיחים שאף הזמנה לא תלך לאיבוד.
מחשבון תשלומים בתשלומים באתר
הצגת התשלום החודשי ליד המחיר היא נוהג סטנדרטי. החישוב פשוט: הסכום מחולק במספר החודשים:
interface InstallmentOption {
months: number;
monthlyPayment: number;
}
function calculateInstallments(price: number, availableTerms: number[]): InstallmentOption[] {
return availableTerms.map(months => ({
months,
monthlyPayment: Math.ceil(price / months * 100) / 100,
}));
}
// Пример использования
const options = calculateInstallments(299.90, [3, 6, 12]);
// [{ months: 3, monthlyPayment: 99.97 }, { months: 6, monthlyPayment: 49.99 }, ...] function InstallmentBadge({ price }: { price: number }) {
const minMonthly = Math.ceil(price / 24 * 100) / 100; // максимальный срок
return (
<div className="installment-badge">
от <strong>{minMonthly.toFixed(2)} BYN/мес</strong>{' '}
в рассрочку «Карта покупок»
</div>
);
} קבלת תנאים זמינים
תנאי התשלום בתשלומים תלויים בקטגוריית המוצר ובסכום. תנאים עדכניים נמשכים דרך API:
$terms = Http::withHeaders([
'X-Partner-Id' => env('KP_PARTNER_ID'),
'X-Partner-Token' => env('KP_TOKEN'),
])->get(self::BASE_URL . '/terms', [
'amount' => $order->total,
'category' => $product->kp_category_code,
])->json('available_terms');אם ה-API מחזיר מערך ריק, המוצר או הסכום אינם זכאים לתשלום בתשלומים. יש להסתיר את אפשרות התשלום של Karta Pokupok עבור אותו פריט.
השוואת תנאים לפי קטגוריה
| קטגוריית מוצר | תנאים זמינים (חודשים) | סכום מינימלי (BYN) |
|---|---|---|
| אלקטרוניקה | 3, 6, 12, 18, 24 | 100 |
| ביגוד והנעלה | 3, 6, 12 | 50 |
| מוצרי חשמל לבית | 3, 6, 12, 18, 24 | 150 |
| ציוד ספורט | 3, 6, 12 | 80 |
מידע נוסף על אבטחת Webhook
כדי לוודא את אותנטיות הבקשה, נעשה שימוש בחתימת HMAC המבוססת על מפתח סודי. כל בקשות ה-webhook הנכנסות חייבות להכיל את כותרת X-Signature. אנחנו תמיד מאמתים את החתימה לפני העיבוד כדי למנוע זיוף בקשות. בנוסף, אנו מגדירים ניטור ניסיונות חוזרים: שירות Karta Pokupok שולח webhooks מחדש עד 3 פעמים במרווח של 5 דקות.איך לתקן בקשה תקולה?
שגיאות נפוצות: APPROVED לא נכון (שליחת מחרוזת במקום מספר), REJECTED לא חוקי (ערך לא ברשימה), או interface InstallmentOption { months: number; monthlyPayment: number; } function calculateInstallments(price: number, availableTerms: number[]): InstallmentOption[] { return availableTerms.map(months => ({ months, monthlyPayment: Math.ceil(price / months * 100) / 100, })); } // Пример использования const options = calculateInstallments(299.90, [3, 6, 12]); // [{ months: 3, monthlyPayment: 99.97 }, { months: 6, monthlyPayment: 49.99 }, ...] לקוח לא חוקי. השיטה המומלצת היא לרשום את תגובת ה-API המלאה ולבדוק את שדה function InstallmentBadge({ price }: { price: number }) { const minMonthly = Math.ceil(price / 24 * 100) / 100; // максимальный срок return ( <div className="installment-badge"> от <strong>{minMonthly.toFixed(2)} BYN/мес</strong>{' '} в рассрочку «Карта покупок» </div> ); } . לדוגמה, $terms = Http::withHeaders([ 'X-Partner-Id' => env('KP_PARTNER_ID'), 'X-Partner-Token' => env('KP_TOKEN'), ])->get(self::BASE_URL . '/terms', [ 'amount' => $order->total, 'category' => $product->kp_category_code, ])->json('available_terms'); עם מערך שגיאות לפי שדה. אנחנו כוללים נקודת קצה לשליפה ידנית חוזרת של סטטוס: amount, שמחזירה את הנתונים העדכניים ביותר מ-Karta Pokupok—זה עוזר לתמיכה ללא מעורבות מפתחים.
מה כלול בעבודה
| שלב | מה אנחנו עושים | תוצאה |
|---|---|---|
| ניתוח | לימוד ארכיטקטורת התשלומים הנוכחית, הסכמה על התוכנית | מפרט טכני |
| עיצוב | עיצוב השילוב: בקשות API, webhook, תרחישי שגיאה | תיעוד תוכנית |
| יישום | כתיבת קוד השילוב על הסטאק שלך (Laravel, Symfony, WordPress וכו') | קוד עובד במאגר |
| בדיקות | הרצת תרחישי בדיקה: יצירה, ביטול, שגיאות | דוח בדיקות |
| פריסה | פריסה לשרת הייצור, הגדרת ניטור | גישה למערכת הניטור |
| הדרכה | העברת סשן הדגמה לצוות התמיכה | הוראות והקלטת וידאו |
אנחנו מבטיחים איכות: קוד המקור נשאר שלך, ואנחנו מספקים 3 חודשים של תמיכה חינם לאחר הפריסה. קבלו ייעוץ עכשיו—נעריך את המורכבות ואת לוח הזמנים של הפרויקט שלכם. בקשו הערכה—נגיב תוך יום עסקים אחד.







