Payout With FX
Pay your employees in the right currency. | Enterprise
Rapyd makes it easy for employers to pay their employees in a foreign currency. The employer has the option of confirming the FX rate before the payout is completed.
Common use cases may include:
A gig-platform pays a worker's overseas bank in their preferred currency for a completed project
Your company begins hiring workers across borders and offers to pay in their currency
Update: You Can Do a Payout With FX with the Sender Side Fixed
In the current example, we are showing an FX payout with a fixed beneficiary amount. The Rapyd payout API also supports fixing the sender (Debit) amount.
For example, the sender wants to pay 1000 USD and the beneficiary will get the equivalent amount of BGN (Bulgarian Lev), based on the current FX rate.
Note: To complete the payout with FX without requiring the second API call, you can set confirm_automatically
to true.
Your gig-platform uses the Client Wallet, which is in USD (U.S. Dollars). One of the workers lives in Bulgaria and needs to be paid in BGN (Bulgarian Lev).
You request a salary payout from your wallet USD account to the employee's BGN bank account with Create Payout.
Rapyd processes the request and sends you the exchange rate.
You confirm the exchange rate with Confirm Payout with FX.
Rapyd processes the payout to the employees's bank account and sends you a response.
You receive the payout confirmation. When the bank confirms receipt of the funds, you also receive a webhook.
The message sequence diagrams below describe how information is exchanged between Rapyd, the merchant, and the beneficiary.
Create Payout With FX - Automatic Confirmation
Create Payout With FX - Manual Confirmation
The finite state diagram below summarizes the statuses for payouts with FX.
Description of Statuses
Status | Description |
---|---|
Created | The payout was created. |
Pending | The payout is processing. The FX rate must be confirmed. |
Confirmation | The beneficiary has received the payout funds. |
Completed | The payout has been completed. The beneficiary has received the payout funds. |
Canceled | The payout was canceled. |
Error | The payout has not been created, or the payout has failed. |
Expired | The payout has expired. |
Prerequisites
To run the examples of this use case, you must run the following API calls:
'ewallet' - Run Create Wallet for the wallet of the ride-sharing service. Use the 'id' you get in the response. For more information, see Creating a Rapyd Wallet.
payout_method_type
- Run List Payout Method Types to get the available payout method types for the country you want. In this example, we use Bulgaria (BG).Required fields - Run Get Payout Required Fields to get the fields that are required for the beneficiary, the sender, and the payout itself. In this example, we use bg_general_bank.
Note: If no rate confirmation is required, you can perform the entire payout operation automatically. Set automatic_confirmation to true.
Note: You can check the current currency exchange rate with Get FX Rate.
The payroll manager requests a payout in USD (U.S. Dollars) for sending 2000 BGN (Bulgarian Lev) to the employee's bank account.
For that, you use Create Payout with the following parameters:
Description of Body Parameters
Body Parameter | Description |
---|---|
beneficiary | Fill out the 'beneficiary' object with the following details:
|
beneficiary_country | Enter BG as the country code of the beneficiary. |
beneficiary_entity _type | Enter individual as the type of entity for the beneficiary. |
confirm_automatically | Enter false to indicate that manual confirmation is required. |
description | Enter Salary as the description. |
ewallet | Enter the wallet 'id' that you received when you created the wallet in your sandbox. For purposes of this use case lesson, we are using ewallet_82dd0417a86aebb564da2f96936ce2d2, which is the ID of the wallet we created in our sandbox. |
payout_amount | Enter 2000 as the amount of currency to buy, in units of the buy_currency. |
payout_currency | Enter BGN as the payout currency. A three-letter ISO 4217 code for the currency to buy. |
payout_method_type | Enter bg_general_bank as the method type. Use List Payout Method Types and Get Payout Required Fields. |
sender | Fill out the 'sender' object with the following details:
|
sender_country | Enter BG as the country code for Bulgaria. |
sender_currency | Enter USD as the sender's currency. |
sender_entity_type | Enter company as the sender entity type. |
You ask Rapyd to process the payroll manager's payout of 2,000 BGN (Bulgarian Lev) to the employees bank account.
Create Payout Request
Request
// Request URL: POST https://sandboxapi.rapyd.net/v1/payouts // Message body: { "beneficiary": { "payment_type": "priority", "address": "456 Second Street", "city": "Plovdiv", "first_name": "Test", "last_name": "Employee", "iban": "DE3376599444263666923298", "bic_swift": "BUINBGSF" }, "beneficiary_country": "BG", "beneficiary_entity_type": "individual", "confirm_automatically": false, "description": "Salary", "ewallet": "ewallet_82dd0417a86aebb564da2f96936ce2d2", "payout_amount": "2000", "payout_currency": "BGN", "payout_method_type": "bg_general_bank", "sender": { "first_name": "Test", "last_name": "Manager", "address": "123 First Street", "city": "Sofia", "date_of_birth": "22/02/1980" }, "sender_country": "BG", "sender_currency": "USD", "sender_entity_type": "company" }
.NET Core
using System; using System.Text.Json; namespace RapydApiRequestSample { class Program { static void Main(string[] args) { try { var requestObj = new { beneficiary = new { payment_type = "priority", address = "456 Second Street", city = "Plovdiv", first_name = "John", last_name = "Doe", iban = "DE3376599444263666923298", bic_swift = "BUINBGSF" }, beneficiary_country = "BG", beneficiary_entity_type = "individual", confirm_automatically = false, description = "Salary", ewallet = "ewallet_82dd0417a86aebb564da2f96936ce2d2", payout_amount = "2000", payout_currency = "BGN", payout_method_type = "bg_general_bank", sender = new { first_name = "Jane", last_name = "Doe", address = "123 First Street", city = "Sofia", date_of_birth = "22/02/1980" }, sender_country = "BG", sender_currency = "USD", sender_entity_type = "company" }; string request = JsonSerializer.Serialize(requestObj); string result = RapydApiRequestSample.Utilities.MakeRequest("POST", "/v1/payouts", request); Console.WriteLine(result); } catch (Exception e) { Console.WriteLine("Error completing request: " + e.Message); } } } }
JavaScript
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest; async function main() { try { const body = { beneficiary: { payment_type: 'priority', address: '456 Second Street', city: 'Plovdiv', first_name: 'John', last_name: 'Doe', iban: 'DE3376599444263666923298', bic_swift: 'BUINBGSF' }, beneficiary_country: 'BG', beneficiary_entity_type: 'individual', confirm_automatically: false, description: 'Salary', ewallet: 'ewallet_82dd0417a86aebb564da2f96936ce2d2', payout_amount: '2000', payout_currency: 'BGN', payout_method_type: 'bg_general_bank', sender: { first_name: 'Jane', last_name: 'Doe', address: '123 First Street', city: 'Sofia', date_of_birth: '22/02/1980' }, sender_country: 'BG', sender_currency: 'USD', sender_entity_type: 'company' }; const result = await makeRequest('POST', '/v1/payouts', body); console.log(result); } catch (error) { console.error('Error completing request', error); } }
PHP
<?php $path = $_SERVER['DOCUMENT_ROOT']; $path .= "/<path-to-your-utility-file>/utilities.php"; include($path); $body = [ "beneficiary" => array( "payment_type" => "priority", "address" => "456 Second Street", "city" => "Plovdiv", "first_name" => "John", "last_name" => "Doe", "iban" => "DE3376599444263666923298", "bic_swift" => "BUINBGSF" ), "beneficiary_country" => "BG", "beneficiary_entity_type" => "individual", "confirm_automatically" => false, "description" => "Salary", "ewallet" => "ewallet_82dd0417a86aebb564da2f96936ce2d2", "payout_amount" => "2000", "payout_currency" => "BGN", "payout_method_type" => "bg_general_bank", "sender" => array( "first_name" => "Jane", "last_name" => "Doe", "address" => "123 First Street", "city" => "Sofia", "date_of_birth" => "22/02/1980" ), "sender_country" => "BG", "sender_currency" => "USD", "sender_entity_type" => "company" ]; try { $object = make_request('post', '/v1/payouts', $body); var_dump($object); } catch (Exception $e) { echo "Error: $e"; } ?>
Python
from pprint import pprint from utilities import make_request beneficiary_fields = { "payment_type": "priority", "address": "456 Second Street", "city": "Plovdiv", "first_name": "John", "last_name": "Doe", "iban": "DE3376599444263666923298", "bic_swift": "BUINBGSF" } sender_fields = { "first_name": "Jane", "last_name": "Doe", "address": "123 First Street", "city": "Sofia", "date_of_birth": "22/02/1980" } payout_body = { "beneficiary": beneficiary_fields, "beneficiary_country": "BG", "beneficiary_entity_type": "individual", "confirm_automatically": False, "description": "Salary", "ewallet": "ewallet_82dd0417a86aebb564da2f96936ce2d2", "payout_amount": "2000", "payout_currency": "BGN", "payout_method_type": "bg_general_bank", "sender": sender_fields, "sender_country": "BG", "sender_currency": "USD", "sender_entity_type": "company" } result = make_request(method='post', path='/v1/payouts', body=payout_body) pprint(result)
Create Payout Response
Let's take a look at the response.
Response
{ "status": { "error_code": "", "status": "SUCCESS", "message": "", "response_code": "", "operation_id": "77745716-89fc-4313-abbe-162a4d25f12f" }, "data": { "id": "payout_56010c333d71789b6110fd36bc5066ca", "payout_type": "bank", "payout_method_type": "bg_general_bank", "amount": 2000, "payout_currency": "BGN", "sender_amount": 1191.1, "sender_currency": "USD", "status": "Confirmation", "sender_country": "BG", "sender": { "last_name": "Manager", "first_name": "Test", "country": "BG", "entity_type": "company", "address": "123 First Street", "name": "Test Manager", "date_of_birth": "22/02/1980", "city": "Sofia", "currency": "USD" }, "beneficiary_country": "BG", "beneficiary": { "last_name": "Employee", "first_name": "Test", "country": "BG", "entity_type": "individual", "address": "456 Second Street", "name": "Test Employee", "city": "Plovdiv", "currency": "BGN", "bic_swift": "BUINBGSF", "iban": "DE3376599444263666923298", "payment_type": "priority" }, "fx_rate": 0.59555, "instructions": { // ... }, "ewallets": [ { "ewallet_id": "ewallet_82dd0417a86aebb564da2f96936ce2d2", "amount": 1191.1, "percent": 100 } ], "metadata": {}, "description": "Salary" // ... } }
The data
section of this response shows:
The
id
of the 'payout' object is payout_56010c333d71789b6110fd36bc5066ca. When you run this example in your own sandbox, you will get a different ID, which you will need for a later step in this use case.The
fx_rate
is 0.59555.
When you receive the response, you have a short time to approve the exchange rate. The exact amount of time varies from payout method to payout method.
Confirm Payout Request
To confirm the payout, use Confirm Payout with FX with the following parameters:
Description of Path Parameters
Path Parameter | Description |
---|---|
Payout ID | Enter the payout 'id' that you received when you created the payout in your sandbox. For purposes of this use case lesson, we are using payout_56010c333d71789b6110fd36bc5066ca, which is the ID of the payout we created in our sandbox. |
Request
// Request URL: POST https://sandboxapi.rapyd.net/v1/payouts/confirm/payout_56010c333d71789b6110fd36bc5066ca // Message body absent.
.NET Core
using System; namespace RapydApiRequestSample { class Program { static void Main(string[] args) { try { string payout = "payout_56010c333d71789b6110fd36bc5066ca"; string result = RapydApiRequestSample.Utilities.MakeRequest("POST", $"/v1/payouts/confirm/{payout}"); Console.WriteLine(result); } catch (Exception e) { Console.WriteLine("Error completing request: " + e.Message); } } } }
JavaScript
const makeRequest = require('<path-to-your-utility-file>/utilities').makeRequest; async function main() { try { const body = {}; const result = await makeRequest( 'POST', '/v1/payouts/confirm/payout_56010c333d71789b6110fd36bc5066ca', body ); console.log(result); } catch (error) { console.error('Error completing request', error); } }
PHP
<?php $path = $_SERVER['DOCUMENT_ROOT']; $path .= "/<path-to-your-utility-file>/utilities.php"; include($path); try { $object = make_request('post', '/v1/payouts/confirm/payout_56010c333d71789b6110fd36bc5066ca'); var_dump($object); } catch (Exception $e) { echo "Error: $e"; } ?>
Python
from pprint import pprint from utilities import make_request payout = 'payout_56010c333d71789b6110fd36bc5066ca' results = make_request(method='post', path=f'/v1/payouts/confirm/{payout}') pprint(results)
Confirm Payout Response
Let's take a look at the response.
Response
{ "status": { "error_code": "", "status": "SUCCESS", "message": "", "response_code": "", "operation_id": "bb05d0a9-295d-4cad-958c-e20dd8dbe461" }, "data": { "id": "payout_89a8df5e8716b9785f4f1de42e453bac", "payout_type": "bank", "payout_method_type": "bg_general_bank", "amount": 2000, "payout_currency": "BGN", "sender_amount": 1191.1, "sender_currency": "USD", "status": "Created", "sender_country": "BG", "sender": { "id": "sender_4bc400c5c08fd6e6d4655d5ddef73e4e", "last_name": "Manager", "first_name": "Test", "country": "BG", "entity_type": "company", "address": "123 First Street", "name": "Test Manager", "date_of_birth": "22/02/1980", "city": "Sofia", "currency": "USD" }, "beneficiary_country": "BG", "beneficiary": { "id": "beneficiary_97f8a3c6955967280a11223f7c3114ca", "last_name": "Employee", "first_name": "Test", "country": "BG", "entity_type": "individual", "address": "456 Second Street", "name": "Test Employee", "city": "Plovdiv", "currency": "BGN", "bank_name": "Test Employee", "bic_swift": "BUINBGSF", "iban": "DE3376599444263666923298", "payment_type": "priority" }, "fx_rate": 0.59555, "instructions": { // ... } ], "ewallets": [ { "ewallet_id": "ewallet_82dd0417a86aebb564da2f96936ce2d2", "amount": 1191.1, "percent": 100 } ], "metadata": {}, "description": "Salary", "created_at": 1583676917, // ... } }
The data
section of this response shows:
status
- Created - This indicates that the payout process has begun.amount
- The amount of money that will be transferred into the employee's bank account, 2000 BGN.payout_currency
- The currency sent to the employee's bank account, BGN.sender_currency
- The currency of your eWallet account, USD.created at
- The time the payout was created, in Unix time.
The ewallets
object shows the following information:
ewallet_id
- The ID of your company wallet.amount
- The amount of USD taken from your wallet, 1191.10 USD.
Simulating Payout Completion
The sandbox does not directly simulate the action of the beneficiary receiving the payout funds. You can simulate this action with the procedure described in Complete Payout. For this, you will need the payout ID and payout amount that you generated in your sandbox.
When a payout completion is simulated, Rapyd sends a webhook. Configure your system to receive webhooks with the procedure described in Defining a Webhook Endpoint
After you simulate that the employee's bank finalizes receipt of his salary, Rapyd sends you Webhook - Payout Completed. To indicate that the payout was completed, the status
field changes to Completed.
Looking for More In-Depth Technical Information?
Want to see the Rapyd API methods and objects that you'll use? Visit the API Reference for more technical details.