Как справиться с выплатами по рапиде с помощью FX

Аллан Макгрегор
Фото Аль Амин Шамим

В современных условиях удаленной работы все чаще приходится работать с иностранными сотрудниками, поставщиками и подрядчиками. Работа с выплатами в иностранной валюте может быть довольно сложной и усложнить бизнес, поскольку может потребовать учета курсов конвертации или работы с несколькими платежными процессорами.

К счастью, с помощью Rapyd Payouts with FX вы можете легко обрабатывать выплаты иностранным сотрудникам и поставщикам без высоких комиссий и валютных сборов.

Принятие программного решения для обработки выплат в иностранной валюте может помочь в следующих сценариях:

  • Автоматические выплаты международным сотрудникам в разных валютах.
  • Определение курса иностранной валюты (FX) перед осуществлением выплаты.
  • Оптимизация коэффициентов конвертации для различных валют.
  • Обработка массовых выплат в рамках одной операции.

В этой статье показано, как построить простое приложение, использующее Rapyd Payouts с иностранными валютами, и проиллюстрирован поток данных для создания и обработки платежа в иностранной валюте.

Что такое Rapyd Payouts с FX?

Rapyd Disburse — это глобальная платформа выплат с поддержкой более ста стран и широкого спектра методов выплат, включая:

  • банковские переводы
  • электронные кошельки
  • Карты
  • наличные

Rapyd Disburse, доступная в виде API и веб-интерфейса, позволяет торговцам, разработчикам и другим поставщикам услуг создавать и управлять выплатами простым и интуитивно понятным способом.

Различные сценарии могут потребовать от вас выплат в иностранной валюте, включая следующие примеры:

  • Работа с международными сотрудниками из разных стран, которые хотят получать зарплату в своей национальной валюте.
  • Оплата напрямую международным поставщикам.
  • Покупка цифровых товаров на международных торговых площадках.

Ниже приводится высокоуровневая иллюстрация рабочего процесса, который вы будете реализовывать с помощью этого руководства.

Необходимые условия для данного учебника

Для этого учебника вам нужно убедиться, что у вас есть хорошо функционирующая среда Elixir; самый простой способ сделать это — следовать инструкциям по установке Elixir, которые дадут вам несколько вариантов:

  • Локальная установка на Linux, Windows и macOS.
  • Dockerized версии Elixir.
  • Настройки версий менеджера пакетов.

Для данного руководства рекомендуется локальная установка, так как это самый простой способ начать работу. Кроме того, вам понадобится локально установленный npm и работающая версия PostgreSQL.

NPM

Установите Node.js. Обратите внимание, что в вашей системе он может быть предустановлен.

PostgreSQL

PostgreSQL может быть немного сложным в установке в зависимости от используемой операционной системы. В этом учебнике вы можете использовать Docker и запустить локальную версию, выполнив следующие действия:

  1. Создайте папку для хранения данных БД:
> mkdir ${HOME}/phoenix-postgres-data/
Войдите в полноэкранный режим Выйти из полноэкранного режима
  1. Запустите контейнер Docker с образом PostgreSQL:
$ docker run -d 
    --name phoenix-psql 
    -e POSTGRES_PASSWORD=Phoenix1234 
    -v ${HOME}/phoenix-postgres-data/:/var/lib/postgresql/data 
    -p 5432:5432 
    postgres
Войти в полноэкранный режим Выйти из полноэкранного режима
  1. Убедитесь, что контейнер запущен:
> docker ps

CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS        PORTS                                  NAMES
11cbe1d2bc2f   postgres   "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds  5432/tcp, 0.0.0.0:5432->5432/tcp       phoenix-psql
I can
that was
Войти в полноэкранный режим Выйти из полноэкранного режима
  1. Убедитесь, что PostgreSQL запущен и работает:
> docker exec -it phoenix-psql bash

root@11cbe1d2bc2f:/# psql -h localhost -U postgres

psql (13.2 (Debian 13.2-1.pgdg100+1))
Type "help" for help.

postgres=# l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges   
-----------+----------+----------+------------+------------+-----------------------
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 | ...

Войти в полноэкранный режим Выйти из полноэкранного режима

Установка Phoenix

Теперь, когда у вас есть необходимые зависимости, вы можете установить генератор приложений Phoenix и создать свое первое приложение Phoenix. Генератор Phoenix распространяется в виде архива mix и может быть установлен путем выполнения следующей команды:

> mix archive. install hex phx_new 1.5.8
Войти в полноэкранный режим Выйти из полноэкранного режима

