Skip to main content
POST
Create v2

Authorizations

Authorization
string
header
required

JWT issued by POST /api/v1.1/access-token/b2b. Send Authorization: Bearer <token>.

X-PARTNER-ID
string
header
required

Merchant API key (Credential.api_key). Required on every request.

Path Parameters

account_id
string
required

Account identifier in ULID format.

Body

application/json

v2 simplifies the v1 body: title, is_multiple_payment, is_unlimited_usage, and redirect_url_enabled are no longer accepted — they are derived automatically from the other fields.

reff_no
string
required

Merchant reference number for this payment link.

Maximum string length: 40
Pattern: ^[^\s\/]+$
Example:

"INV20240513001"

Must be exactly total or items (422 on any other value). Determines which of total_amount / items is required — the other one must not be sent at all: total requires total_amount and rejects items if sent (422); items requires items and rejects total_amount if sent (422), since it's computed from items server-side.

Available options:
total,
items
Example:

"total"

description
string | null

Optional free-text description for the payment link.

Maximum string length: 255
Example:

"Invoice #INV20240513001"

max_usage
integer | null

Maximum number of successful payments allowed. Omit for a single-use link (defaults to 1). 0 means unlimited. Any value greater than 1 makes this a multi-use link — is_multiple_payment/is_unlimited_usage/required_customer_detail are derived from this value and cannot be set directly.

Required range: 0 <= x <= 999
Example:

1

expired_at
string<date-time> | null

Optional expiration timestamp, any date/time string parseable by PHP (ISO 8601 recommended, e.g. 2026-08-10T00:00:00+07:00). Must be in the future. Omit or send null to default to 24 hours from creation (D+1) — unlike v1, this is never left unset.

Example:

"2026-08-10T00:00:00+07:00"

total_amount
number | null

Total payment amount. Required when payment_link_type is total; must not be sent at all when payment_link_type is items (422) — it's computed from items server-side instead, so sending both would be ambiguous. Minimum/maximum depend on merchant configuration and the resolved payment methods.

Example:

150000

items
object[] | null

Line items. Required when payment_link_type is items; must not be sent at all when payment_link_type is total (422).

Minimum array length: 1
whitelisted_payment_method
string[] | null

Restricts accepted payment methods for this link. Omit, send null, or send an empty array to auto-select whichever active payment-link methods are actually eligible for the resolved total_amount — v2 never leaves this unrestricted the way v1 does. Each entry must be a valid payment method code.

success_redirect_url
string<uri> | null

URL to redirect the payer after successful payment. Must start with http:// or https://. Sending either this or expired_redirect_url automatically enables redirect_url.

Maximum string length: 2048
Example:

"https://merchant.example.com/payment/success"

expired_redirect_url
string<uri> | null

URL to redirect the payer after payment expiry. Must start with http:// or https://.

Maximum string length: 2048
Example:

"https://merchant.example.com/payment/expired"

optional_metadata
object | null

Optional merchant-defined metadata stored with the payment link.

customer_name
string | null

Pre-fills the known customer name for a single-use link. Only allowed when max_usage resolves to 1; sending this alongside a multi-use max_usage returns a 422. Required together with customer_email/customer_phone if any of the three is provided, and required (along with the other two) whenever customer_notification_preference.payment_link_created or customer_notification_preference.payment_link_reminder is non-empty — regardless of which channel(s) are selected.

Maximum string length: 100
Example:

"Jane Doe"

customer_email
string<email> | null

Pre-fills the known customer email. See customer_name.

Maximum string length: 255
Example:

"jane@example.com"

customer_phone
string | null

Pre-fills the known customer phone number. Unlike customer_name/customer_email, not required merely by providing one of the other two fields — only required when customer_notification_preference.payment_link_created or customer_notification_preference.payment_link_reminder is non-empty.

Maximum string length: 50
Example:

"081234567890"

required_customer_number
boolean | null

Only meaningful when max_usage > 1. Whether the payer must fill in a phone number at checkout. Defaults to true for multi-use links unless explicitly set to false.

Example:

true

required_customer_email
boolean | null

Only meaningful when max_usage > 1. Whether the payer must fill in an email at checkout. Defaults to true for multi-use links unless explicitly set to false.

Example:

true

customer_notification_preference
object | null

Which channels notify the customer at each lifecycle event. Only accepted for a single-use link. Having any channel (whatsapp or email) in either payment_link_created or payment_link_reminder requires customer_name, customer_email, AND customer_phone all three — not just the field the selected channel would use (422 if any is missing). WhatsApp incurs a fixed notification fee charged to the merchant's balance at send time; email is always free.

reminder_unit
enum<string> | null

Unit for reminder_period. Tied directly to customer_notification_preference.payment_link_reminder, not just to reminder_period: required (422 if missing) whenever payment_link_reminder has at least one channel, and prohibited (422 if sent) whenever it's empty or customer_notification_preference is omitted entirely.

Available options:
day,
hour
Example:

"day"

reminder_period
integer | null

How long before expired_at the reminder fires, in reminder_unit units: 1–24 for hour, 1–30 for day. Must resolve to a time strictly after created_at (422 otherwise). Same payment_link_reminder-tied required/prohibited 422 rule as reminder_unit.

Example:

1

Response

Created

status
integer
required

HTTP status code.

Example:

200

success
boolean
required

Indicates whether the request was successful.

Example:

true

data
object

Payment link resource payload.