> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Ruby

> Tích hợp Dodo Payments vào các ứng dụng Ruby của bạn với một SDK tự nhiên cho Ruby

SDK Ruby cung cấp một cách đơn giản và trực quan để tích hợp Dodo Payments vào các ứng dụng Ruby của bạn. Nó tuân theo các quy ước và thực tiễn tốt nhất của Ruby, cung cấp xử lý lỗi toàn diện, phân trang và hỗ trợ middleware.

## Cài đặt

Thêm gem vào Gemfile của bạn:

```ruby Gemfile theme={null}
gem "dodopayments", "~> 2.9"
```

<Tip>
  Luôn sử dụng phiên bản SDK mới nhất để truy cập các tính năng mới nhất của Dodo Payments. Chạy `bundle update dodopayments` thường xuyên để luôn cập nhật.
</Tip>

Sau đó chạy:

```bash theme={null}
bundle install
```

<Info>
  SDK hỗ trợ Ruby 3.2.0 và các phiên bản mới hơn, với các kiểu toàn diện, xử lý lỗi và cơ chế thử lại.
</Info>

## Khởi động nhanh

Khởi tạo client và tạo một phiên giao dịch thanh toán:

```ruby theme={null}
require "bundler/setup"
require "dodopayments"

dodo_payments = Dodopayments::Client.new(
  bearer_token: ENV["DODO_PAYMENTS_API_KEY"], # This is the default and can be omitted
  environment: "test_mode" # defaults to "live_mode"
)

checkout_session_response = dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 1}]
)

puts(checkout_session_response.session_id)
```

<Warning>
  Lưu trữ khóa API của bạn một cách an toàn bằng biến môi trường. Không bao giờ đưa chúng vào hệ thống kiểm soát phiên bản hoặc để lộ trong mã của bạn.
</Warning>

## Tính năng chính

<CardGroup cols={2}>
  <Card title="Ruby Conventions" icon="gem">
    Tuân theo quy ước đặt tên và các mẫu ngữ cảnh của Ruby
  </Card>

  <Card title="Elegant Syntax" icon="code">
    API sạch, dễ đọc mang lại cảm giác tự nhiên cho các nhà phát triển Ruby
  </Card>

  <Card title="Auto-Pagination" icon="arrows-rotate">
    Trình lặp phân trang tự động tích hợp cho các phản hồi danh sách
  </Card>

  <Card title="Type Safety" icon="shield-check">
    Các kiểu Sorbet tùy chọn để tăng cường tính an toàn kiểu
  </Card>
</CardGroup>

## Cấu hình

### Cấu hình thời gian chờ

Cấu hình thời gian chờ yêu cầu:

```ruby theme={null}
# Configure default for all requests (default is 60 seconds)
dodo_payments = Dodopayments::Client.new(
  timeout: nil # disable timeout
)

# Or, configure per-request
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 1}],
  request_options: {timeout: 5}
)
```

### Cấu hình thử lại

Cấu hình hành vi thử lại tự động:

```ruby theme={null}
# Configure default for all requests (default is 2)
dodo_payments = Dodopayments::Client.new(
  max_retries: 0 # disable retries
)

# Or, configure per-request
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 1}],
  request_options: {max_retries: 5}
)
```

## Các thao tác phổ biến

### Tạo một phiên giao dịch thanh toán

Tạo một phiên giao dịch thanh toán:

```ruby theme={null}
session = dodo_payments.checkout_sessions.create(
  product_cart: [
    {
      product_id: "prod_123",
      quantity: 1
    }
  ],
  return_url: "https://yourdomain.com/return"
)

# Redirect to checkout
redirect_to session.checkout_url
```

### Quản lý khách hàng

Tạo và truy xuất thông tin khách hàng:

```ruby theme={null}
# Create a customer
customer = dodo_payments.customers.create(
  email: "customer@example.com",
  name: "John Doe",
  metadata: {
    user_id: "12345"
  }
)

# Retrieve customer
customer = dodo_payments.customers.retrieve("cus_123")
puts "Customer: #{customer.name} (#{customer.email})"
```

