Ví dụ tích hợp với PayPal
Trong bài hướng dẫn này, chúng tôi sẽ chỉ cho bạn cách tích hợp PayPal và xem xét các node mới.
1. Theo dõi sự kiện tạo đơn hàng
1.1. Sự kiện "đơn hàng đã được tạo" trong module "Events".
Để theo dõi các sự kiện trong module "Integrations", hãy tạo một sự kiện trong module "Events".
Chi tiết về block Events được mô tả ở đây.
1.2. Theo dõi sự kiện tạo đơn hàng.
- Kéo node "events" vào không gian làm việc.
- Thay đổi giá trị trong trường "Set" thành "orderEvent".
- Sự kiện sẽ được lưu trong đối tượng "msg.orderEvent" và có thể được sử dụng trong các node khác.
- Chọn sự kiện "đơn hàng đã được tạo" từ danh sách và nhấn "submit".
Trong ví dụ này, chúng tôi đăng ký sự kiện tạo đơn hàng và lưu sự kiện vào "msg.orderEvent" để sử dụng sau này.
Chi tiết về node Events có thể được tìm thấy ở đây.
2. Tạo phiên thanh toán
2.1. Tạo tài khoản thanh toán
Trước khi bắt đầu tích hợp, hãy tạo một tài khoản tùy chỉnh cho PayPal.
Cách thực hiện điều này được mô tả ở đây.
2.2. Tạo phiên thanh toán
- Kéo node "admin-api" vào không gian làm việc và kết nối với node từ bước trước.
- Chọn phương thức "Creating a payment session" và dán mã từ mô tả dưới đây vào trường "Request body".
{
"orderId": {{orderEvent.order.id}},
"type": "session"
}
Ở đây, chúng tôi trích xuất ID đơn hàng từ đối tượng "msg.orderEvent" và tạo yêu cầu để tạo phiên thanh toán. Yêu cầu tạo phiên nhận các tham số: "orderId" - ID và "type" - loại phiên thanh toán (session hoặc intent).
Chi tiết về node admin-api có thể được tìm thấy ở đây.
2.3. Đặt ID nhận được vào msg.paymentSessionId
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Ở đây, chúng tôi đặt ID phiên thanh toán vào "msg.paymentSessionId", ID này được nhận từ việc thực hiện node trước đó.
msg.paymentSessionId = msg.payload.id
return msg
Chi tiết về node Function có thể được tìm thấy ở đây.
3. Xác thực với PayPal
3.1. Đặt tham số cho xác thực với PayPal
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Ở đây, chúng tôi đặt giá trị vào các trường "payload" và "headers" của đối tượng "msg". Những giá trị này cần thiết cho việc thực hiện node tiếp theo.
// đặt thân yêu cầu
msg.payload = {
grant_type: 'client_credentials',
}
// đặt tiêu đề
msg.headers = {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
}
return msg
Chi tiết về các tham số cho thanh toán có thể được tìm thấy trong tài liệu của PayPal
Chi tiết về node Function có thể được tìm thấy ở đây.
3.2. Yêu cầu nhận access token
- Kéo node "http request" vào không gian làm việc và kết nối với node từ bước trước.
- Chọn phương thức "POST" trong trường Method.
- Chọn "Send as request body" trong trường Data.
- Dán liên kết
https://api-m.sandbox.paypal.com/v1/oauth2/tokenvào trường Link. - Chọn "Object JSON" trong trường Return.
- Chọn "Use Authentication".
- Nhập client ID của bạn vào trường "Username" và client secret của bạn cho PayPal vào trường "Password".
Yêu cầu này cần thiết để nhận "access_token".
Chi tiết về xác thực có thể được tìm thấy trong tài liệu của PayPal
Chi tiết về node http request có thể được tìm thấy ở đây.
3.3. Đặt tham số để tạo liên kết thanh toán
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Trong ví dụ này, chúng tôi tạo yêu cầu để tạo liên kết thanh toán dựa trên dữ liệu từ các node trước.
// access_token cho paypal, nhận được từ node "paypal auth"
const accessToken = msg.payload.access_token
// dữ liệu đơn hàng, nhận được từ node "đơn hàng đã được tạo"
// đối tượng order tương ứng với đơn hàng từ api orders https://oneentry.cloud/instructions/api
const order = msg.orderEvent.order
// ID phiên thanh toán, nhận được từ node "tạo phiên thanh toán"
const paymentSessionId = msg.paymentSessionId
// tạo dữ liệu cho paypal dựa trên dữ liệu đơn hàng
const items = order.products.map((product) => {
return {
name: product.title,
description: 'mô tả của bạn',
quantity: String(product.quantity),
unit_amount: {
currency_code: order.currency,
value: product.price,
},
}
})
const totalSum = parseFloat(order.totalSum)
const data = {
intent: 'CAPTURE',
purchase_units: [
{
items,
custom_id: String(paymentSessionId),
amount: {
currency_code: order.currency,
value: totalSum,
breakdown: {
item_total: {
currency_code: order.currency,
value: totalSum,
},
},
},
payment_instruction: {
billingId: String(order.id),
},
},
],
payment_source: {
paypal: {
experience_context: {
payment_method_preference: 'UNRESTRICTED',
payment_method_selected: 'PAYPAL',
brand_name: 'EXAMPLE INC',
locale: 'en-US',
landing_page: 'LOGIN',
shipping_preference: 'NO_SHIPPING',
user_action: 'PAY_NOW',
return_url: 'https://example.com/return',
cancel_url: 'https://example.com/cancel',
},
},
},
}
// Thân yêu cầu
msg.payload = data
// Tiêu đề yêu cầu
msg.headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
Prefer: 'return=representation',
}
return msg
Chi tiết có thể được tìm thấy trong tài liệu của PayPal
Chi tiết về node Function có thể được tìm thấy ở đây.
4. Tạo liên kết thanh toán
Trong ví dụ này, node "http request" được sử dụng. Nó có thể được sử dụng để thực hiện các yêu cầu http.
- Kéo node "http request" vào không gian làm việc và kết nối với node từ bước trước.
- Chọn phương thức "POST" trong trường Method.
- Chọn "Send as request body" trong trường Data.
- Dán liên kết
https://api-m.sandbox.paypal.com/v2/checkout/ordersvào trường Link. - Chọn "Object JSON" trong trường Return.
Trong ví dụ này, chúng tôi đã thực hiện yêu cầu đến PayPal để tạo liên kết thanh toán với dữ liệu từ node trước.
Chi tiết có thể được tìm thấy trong tài liệu của PayPal
Chi tiết về node http request có thể được tìm thấy ở đây.
5. Cập nhật phiên thanh toán
- Kéo node "admin-api" vào không gian làm việc và kết nối với node từ bước trước.
- Chọn phương thức "Payment session update".
- Dán mã từ mô tả dưới đây vào trường "Query parameters".
{
"id": {{paymentSessionId}}
}
- Dán mã từ mô tả dưới đây vào trường "Request body".
{
"paymentUrl": "{{{payload.links.1.href}}}"
}
Ở đây, chúng tôi trích xuất ID liên kết thanh toán "msg.paymentSessionId" và liên kết thanh toán "msg.payload.links[0].href" từ các yêu cầu trước.
Chi tiết về các giá trị trả về có thể được tìm thấy trong tài liệu của PayPal
Chi tiết về node admin-api có thể được tìm thấy ở đây.
6. Thêm endpoint để nhận liên kết thanh toán
6.1. Đặt topic "createPaymentLink"
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Điều này cần thiết để xác định luồng hiện tại.
msg.topic = 'createPaymentLink'
return msg
Chi tiết về node Function có thể được tìm thấy ở đây.
6.2. Tạo endpoint để nhận liên kết thanh toán
- Kéo node "http in" vào không gian làm việc.
- Chọn phương thức "POST".
- Nhập liên kết
/get-payment-link.
Endpoint này sẽ cần thiết để nhận liên kết thanh toán hiện tại.
Chi tiết về node http in có thể được tìm thấy ở đây.
6.3. Đặt topic "getPaymentLink"
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Điều này cần thiết để xác định luồng hiện tại.
msg.topic = 'getPaymentLink'
return msg
Chi tiết về node Function có thể được tìm thấy ở đây.
6.4. Lưu dữ liệu vào ngữ cảnh
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Điều này cần thiết để tạo phản hồi.
// lấy ID đơn hàng hiện tại
const orderId = msg.payload.orderId
// khóa ngữ cảnh hiện tại
const contextKey = `payment_link_${orderId}`
// lấy api OneEntry
const api = global.get('api')
// dữ liệu ngữ cảnh hiện tại
const contextData = flow.get(contextKey) || {}
// đặt dữ liệu vào ngữ cảnh theo topic
if (msg.topic === 'createPaymentLink') {
contextData.paymentSessionId = msg.paymentSessionId
contextData.createPaymentLinkCompleted = true
}
if (msg.topic === 'getPaymentLink') {
contextData.getPaymentLinkCompleted = true
contextData.res = msg.res
}
// đặt dữ liệu ngữ cảnh vào ngữ cảnh
flow.set(contextKey, contextData)
// nếu createPaymentLink và getPaymentLink hoàn thành, gửi phản hồi với phiên hiện tại
if (
contextData.createPaymentLinkCompleted &&
contextData.getPaymentLinkCompleted
) {
// lấy phiên thanh toán theo ID từ api
const paymentSession = await api.getPaymentSessionById({
id: contextData.paymentSessionId,
})
msg.payload = paymentSession
msg.res = contextData.res
// xóa api
flow.set(contextKey, null)
return msg
}
return null
Chi tiết về node Function có thể được tìm thấy ở đây.
6.5. Điểm đầu ra cho liên kết thanh toán
- Kéo node "http response" vào không gian làm việc và kết nối với node từ bước trước.
Điều này cần thiết để xuất phản hồi cho yêu cầu.
Chi tiết về node http response có thể được tìm thấy ở đây.
7. Cấu hình webhook cho PayPal
7.1. Điểm đầu vào cho PayPal
- Kéo node "http in" vào không gian làm việc.
- Chọn phương thức "POST".
- Nhập liên kết
/paypal.
Endpoint này sẽ cần thiết để cập nhật trạng thái thanh toán qua PayPal.
Chi tiết về node http in có thể được tìm thấy ở đây.
7.2. Phản h ồi cho yêu cầu
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Điều này cần thiết để tạo phản hồi.
msg.payload = {
ok: true,
}
return msg
Chi tiết về node function có thể được tìm thấy ở đây.
7.3. Điểm đầu ra cho PayPal
- Kéo node "http response" vào không gian làm việc và kết nối với node từ bước trước.
Node này cần thiết để xuất phản hồi cho yêu cầu.
Chi tiết về node http response có thể được tìm thấy ở đây.
7.4. Nhận trạng thái thanh toán
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Trong node này, chúng tôi lấy giá trị nhận được từ node "paypal webhook" và ghi nó vào "msg.status" để sử dụng trong node tiếp theo.
msg.status = msg.payload.resource.status
return msg
Chi tiết về node Function có thể được tìm thấy ở đây.
7.5. Kiểm tra trạng thái thanh toán
- Kéo node "switch" vào không gian làm việc và kết nối với node từ bước trước.
- Trong "Property", nhập giá trị "status".
- Thêm quy tắc đầu tiên để kiểm tra. Chọn điều kiện "==", nhập giá trị "APPROVED".
- Thêm quy tắc thứ hai để kiểm tra. Chọn điều kiện "else".
Node này sẽ kiểm tra giá trị từ "msg.status" theo các quy tắc đã đặt. Nếu giá trị bằng "APPROVED", các node từ nhánh đầu tiên sẽ được thực hiện, nếu không thì từ nhánh thứ hai.
Chi tiết về node switch có thể được tìm thấy ở đây.
7.6. Nhận ID phiên thanh toán
- Kéo node "function" vào không gian làm việc và kết nối với node từ bước trước.
- Dán mã từ ví dụ vào trường "Function".
Trong node này, chúng tôi lấy ID phiên thanh toán mà chúng tôi đã lưu trong node "set payment data".
msg.paymentSessionId = parseInt(
msg.payload.resource.purchase_units[0].custom_id,
10
)
return msg
Chi tiết về các giá trị trả về có thể được tìm thấy trong tài liệu của PayPal
Chi tiết về node Function có thể được tìm thấy ở đây.
7.7. Cập nhật trạng thái thanh toán
- Kéo node "admin-api" vào không gian làm việc và kết nối với node từ bước trước.
- Chọn phương thức "Payment session update".
- Dán mã từ mô tả dưới đây vào trường "Query parameters".
{
"id": {{paymentSessionId}}
}
- Dán mã từ mô tả dưới đây vào trường "Request body".
{
"status": "completed"
}
Ở đây, chúng tôi cập nhật trạng thái thanh toán theo ID từ "msg.paymentSessionId".
Chi tiết về node admin-api có thể được tìm thấy ở đây.
7.8. Thêm webhook trong tài khoản PayPal của bạn
Liên kết đến dự án của bạn + /api/admin/workflows/endpoints/paypal
Ví dụ:
https://<dự-án-của-bạn>.oneentry.cloud/api/admin/workflows/endpoints/paypal
Chi tiết có thể được tìm thấy trong tài liệu của PayPal
8. Kiểm tra tích hợp
8.1. Tạo đơn hàng


Cách tạo đơn hàng được mô tả trong tài liệu API
8.2. Nhận liên kết thanh toán

-
Thực hiện yêu cầu POST đến
https://<dự-án-của-bạn>.oneentry.cloud/api/admin/workflows/endpoints/get-payment-link, thay thếhttps://<dự-án-của-bạn>.oneentry.cloudbằng liên kết đến dự án của bạn. -
Trong thân yêu cầu, hãy chỉ định ID của đơn hàng đã tạo trước đó:
{
"orderId": 15
}
8.3. Thanh toán cho đơn hàng

8.4. Kiểm tra trạng thái đơn hàng
