12/08/2018, 13:07

Thanh toán qua paypal với rails

1. Giới thiệu Paypal là một côngr thanh toán điện tử trực tuyến để tiến hành các giao dịch mua bán trên mạng.Paypal như một điểm trung gian trong giao dịch của ban. Nếu có một tài khoản Paypal, bạn có thể chuyển tiền vào tài khoản này để thanh toán online or rút tiền đó về tài khoản của bạn. ...

1. Giới thiệu

Paypal là một côngr thanh toán điện tử trực tuyến để tiến hành các giao dịch mua bán trên mạng.Paypal như một điểm trung gian trong giao dịch của ban. Nếu có một tài khoản Paypal, bạn có thể chuyển tiền vào tài khoản này để thanh toán online or rút tiền đó về tài khoản của bạn.

Lợi ích khi sử dụng pay pal:

  • Mức độ bảo mật cao
  • Hỗ trợ an toàn trong giao dịch của cả người mua lẫn người bán
  • Thanh toán nhanh, an toàn, tiện lợi
  • Hạn chế bị lộ thông tin tài khoản ngân hàng, vì mỗi lần thanh toán, bạn không phải nhập số thẻ thanh toán quốc tế (VISA, Mastercard) của mình vì đã cung cấp cho PayPal khi đăng ký tài khoản.
  • Uyển chuyển trong việc quản lý tiền trong tài khoản. Bạn có thể lấy lại tiền sau khi đã chuyển tiền đến tài khoản khác, thông qua chức năng chargeback. Vì vậy, người sử dụng có thể hoàn toàn an tâm về vấn đề bị lừa đảo.
  • Tính phổ biến của PayPal trên thế giới hiện nay sẽ giúp bạn thuận tiện hơn rất nhiều cho việc thanh toán trực tuyến.

2. Hai cách để thanh toán qua paypal

  • Cách thứ nhất ta có thể thực hiện thanh toán qua phương pháp basic như trong bài viết đã có trên viblo: https://viblo.asia/DinhHuan/posts/XogBG2JbGxnL or tham khảo tại link: https://launchschool.com/blog/basic-paypal-checkout-processing-in-rails nên tôi ko nhắc lại nữa

  • Cách thứ 2 ta có thê dùng paypal checkout express. Nguyên tắc như phương phap basic nhưng ta dùng Credentials cho người nhận để thanh toán

3. Demo thanh toán qua phương pháp paypal express

Bắt đầu vào việc nào

** Chuẩn bị **

Bước 1.

Đăng kí 1 tài khoản paypal. Sau đó tạo tk người mua và tài khoản người nhận trong sandbox để test. https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&sqi=2&ved=0ahUKEwjfo8zE1v7JAhVGHI4KHYuuAFwQFggcMAA&url=https%3A%2F%2Fdeveloper.paypal.com%2Fdeveloper%2Faccounts%2F&usg=AFQjCNH5sPVNV8z-a0INyJ2SrVlmex6j_w&sig2=FWDBMxjZxRMrueGpmtYAwg&bvm=bv.110151844,d.c2E&cad=rja

Bạn click create account sẽ sang trang tạo tài khoản sandbox. Bạn nên tạo cả tài khoản nhận lẫn tài khoản mua( buyer account và merchant account) trong lựa chọn account type.

Sau khi tạo xong ta có 2 tài khoản test như sau Merchant: 1.png2.png

Buyer: buyer2.pngbuyer1.png

Chú ý sau khi tạo tài khoản người nhận các bạn mở sang tab API Credentials sẽ lưu cac thông tin như username, password và signarute lại sau sẽ dùng trong app demo của chúng ta.

Bước 2. Tạo một rails app . Cái này mình sẽ ko đi sâu việc tạo app rails như nào mà chỉ bắt đầu với việc tạo một model payment để lưu một giao dịch khi thanh toán qua paypal.

Sử dụng gem paypal-express add vào trong gemfile

gem "paypal-express"

File migration của ta như sau:

class CreatePayments < ActiveRecord::Migration
  def change
    create_table :payments do |t|
      t.datetime :expires_at
      t.datetime :purchased_at
      t.integer :quantity
      t.string :status
      t.datetime :deleted_at

      t.timestamps
    end
  end
end

Flow của chúng ta là khi người dùng mở trang payment/new → sẽ ra 1 trang mua sản phẩm nào đó → create một payment với paypal token → Sau đó 1 popup của paypal hiện lên. Chúng tao có thể thanh toán or cancel giao dịch đó → callback trở lại controller để tìm payment với token kia và handle theo status của giao dịch

Trong controller của payment ta chú ý các hàm khi được gọi ví dụ trong create khi payment được save ta sẽ gọi payment.setup để cấu hình url của function success or cancel khi thao tấc với paypal:

 payment.setup!(
     success_payments_url,
     cancel_payments_url
 )

Hai hàm successs và cancel sẽ đảm nhận việc callack tư popup khi thanh toán