Реализация выплат Rapyd с помощью FX

Наряду с ранее упомянутыми предварительными условиями, вам также потребуется учетная запись Rapyd и локальная копия репозитория проекта Rapyd FX.

Получение API-ключа и настройка авторизации запросов

Прежде чем приступить к созданию страницы оформления заказа, вам необходимо получить API-ключ от Rapyd. Этот API-ключ будет использоваться для создания ваших заголовков авторизации, добавляемых к каждому API-запросу.

Из учетной записи песочницы, которую вы создали на клиентском портале Rapyd, получите секретный ключ и ключ доступа. Доступ к этому разделу можно получить, нажав кнопку Developers в навигации слева.

Каждый запрос к API Rapyd требует следующих заголовков:

  • access_key: Ключ доступа, сгенерированный при создании аккаунта Rapyd.
  • content_type: Тип содержимого запроса. Это всегда application/json.
  • salt (соль): Случайная строка, используемая для создания подписи.
  • подпись: Генерируемое значение для каждого запроса.
  • временная метка: Текущее время в миллисекундах.

Заголовок подписи должен генерироваться для каждого запроса к API Rapyd; без этого заголовка невозможно проверить подлинность запроса, и он обязательно будет отклонен. В рамках вашей реализации вы должны будете вычислить подпись и добавить ее в заголовки запроса.

Подпись вычисляется по следующей формуле:

signature = BASE64 ( HASH ( http_method + url_path + salt + timestamp + access_key + secret_key + body_string ) )

Образец приложения предоставляет пример конечной точки для проверки ключа и подписи API. Давайте посмотрим, что произойдет, если у вас не настроен ключ или подпись.

Убедитесь, что приложение запущено, и посетите localhost:4000/testing; когда вы нажмете на кнопку, вы должны увидеть следующий ответ.

Давайте посмотрим на код контроллера в /lib/rapyd_fx_example_web/controllers/testing_controller.ex:

  def index(conn, _params) do
    response = HTTPoison.get! "https://sandboxapi.rapyd.net/v1/data/countries"
    response = response.body |> Jason.decode!
    render(conn, "index.html", response: response)
  end
Вход в полноэкранный режим Выход из полноэкранного режима

Запрос завершился неудачно, поскольку полностью отсутствуют заголовки аутентификации. Вы можете рефакторить код приложения для обработки подписи запроса. Сначала обновите config/dev.exs и добавьте следующий блок кода:

config :rapyd_fx_example,
  rapyd_access_key: "YOUR_ACCESS_KEY",
  rapyd_secret_key: "YOUR_SECRET_KEY"
Вход в полноэкранный режим Выйти из полноэкранного режима

Затем замените значения на ваши API-ключ и секретный ключ с клиентского портала Rapyd.

Далее рефакторим контроллер index, чтобы учесть заголовки:

  def index(conn, _params) do
    # Define the base url and target path
    base_url = "https://sandboxapi.rapyd.net"
    url_path = "/v1/data/countries"

    # Generate the values needed for the headers
    access_key = Application.fetch_env!(:rapyd_fx_example, :rapyd_access_key)
    salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
    timestamp = System.os_time(:second)
    signature = sign_request("get", url_path, salt, timestamp, access_key, "")

    # Build the headers
    headers = [
      {"access_key", access_key},
      {"salt", salt},
      {"timestamp", timestamp},
      {"url_path", url_path},
      {"signature", signature}
    ]

    response = HTTPoison.get!(base_url <> url_path, headers)
    response = response.body |> Jason.decode!()
    render(conn, "index.html", response: response)
  end
Войти в полноэкранный режим Выход из полноэкранного режима

Как вы можете видеть, все, что вы сделали, это добавили заголовки в запрос. Что еще более важно, следующий код генерирует подпись:

  def sign_request(http_method, url_path, salt, timestamp, access_key, body) do
    secret_key = Application.fetch_env!(:rapyd_fx_example, :rapyd_secret_key)

    cond do
      body == "" ->
        body = ""
      true ->
        {:ok, body} = body |> Jason.encode()
    end

    signature_string =
      [http_method, url_path, salt, timestamp, access_key, secret_key, body] |> Enum.join("")

    :crypto.mac(:hmac, :sha256, secret_key, signature_string)
    |> Base.encode16(case: :lower)
    |> Base.encode64()
  end
Войти в полноэкранный режим Выйти из полноэкранного режима