### Xử lý đăng ký

Tạo và quản lý các đăng ký định kỳ:

```ruby theme={null}
# Create a subscription
subscription = dodo_payments.subscriptions.create(
  billing: {
    country: "US",
    city: "San Francisco",
    state: "CA",
    street: "1 Market St",
    zipcode: "94105"
  },
  customer: { customer_id: "cus_123" }, # or { email: "...", name: "..." } for a new customer
  product_id: "pdt_456",
  quantity: 1
)

# Charge an on-demand subscription
# product_price is in the lowest currency denomination (e.g., 2500 = $25.00 USD)
charge = dodo_payments.subscriptions.charge(
  subscription.subscription_id,
  product_price: 2500
)

# Update subscription metadata
updated = dodo_payments.subscriptions.update(
  subscription.subscription_id,
  metadata: { plan_type: "premium" }
)
```

<Info>
  `billing` yêu cầu ít nhất mã ISO hai chữ cái `country`. `customer` chấp nhận hoặc `{ customer_id: "..." }` để đính kèm khách hàng hiện tại hoặc `{ email: "...", name: "..." }` để tạo mới. `product_price` là ở mệnh giá tiền tệ thấp nhất.
</Info>

## Phân trang

### Tự động phân trang

Tự động lặp qua tất cả các trang:

```ruby theme={null}
page = dodo_payments.payments.list

# Fetch single item from page
payment = page.items[0]
puts(payment.brand_id)

# Automatically fetches more pages as needed
page.auto_paging_each do |payment|
  puts(payment.brand_id)
end
```

### Phân trang thủ công

Để kiểm soát phân trang nhiều hơn:

```ruby theme={null}
page = dodo_payments.payments.list

if page.next_page?
  new_page = page.next_page
  puts(new_page.items[0].brand_id)
end
```

## Xử lý Lỗi

Xử lý các lỗi API Dodo Payments khác nhau:

```ruby theme={null}
begin
  checkout_session = dodo_payments.checkout_sessions.create(
product_cart: [{product_id: "product_id", quantity: 1}]
  )
rescue Dodopayments::Errors::APIConnectionError => e
  puts("The server could not be reached")
  puts(e.cause)  # an underlying Exception, likely raised within `net/http`
rescue Dodopayments::Errors::RateLimitError => e
  puts("A 429 status code was received; we should back off a bit.")
rescue Dodopayments::Errors::APIStatusError => e
  puts("Another non-200-range status code was received")
  puts(e.status)
end
```

<Tip>
  Triển khai logic thử lại với backoff lũy tiến cho các lỗi giới hạn tốc độ để đảm bảo ứng dụng của bạn xử lý tốt các tình huống tải lớn.
</Tip>

## An toàn loại với Sorbet

Sử dụng Sorbet cho các tham số yêu cầu an toàn-loại:

```ruby theme={null}
# Type-safe using Sorbet RBI definitions
dodo_payments.checkout_sessions.create(
  product_cart: [
    Dodopayments::ProductItemReq.new(
      product_id: "product_id",
      quantity: 1
    )
  ]
)

# Hashes work, but are not typesafe
dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 1}]
)

# You can also splat a full Params class
params = Dodopayments::CheckoutSessionCreateParams.new(
  product_cart: [
    Dodopayments::ProductItemReq.new(
      product_id: "product_id",
      quantity: 1
    )
  ]
)
dodo_payments.checkout_sessions.create(**params)
```

## Sử dụng Nâng cao

### Endpoint không được tài liệu hóa

Gửi yêu cầu tới các endpoint không được tài liệu hóa:

```ruby theme={null}
response = dodo_payments.request(
  method: :post,
  path: '/undocumented/endpoint',
  query: {"dog": "woof"},
  headers: {"useful-header": "interesting-value"},
  body: {"hello": "world"}
)
```

### Tham số không được tài liệu hóa

Gửi tham số không được tài liệu hóa:

