# Hướng dẫn bắt đầu nhanh (/vi/online/getting-started/quick_start_guide)



Hosted Checkout cung cấp cho bạn một trang thanh toán dựng sẵn cho thẻ, Apple Pay và Google Pay. Máy chủ của bạn tạo một phiên cho đơn hàng, khách hàng thanh toán, và máy chủ của bạn xác nhận kết quả trước khi hoàn tất đơn hàng. Embedded Checkout gắn các trường nhập thẻ bảo mật trực tiếp vào trang của riêng bạn.

Hãy thử cả hai luồng bên dưới. Thẻ thử nghiệm đã được điền sẵn, vì vậy hãy chọn **Pay** và theo dõi khoản thanh toán đến cuối, hoặc thử Apple Pay hay Google Pay. Cả hai đều là bản mô phỏng, nên không có dữ liệu nào rời khỏi trình duyệt của bạn.

<Tabs defaultValue="hosted" className="my-6 overflow-visible rounded-none border-0 bg-transparent">
  <TabsList className="px-0">
    <TabsTrigger value="hosted">
      Hosted Checkout
    </TabsTrigger>

    <TabsTrigger value="embedded">
      Trường nhúng
    </TabsTrigger>
  </TabsList>

  <TabsContent value="hosted" className="rounded-none bg-transparent px-0 pt-6 pb-0">
    <HostedCheckoutDemo />
  </TabsContent>

  <TabsContent value="embedded" className="rounded-none bg-transparent px-0 pt-6 pb-0">
    <EmbeddedCheckoutDemo />
  </TabsContent>
</Tabs>

## Chọn cách khách hàng thanh toán [#choose-how-customers-pay]

<CheckoutComparison />