Этот функционал принимает следующие параметры:

  • http_method: Метод HTTP, используемый в запросе.
  • url_path: Путь запроса.
  • salt (соль): Случайная строка, используемая для генерации подписи.
  • временная метка: Текущее время в миллисекундах.
  • access_key: Ключ доступа, сгенерированный при создании учетной записи Rapyd.
  • secret_key: Секретный ключ, сгенерированный при создании учетной записи Rapyd.
  • body: Тело запроса.

Для генерации подписи вам следует убедиться, что вы кодируете тело запроса с помощью Base64, так как в противном случае это может привести к несоответствию между сгенерированной подписью и проверкой на стороне Rapyd API.

Теперь вы должны иметь возможность сделать запрос к API и увидеть ответ. В данном случае это список всех стран, поддерживаемых Rapyd.

Создание электронного кошелька и бенефициара

Прежде чем приступить к реализации потока выплат, вам необходимо создать следующее:

  • Электронный кошелек, который будет являться счетом, используемым для осуществления выплат.
  • Бенефициара — счет, на который будут перечислены средства.

Кошелек Rapyd

Rapyd Wallet — это цифровой кошелек, используемый для получения, хранения и отправки денег. Rapyd Wallet может содержать один или несколько счетов, каждый со своей валютой и балансом.

Вы можете создать тестовый кошелек из панели инструментов песочницы. Для начала войдите в панель Rapyd и убедитесь, что аккаунт находится в режиме песочницы.

Затем перейдите в раздел управления кошельком, перейдя в Wallets > Accounts.

Далее нажмите на кнопку Создать кошелек и в модальном окне выберите Личный кошелек.

В диалоговом окне «Создание личного кошелька» обязательно заполните всю информацию и не стесняйтесь использовать поддельные данные, если это необходимо.

После этого вы должны получить уведомление, подтверждающее успешное создание кошелька и отображающее его ID.

Теперь, когда ваш кошелек создан, вам нужно добавить некоторые средства. Нажмите на ссылку «Просмотр сведений» на только что созданном кошельке, прокрутите страницу до раздела «Виртуальный счет» и нажмите «Создать виртуальный счет».

Затем нажмите на новом виртуальном счете Simulate Bank Transfer.

Если все прошло успешно, вы должны увидеть вновь созданный кошелек в списке кошельков. Запомните идентификатор кошелька, так как вы будете использовать его в запросе на выплату.

Получатель

Аналогичным образом вам нужно будет создать учетную запись бенефициара. Бенефициар — это получатель, который будет получать вашу выплату.

Начните с создания нового контроллера и соответствующих представлений с помощью следующей команды:

mix phx.gen.html Rapyd Beneficiary beneficiaries first_name:string last_name:string currency:string uuid:string
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем выполните следующую команду:

mix ecto.migrate
Enter fullscreen mode Выйти из полноэкранного режима

Далее необходимо сделать маршрут доступным, добавив следующий код в файл lib/rapyd_fx_example_web/router.ex:

…
  scope "/", RapydFxExampleWeb do
    pipe_through :browser
    resources "/beneficiaries", BeneficiaryController
…
end
Вход в полноэкранный режим Выйти из полноэкранного режима

Скопируйте следующие методы генерации подписи и тела запроса в файл lib/rapyd_fx_example_web/controllers/beneficiary_controller.ex:

  def sign_request(http_method, url_path, salt, timestamp, access_key, body) do
    secret_key = Application.fetch_env!(:rapyd_fx_example, :rapyd_secret_key)

    cond do
      body == "" ->
        body = ""
      true ->
        {:ok, body} = body |> Jason.encode()
    end

    signature_string =
      [http_method, url_path, salt, timestamp, access_key, secret_key, body] |> Enum.join("")

    :crypto.mac(:hmac, :sha256, secret_key, signature_string)
    |> Base.encode16(case: :lower)
    |> Base.encode64()
  end

  defp create_beneficiary_request(params) do
    {:ok, body} =
      %{
        first_name: params["first_name"],
        last_name: params["last_name"],
        country: "CA",
        city: "Toronto",
        address: "123 Fake Street",
        state: "Ontario",
        postcode: "M6C2R8",
        currency: params["currency"],
        category: "bank",
        entity_type: "individual",
        payment_type: "priority",
        account_number: "111111111111",
        bic_swift: "11111111"
      }
      |> Jason.encode()

      body
  end
Вход в полноэкранный режим Выход из полноэкранного режима

