curl -X POST "${BASE_URL}/api/v2/trans/cancelDirectPay" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data-raw '{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}'import json
import os
import urllib.parse
import urllib.request
base_url = os.environ["BASE_URL"].rstrip("/")
url = base_url + "/api/v2/trans/cancelDirectPay"
headers = {"Accept": "application/json"}
headers["Authorization"] = "Bearer " + os.environ["ACCESS_TOKEN"]
payload = json.loads(r'''{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}''')
body = json.dumps(payload).encode("utf-8")
headers["Content-Type"] = "application/json"
request = urllib.request.Request(url, data=body, headers=headers, method="POST")
with urllib.request.urlopen(request, timeout=30) as response:
print(response.read().decode("utf-8"))
const env = (name) => {
const value = process.env[name];
if (!value) throw new Error(`Missing environment variable: ${name}`);
return value;
};
const baseUrl = env("BASE_URL").replace(/\/+$/, "");
const url = new URL(baseUrl + "/api/v2/trans/cancelDirectPay");
const headers = { Accept: "application/json" };
headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
const payload = {
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
};
const body = JSON.stringify(payload);
headers["Content-Type"] = "application/json";
const response = await fetch(url, {
method: "POST",
headers,
body,
signal: AbortSignal.timeout(30_000),
});
console.log(await response.text());
<?php
$env = static function (string $name): string {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Missing environment variable: " . $name);
}
return $value;
};
$baseUrl = rtrim($env('BASE_URL'), '/');
$url = $baseUrl . "/api/v2/trans/cancelDirectPay";
$headers = ['Accept: application/json'];
$headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
$body = <<<'JSON'
{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}
JSON;
$headers[] = 'Content-Type: application/json';
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($curl);
if ($response === false) {
$error = curl_error($curl);
curl_close($curl);
throw new RuntimeException($error);
}
curl_close($curl);
echo $response, PHP_EOL;
package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func mustEnv(name string) string {
value := os.Getenv(name)
if value == "" { panic("Missing environment variable: " + name) }
return value
}
func main() {
baseURL := strings.TrimRight(mustEnv("BASE_URL"), "/")
endpoint := baseURL + "/api/v2/trans/cancelDirectPay"
payload := `{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}`
body := strings.NewReader(payload)
req, err := http.NewRequest("POST", endpoint, body)
if err != nil { panic(err) }
req.Header.Set("Accept", "application/json")
req.Header.Set("Authorization", "Bearer " + mustEnv("ACCESS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(req)
if err != nil { panic(err) }
defer response.Body.Close()
result, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
fmt.Println(string(result))
}
import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
public class Example {
static String requireEnv(String name) {
String value = System.getenv(name);
if (value == null || value.isEmpty()) {
throw new IllegalArgumentException("Missing environment variable: " + name);
}
return value;
}
public static void main(String[] args) throws Exception {
String baseUrl = requireEnv("BASE_URL").replaceAll("/+$", "");
String endpoint = baseUrl + "/api/v2/trans/cancelDirectPay";
String payload =
"{\n" +
" \"merchant_id\": \"48290713\",\n" +
" \"merchant_order_no\": [\n" +
" \"BB-20300101-005\",\n" +
" \"BB-20300101-0099\"\n" +
" ]\n" +
"}";
HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(endpoint))
.timeout(Duration.ofSeconds(30))
.header("Accept", "application/json");
builder.header("Authorization", "Bearer " + requireEnv("ACCESS_TOKEN"));
builder.header("Content-Type", "application/json");
HttpRequest request = builder.method("POST", HttpRequest.BodyPublishers.ofString(payload, StandardCharsets.UTF_8)).build();
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
System.out.println(response.body());
}
}
require "net/http"
require "uri"
base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
uri = URI(base_url + "/api/v2/trans/cancelDirectPay")
request = Net::HTTP::Post.new(uri)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer " + ENV.fetch("ACCESS_TOKEN")
request["Content-Type"] = "application/json"
request.body = <<~'JSON'
{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}
JSON
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
http.open_timeout = 30
http.read_timeout = 30
puts http.request(request).body
{
"code": 0,
"message": "success",
"data": {
"total": 2,
"cancelled": 1,
"skipped": 1,
"items": [
{
"merchant_order_no": "BB-20300101-005",
"result": "cancelled"
},
{
"merchant_order_no": "BB-20300101-0099",
"result": "skipped",
"reason": "Order not found"
}
]
}
}Cancel scheduled payments
Only scheduled transactions belonging to the current merchant and business, with Pending status and not already cancelled, can be cancelled. Cancellation must occur strictly before 08:15 Australia/Sydney on process_date. Cancellation is no longer permitted at the cutoff; immediate transactions cannot be cancelled. Successfully cancelled transactions become Failed. Merchant order numbers are deduplicated, and each result is cancelled or skipped. Top-level success does not mean every transaction was cancelled.
All examples illustrate request and response formats. Replace customers, orders, cards and accounts with approved test data. BASE_URL is the service root domain without /api/v2. ACCESS_TOKEN is the access_token returned by /oauth/token. Example dates are in 2030; replace them with actual dates that satisfy the current date restrictions.
curl -X POST "${BASE_URL}/api/v2/trans/cancelDirectPay" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data-raw '{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}'import json
import os
import urllib.parse
import urllib.request
base_url = os.environ["BASE_URL"].rstrip("/")
url = base_url + "/api/v2/trans/cancelDirectPay"
headers = {"Accept": "application/json"}
headers["Authorization"] = "Bearer " + os.environ["ACCESS_TOKEN"]
payload = json.loads(r'''{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}''')
body = json.dumps(payload).encode("utf-8")
headers["Content-Type"] = "application/json"
request = urllib.request.Request(url, data=body, headers=headers, method="POST")
with urllib.request.urlopen(request, timeout=30) as response:
print(response.read().decode("utf-8"))
const env = (name) => {
const value = process.env[name];
if (!value) throw new Error(`Missing environment variable: ${name}`);
return value;
};
const baseUrl = env("BASE_URL").replace(/\/+$/, "");
const url = new URL(baseUrl + "/api/v2/trans/cancelDirectPay");
const headers = { Accept: "application/json" };
headers.Authorization = `Bearer ${env("ACCESS_TOKEN")}`;
const payload = {
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
};
const body = JSON.stringify(payload);
headers["Content-Type"] = "application/json";
const response = await fetch(url, {
method: "POST",
headers,
body,
signal: AbortSignal.timeout(30_000),
});
console.log(await response.text());
<?php
$env = static function (string $name): string {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Missing environment variable: " . $name);
}
return $value;
};
$baseUrl = rtrim($env('BASE_URL'), '/');
$url = $baseUrl . "/api/v2/trans/cancelDirectPay";
$headers = ['Accept: application/json'];
$headers[] = 'Authorization: Bearer ' . $env('ACCESS_TOKEN');
$body = <<<'JSON'
{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}
JSON;
$headers[] = 'Content-Type: application/json';
$curl = curl_init($url);
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($curl);
if ($response === false) {
$error = curl_error($curl);
curl_close($curl);
throw new RuntimeException($error);
}
curl_close($curl);
echo $response, PHP_EOL;
package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
"time"
)
func mustEnv(name string) string {
value := os.Getenv(name)
if value == "" { panic("Missing environment variable: " + name) }
return value
}
func main() {
baseURL := strings.TrimRight(mustEnv("BASE_URL"), "/")
endpoint := baseURL + "/api/v2/trans/cancelDirectPay"
payload := `{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}`
body := strings.NewReader(payload)
req, err := http.NewRequest("POST", endpoint, body)
if err != nil { panic(err) }
req.Header.Set("Accept", "application/json")
req.Header.Set("Authorization", "Bearer " + mustEnv("ACCESS_TOKEN"))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second}
response, err := client.Do(req)
if err != nil { panic(err) }
defer response.Body.Close()
result, err := io.ReadAll(response.Body)
if err != nil { panic(err) }
fmt.Println(string(result))
}
import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
public class Example {
static String requireEnv(String name) {
String value = System.getenv(name);
if (value == null || value.isEmpty()) {
throw new IllegalArgumentException("Missing environment variable: " + name);
}
return value;
}
public static void main(String[] args) throws Exception {
String baseUrl = requireEnv("BASE_URL").replaceAll("/+$", "");
String endpoint = baseUrl + "/api/v2/trans/cancelDirectPay";
String payload =
"{\n" +
" \"merchant_id\": \"48290713\",\n" +
" \"merchant_order_no\": [\n" +
" \"BB-20300101-005\",\n" +
" \"BB-20300101-0099\"\n" +
" ]\n" +
"}";
HttpRequest.Builder builder = HttpRequest.newBuilder(URI.create(endpoint))
.timeout(Duration.ofSeconds(30))
.header("Accept", "application/json");
builder.header("Authorization", "Bearer " + requireEnv("ACCESS_TOKEN"));
builder.header("Content-Type", "application/json");
HttpRequest request = builder.method("POST", HttpRequest.BodyPublishers.ofString(payload, StandardCharsets.UTF_8)).build();
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
System.out.println(response.body());
}
}
require "net/http"
require "uri"
base_url = ENV.fetch("BASE_URL").sub(%r{/+$}, "")
uri = URI(base_url + "/api/v2/trans/cancelDirectPay")
request = Net::HTTP::Post.new(uri)
request["Accept"] = "application/json"
request["Authorization"] = "Bearer " + ENV.fetch("ACCESS_TOKEN")
request["Content-Type"] = "application/json"
request.body = <<~'JSON'
{
"merchant_id": "48290713",
"merchant_order_no": [
"BB-20300101-005",
"BB-20300101-0099"
]
}
JSON
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
http.open_timeout = 30
http.read_timeout = 30
puts http.request(request).body
{
"code": 0,
"message": "success",
"data": {
"total": 2,
"cancelled": 1,
"skipped": 1,
"items": [
{
"merchant_order_no": "BB-20300101-005",
"result": "cancelled"
},
{
"merchant_order_no": "BB-20300101-0099",
"result": "skipped",
"reason": "Order not found"
}
]
}
}Authorizations
OAuth2 client_credentials authorization. Obtain a new access_token when it expires.
Body
Request parameters.
Business identifier assigned by BillBuddy.
1 - 20Merchant order numbers to cancel: 1 to 100 items. Each item is a required string of at most 60 characters. Duplicates are deduplicated.
1 - 100 elementsMerchant order number to cancel. Required string of at most 60 characters; cannot be null, empty or whitespace-only.
1 - 60\SResponse
HTTP 200. Distinguish success, business errors, validation errors and business authentication errors using the response body code.