```ruby theme={null}
checkout_session_response = dodo_payments.checkout_sessions.create(
  product_cart: [{product_id: "product_id", quantity: 1}],
  request_options: {
    extra_query: {my_query_parameter: value},
    extra_body: {my_body_parameter: value},
    extra_headers: {"my-header": value}
  }
)

# Access undocumented response properties
puts(checkout_session_response[:my_undocumented_property])
```

## Tích hợp Rails

### Tạo Initializer

Tạo `config/initializers/dodo_payments.rb`:

```ruby theme={null}
require "dodopayments"

DODO_CLIENT = Dodopayments::Client.new(
  bearer_token: Rails.application.credentials.dodo_api_key,
  environment: Rails.env.production? ? "live_mode" : "test_mode"
)
```

### Mẫu Đối tượng Dịch vụ

Tạo dịch vụ thanh toán:

```ruby theme={null}
# app/services/payment_service.rb
class PaymentService
  def initialize
    @client = DODO_CLIENT
  end

  def create_checkout(items)
    @client.checkout_sessions.create(
      product_cart: items,
      return_url: Rails.application.routes.url_helpers.checkout_return_url
    )
  end

  def process_payment(amount:, currency:, customer_id:)
    @client.payments.create(
      amount: amount,
      currency: currency,
      customer_id: customer_id
    )
  end
end
```

### Tích hợp Controller

Sử dụng trong các controller của Rails:

```ruby theme={null}
# app/controllers/checkouts_controller.rb
class CheckoutsController < ApplicationController
  def create
    service = PaymentService.new
    session = service.create_checkout(checkout_params[:items])
    
    redirect_to session.checkout_url, allow_other_host: true
  rescue Dodopayments::Errors::APIError => e
    flash[:error] = "Payment error: #{e.message}"
    redirect_to cart_path
  end

  private

  def checkout_params
    params.require(:checkout).permit(items: [:product_id, :quantity])
  end
end
```

## Tích hợp Sinatra

Sử dụng với các ứng dụng Sinatra:

```ruby theme={null}
require "sinatra"
require "dodopayments"

configure do
  set :dodo_client, Dodopayments::Client.new(
    bearer_token: ENV["DODO_API_KEY"]
  )
end

post "/create-checkout" do
  content_type :json
  
  begin
    session = settings.dodo_client.checkout_sessions.create(
      product_cart: JSON.parse(request.body.read)["items"],
      return_url: "#{request.base_url}/return"
    )
    
    { checkout_url: session.checkout_url }.to_json
  rescue Dodopayments::Errors::APIError => e
    status 400
    { error: e.message }.to_json
  end
end
```

## Tài nguyên

<CardGroup cols={2}>
  <Card title="GitHub Repository" icon="github" href="https://github.com/dodopayments/dodopayments-ruby">
    Xem mã nguồn và đóng góp
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference/introduction">
    Hoàn thành tài liệu API
  </Card>

  <Card title="Discord Community" icon="discord" href="https://discord.gg/bYqAp4ayYh">
    Nhận trợ giúp và kết nối với các nhà phát triển
  </Card>

  <Card title="Report Issues" icon="bug" href="https://github.com/dodopayments/dodopayments-ruby/issues">
    Báo cáo lỗi hoặc yêu cầu tính năng
  </Card>
</CardGroup>

## Hỗ trợ

Cần trợ giúp với Ruby SDK?

* **Discord**: Tham gia [máy chủ cộng đồng](https://discord.gg/bYqAp4ayYh) của chúng tôi để được hỗ trợ theo thời gian thực.
* **Email**: Liên hệ với chúng tôi tại [support@dodopayments.com](mailto:support@dodopayments.com)
* **GitHub**: Mở một vấn đề trên [repository](https://github.com/dodopayments/dodopayments-ruby)

## Đóng góp

Chúng tôi hoan nghênh đóng góp! Xem [hướng dẫn đóng góp](https://github.com/dodopayments/dodopayments-ruby/blob/main/CONTRIBUTING.md) để bắt đầu.