Далее перейдите к обновлению функции create на том же контроллере:

  def create(conn, %{"beneficiary" => beneficiary_params}) do
    # Define the base url and target path
    base_url = "https://sandboxapi.rapyd.net"
    url_path = "/v1/payouts/beneficiary"

    # Generate the values needed for the headers
    access_key = Application.fetch_env!(:rapyd_fx_example, :rapyd_access_key)
    salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
    timestamp = System.os_time(:second)

    # Generate request body
    body = create_beneficiary_request(beneficiary_params)

    signature = sign_request("post", url_path, salt, timestamp, access_key, to_string(body))

    # Build the headers
    headers = [
      {"access_key", access_key},
      {"salt", salt},
      {"timestamp", timestamp},
      {"url_path", url_path},
      {"signature", signature}
    ]

    response = HTTPoison.post!(base_url <> url_path, body, headers)
    response = response.body |> Jason.decode!()

    # Replace the Wallet params for id and url
    beneficiary_params = beneficiary_params
      |> Map.put("uuid", response["data"]["id"])

    case Rapyd.create_beneficiary(beneficiary_params) do
      {:ok, beneficiary} ->
        conn
        |> put_flash(:info, "Beneficiary created successfully.")
        |> redirect(to: Routes.beneficiary_path(conn, :show, beneficiary))

      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end
Войти в полноэкранный режим Выйти из полноэкранного режима

И обновите форму lib/rapyd_fx_example_web/templates/beneficiary/form.html.heex до следующей:

<.form let={f} for={@changeset} action={@action}>
  <%= if @changeset.action do %>
    <div class="alert alert-danger">
      <p>Oops, something went wrong! Please check the errors below.</p>
    </div>
  <% end %>

  <%= label f, :first_name %>
  <%= text_input f, :first_name %>
  <%= error_tag f, :first_name %>

  <%= label f, :last_name %>
  <%= text_input f, :last_name %>
  <%= error_tag f, :last_name %>

  <%= label f, :currency %>
  <%= text_input f, :currency %>
  <%= error_tag f, :currency %>

  <div>
    <%= submit "Save" %>
  </div>
</.form>
Вход в полноэкранный режим Выйти из полноэкранного режима

Откройте localhost:4000/beneficiaries/new и создайте бенефициара, введя его имя, фамилию и валюту, в которой он будет получать выплаты, и нажмите кнопку Сохранить.

Теперь вы должны увидеть вновь созданного бенефициара в списке бенефициаров на приборной панели Rapyd. Сохраните идентификатор бенефициара, так как вы будете использовать его в запросе на выплату.

Создание запроса на выплату

Теперь, когда у вас есть кошелек и бенефициар, вы можете создать запрос на выплату. Вы можете создавать запросы на выплату с помощью FX несколькими различными способами. В данном примере вы создадите запрос на выплату, который требует ручного подтверждения обменного курса.

Следующий рабочий процесс иллюстрирует необходимые шаги.

Начните с создания нового контроллера и соответствующих представлений с помощью следующей команды:

mix phx.gen.html Rapyd Payout payouts beneficiary:string beneficiary_entity_type:string payout_amount:float payout_currency:string ewallet_id:string payout_transaction:string
Войти в полноэкранный режим Выйти из полноэкранного режима

Затем выполните следующую команду:

mix ecto.migrate
Войти в полноэкранный режим Выйти из полноэкранного режима

Далее необходимо сделать маршрут доступным, добавив следующий код в файл lib/rapyd_fx_example_web/router.ex:

…
  scope "/", RapydFxExampleWeb do
    pipe_through :browser

    resources "/payouts", PayoutController
…
Войти в полноэкранный режим Выйти из полноэкранного режима

Скопируйте следующие методы генерации подписи и тела запроса в файл lib/rapyd_fx_example_web/controllers/payout_controller.ex:

  def sign_request(http_method, url_path, salt, timestamp, access_key, body) do
    secret_key = Application.fetch_env!(:rapyd_fx_example, :rapyd_secret_key)

    cond do
      body == "" ->
        body = ""
      true ->
        {:ok, body} = body |> Jason.encode()
    end

    signature_string =
      [http_method, url_path, salt, timestamp, access_key, secret_key, body] |> Enum.join("")

    :crypto.mac(:hmac, :sha256, secret_key, signature_string)
    |> Base.encode16(case: :lower)
    |> Base.encode64()
  end

  defp create_payout_request(params) do
    {:ok, body} =
      %{
        beneficiary: params["beneficiary"],
        ewallet: params["ewallet_id"],
        beneficiary_entity_type: params["beneficiary_entity_type"],
        confirm_automatically: false,
        description: "FX with confirmation",
        payout_amount: params["payout_amount"],
        payout_method_type: "ca_general_bank",
        payout_currency: params["payout_currency"],
        sender: %{
          country: "US",
          city: "Austin",
          address: "123 Rodeo Drive",
          state: "Texas",
          postcode: "73220",
          name: "Bob Smith",
          currency: "USD",
          entity_type: "company",
          identification_value: "123456789",
          identification_type: "incorporation_number"
        },
        sender_country: "US",
        sender_currency: "USD",
        sender_entity_type: "company",
      }
      |> Jason.encode()

      body
  end
