• בלוג
  • סליקת אשראי לחנויות אינטרנט: מדריך למפתחים

סליקת אשראי לחנויות אינטרנט: מדריך למפתחים

26/11/2017

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

1. איך זה עובד

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

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

בפוסט זה אתמקד באפשרות הראשונה (דפי סליקה חיצוניים).

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

2. דף סליקה זמני + IPN

דרך אחת היא לשלוח את הגולש לדף סליקה זמני שנוצר (או מותאם) בתגובה לפרמטרים בכתובת הקישור. לפייפאל יש מנגנון כזה וגם ל iCount. לדוגמא עמוד הסליקה הבא ב iCount יציע לכם את המוצר שלי בעשרה ש"ח:

https://app.icount.co.il/m/617a5?cs=10&cd=my%20product

וכמובן שאפשר להשתמש באותו טופס כדי להציג דף סליקה למוצר אחר ולמחיר אחר:

https://app.icount.co.il/m/617a5?cd=my%20other%20product&cs=20

גם לפייפאל יש מנגנון דומה. הקישור הבא לדוגמא ישלח אתכם לדף תשלום עבור מוצר שעולה 99$ בפייפאל:

https://www.paypal.com/cgi-bin/webscr?cmd=xclick&add=1&business=ynonperek@gmail.com&itemname=my product&item_number=123456&amount=99.99

כל הפרמטרים של דף המכירה עוברים לטופס דרך ה URL. כל אחד יכול לבחור איזה ערכים שרוצה בשביל לייצר עמוד מכירה לכל מוצר בחנות.

דפי סליקה זמניים יקבלו תמיד שני פרמטרים באמצעותם אנו מייצרים חווית קניה רציפה ללקוח:

  1. דף תודה - אליו מועבר הגולש לאחר התשלום. דף התודה צריך להציג למשתמש הודעת תודה ששילמת, אבל אל תניחו שרק בגלל שמישהו הגיע לדף התודה זה אומר שהוא שילם. קל מאוד לכל אחד להעתיק את כתובת דף התודה ולהדביק אותה במחשב אחר או לשנות פרמטרים ב URL כדי להגיע לדף תודה למוצר אחר.

בפייפאל הפרמטר לדף התודה נקרא return.

  1. כתובת IPN - לצורך פתיחה אוטומטית של המוצר הדיגיטלי ללקוח אנו צריכים דרך אמינה לדעת שהיתה רכישה בסכום שדרשנו. המנגנון שמשתמשים בו בדפי סליקה נקרא IPN שזה קיצור ל Instant Payment Notification. הפרמטר השני לטופס התשלום נקרא notify_url והוא מייצג כתובת אליה פייפאל יודיע שהתקבל תשלום לאחר ביצוע התשלום.

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

דוגמת הקוד הבאה ממחישה את הטיפול בעמוד סליקה של פייפאל דרך אתר ריילס:

class PaymentNotificationsController < ApplicationController
  protect_from_forgery :except => [:create] #Otherwise the request from PayPal wouldn't make it to the controller
  def create
    response = validate_IPN_notification(request.raw_post)
    case response
    when "VERIFIED"
      # check that paymentStatus=Completed
      # check that txnId has not been previously processed
      # check that receiverEmail is your Primary PayPal email
      # check that paymentAmount/paymentCurrency are correct
      # process payment
    when "INVALID"
      # log for investigation
    else
      # error
    end
    render :nothing => true
  end 

  protected 

  def validate_IPN_notification(raw)
    uri = URI.parse('https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate')
    http = Net::HTTP.new(uri.host, uri.port)
    http.open_timeout = 60
    http.read_timeout = 60
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    http.use_ssl = true
    response = http.post(uri.request_uri, raw,
                         'Content-Length' => "#{raw.size}",
                         'User-Agent' => "My custom user agent"
                        ).body
  end
end

3. דף סליקה קבוע דרך API

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

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

אחר כך שולחים את הגולש לדף הסליקה שיצרתם, הגולש משלם וחוזר לדף התודה ומיד כשמגיע לדף התודה אפשר לפנות שוב ל API של ספק הסליקה (פייפאל) ולשאול אם התשלום בבקשת הסליקה שיצרנו בוצע בהצלחה. התשובה היא מיידית והיתרון שלא צריך לחכות ל IPN.

להמחשה כך נראה קוד שפותח בקשת סליקה דרך ה API של פייפאל:

require 'paypal-sdk-rest'
include PayPal::SDK::REST

PayPal::SDK::REST.set_config(
  :mode => "sandbox", # "sandbox" or "live"
  :client_id => "EBWKjlELKMYqRNQ6sYvFo64FtaRLRR5BdHEESmha49TM",
  :client_secret => "EO422dn3gQLgDbuwqTjzrFgFtaRLRR5BdHEESmha49TM")

# Build Payment object
@payment = Payment.new({
  :intent =>  "sale",
  :payer =>  {
    :payment_method =>  "paypal" },
  :redirect_urls => {
    :return_url => "http://localhost:3000/payment/execute",
    :cancel_url => "http://localhost:3000/" },
  :transactions =>  [{
    :item_list => {
      :items => [{
        :name => "item",
        :sku => "item",
        :price => "5",
        :currency => "USD",
        :quantity => 1 }]},
    :amount =>  {
      :total =>  "5",
      :currency =>  "USD" },
    :description =>  "This is the payment transaction description." }]})

if @payment.create
  @payment.id     # Payment Id
else
  @payment.error  # Error Hash
end

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

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

payment = Payment.find("PAY-57363176S1057143SKE2HO3A")

if payment.execute( :payer_id => "DUFRQ8GWYMJXC" )
  # Success Message
  # Note that you'll need to `Payment.find` the payment again to access user info like shipping address
else
  payment.error # Error Hash
end

4. אמ;לק

כדי לבצע סליקת אשראי דרך חנות אינטרנט שלכם יש צורך:

  1. לשלוח את הגולש לדף סליקה חיצוני.
  2. להציג לגולש שחוזר דף ״תודה ששילמת״.
  3. לוודא מול ספק הסליקה שהתשלום עבר בהצלחה, ואז לפתוח ללקוח החדש את הגישה למוצר.

אם אתם מוכנים לחיות עם כמה דקות המתנה לפני שגולש מקבל את המוצר מומלץ וקל להשתמש בדף סליקה זמני עבור כל רכישה, להתאים את הפרמטרים למוצר ולחכות ל IPN. (ולא לשכוח לוודא בסוף שה IPN מקורי וסכום הקניה תואם את מה שתכננתם).

אם אתם מעדיפים שהגולשים שלכם לא יחכו אפילו דקה תצטרכו לעבוד דרך ה API: לפתוח בקשת סליקה ולהעביר את כל הפרמטרים מהשרת שלכם לספק הסליקה. בכניסה לעמוד התודה פנו לספק הסליקה ובדקו שהבקשה הושלמה ותשלום עבר (לפי מזהה הבקשה שיצרתם קודם) ואז תוכלו לפתוח ללקוח את הגישה למוצר הדיגיטלי.