Scheduling payouts

This page will show you how to schedule account-to-account payments

Payouts is short-hand for account-to-account bank transfers such as ACH, SEPA and faster payments.

By default our payouts are scheduled which means we will pay out on the due date of the payout. Making an immediate payment is a 2-step process: first you schedule a payout and then you trigger an immediate payment on that payout.

This page explains how to create orders by API and has the following sections:

Orders can also be managed manually from the orders section of our web app.

📘

Creating orders by CSV file

To avoid an API integration and go live faster, you can start by creating orders by CSV. Please contact us to set this up.

Scheduling a payout

Scheduling a payout can be done as follows:

curl {baseURL}/aggregate/orders  
-H "Authorization:your-api-key"  
-H "Content-type: application/json"  
-X POST  
-d '{ 
  "buyerId" : "your-trader-id",
  "sellerId" : ":seller_id",
  "orderCurrency": "USD",
  "lineItems": [
    {
      "lineItemNumber": 1,
      "type": "PRODUCT",
      "name": "Book",
      "listPriceInCents": 1500,
      "quantity": 1
    }
  ],
  "paymentDueDate": "2021-10-20",
  "services": [
    {
      "serviceName": "MASSPAY",
      "tags": {
        "sellerCurrency": "USD",
        "buyerCurrency": "USD"
      }
    }
  ],
  "terms": "Net30",
  "payoutYordexPayAccountId": "9d1284fc-0e68-45bb-9628-d33df653328f",
  "buyerTags": {
    "orderType": "PO"
  }
}'
// Set up the order
Order newOrder = Order.builder().
  buyerId("buyerId").
  sellerId("sellerId").
  orderCurrency("GBP").
  orderAmountInCents(12222).
  terms("30% upfront 70% before shipping").
  build();

// Set up the API keys
RequestOptions requestOptions = RequestOptions.builder().
  apiKey("buyerApiKey").
  build();

// Create the order
try {
	newOrder = Order.createAndApproveOrder(newOrder, buyerApiKey, sellerApiKey, requestOptions );
} catch(YordexException ex) {
	// Handle the error
}

// Get the order ID and store it in your database
newOrderId = newOrder.getId();

❗️

Amount in cents

Amounts are always sent through in cents. In this example, the value of the order is £15.

The buyerId, sellerId and orderCurrency are mandatory.

Instead of providing lineItems, you can also provide the order amount directly. See below how to do this. If you provide both the line items and an order amount, the sum of the amount of the line items will overwrite the order amount.

curl {baseURL}/aggregate/orders  
-H "Authorization:your-api-key"  
-H "Content-type: application/json"  
-X POST  
-d '{ 
  ...
  "orderAmountInCents" : 1500
  ...
}'

The paymentDueDate specified when the payment should be made.

The MASSPAY services object specifies Yordex should pay this as an account-to-account transaction. Having both buyer and seller currency set to USD specifies this should be a local ACH payment. To make it a cross-border payment you can for example specify the sellerCurrency is EUR in which case this will be a USD to EUR payment.

When scheduling a payout order, you can also add the optional object: payoutYordexPayAccountId to specify which Yordex pay account should make the payment. This should only apply if you have multiple accounts of the same currency configured to make payments.

To indicate an order should be paid on card, you should add the YORDEX_CARD service when creating the order:

curl {baseURL}/aggregate/orders  
-H "Authorization:your-api-key"  
-H "Content-type: application/json"  
-X POST  
-d '{ 
  ...
  "services": [
    {
      "serviceName": "YORDEX_CARD"
    }
  ],
  ... 
}'

In this example, a one-off virtual card will be created once the order is approved.

To associate an already existing card with the PO, you should create the order like this:

curl {baseURL}/aggregate/orders  
-H "Authorization:your-api-key"  
-H "Content-type: application/json"  
-X POST  
-d '{ 
  ...
  "services": [
    {
      "serviceName": "YORDEX_CARD",
      "tags": {
        "cardId": ":card-id"
      }
    }
  ],
  ... 
}'

The terms field specifies the payment terms. These are managed from the terms page in our admin portal. As we will see later, term are translated into event. You can also manage terms or events by API directly to get more fine grained control over payment terms. If you wish to do this, please contact us.

The buyerTags are not mandatory but they will make sure the order shows up on the "Purchase orders" tab of our admin portal.

The response will look as follows:

{
  "id" : "order_id",
  "buyerId" : "your-trader-id",
  "buyerCompanyTradingName": "Your company name",
  "sellerId" : ":seller_id",
  "sellerCompanyTradingName": "Acme Inc",
  "orderCurrency": "USD",
  "orderAmountInCents": 1500,
  "status": "NOT_APPROVED",
  "lineItems": [
    {
      "id": "lineitem-id",
      "lineItemNumber": 1,
      "type": "PRODUCT",
      "name": "Book",
      "listPriceInCents": 1500,
      "quantity": 1,
      "lineItemAmountInCents": 1500
    }
  ],
  "events": [
    {
      "id": "event-id",
      "paymentDueDate": "2021-10-20",
      "pctToBePaid": 100,
      "eventName": "Invoice payment",
      "eventNumber": 1,
      "paymentType": "PAYMENT",
      "amountToBePaidInCents": 1500,
      "status": "NOT_STARTED
    }
  ],
  "services": [
    {
      "serviceName": "MASSPAY",
      "tags": {
        "sellerCurrency": "USD",
        "buyerCurrency": "USD"
      }
    }
  ],
  "payoutYordexPayAccountId": "9d1284fc-0e68-45bb-9628-d33df653328f",
  "buyerTags": {
    "orderType": "PO"
  }
}