Вход в полноэкранный режим Выход из полноэкранного режима

Далее, как вы уже делали ранее, обновите метод create до следующего:

  def create(conn, %{"payout" => payout_params}) do

    # Define the base url and target path
    base_url = "https://sandboxapi.rapyd.net"
    url_path = "/v1/payouts"

    # Generate the values needed for the headers
    access_key = Application.fetch_env!(:rapyd_fx_example, :rapyd_access_key)
    salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
    timestamp = System.os_time(:second)

    # Generate request body
    body = create_payout_request(payout_params)

    signature = sign_request("post", url_path, salt, timestamp, access_key, to_string(body))

    # Build the headers
    headers = [
      {"access_key", access_key},
      {"salt", salt},
      {"timestamp", timestamp},
      {"url_path", url_path},
      {"signature", signature}
    ]

    response = HTTPoison.post!(base_url <> url_path, body, headers)
    response = response.body |> Jason.decode!()

    # Replace the Wallet params for id and url
    payout_params = payout_params
      |> Map.put("payout_transaction", response["data"]["id"])

    case Rapyd.create_payout(payout_params) do
      {:ok, payout} ->
        conn
        |> put_flash(:info, "Payout created successfully.")
        |> redirect(to: Routes.payout_path(conn, :show, payout))

      {:error, %Ecto.Changeset{} = changeset} ->
        render(conn, "new.html", changeset: changeset)
    end
  end
Вход в полноэкранный режим Выйти из полноэкранного режима

Теперь вы можете двигаться дальше и инициировать операции по выплатам. Откройте http://localhost:4000/payouts/new в своем браузере и введите следующую информацию:

  • Бенефициар: ID бенефициара, который вы создали на предыдущем шаге.
  • Тип субъекта бенефициара: В данном случае individual.
  • Сумма выплаты: Сумма денег, которую вы хотите перевести; в данном случае используйте 20 долларов.
  • Валюта выплаты: Она должна совпадать с валютой получателя, поэтому используйте «CAD».
  • Электронный кошелек: ID кошелька, который вы создали в начале этой статьи.
  • Транзакция выплаты: Это значение будет заменено по мере создания запроса на выплату, введите «0» в форму.

Если все сработало правильно, вы должны увидеть следующее подтверждение.

Однако, если вы посмотрите на приборную панель Rapyd, выплаты там все еще нет, потому что ее еще нужно подтвердить в отдельном запросе.

Создание запроса на подтверждение выплаты

Поскольку вы генерируете выплату в иностранной валюте, вам необходимо подтвердить перевод. Это можно сделать с помощью простого вызова API.

Начните с обновления lib/rapyd_fx_example_web/controllers/payout_controller.ex и добавления нового действия подтверждения:

  def confirm(conn, %{"id" => id}) do
    # Define the base url and target path
    base_url = "https://sandboxapi.rapyd.net"
    url_path = "/v1/payouts/confirm/" <> id

    # Generate the values needed for the headers
    access_key = Application.fetch_env!(:rapyd_fx_example, :rapyd_access_key)
    salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
    timestamp = System.os_time(:second)

    # Generate request body
    body = ""

    signature = sign_request("post", url_path, salt, timestamp, access_key, to_string(body))

    # Build the headers
    headers = [
      {"access_key", access_key},
      {"salt", salt},
      {"timestamp", timestamp},
      {"url_path", url_path},
      {"signature", signature}
    ]

    response = HTTPoison.post!(base_url <> url_path, body, headers)
    response = response.body |> Jason.decode!()

    conn
    |> put_flash(:info, "Payout confirmed successfully.")
    |> redirect(to: Routes.payout_path(conn, :index, []))
  end
Войти в полноэкранный режим Выйти из полноэкранного режима

Далее обновите шаблон librapyd_fx_example_webtemplatespayoutindex.html.heex, добавив новое действие подтверждения выплаты:

