curl --request PUT \
--url https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-PARTNER-ID: <api-key>' \
--data '
{
"max_usage": 1,
"status": "open",
"required_customer_detail": true,
"customer_pays_fee": false,
"expired_at": "1705305600000",
"whitelisted_payment_method": [
"<string>"
],
"redirect_url": "https://example.com/payment-link",
"success_redirect_url": "https://merchant.example.com/payment/success",
"expired_redirect_url": "https://merchant.example.com/payment/expired",
"optional_metadata": {
"invoice_number": "INV20240513001"
}
}
'import requests
url = "https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}"
payload = {
"max_usage": 1,
"status": "open",
"required_customer_detail": True,
"customer_pays_fee": False,
"expired_at": "1705305600000",
"whitelisted_payment_method": ["<string>"],
"redirect_url": "https://example.com/payment-link",
"success_redirect_url": "https://merchant.example.com/payment/success",
"expired_redirect_url": "https://merchant.example.com/payment/expired",
"optional_metadata": { "invoice_number": "INV20240513001" }
}
headers = {
"Authorization": "Bearer <token>",
"X-PARTNER-ID": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
Authorization: 'Bearer <token>',
'X-PARTNER-ID': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
max_usage: 1,
status: 'open',
required_customer_detail: true,
customer_pays_fee: false,
expired_at: '1705305600000',
whitelisted_payment_method: ['<string>'],
redirect_url: 'https://example.com/payment-link',
success_redirect_url: 'https://merchant.example.com/payment/success',
expired_redirect_url: 'https://merchant.example.com/payment/expired',
optional_metadata: {invoice_number: 'INV20240513001'}
})
};
fetch('https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}', 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://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'max_usage' => 1,
'status' => 'open',
'required_customer_detail' => true,
'customer_pays_fee' => false,
'expired_at' => '1705305600000',
'whitelisted_payment_method' => [
'<string>'
],
'redirect_url' => 'https://example.com/payment-link',
'success_redirect_url' => 'https://merchant.example.com/payment/success',
'expired_redirect_url' => 'https://merchant.example.com/payment/expired',
'optional_metadata' => [
'invoice_number' => 'INV20240513001'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-PARTNER-ID: <api-key>"
],
]);
$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://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}"
payload := strings.NewReader("{\n \"max_usage\": 1,\n \"status\": \"open\",\n \"required_customer_detail\": true,\n \"customer_pays_fee\": false,\n \"expired_at\": \"1705305600000\",\n \"whitelisted_payment_method\": [\n \"<string>\"\n ],\n \"redirect_url\": \"https://example.com/payment-link\",\n \"success_redirect_url\": \"https://merchant.example.com/payment/success\",\n \"expired_redirect_url\": \"https://merchant.example.com/payment/expired\",\n \"optional_metadata\": {\n \"invoice_number\": \"INV20240513001\"\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-PARTNER-ID", "<api-key>")
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.put("https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}")
.header("Authorization", "Bearer <token>")
.header("X-PARTNER-ID", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"max_usage\": 1,\n \"status\": \"open\",\n \"required_customer_detail\": true,\n \"customer_pays_fee\": false,\n \"expired_at\": \"1705305600000\",\n \"whitelisted_payment_method\": [\n \"<string>\"\n ],\n \"redirect_url\": \"https://example.com/payment-link\",\n \"success_redirect_url\": \"https://merchant.example.com/payment/success\",\n \"expired_redirect_url\": \"https://merchant.example.com/payment/expired\",\n \"optional_metadata\": {\n \"invoice_number\": \"INV20240513001\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["X-PARTNER-ID"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"max_usage\": 1,\n \"status\": \"open\",\n \"required_customer_detail\": true,\n \"customer_pays_fee\": false,\n \"expired_at\": \"1705305600000\",\n \"whitelisted_payment_method\": [\n \"<string>\"\n ],\n \"redirect_url\": \"https://example.com/payment-link\",\n \"success_redirect_url\": \"https://merchant.example.com/payment/success\",\n \"expired_redirect_url\": \"https://merchant.example.com/payment/expired\",\n \"optional_metadata\": {\n \"invoice_number\": \"INV20240513001\"\n }\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"success": true,
"data": {
"id": 103,
"reff_no": "INV20240513001",
"title": "Invoice Payment",
"description": "Invoice #INV20240513001",
"source": "api v2",
"payment_url": "https://example.com/payment-link",
"status": "open",
"status_computed": "open",
"is_expired": false,
"required_customer_detail": true,
"is_multiple_payment": false,
"is_unlimited_usage": false,
"required_customer_fields": {
"name": true,
"phone": false,
"email": false
},
"customer_pays_fee": false,
"max_usage": 1,
"current_usage": 0,
"expired_at": "2024-05-13T00:00:00Z",
"total_amount": 150000,
"items": [
{
"name": "Product A",
"quantity": 1,
"unit_price": 150000,
"subtotal": 150000
}
],
"whitelisted_payment_method": [
"<string>"
],
"redirect_url": "https://example.com/payment-link",
"success_redirect_url": "https://merchant.example.com/payment/success",
"expired_redirect_url": "https://merchant.example.com/payment/expired",
"customer_name": "Jane Doe",
"customer_email": "jane@example.com",
"customer_phone": "081234567890",
"optional_metadata": {},
"payment_date": "2024-05-13T00:00:00Z",
"created_at": "2024-05-13T00:00:00Z",
"updated_at": "2024-05-13T00:00:00Z",
"account": {
"id": 1,
"name": "Account 1"
}
}
}{
"status": 401,
"success": false,
"error": {
"code": 401,
"message": "Unauthorized merchant, please sign in"
}
}{
"status": 404,
"success": false,
"error": {
"code": 404,
"message": "Account not found."
}
}{
"status": 405,
"success": false,
"error": {
"code": 4059901,
"message": "The PATCH method is not supported for this route. Supported methods: GET, HEAD, POST."
}
}{
"status": 422,
"success": false,
"error": {
"code": 422,
"message": "Validation error.",
"errors": {
"field": [
"error message"
]
}
},
"data": {
"errors": {
"field": [
"error message"
]
}
}
}Update v1 (Legacy)
Updates an existing payment link within the specified account. Only mutable fields are accepted in the request body.
curl --request PUT \
--url https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-PARTNER-ID: <api-key>' \
--data '
{
"max_usage": 1,
"status": "open",
"required_customer_detail": true,
"customer_pays_fee": false,
"expired_at": "1705305600000",
"whitelisted_payment_method": [
"<string>"
],
"redirect_url": "https://example.com/payment-link",
"success_redirect_url": "https://merchant.example.com/payment/success",
"expired_redirect_url": "https://merchant.example.com/payment/expired",
"optional_metadata": {
"invoice_number": "INV20240513001"
}
}
'import requests
url = "https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}"
payload = {
"max_usage": 1,
"status": "open",
"required_customer_detail": True,
"customer_pays_fee": False,
"expired_at": "1705305600000",
"whitelisted_payment_method": ["<string>"],
"redirect_url": "https://example.com/payment-link",
"success_redirect_url": "https://merchant.example.com/payment/success",
"expired_redirect_url": "https://merchant.example.com/payment/expired",
"optional_metadata": { "invoice_number": "INV20240513001" }
}
headers = {
"Authorization": "Bearer <token>",
"X-PARTNER-ID": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {
Authorization: 'Bearer <token>',
'X-PARTNER-ID': '<api-key>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
max_usage: 1,
status: 'open',
required_customer_detail: true,
customer_pays_fee: false,
expired_at: '1705305600000',
whitelisted_payment_method: ['<string>'],
redirect_url: 'https://example.com/payment-link',
success_redirect_url: 'https://merchant.example.com/payment/success',
expired_redirect_url: 'https://merchant.example.com/payment/expired',
optional_metadata: {invoice_number: 'INV20240513001'}
})
};
fetch('https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}', 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://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'max_usage' => 1,
'status' => 'open',
'required_customer_detail' => true,
'customer_pays_fee' => false,
'expired_at' => '1705305600000',
'whitelisted_payment_method' => [
'<string>'
],
'redirect_url' => 'https://example.com/payment-link',
'success_redirect_url' => 'https://merchant.example.com/payment/success',
'expired_redirect_url' => 'https://merchant.example.com/payment/expired',
'optional_metadata' => [
'invoice_number' => 'INV20240513001'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json",
"X-PARTNER-ID: <api-key>"
],
]);
$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://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}"
payload := strings.NewReader("{\n \"max_usage\": 1,\n \"status\": \"open\",\n \"required_customer_detail\": true,\n \"customer_pays_fee\": false,\n \"expired_at\": \"1705305600000\",\n \"whitelisted_payment_method\": [\n \"<string>\"\n ],\n \"redirect_url\": \"https://example.com/payment-link\",\n \"success_redirect_url\": \"https://merchant.example.com/payment/success\",\n \"expired_redirect_url\": \"https://merchant.example.com/payment/expired\",\n \"optional_metadata\": {\n \"invoice_number\": \"INV20240513001\"\n }\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("X-PARTNER-ID", "<api-key>")
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.put("https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}")
.header("Authorization", "Bearer <token>")
.header("X-PARTNER-ID", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"max_usage\": 1,\n \"status\": \"open\",\n \"required_customer_detail\": true,\n \"customer_pays_fee\": false,\n \"expired_at\": \"1705305600000\",\n \"whitelisted_payment_method\": [\n \"<string>\"\n ],\n \"redirect_url\": \"https://example.com/payment-link\",\n \"success_redirect_url\": \"https://merchant.example.com/payment/success\",\n \"expired_redirect_url\": \"https://merchant.example.com/payment/expired\",\n \"optional_metadata\": {\n \"invoice_number\": \"INV20240513001\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://sandbox-payment-b2b.singapay.id/api/v1.0/payment-link-manage/{account_id}/{payment_link_id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["X-PARTNER-ID"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"max_usage\": 1,\n \"status\": \"open\",\n \"required_customer_detail\": true,\n \"customer_pays_fee\": false,\n \"expired_at\": \"1705305600000\",\n \"whitelisted_payment_method\": [\n \"<string>\"\n ],\n \"redirect_url\": \"https://example.com/payment-link\",\n \"success_redirect_url\": \"https://merchant.example.com/payment/success\",\n \"expired_redirect_url\": \"https://merchant.example.com/payment/expired\",\n \"optional_metadata\": {\n \"invoice_number\": \"INV20240513001\"\n }\n}"
response = http.request(request)
puts response.read_body{
"status": 200,
"success": true,
"data": {
"id": 103,
"reff_no": "INV20240513001",
"title": "Invoice Payment",
"description": "Invoice #INV20240513001",
"source": "api v2",
"payment_url": "https://example.com/payment-link",
"status": "open",
"status_computed": "open",
"is_expired": false,
"required_customer_detail": true,
"is_multiple_payment": false,
"is_unlimited_usage": false,
"required_customer_fields": {
"name": true,
"phone": false,
"email": false
},
"customer_pays_fee": false,
"max_usage": 1,
"current_usage": 0,
"expired_at": "2024-05-13T00:00:00Z",
"total_amount": 150000,
"items": [
{
"name": "Product A",
"quantity": 1,
"unit_price": 150000,
"subtotal": 150000
}
],
"whitelisted_payment_method": [
"<string>"
],
"redirect_url": "https://example.com/payment-link",
"success_redirect_url": "https://merchant.example.com/payment/success",
"expired_redirect_url": "https://merchant.example.com/payment/expired",
"customer_name": "Jane Doe",
"customer_email": "jane@example.com",
"customer_phone": "081234567890",
"optional_metadata": {},
"payment_date": "2024-05-13T00:00:00Z",
"created_at": "2024-05-13T00:00:00Z",
"updated_at": "2024-05-13T00:00:00Z",
"account": {
"id": 1,
"name": "Account 1"
}
}
}{
"status": 401,
"success": false,
"error": {
"code": 401,
"message": "Unauthorized merchant, please sign in"
}
}{
"status": 404,
"success": false,
"error": {
"code": 404,
"message": "Account not found."
}
}{
"status": 405,
"success": false,
"error": {
"code": 4059901,
"message": "The PATCH method is not supported for this route. Supported methods: GET, HEAD, POST."
}
}{
"status": 422,
"success": false,
"error": {
"code": 422,
"message": "Validation error.",
"errors": {
"field": [
"error message"
]
}
},
"data": {
"errors": {
"field": [
"error message"
]
}
}
}Authorizations
JWT issued by POST /api/v1.1/access-token/b2b. Send Authorization: Bearer <token>.
Merchant API key (Credential.api_key). Required on every request.
Path Parameters
Account identifier in ULID format.
Payment link identifier (payment_links.id).
Body
Maximum number of times this link may be used for payment. Must be greater than or equal to the current usage count.
1 <= x <= 10000001
Payment link lifecycle status.
open, closed, expired "open"
Whether customer details are required at checkout. If omitted, defaults to false.
true
When true, payment method fees are added to the amount charged to the payer. Omit to keep the current value.
false
Optional expiration time as a Unix timestamp in milliseconds (13 digits).
^\d{13}$"1705305600000"
Restricts accepted payment methods for this link. Send an empty array to allow all active payment-link methods. Each entry must be a valid payment method code from the payment methods catalog.
Optional URL to redirect the payer after payment flow completion.
2048"https://example.com/payment-link"
URL to redirect the payer after successful payment. Must start with http:// or https://.
2048"https://merchant.example.com/payment/success"
URL to redirect the payer after payment expiry. Must start with http:// or https://.
2048"https://merchant.example.com/payment/expired"
Optional merchant-defined metadata for this payment link.
{ "invoice_number": "INV20240513001" }