Let’s break this down.

The first and last parts of the response is similar to the request. The only fields we have added are an ids for both the order and the line items, the buyer and seller's company names and a line item number.

In the second part of the response we calculated the totals for the order.

  "orderAmountInCents": 1500,
  ...
  "lineItems": [
    {
      ...
      "lineItemAmountInCents": 1500
    }
  ],

In this example there is only one line item so the orderAmountInCents is the same as the lineItemAmountInCents. If there are multiple line items, the orderAmountInCents is the sum of the lineItemAmountInCents for all line items.

In third part of the response we translated the terms and paymentDueDate fields that were specified in the request into an events array. What events are is explained here.

  "events": [
    {
      "id": "event-id",
      "paymentDueDate": "2021-10-20",
      "pctToBePaid": 100,
      "eventName": "Invoice payment",
      "eventNumber": 1,
      "paymentType": "PAYMENT",
      "amountToBePaidInCents": 1500
    }
  ],

The paymentDueDate was specified in the request and the pctToBePaid, eventName and paymentType fields came from the terms. We added the id, eventNumber and amountToBePaidInCents fields.

In this example there is only one event with pctToBePaid of 100% so the amountToBePaidInCents is the same as the orderAmountInCents. If there are multiple events, for example for subscriptions of partially received orders, the amountToBePaidInCents will be lower than the orderAmountInCents.

The fourth part of the response contains the statuses for both the order and the events. Order and event status are explained here.

  "status": "NOT_APPROVED",
  ...
  "events": [
    {
      ...
      "status": "NOT_STARTED
    }
  ],

New orders will always have the order status “NOT_APPROVED” and the event status "NOT_STARTED". The approving an order section explains how to approve this order.

Orders have many other fields and functionalities which are not all described on this page. The Admin APIs introduction page explains what other functionality is available. Please contact us if you want to use some of these.

Updating an order

It is only possible to update orders that that are in the NOT_APPROVED status. If your order was already approved and you want to change it, you should amend it first like this:

curl {baseURL}/orders/:order-id  
-H "Authorization:your-api-key"  
-H "Content-type: application/json"  
-X PUT  
-d '{ 
    "description": "My first order",
    "orderCurrency": "USD",
    "buyerOrderReference":"PO number",
    "terms": "30% upfront 70% before shipping"
}'
Order updatedOrder = Order.builder().
        orderCurrency("GBP").
        orderAmountInCents(12222).
        buyerOrderReference("buyerReference").
        sellerOrderReference("sellerOrderReference").
        description("First Order").
        terms("30% upfront 70% before shipping").
        build();
RequestOptions requestOptions = RequestOptions.builder().apiKey("apiKey").build();
updatedOrder = Order.update(updatedOrder, requestOptions);

Only the fields listed here can be updated.

🚧

Specify all fields

We are using a PUT to update the order. This means that fields that are not specified will be set to null. For example, if your order was created with a description but you do not provide that description in this API call, the description field will be set to null.

Many of these fields can also be updated one-by-one as described here

You can only update terms when the order has no events. When the order already has events, you have to delete the existing events first.

You cannot update the buyerId or sellerId of the order. You should create a new order and close the old order if you want to change them.

Approving an order or payment

Once created, an order is always NOT_APPROVED. You can approve an order like this:

curl{baseURL}/orders/:order-id/approvals
-H "Authorization:your-api-key"  
-H "Content-type: application/json"  
-X POST  
-d '{ 
  "approved" : true
}'

After this, the order will have the status APPROVED.

Normally the status of the first event will be PAYMENT_DUE. If not, that means events require confirmation. To avoid having to confirm events, you should adjust the terms on the terms page of our admin portal.

Making an immediate payout

An immediate payment can be triggered as follows:

curl {baseURL}/payouts/immediate
-H "Authorization:your-api-key"  
-X POST
-d '{
   "token": <payout token>,
   "eventIds": ["id1"]  
}'  

eventIds are the event ids for the payments you want to trigger. They will be returned when getting order details

📘

Token required

For security reason, a token is required when triggering an immediate payout. Please contact us if you want to obtain this token by API

Closing an order

Orders that you know won’t complete anymore should be closed. Closing an order can be done as follows:

curl {baseURL}/orders/order-id/close
-H "Authorization:your-api-key"  
-X POST

If you have closed an order by accident, or if the negotiations re-opened and you do want to continue with the order, you can re-open the order again:

curl {baseURL}/orders/order-id/open
-H "Authorization:your-api-key"  
-X POST

No information will be lost when closing an order and then re-opening it again. You can pick up where you had left off.


What’s Next