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.
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ợ.