POST
/
v1
/
customers
/
{customerId}
/
accounts
/
{accountId}
/
payments
Create a payment
curl --request POST \
  --url https://api.next.orenda.finance/v1/customers/{customerId}/accounts/{accountId}/payments \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "amount": "150.00",
  "currency": "GBP",
  "reference": "Invoice 1024",
  "beneficiaryId": "ben_4b8e1c9d",
  "purpose": "PP001",
  "chargeBearer": "SHA"
}
'
import requests

url = "https://api.next.orenda.finance/v1/customers/{customerId}/accounts/{accountId}/payments"

payload = {
"amount": "150.00",
"currency": "GBP",
"reference": "Invoice 1024",
"beneficiaryId": "ben_4b8e1c9d",
"purpose": "PP001",
"chargeBearer": "SHA"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
amount: '150.00',
currency: 'GBP',
reference: 'Invoice 1024',
beneficiaryId: 'ben_4b8e1c9d',
purpose: 'PP001',
chargeBearer: 'SHA'
})
};

fetch('https://api.next.orenda.finance/v1/customers/{customerId}/accounts/{accountId}/payments', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.next.orenda.finance/v1/customers/{customerId}/accounts/{accountId}/payments",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'amount' => '150.00',
'currency' => 'GBP',
'reference' => 'Invoice 1024',
'beneficiaryId' => 'ben_4b8e1c9d',
'purpose' => 'PP001',
'chargeBearer' => 'SHA'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.next.orenda.finance/v1/customers/{customerId}/accounts/{accountId}/payments"

payload := strings.NewReader("{\n \"amount\": \"150.00\",\n \"currency\": \"GBP\",\n \"reference\": \"Invoice 1024\",\n \"beneficiaryId\": \"ben_4b8e1c9d\",\n \"purpose\": \"PP001\",\n \"chargeBearer\": \"SHA\"\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.next.orenda.finance/v1/customers/{customerId}/accounts/{accountId}/payments")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"amount\": \"150.00\",\n \"currency\": \"GBP\",\n \"reference\": \"Invoice 1024\",\n \"beneficiaryId\": \"ben_4b8e1c9d\",\n \"purpose\": \"PP001\",\n \"chargeBearer\": \"SHA\"\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.next.orenda.finance/v1/customers/{customerId}/accounts/{accountId}/payments")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"amount\": \"150.00\",\n \"currency\": \"GBP\",\n \"reference\": \"Invoice 1024\",\n \"beneficiaryId\": \"ben_4b8e1c9d\",\n \"purpose\": \"PP001\",\n \"chargeBearer\": \"SHA\"\n}"

response = http.request(request)
puts response.read_body
{
  "success": true,
  "data": {
    "bankTransfer": {
      "status": "success",
      "requestId": "p_111222333"
    }
  }
}
{
"success": false,
"code": "<string>",
"message": "<string>"
}
{
"success": false,
"code": "<string>",
"message": "<string>"
}
{
"success": false,
"code": "IDEMPOTENT_REQUEST_IN_PROGRESS",
"message": "A request with this Idempotency-Key is already in progress"
}
This sends a payment out of the account. Use it for normal payments, and for future or repeating payments.

Scheduling

To schedule instead of sending now, add scheduledDate (and frequency for a repeating payment) to the same request:
{
  "beneficiaryId": "ben_123",
  "amount": "150.00",
  "reference": "Rent",
  "scheduledDate": "2026/07/01",
  "frequency": "MONTHLY"
}
frequency sets the repeat interval — one of DAILY, WEEKLY, FORTNIGHTLY, or MONTHLY. Omit it (or send NEVER) for a one-off scheduled payment. For MONTHLY, the day is taken from scheduledDate; months without that day fall back to the last day of the month. Manage the result with Scheduled payments.

Tracking the payment

The response confirms acceptance, not settlement. To follow it through:
  1. In flight — it appears in payment requests (PENDING, or PENDING_TM while held for compliance review).
  2. Settled — it lands in transactions; failed ones show there with a FAILURE status.
Watch the reference length. The field allows up to 140 characters, but some programs accept fewer (as low as 35). If you go over your program’s limit, the payment is rejected. See Program capabilities.
Do not send programId or sandbox — we read them from your token. Send either a beneficiaryId or a cryptoQuote.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Headers

Idempotency-Key
string<uuid>

Optional. Makes the request retry-safe: a retry with the same key resolves to the same resource instead of creating a duplicate. Must be a UUID, and is scoped to the authenticated customer. Preferred over any idempotencyKey body field.

Path Parameters

customerId
string
required

Customer identifier.

accountId
string
required

Account identifier. The account determines which optional features and limits apply.

Body

application/json
amount
string
required

Decimal string, max 2 dp.

Pattern: ^\d+(\.\d{1,2})?$
Example:

"150.00"

purpose
string
required

Purpose code.

Minimum string length: 1
Example:

"PP001"

currency
string

ISO 4217. Defaults to the account currency if omitted.

Required string length: 3
reference
string

Statement reference. The field allows up to 140 characters, but some programs accept fewer (as low as 35). Stay within your program's limit.

Maximum string length: 140
beneficiaryId
string

Saved beneficiary. Required unless cryptoQuote is supplied.

chargeBearer
enum<string>
Available options:
SHA,
OUR,
BEN
debtorViban
string

Specific source virtual IBAN. For domestic GBP must start with GB.

scheduledDate
string<date-time>

Future date (UTC) to schedule the payment.

frequency
enum<string>

Repeat interval for a recurring scheduled payment. Omit (or send NEVER) for a one-off. MONTHLY uses the day from scheduledDate.

Available options:
NEVER,
DAILY,
WEEKLY,
FORTNIGHTLY,
MONTHLY
waiveFee
boolean

Admin-only.

cryptoQuote
object | null

Provide instead of beneficiaryId for crypto-funded payments.

idempotencyKey
string<uuid>

Optional. Idempotency key for retry-safety (parity with batch payments). The Idempotency-Key header is preferred and overrides this field. Reusing a key with different amount/accountId/beneficiaryId returns 400; a key whose payment is still being claimed returns 409.

Response

Payment accepted

success
boolean
Example:

true

data
object

The payment result (e.g. bankTransfer with its status).