0

Tích Hợp Thanh Toán Với PayJP Trong Ruby on Rails

Trong thời đại số, việc tích hợp thanh toán trực tuyến vào ứng dụng web không còn là lựa chọn, mà là yêu cầu bắt buộc nếu bạn muốn xây dựng một sản phẩm thực sự có giá trị.
Trong bài viết này, chúng ta sẽ tìm hiểu về PayJP – nền tảng thanh toán mạnh mẽ tại Nhật Bản – và cách sử dụng gem payjp để tích hợp thanh toán vào ứng dụng Ruby on Rails.

ChatGPT Image May 26, 2025, 04_50_08 PM.png

1. Giới thiệu PayJP

PayJP là một nền tảng thanh toán trực tuyến đến từ Nhật Bản, cung cấp giải pháp xử lý thanh toán đơn giản, an toàn và hiện đại dành cho lập trình viên và doanh nghiệp.

🌟 Một số tính năng nổi bật

  • Hỗ trợ các loại thẻ phổ biến: Visa, MasterCard, JCB, AMEX
  • Giao diện API hiện đại: RESTful API dễ dùng
  • Thanh toán định kỳ (Subscription): Hỗ trợ các mô hình SaaS
  • Quản lý giao dịch và khách hàng trên dashboard trực quan
  • Bảo mật PCI DSS: Bạn không cần lưu trữ thông tin thẻ

PayJP là lựa chọn lý tưởng cho các sản phẩm phục vụ thị trường Nhật Bản, từ ứng dụng thương mại điện tử đến dịch vụ đăng ký thành viên.

2. Yêu cầu trước khi bắt đầu

Trước tiên, hãy đảm bảo bạn đã cài đặt:

  • Ruby >= 3.0
  • Rails >= 7.0
  • Node.js & Yarn
  • PostgreSQL (hoặc SQLite cho đơn giản)
  • Tài khoản PAY.JP: https://pay.jp/

3. Tạo App Rails mới

Ở đây mình sẽ dùng Postgresql nhé.

rails new payjp_app -d=postgresql

Cấu hình database.yml

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: your_db_username
  password: your_db_password
  host: localhost

development:
  <<: *default
  database: payjp_app_development

test:
  <<: *default
  database: payjp_app_test

production:
  <<: *default
  database: payjp_app_production
  username: payjp_app
  password: <%= ENV['PAYJP_APP_DATABASE_PASSWORD'] %>

Sau đó, bạn run:

rails db:create

4. Cài đặt PAY.JP SDK

Gem Ruby Thêm vào Gemfile:

gem 'payjp'
gem 'dotenv-rails' # để quản lý biến môi trường

Sau đó run:

bundle install

JavaScript SDK

Cài Webpacker (nếu chưa):

bundle exec rails webpacker:install

Cài PAY.JP JS SDK:

yarn add @payjp/payjp-js

5. Cấu hình biến môi trường PAY.JP

Tạo file .env trong thư mục gốc:

PAYJP_PUBLIC_KEY=pk_test_xxxxx
PAYJP_SECRET_KEY=sk_test_xxxxx

| Nhớ thêm .env vào .gitignore để không đẩy lên repo

Tạo file config/initializers/payjp.rb

Payjp.api_key = ENV['PAYJP_SECRET_KEY']

6. Tạo model: User & Payment

rails generate model User name:string email:string
rails generate model Payment user:references amount:integer payjp_charge_id:string status:string
rails db:migrate

7. Tạo controller payments

rails generate controller Payments new create

8. Cấu hình route

Trong config/routes.rb:

Rails.application.routes.draw do
  root 'payments#new'
  resources :payments, only: [:new, :create]
end

9. Giao diện thanh toán

Trong file app/views/payments/new.html.erb

<h2>Thanh toán đơn hàng 1.000¥</h2>

<%= form_with url: payments_path, local: true, id: "payment-form" do %>
  <%= hidden_field_tag :user_id, User.first.id %> <!-- giả sử user đã tồn tại -->
  <div id="card-form"></div>
  <%= hidden_field_tag :payjp_token %>
  <%= submit_tag "Thanh toán", id: "submit-button" %>
<% end %>

<script src="https://js.pay.jp/v2/pay.js"></script>
<script type="module">
  import Payjp from "@payjp/payjp-js"

  const payjp = Payjp("<%= ENV['PAYJP_PUBLIC_KEY'] %>")
  const elements = payjp.elements()
  const card = elements.create('card')
  card.mount('#card-form')

  const form = document.getElementById('payment-form')
  form.addEventListener('submit', async (e) => {
    e.preventDefault()
    const { token, error } = await payjp.createToken(card)

    if (error) {
      alert(error.message)
    } else {
      document.querySelector("input[name='payjp_token']").value = token.id
      form.submit()
    }
  })
</script>

10. Xử lý thanh toán trong controller

Tại file app/controllers/payments_controller.rb

class PaymentsController < ApplicationController
  def new; end

  def create
    Payjp.api_key = ENV['PAYJP_SECRET_KEY']

    user = User.find(params[:user_id])

    charge = Payjp::Charge.create(
      amount: 1000,
      card: params[:payjp_token],
      currency: 'jpy'
    )

    Payment.create!(
      user: user,
      amount: charge.amount,
      payjp_charge_id: charge.id,
      status: charge.status
    )

    redirect_to root_path, notice: "Thanh toán thành công!"
  rescue => e
    redirect_to root_path, alert: "Lỗi khi thanh toán: #{e.message}"
  end
end

11. Thêm seed dữ liệu User đơn giản

Trong file db/seeds.rb

User.create!(name: "Test User", email: "test@example.com")

sau đó run:

rails db:seed

12. Kiểm thử với thẻ giả lập

Run:

rails server 

Truy cập http://localhost:3000 và dùng thẻ test của PAY.JP

PayJP hỗ trợ nhiều thẻ test, ví dụ:

  • Số thẻ: 4242 4242 4242 4242
  • Hạn sử dụng: bất kỳ tương lai
  • CVC: 123

13. Tổng kết

Việc tích hợp thanh toán trong Rails trở nên đơn giản hơn bao giờ hết nhờ vào gem payjp và hệ thống API rõ ràng, dễ sử dụng của PayJP. Đây là một giải pháp mạnh mẽ nếu bạn đang xây dựng sản phẩm hướng đến thị trường Nhật Bản hoặc cần một phương thức thanh toán nội địa tin cậy.

Nếu bạn muốn mở rộng với subscription, quản lý khách hàng hoặc xử lý webhook tự động – PayJP cũng sẵn sàng hỗ trợ.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí