Пример интеграции с PayPal
В этом обучающем уроке мы покажем как интегрировать PayPal и рассмотрим новые ноды
1. Отслеживание события создания заказа
1.1. Событие "order created" в модуле "Events".
Для отслеживания событий в модуле "Integrations" создайте событие в модуле "Events"
Подробно блок Events описан здесь.
1.2. Отслеживание события создания заказа.
- Перетащите ноду "events" на рабочую область.
- Измените значение в поле "Set" на "orderEvent".
- Событие сохраниться в объекте "msg.orderEvent" и его можно будет использовать в других нодах.
- Выберите из списка созданное событие "order created" и нажмите "submit"
В данном примере мы подписываемся на событие создание заказа и сохраняем событие в "msg.orderEvent" для использования в дальнейшем.
Подробно о ноде Events можно узнать здесь.
2. Создание платёжной сессии
2.1. Создайте платёжный аккаунт
Перед началом интеграции создайте кастомный аккаунт для paypal
О том как это сделать описано здесь.
2.2. Создайте платёжную сессию
- Перетащите ноду "api" на рабочую область и соедините с нодой из предыдущего шага.
- Выберите метод "Create Payment Session" и вставьте код из описания ниже в поле "Data".
Здесь мы извлекаем идентификатор заказа из объекта "msg.orderEvent" и формируем запрос на создание платёжной сессии.
Запрос на создание сессии принимает на вход пераметры: "orderId" - идентификатор и "type" - тип платёжной сессии (session
или intent
).
{ "orderId": {{orderEvent.order.id}}, "type": "session" }
Подробно о ноде API можно узнать здесь.
2.3. Установите полученный идентификатор в msg.paymentSessionId
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
Здесь мы устанавливаем в "msg.paymentSessionId" идентификатор платёжной сессии, полученный в результате выполнения предыдущей ноды.
msg.paymentSessionId = msg.payload.id
return msg
Подробно о ноде Function можно узнать здесь.
3. Аутентификация в PayPal
3.1. Установите параметры для аутентификации в paypal
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
Здесь мы устанавливаем значение в поля "payload" и "headers" объекта "msg". Данные значение нужны для выполнения следующей ноды.
// устанавливаем тело запроса
msg.payload = {
grant_type: 'client_credentials',
}
// устанавливаем заголовки
msg.headers = {
'Content-Type': 'application/x-www-form-urlencoded',
Accept: 'application/json',
}
return msg
Подробнее о параметрах для оплаты можно узнать в документации PayPal
Подробно о ноде Function можно узнать здесь.
3.2. Запрос на получение access token
- Перетащите ноду "http request" на рабочую область и соедините с нодой из предыдущего шага.
- Выберите в поле Method вариант "POST".
- Выберите в поле Data вариант "Send as request body".
- Вставьте в поле Link ссылку
https://api-m.sandbox.paypal.com/v1/oauth2/token
. - Выберите в поле Return вариант "Object JSON".
- Выберите "Use Authentication".
- В поле "Username" введите ваш client ID, а в поле "Password" ваш client secret для PayPal.
Данный запрос нужен для получения "access_token".
Подробнее об аутентификации можно узнать в документации PayPal
Подробно о ноде http request можно узнать здесь.
3.3. Установите параметры для создания ссылки на оплату
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
В данном примере формируется запрос на создание ссылки на оплату на основе данных из предыдущих нод.
// access_token для paypal, полученный в ноде "paypal auth"
const accessToken = msg.payload.access_token
// данных заказы, полученые в ноде "order created"
// объект order соответствует заказу из orders api https://oneentry.cloud/instructions/api
const order = msg.orderEvent.order
// идентификатор платёжной сессии, полученные в ноде "create payment session"
const paymentSessionId = msg.paymentSessionId
// формируем данные для paypal на основе данных заказа
const items = order.products.map((product) => {
return {
name: product.title,
description: 'your description',
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',
},
},
},
}
// Тело запроса
msg.payload = data
// Заголовки запроса
msg.headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`,
Prefer: 'return=representation',
}
return msg
Подробнее можно узнать в документации PayPal
Подробно о ноде Function можно узнать здесь.
4. Создание ссылки на оплату
В данном примере используется нода "http request". Её можно использовать для совершения http запросов.
- Перетащите ноду "http request" на рабочую область и соедините с нодой из предыдущего шага.
- Выберите в поле Method вариант "POST".
- Выберите в поле Data вариант "Send as request body".
- Вставьте в поле Link ссылку
https://api-m.sandbox.paypal.com/v2/checkout/orders
. - Выберите в поле Return вариант "Object JSON".
В данном примере мы сделали запрос к PayPal на формирование ссылки на оплату с данным из предыдущей ноды.
Подробнее можно узнать в документации PayPal
Подробно о ноде http request можно узнать здесь.
5. Обновление платёжной сессии
- Перетащите ноду "api" на рабочую область и соедините с нодой из предыдущего шага.
- Выберите метод "Update Payment Session" и вставьте код из описания ниже в поле "Data".
Здесь мы извлекаем идентификатор платёжной ссылки "msg.paymentSessionId" и ссылку на оплату "msg.payload.links[0].href" из предыщих запросов.
{ "id": {{paymentSessionId}}, "paymentUrl": "{{{payload.links.1.href}}}" }
Подробнее о возвращаемых значениях можно узнать в документации PayPal
Подробно о ноде API можно узнать здесь.
6. Добавление endpoint для получения ссылки на оплату
6.1. Установите топик "createPaymentLink"
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
Это нужно для идентификации текущего потока.
msg.topic = 'createPaymentLink'
return msg
Подробно о ноде Function можно узнать здесь.
6.2. Создайте конечную точку для получения ссылки на оплату
- Перетащите ноду "http in" на рабочую область.
- Выберите метод "POST"
- Введите ссылку
/get-payment-link
Данная конечная точка нужна будет для получения актуальной ссылки на оплату
Подробно о ноде http in можно узнать здесь.
6.3. Установите топик "getPaymentLink"
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
Это нужно для идентификации текущего потока.
msg.topic = 'getPaymentLink'
return msg
Подробно о ноде Function можно узнать здесь.
6.4. Сохраните данные в контексте
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
Это нужно для формирования ответа.
// get current order id
const orderId = msg.payload.orderId
// current context key
const contextKey = `payment_link_${orderId}`
// get OneEntry api
const api = global.get('api')
// current context data
const contextData = flow.get(contextKey) || {}
// set data to context by topic
if (msg.topic === 'createPaymentLink') {
contextData.paymentSessionId = msg.paymentSessionId
contextData.createPaymentLinkCompleted = true
}
if (msg.topic === 'getPaymentLink') {
contextData.getPaymentLinkCompleted = true
contextData.res = msg.res
}
// set context data to context
flow.set(contextKey, contextData)
// if createPaymentLink and getPaymentLink completed, send response with current session
if (
contextData.createPaymentLinkCompleted &&
contextData.getPaymentLinkCompleted
) {
// get payment session by id from api
const paymentSession = await api.getPaymentSessionById({
id: contextData.paymentSessionId,
})
msg.payload = paymentSession
msg.res = contextData.res
// clear api
flow.set(contextKey, null)
return msg
}
return null
Подробно о ноде Function можно узнать здесь.
6.5. Выходная точка для ссылки на оплату
- Перетащите ноду "http response" на рабочую область и соедините с нодой из предыдущего шага.
Это нужно для вывода ответа на запрос
Подробно о ноде http response можно узнать здесь.
7. Настройка вебхуков для PayPal
7.1. Входная точки для paypal
- Перетащите ноду "http in" на рабочую область.
- Выберите метод "POST"
- Введите ссылку
/paypal
Данная конечная точка нужна будет для обновления статуса оплаты через PayPal
Подробно о ноде http in можно узнать здесь.
7.2. Ответ на запрос
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
Это нужно для формирования ответа.
msg.payload = {
ok: true,
}
return msg
Подробно о ноде function можно узнать здесь.
7.3. Выходная точка для paypal
- Перетащите ноду "http response" на рабочую область и соедините с нодой из предыдущего шага.
Эта нода нужна для вывода ответа на запрос
Подробно о ноде http response можно узнать здесь.
7.4. Получение статуса оплаты
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
В данной ноде мы берём значение, полученное из ноды "paypal webhook" и записываем его в "msg.status", чтобы использовать в следующей ноде.
msg.status = msg.payload.resource.status
return msg
Подробно о ноде Function можно узнать здесь.
7.5. Проверка статуса оплаты
- Перетащите ноду "swith" на рабочую область и соедините с нодой из предыдущего шага.
- В "Property" пропишите значение "status"
- Добавьте первое правило для проверки. Выберите условие "==", в значении введите "APPROVED"
- Добавьте второе правило для проверки. Выберите условие "else".
Данная нода будет проверять значение из "msg.status" на соответвие заданным правилам. Если значение равно "APPROVED", то будут выполняться ноды из первой ветки, иначе из второй
Подробно о ноде switch можно узнать здесь.
7.6. Получение идентификатора платёжной сессии
- Перетащите ноду "function" на рабочую область и соедините с нодой из предыдущего шага.
- Вставьте код из примера в поле "Function".
В данной ноде мы берём идентификатор платёжной сессии, который сохранили в ноде "set payment data".
msg.paymentSessionId = parseInt(
msg.payload.resource.purchase_units[0].custom_id,
10
)
return msg
Подробнее о возвращаемых значениях в документации PayPal
Подробно о ноде Function можно узнать здесь.
7.7. Обновление статус оплаты
- Перетащите ноду "api" на рабочую область и соедините с нодой из предыдущего шага.
- Выберите метод "Update Payment Session" и вставьте код из описания ниже в поле "Data".
Здесь мы обновляем статус платежа по его идентификатору из "msg.paymentSessionId".
{ "id": {{paymentSessionId}}, "status": "completed" }
Подробно о ноде api можно узнать здесь.
7. Добавьте webhook в личном кабинете paypal
Ссылка на ваш проект + /api/admin/workflows/endpoints/paypal
Пример:
https://integrations-study.oneentry.cloud/api/admin/workflows/endpoints/paypal
Подробнее можно узнать в документации PayPal
8. Проверка интеграции
8.1. Создайте заказ
О том как создать создать заказ описано в API документации
8.2. Получите ссылку на оплату
-
Выполните POST запрос к
https://integrations-study.oneentry.cloud/api/admin/workflows/endpoints/get-payment-link
, вместоhttps://integrations-study.oneentry.cloud
подставьте ссылку на ваш проект -
В теле запроса укажите идентификатор созданного ранее заказа:
{
"orderId": 15
}
8.3. Оплатите заказ
8.4. Проверьте статус заказа