...
<%= for payout <- @payouts do %>
    <tr>
      <td><%= payout.beneficiary %></td>
      <td><%= payout.beneficiary_entity_type %></td>
      <td><%= payout.payout_amount %></td>
      <td><%= payout.payout_currency %></td>
      <td><%= payout.ewallet_id %></td>
      <td><%= payout.payout_transaction %></td>

      <td>
        <span><%= link "Show", to: Routes.payout_path(@conn, :show, payout) %></span>
        <span><%= link "Confirm", to: Routes.payout_path(@conn, :confirm, payout) %></span>
        <span><%= link "Delete", to: Routes.payout_path(@conn, :delete, payout), method: :delete, data: [confirm: "Are you sure?"] %></span>
      </td>
    </tr>
<% end %>

...
Войти в полноэкранный режим Выйти из полноэкранного режима

Добавив действие подтверждения, вы можете легко подтвердить транзакцию после ее создания.

В представлении списка вы можете щелкнуть по ссылке подтверждения, которую вы только что добавили, чтобы подтвердить транзакцию и позволить средствам перейти в другие руки. Теперь выплата должна быть видна в списке транзакций кошелька отправителя.

Примечание: Транзакции должны быть подтверждены в течение пяти минут после их создания, иначе они будут автоматически закрыты.

Вы еще не закончили, так как транзакцию необходимо закрыть до того, как деньги будут переведены.

Закрытие транзакции выплаты

Сначала создайте новое действие контроллера для обработки запроса на завершение платежа, открыв lib/rapyd_fx_example_web/controllers/payout_controller.ex и добавив следующий код:

  def complete(conn, %{"id" => id}) do
    payout = Rapyd.get_payout!(id)
    IO.inspect(payout)
    # Define the base url and target path
    base_url = "https://sandboxapi.rapyd.net"
    url_path = "/v1/payouts/complete/" <> payout.payout_transaction <> "/" <> to_string(payout.payout_amount * 100)

    # Generate the values needed for the headers
    access_key = Application.fetch_env!(:rapyd_fx_example, :rapyd_access_key)
    salt = :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8)
    timestamp = System.os_time(:second)

    # Generate request body
    body = ""

    signature = sign_request("post", url_path, salt, timestamp, access_key, to_string(body))

    # Build the headers
    headers = [
      {"access_key", access_key},
      {"salt", salt},
      {"timestamp", timestamp},
      {"url_path", url_path},
      {"signature", signature}
    ]

    response = HTTPoison.post!(base_url <> url_path, body, headers)
    response = response.body |> Jason.decode!()

    conn
    |> put_flash(:info, "Payout completed successfully.")
    |> redirect(to: Routes.payout_path(conn, :index, []))
  end
Вход в полноэкранный режим Выйти из полноэкранного режима

Далее, как и раньше, обновите шаблон librapyd_fx_example_webtemplatespayoutindex.html.heex, чтобы включить действие подтверждения:

...
<%= for payout <- @payouts do %>
    <tr>
      <td><%= payout.beneficiary %></td>
      <td><%= payout.beneficiary_entity_type %></td>
      <td><%= payout.payout_amount %></td>
      <td><%= payout.payout_currency %></td>
      <td><%= payout.ewallet_id %></td>
      <td><%= payout.payout_transaction %></td>

      <td>
        <span><%= link "Show", to: Routes.payout_path(@conn, :show, payout) %></span>
        <span><%= link "Confirm", to: Routes.payout_path(@conn, :confirm, payout) %></span>
        <span><%= link "Complete", to: Routes.payout_path(@conn, :complete, payout) %></span>
        <span><%= link "Delete", to: Routes.payout_path(@conn, :delete, payout), method: :delete, data: [confirm: "Are you sure?"] %></span>
      </td>
    </tr>
<% end %>
Войти в полноэкранный режим Выйти из полноэкранного режима

Наконец, вы можете перейти на вкладку Disburse, чтобы подтвердить успешное завершение транзакции.

Заключение

В этой статье вы узнали о мощном наборе API, который Rapyd предоставляет для обработки платежей и выплат через границы, и о том, как вы можете использовать эти API для программной генерации выплат в иностранных валютах.

В статье также был показан поток, необходимый для создания и выдачи выплаты в иностранной валюте, и различные объекты, которые должны быть созданы для генерации транзакции.

С Rapyd Payout выплата заработной платы вашим сотрудникам в нужной валюте с легкостью и уверенностью — это просто и чрезвычайно гибко.

Оцените статью
devanswers.ru
Добавить комментарий