<Callout title="Tình trạng khả dụng" type="info">
  Checkout đã hoạt động chính thức cho các merchant đã được phê duyệt. Cả Hosted Checkout và Embedded Checkout đều hỗ trợ thẻ, Apple Pay và Google Pay. Khả năng hiển thị ví phụ thuộc vào [Cài đặt Checkout](/online/integration/checkout_settings), việc đăng ký tên miền, cũng như thiết bị và trình duyệt của khách hàng. Embedded Checkout dùng Tapaya.js **0.2.0** và Node.js SDK **0.3.0**. Hãy bắt đầu với sandbox, sau đó làm theo phần [Vận hành chính thức](#go-live).
</Callout>

## Nhận một khoản thanh toán [#accept-a-payment]

<div className="fd-steps [&_h3]:fd-step">
  ### Onboarding merchant của bạn [#onboard-your-merchant]

  Hoàn tất [onboarding merchant](/merchants/onboarding) với tính năng thanh toán trực tuyến, hoặc cả thanh toán trực tuyến lẫn thanh toán tại cửa hàng. Một merchant chỉ dùng Checkout không cần máy thanh toán. Cung cấp website của cửa hàng và thông tin kinh doanh trực tuyến, rồi chờ đơn vị xử lý thanh toán phê duyệt. Chỉ riêng việc tạo bản ghi merchant hoặc API key không kích hoạt thanh toán.

  Mở **Checkout** trong [Tapaya Platform](https://platform.tapaya.com/checkout-settings). Các merchant yêu cầu thanh toán trực tuyến tự động xuất hiện, kể cả những merchant đang chờ phê duyệt. Tiếp tục khi merchant ở trạng thái **Ready**.

  Mở **Settings** của merchant. Trong **Merchant API key redirects**, thêm cửa hàng của bạn vào **Allowed websites** và đặt URL thành công và URL hủy mặc định. Một nền tảng dùng Secret key của tổ chức sẽ đặt các giá trị này trong **Organization defaults**. Các ví dụ dùng `https://shop.example`. Xem [Cài đặt Checkout](/online/integration/checkout_settings) để biết về ví và thương hiệu.

  ### Lưu key trên máy chủ [#store-your-key-on-the-server]

  Trong **Settings** của merchant, chọn **Create merchant key** và sao chép key `tapaya_test_…`. Key chỉ hiển thị một lần. Chỉ giữ key trong cấu hình phía máy chủ. Key không bao giờ được nằm trong mã trình duyệt hoặc hệ thống quản lý mã nguồn.

  ```bash title=".env"
  TAPAYA_ENVIRONMENT=sandbox
  TAPAYA_CHECKOUT_API_URL=https://api.sandbox.tapaya.com
  TAPAYA_SECRET_KEY=tapaya_test_...
  ```

  SDK tự động đọc `TAPAYA_SECRET_KEY` và `TAPAYA_ENVIRONMENT`. Các ví dụ HTTP bên dưới dùng `TAPAYA_CHECKOUT_API_URL`. Hãy nạp các biến này vào tiến trình máy chủ của bạn; SDK không tải tệp `.env`.

  Gửi key dưới dạng `Authorization: Bearer <key>`. Key của merchant tự xác định merchant của nó, nên không cần header nào khác. Một nền tảng phục vụ nhiều merchant sẽ dùng Secret key của tổ chức và gửi `X-Tapaya-Merchant-Token` trong mọi yêu cầu. Xem [Xác thực Checkout](/online/integration/api_integration#authentication).

  ### Tạo một phiên Checkout [#create-a-checkout-session]

  Khi khách hàng nhấn **Checkout** trong cửa hàng của bạn, hãy tính tổng tiền cuối cùng trên máy chủ, lưu đơn hàng cùng một key duy nhất cho lần thử thanh toán và tạo phiên. `merchantOrderId` là bắt buộc, và một đơn hàng chỉ có thể được thanh toán một lần. Số tiền được tính theo đơn vị nhỏ nhất của tiền tệ, nên `12100` là 121,00 EUR.

  Với Node.js 22.13.0 trở lên, hãy cài đặt ESM SDK trước khi dùng ví dụ **Node.js SDK**:

  <CodeBlockTabs defaultValue="npm" groupId="package-manager">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="npm">
        npm
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="pnpm">
        pnpm
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="bun">
        Bun
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="npm">
      ```sh
      npm install @tapayadot/checkout
      ```
    </CodeBlockTab>

    <CodeBlockTab value="pnpm">
      ```sh
      pnpm add @tapayadot/checkout
      ```
    </CodeBlockTab>

    <CodeBlockTab value="bun">
      ```sh
      bun add @tapayadot/checkout
      ```
    </CodeBlockTab>
  </CodeBlockTabs>

  <CodeBlockTabs defaultValue="fetch" groupId="quick-start-server">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="fetch">
        HTTP (fetch)
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="node">
        Node.js SDK
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="curl">
        cURL
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="fetch">
      ```js title="server/checkout.js"
      const response = await fetch(
        new URL('/merchant/checkout-sessions', process.env.TAPAYA_CHECKOUT_API_URL),
        {
          method: 'POST',
          headers: {
            Authorization: `Bearer ${process.env.TAPAYA_SECRET_KEY}`,
            'Content-Type': 'application/json',
            'Idempotency-Key': order.checkoutAttemptKey,
          },
          body: JSON.stringify({
            merchantOrderId: order.id,
            amount: order.totalInMinorUnits,
            currency: order.currency,
            successUrl: 'https://shop.example/checkout/return',
            cancelUrl: 'https://shop.example/checkout/cancel',
          }),
        },
      );
      if (!response.ok) throw new Error(`Checkout failed (${response.status})`);
      const session = await response.json();
      ```
    </CodeBlockTab>

    <CodeBlockTab value="node">
      ```ts title="server/checkout.ts"
      import { Tapaya } from '@tapayadot/checkout';

      const tapaya = new Tapaya();
      const session = await tapaya.checkout.sessions.create(
      	{
      		merchantOrderId: order.id,
      		amount: order.totalInMinorUnits,
      		currency: order.currency,
      		successUrl: 'https://shop.example/checkout/return',
      		cancelUrl: 'https://shop.example/checkout/cancel',
      	},
      	{ idempotencyKey: order.checkoutAttemptKey },
      );
      ```
    </CodeBlockTab>

    <CodeBlockTab value="curl">
      ```bash title="Terminal"
      curl --request POST "$TAPAYA_CHECKOUT_API_URL/merchant/checkout-sessions" \
        --header "Authorization: Bearer $TAPAYA_SECRET_KEY" \
        --header 'Content-Type: application/json' \
        --header 'Idempotency-Key: order-1001-checkout-1' \
        --data '{
          "merchantOrderId": "order-1001",
          "amount": 12100,
          "currency": "EUR",
          "successUrl": "https://shop.example/checkout/return",
          "cancelUrl": "https://shop.example/checkout/cancel"
        }'
      ```
    </CodeBlockTab>
  </CodeBlockTabs>

  Nếu yêu cầu hết thời gian chờ, hãy thử lại với **cùng** key và phần thân. API sẽ trả về lại phiên ban đầu thay vì tạo phiên thứ hai.

  ### Chuyển hướng khách hàng [#redirect-the-customer]

  Lưu `session.id` cùng với đơn hàng, sau đó chuyển trình duyệt đến `session.url` bằng HTTP 303. Dùng URL đúng như được trả về.

  ```ts
  // First persist session.id as the order's checkoutSessionId.
  return Response.redirect(session.url, 303);
  ```

  Tapaya hiển thị tóm tắt đơn hàng và biểu mẫu thanh toán bảo mật, đồng thời xử lý tokenization, 3-D Secure và việc trừ tiền. Sau khi bị từ chối, khách hàng có thể thử thẻ khác trên cùng trang. Các phiên nhận thanh toán mới trong 30 phút.

  ### Xác minh thanh toán trên máy chủ của bạn [#verify-the-payment-on-your-server]

  Khi khách hàng đến URL thành công hoặc URL hủy của bạn, hãy truy xuất phiên bằng Secret key và so sánh với đơn hàng đã lưu. Chỉ riêng một lần chuyển hướng không bao giờ chứng minh việc thanh toán.

  <CodeBlockTabs defaultValue="fetch" groupId="quick-start-status">
    <CodeBlockTabsList>
      <CodeBlockTabsTrigger value="fetch">
        HTTP (fetch)
      </CodeBlockTabsTrigger>

      <CodeBlockTabsTrigger value="node">
        Node.js SDK
      </CodeBlockTabsTrigger>
    </CodeBlockTabsList>

    <CodeBlockTab value="fetch">
      ```js title="server/return.js"
      const response = await fetch(
        new URL(
          `/merchant/checkout-sessions/${encodeURIComponent(order.checkoutSessionId)}`,
          process.env.TAPAYA_CHECKOUT_API_URL,
        ),
        { headers: { Authorization: `Bearer ${process.env.TAPAYA_SECRET_KEY}` } },
      );
      if (!response.ok) throw new Error(`Status check failed (${response.status})`);
      const current = await response.json();
      ```
    </CodeBlockTab>

    <CodeBlockTab value="node">
      ```ts title="server/return.ts"
      import { Tapaya } from '@tapayadot/checkout';

      const tapaya = new Tapaya();
      const current = await tapaya.checkout.sessions.get(order.checkoutSessionId);
      ```
    </CodeBlockTab>
  </CodeBlockTabs>

  Với cả hai cách tích hợp, hãy so sánh kết quả với đơn hàng đã lưu trước khi hoàn tất đơn hàng:

  ```ts
  const matches =
    current.id === order.checkoutSessionId &&
    current.merchantOrderId === order.id &&
    current.amount === order.totalInMinorUnits &&
    current.currency === order.currency;

  if (matches && current.paymentStatus === 'successful') {
    await fulfillOnce(order); // idempotent, safe on repeated visits
  }
  ```

  Nếu trạng thái vẫn là `unpaid` hoặc việc truy xuất thất bại, hãy giữ ID phiên và kiểm tra lại. Hiện chưa có webhook, vì vậy hãy chạy một tác vụ đối soát cho những khách hàng đóng tab trước khi quay lại.
</div>

## Vận hành chính thức [#go-live]

1. Hoàn tất [onboarding merchant](/merchants/onboarding) trên production với thanh toán trực tuyến, hoặc cả thanh toán trực tuyến lẫn thanh toán tại cửa hàng. Cung cấp website của cửa hàng và thông tin kinh doanh trực tuyến. Một merchant đã có thanh toán tại cửa hàng vẫn cần được đơn vị xử lý thanh toán trực tuyến phê duyệt.

2. Kiểm tra rằng merchant ở trạng thái **Ready** trong [Cài đặt Checkout](/online/integration/checkout_settings). Điều này yêu cầu merchant đang hoạt động, được đơn vị xử lý thanh toán trực tuyến phê duyệt và có cổng thanh toán chính thức đã được cấu hình.

3. Tạo checkout key production của merchant, hoặc dùng Secret key production của tổ chức cùng với merchant token. Giữ thông tin xác thực chính thức trên máy chủ của bạn.

4. Đặt origin API và môi trường production. Thay thế cấu hình sandbox trong bản triển khai của bạn:

   ```bash title="Production server configuration"
   TAPAYA_ENVIRONMENT=production
   TAPAYA_CHECKOUT_API_URL=https://api.tapaya.com
   TAPAYA_SECRET_KEY=tapaya_live_...
   ```

   Các ví dụ HTTP dùng `TAPAYA_CHECKOUT_API_KEY`; hãy đặt cả biến này thành key chính thức của bạn. Dùng URL của phiên đúng như được trả về. Các trang Hosted Checkout trên production mở tại `https://checkout.tapaya.com`.

5. Cấu hình các URL trả về production cho Hosted Checkout. Với Apple Pay nhúng, hãy đăng ký từng tên miền cửa hàng và lưu trữ tệp xác minh của tên miền đó. Google Pay ở chế độ chính thức yêu cầu đã cấu hình Google Pay merchant ID.

6. Hoàn tất [Danh sách kiểm tra QA](/online/getting-started/checklist), bao gồm việc xác minh trên máy chủ và tác vụ production kiểm tra các khoản thanh toán chưa xác định kết quả. Dùng phương thức thanh toán thật trên production. Thẻ thử nghiệm sandbox chỉ dành cho sandbox.

## Bước tiếp theo [#next-steps]

<Cards>
  <Card title="Kiểm thử" href="/online/getting-started/testing" description="Thẻ thử nghiệm cho các trường hợp thành công, bị từ chối và 3-D Secure trên cổng thanh toán sandbox." />

  <Card title="Hosted Checkout" href="/online/integration/hosted_checkout" description="Hướng dẫn đầy đủ cho máy chủ, kèm cách xử lý lỗi và thử lại cho từng phương án." />

  <Card title="Node.js SDK" href="/online/integration/node_sdk" description="Tùy chọn client, phương thức phiên, thử lại và lỗi có kiểu." />

  <Card title="Tích hợp API" href="/online/integration/api_integration" description="Các mặt hàng, chi tiết thuế, thông tin khách hàng và mọi trạng thái phiên." />

  <Card title="Cài đặt Checkout" href="/online/integration/checkout_settings" description="Ví, thương hiệu và đích trả về trong Tapaya Platform." />

  <Card title="Embedded Checkout" href="/online/integration/embedded_checkout" description="Gắn các trường nhập thẻ bảo mật vào trang thanh toán của riêng bạn và gửi thanh toán từ nút thanh toán của riêng bạn." />
</Cards>