def success
    handle_callback do |payment|
      payment.complete!(params[:PayerID])
      flash[:notice] = 'Payment Transaction Completed'
      close_popup_payments_url
      # payment_url(payment.transaction_id)
    end
  end

  def cancel
    handle_callback do |payment|
      payment.cancel!
      flash[:notice] = 'Payment Request Canceled'
      close_popup_payments_url
    end
  end
def handle_callback
    payment = Payment.find_by_token! params[:token]
    @redirect_uri = yield payment
    redirect_to @redirect_uri
  end

Trong payment model ta quan tâm đến 3 hàm setup!, cancel!, complete!

def setup!(return_url, cancel_url)
    payment_request = payment_request self.quantity
    response = client.setup(
      payment_request,
      return_url,
      cancel_url,
      pay_on_paypal: true
    )
    self.token = response.token
    self.save! rescue false
    @redirect_uri = response.redirect_uri
    @popup_uri = response.popup_uri
    self
  end

  def cancel!
    self.canceled = true
    self.save! rescue false
    self
  end

  def complete!(payer_id = nil)
    payment_request = payment_request  self.quantity
    response = client.checkout!(self.token, payer_id, payment_request)
    self.payer_id = payer_id
    self.transaction_id = response.payment_info.first.transaction_id
    self.status = "completed"
    self.purchased_at = Time.now
    #TODO calculate expires_at

    self.save! rescue false
    self
  end

hàm setup như nói ở phần trên. còn 2 hàm cancel! và success! đơn giản việc update lai trạng thái cho payment của chúng ta.

Cấu hình trong config và .ENV

#config/initializers/paypal.rb
 require 'paypal/express'
PAYPAL_CONFIG = YAML::load(ERB.new(File.read("#{Rails.root}/config/paypal.yml")).result)[Rails.env].symbolize_keys
Paypal.sandbox! if PAYPAL_CONFIG[:sandbox]

#paypal.yml
  development: &sandbox
   username: <%= ENV["USERNAME"] %>
   password: <%= ENV["PASSWORD"] %>
   signature: <%= ENV["SIGNATURE"] %>
   sandbox: true

  test:
   <<: *sandbox

  production: &production
   username: <%= ENV["USERNAME"] %>
  password: <%= ENV["PASSWORD"] %>
   signature: <%= ENV["SIGNATURE"] %>
   sandbox: false

#.env.development
USERNAME=chuyenvu90_api1.gmail.com
PASSWORD=G2DTM4A5TEXEGA7X
SIGNATURE=AbZKmTag68MmTDxyTtmM2Vm49BInA5VnOPGTDPx00plc2zNB-vjKNzDV

Ở view ta quan tâm đến đoạn mã javascript có chức năng tạo flow popup của paypal giúp ta thao tác thanh toán trên nó:

%script{src: "https://www.paypalobjects.com/js/external/dg.js"}
:javascript
  $(function(){
    var sandbox = true;
    var submit_id = 'paypal_submit';
    flow_config = {trigger: submit_id};
    if (sandbox) flow_config.stage = sandbox;
    window.paypal_flows = [];
    window.paypal_flows.push(new PAYPAL.apps.DGFlow(flow_config));

    $("#payment_customer_type_collection").click(function(){
      $(".customer").show();
    })
    $("#payment_customer_type_user").click(function(){
      $(".customer").hide();
    })
  });

Chạy để test thôi =))

Các bạn có thể fork project test của mình và chạy:

rake db:create rake db:migrate

Nhập url lên browser: localhost:3000/payments/new aaa.png

Khi tạo 1 payment ta có record như sau:

=> #<Payment:0x0000000403b7f0
 id: 3,
 expires_at: nil,
 purchased_at: nil,
 quantity: 1,
 status: nil,
 deleted_at: nil,
 created_at: Mon, 28 Dec 2015 14:25:51 UTC +00:00,
 updated_at: Mon, 28 Dec 2015 14:25:53 UTC +00:00,
 transaction_id: nil,
 amount: 1,
 token: "EC-2BV62799YX135574K",
 canceled: false,
 payer_id: nil>

Thanh toán khi popup bật lên: 3.png4.png

Sau khi thao tác với paypal thành công update lai payment đó:

id: 2,
 expires_at: nil,
 purchased_at: Mon, 28 Dec 2015 14:24:16 UTC +00:00,
 quantity: 1,
 status: "completed",
 deleted_at: nil,
 created_at: Mon, 28 Dec 2015 14:22:41 UTC +00:00,
 updated_at: Mon, 28 Dec 2015 14:24:16 UTC +00:00,
 transaction_id: "3SK76781JF031145R",
 amount: 1,
 token: "EC-2BV62799YX135574K",
 canceled: false,
 payer_id: "GYBCEHSKAV74C">

4. Kết luận

link tham khảo https://github.com/nov/paypal-express/wiki

Demo: https://github.com/asvenus/paypal_express

0