このページは現在翻訳中です。

Payment Links+

このページで扱うトピック

Payment Links+ API

Payment Links+ is the solution for creating secure payment links with your branding. With Payment Links+, you can effortlessly set up and share payment links, regardless of the sales channel or payment method. To learn more, check out Payment Links+.

This document explains the Payment Links+ API functions.

🔓 Authorization

The Payment Links+ API requires an API key to authenticate calls. Retrieve this key from Settings > API Keys on the Payment Links+ dashboard, and pass it in the Authorization header.

curl --location 'https://linksplus-api.omise.co/external/links' \
--header 'Authorization: {{key}}'

⚠️ Roll your key with care: once a key is rolled from the API Keys screen, the old value is never shown again. If you lose track of the current key, generate a new one by rolling it again — there's no way to retrieve a rolled key afterward.

🧾 Objects

Every endpoint on this page returns one of the objects described here. Rather than repeating the full shape under each endpoint, each one is defined once and referenced by name throughout.

Field Type Description
id integer The link's unique ID.
name string The link's display name. Up to 45 characters.
currency string The payment currency.
amount integer The charge amount, in the smallest unit of currency. Minimum 100.
multiple_usage boolean Whether the link can be used more than once.
additional string, nullable A free-text note about the link, up to 255 characters. Hidden by default on the payment form.
expired_at string, ISO 8601, nullable When the link expires. Returns null if no expiry is set.
features object Key-value pairs matching the product detail fields configured on the link's template.
transaction_id string The ID portion of url.
url string The URL to share with the customer to complete payment.
state string The link's lifecycle stage: "active", "expired", or "used".
template_id integer The template the link was created from.
kind string, nullable null for a standard link, "quick_link" for a link created without a manually selected template.
created_at string, ISO 8601 When the link was created.
updated_at string, ISO 8601 When the link was last updated.
{
  "id": 12840,
  "name": "Adidas School Wear",
  "state": "active",
  "amount": 4000,
  "currency": "THB",
  "multiple_usage": true,
  "additional": "Order #12345 - priority shipping",
  "expired_at": "2026-12-31T23:59:59Z",
  "features": {
    "Type": "School Bags",
    "Size": "Medium"
  },
  "transaction_id": "lNeJd4VbUI",
  "url": "https://linksplus.omise.co/lNeJd4VbUI",
  "template_id": 3672,
  "kind": null,
  "created_at": "2024-04-20T12:23:39.321Z",
  "updated_at": "2024-04-20T12:23:39.321Z"
}

The Template object

Field Type Description
id integer The template's unique ID.
name string The template's display name.
features array of objects The product detail fields configured on the template. Each entry has display_name, value (always null here, reflecting the field definition rather than a filled-in value), and type.
capabilities array of Capability objects The payment methods, currencies, and card brands available on links created from this template.
zero_interest_installment boolean Whether zero-interest installments are enabled.
created_at string, ISO 8601 When the template was created.
updated_at string, ISO 8601 When the template was last updated.

ℹ️ Note: a template's features is an array of field *definitions* (label, type, and an empty value). A link's features is a flat object of the actual values entered for that link. Don't expect the same shape from both.

{
  "id": 3672,
  "name": "Adidas Bags",
  "features": [
    { "display_name": "Type", "value": null, "type": "string" },
    { "display_name": "Size", "value": null, "type": "string" }
  ],
  "capabilities": [
    "... see The Capability object for the \"card\" entry ...",
    "... a second entry with \"payment_method\": \"promptpay\" ..."
  ],
  "zero_interest_installment": false,
  "created_at": "2024-04-19T10:16:49.689Z",
  "updated_at": "2024-04-19T10:16:49.689Z"
}

The Capability object

Each entry in a Template object's capabilities array describes one payment method available on it. A template supporting multiple payment methods has one Capability object per method — the example following shows a single card entry, followed by what the full array looks like when a template also accepts PromptPay.

Field Type Description
payment_method string e.g. "card", "internet_banking_bbl", "promptpay", "truemoney".
currencies array of strings Currencies supported for this payment method.
card_brands array of strings e.g. "JCB", "Visa", "MasterCard". Present even for non-card methods, though it doesn't apply to them.
installment_terms array Available installment terms, if any.
banks array Available banks, if any.
manual boolean Card capability only.
saveCard boolean Card capability only.
{
  "payment_method": "card",
  "currencies": ["THB", "JPY", "USD", "EUR", "GBP", "SGD", "AUD", "CHF", "CNY", "DKK", "HKD", "MYR"],
  "card_brands": ["JCB", "Visa", "MasterCard"],
  "installment_terms": [],
  "banks": [],
  "manual": false,
  "saveCard": false
}

A capabilities array with more than one payment method looks like this — note that manual and saveCard only appear on the card entry, matching the preceding table:

[
  {
    "payment_method": "card",
    "currencies": ["THB", "JPY", "USD", "EUR", "GBP", "SGD", "AUD", "CHF", "CNY", "DKK", "HKD", "MYR"],
    "card_brands": ["JCB", "Visa", "MasterCard"],
    "installment_terms": [],
    "banks": [],
    "manual": false,
    "saveCard": false
  },
  {
    "payment_method": "promptpay",
    "currencies": ["THB"],
    "card_brands": ["JCB", "Visa", "MasterCard"],
    "installment_terms": [],
    "banks": []
  }
]

🚫 Errors

Every error response shares the same shape:

{
  "object": "error",
  "code": "bad_request",
  "message": "human-readable description of what went wrong"
}

The 401 authentication error additionally includes a location field linking to the API errors reference:

{
  "object": "error",
  "location": "https://www.omise.co/api-errors#authentication-failure",
  "code": "authentication_failure",
  "message": "authentication failed"
}
HTTP Status code Meaning
400 bad_request The request is malformed, or a parameter failed validation. The message field describes the specific problem — see each endpoint's own section for examples unique to it.
401 authentication_failure The API key is missing or invalid.
403 forbidden Your API key doesn't have permission for this action, or doesn't have access to the company that owns the resource.
404 not_found The resource in the URL path (a link, template, or team ID) doesn't exist.

Only unique error cases are called out again under individual endpoints. Every endpoint can also return 400, 401, and 403, whether or not they're repeated there.

🛠️ Endpoints

Object Endpoint
Template GET /external/templates/:template_id
GET /external/:team_id/templates
Link GET /external/links/:link_id
GET /external/:team_id/links
POST /external/links
PUT /external/links/:link_id

Retrieve a template

GET /external/templates/:template_id

Returns the Template object for the specified ID. Find a template's ID on the Payment Links+ dashboard, under Create Template — the 4-digit number shown under each template thumbnail.

Path parameter: template_id (integer, required)

curl 'https://linksplus-api.omise.co/external/templates/3655' \
-X GET \
-h 'Authorization: {{key}}'

Returns: a Template object on success (200):

{
  "id": 3655,
  "name": "Nike Shoes",
  "features": [],
  "capabilities": ["... see The Capability object ..."],
  "zero_interest_installment": false,
  "created_at": "2024-04-17T08:35:55.390Z",
  "updated_at": "2024-04-17T08:35:55.390Z"
}

Unique errors: 404 if the template ID doesn't exist ("message": "template not found").

Retrieve all templates for a team

GET /external/:team_id/templates

Returns the templates belonging to the specified team. Find a team's ID on the dashboard, under Settings > Teams.

Path parameter: team_id (integer, required)

curl 'https://linksplus-api.omise.co/external/3388/templates' \
-X GET \
-h 'Authorization: {{key}}'

Returns: {"templates": [Template, ...], "total": N}:

{
  "templates": [
    {
      "id": 3672,
      "name": "Adidas Bags",
      "features": [
        { "display_name": "Type", "value": null, "type": "string" },
        { "display_name": "Size", "value": null, "type": "string" }
      ],
      "capabilities": [
        "... see The Capability object for the \"card\" entry ...",
        "... a second entry with \"payment_method\": \"promptpay\" ..."
      ],
      "zero_interest_installment": false,
      "created_at": "2024-04-19T10:16:49.689Z",
      "updated_at": "2024-04-19T10:16:49.689Z"
    },
    {
      "id": 3655,
      "name": "Nike Shoes",
      "features": [],
      "capabilities": ["... see The Capability object ..."],
      "zero_interest_installment": false,
      "created_at": "2024-04-17T08:35:55.390Z",
      "updated_at": "2024-04-17T08:35:55.390Z"
    }
  ],
  "total": 2
}

Unique errors: 404 if the team ID doesn't exist ("message": "team not found").

GET /external/links/:link_id

Returns the Link object for the specified ID. Click Overview, then a payment link, to find its ID in the dashboard URL.

Path parameter: link_id (integer, required)

curl 'https://linksplus-api.omise.co/external/links/12838' \
-X GET \
-h 'Authorization: {{key}}'

Returns: a Link object on success (200):

{
  "id": 12838,
  "name": "Adidas Bags",
  "state": "active",
  "amount": 200000,
  "currency": "THB",
  "multiple_usage": true,
  "additional": null,
  "expired_at": null,
  "features": {
    "Type": "School Bags",
    "Size": "Medium"
  },
  "transaction_id": "q16j2t7uF2",
  "url": "https://linksplus.omise.co/q16j2t7uF2",
  "template_id": 3672,
  "kind": null,
  "created_at": "2024-04-19T10:58:37.429Z",
  "updated_at": "2024-04-19T10:58:37.429Z"
}

Unique errors: 404 if the link ID doesn't exist ("message": "link not found").

GET /external/:team_id/links

Returns the links belonging to the specified team. Find a team's ID on the dashboard, under Settings > Teams.

Path parameter: team_id (integer, required)

curl 'https://linksplus-api.omise.co/external/3388/links' \
-X GET \
-h 'Authorization: {{key}}'

Returns: {"links": [Link, ...], "total": N}:

{
  "links": [
    {
      "id": 12838,
      "name": "Adidas Bags",
      "state": "active",
      "amount": 200000,
      "currency": "THB",
      "multiple_usage": true,
      "additional": null,
      "expired_at": null,
      "features": {
        "Type": "School Bags",
        "Size": "Medium"
      },
      "transaction_id": "q16j2t7uF2",
      "url": "https://linksplus.omise.co/q16j2t7uF2",
      "template_id": 3672,
      "kind": null,
      "created_at": "2024-04-19T10:58:37.429Z",
      "updated_at": "2024-04-19T10:58:37.429Z"
    }
  ],
  "total": 1
}

Unique errors: 404 if the team ID doesn't exist ("message": "team not found").

POST /external/links

Creates a link from the specified template. If the template has product detail fields configured, you must pass the value of each as a features key/value pair.

Parameters

Name Type Required Description
template_id integer Yes The template to use for the link.
team_id integer Yes The team that will own the link. Find a team's ID on the dashboard, under Settings > Teams.
name string Yes The link's display name. Up to 45 characters.
currency string Yes The payment currency.
amount integer Yes The charge amount, in the smallest unit of currency. Minimum 100.
multiple_usage boolean Yes Whether the link can be used more than once.
additional string, nullable No A free-text note about the link, up to 255 characters. Hidden by default on the payment form.
expired_at string, nullable No An ISO 8601 date-time with any timezone offset (e.g. 2026-12-31T23:59:59Z), stored and returned in UTC. Must be a future date. Same format as on Update a link.
features object Conditional Required only if the template has product detail fields configured. Each key must exactly match a configured field name (e.g. Date, Order_ID) — a key that doesn't match returns an error.
custom_webhook string No A custom HTTPS webhook URL for this link — see Webhook configuration, following.
returnUrl string No The URL to redirect users to after payment. Priority order: (1) this value, (2) the template's configured return URL, (3) the account's return URL under Settings > Return URL. If none are set, no redirect button appears on the success page.
curl 'https://linksplus-api.omise.co/external/links' \
    -X POST \
    -h 'Authorization: {{key}}' \
    -d "template_id=3672" \
    -d "team_id=3388" \
    -d "name=Adidas School Wear" \
    -d "currency=THB" \
    -d "amount=4000" \
    -d "features[Type]=School Bags" \
    -d "features[Size]=Medium" \
    -d "multiple_usage=true" \
    -d "additional=Order #12345 - priority shipping" \
    -d "expired_at=2026-12-31T23:59:59Z" \
    -d "custom_webhook=https://merchant.com/payment-webhook" \
    -d "returnUrl=https://demostore.com/payment_status"

Both form-encoded (as shown) and raw JSON request bodies work — Postman's Body → raw → JSON mode sends the same fields as a nested JSON object instead of -d flags.

Returns: a Link object on success (201):

{
  "id": 12840,
  "name": "Adidas School Wear",
  "state": "active",
  "amount": 4000,
  "currency": "THB",
  "multiple_usage": true,
  "additional": "Order #12345 - priority shipping",
  "expired_at": "2026-12-31T23:59:59Z",
  "features": {
    "Type": "School Bags",
    "Size": "Medium"
  },
  "transaction_id": "lNeJd4VbUI",
  "url": "https://linksplus.omise.co/lNeJd4VbUI",
  "template_id": 3672,
  "kind": null,
  "created_at": "2024-04-20T12:23:39.321Z",
  "updated_at": "2024-04-20T12:23:39.321Z"
}

Unique errors: 400 if the template has product detail fields but a required features key is missing ("message": "invalid features. \"Date\" is required").

Webhook configuration

Payment Links+ supports up to three webhook endpoints per payment:

  • Default System Webhook — configured automatically by Payment Links+.
  • Dashboard Webhook — configured in your Merchant Dashboard and fetched automatically.
  • Custom API Webhook — set per link via custom_webhook (v3.10.0+).

⚠️ Requirement: only HTTPS URLs are accepted for custom_webhook. A custom webhook failure never blocks payment processing — the other configured webhooks still fire normally, and all configured webhooks receive the same event notifications.

PUT /external/links/:link_id

Updates an existing link. Every body field is optional — send only what you want to change.

Path parameter: link_id (integer, required)

Parameters

Name Type Description
template_id integer A different template for the link.
name string Up to 45 characters.
currency string One of THB, USD, EUR, GBP, JPY, SGD, MYR. Narrower than the currencies available when creating a link — AUD, CHF, CNY, DKK, and HKD can't be set through this endpoint.
amount integer Minimum 100.
multiple_usage boolean Whether the link can be used more than once.
features object Link-specific feature values.
additional string Up to 255 characters. Hidden by default on the payment form.
expired_at string, nullable An ISO 8601 date-time with any timezone offset (e.g. 2026-12-31T23:59:59Z), stored and returned in UTC. Must be a future date. Pass null to clear an existing expiry.
returnUrl string The URL to redirect users to after payment.

ℹ️ Note: expired_at uses the same ISO 8601 date-time format on Create a payment link as it does here.

ℹ️ Note: team_id can't be changed through this endpoint — a link can't be moved to a different team after creation.

curl 'https://linksplus-api.omise.co/external/links/789' \
    -X PUT \
    -h 'Authorization: {{key}}' \
    -H 'Content-Type: application/json' \
    -d '{
      "name": "Updated Payment for Order #12345",
      "amount": 15000,
      "expired_at": "2026-12-31T23:59:59Z"
    }'

Returns: the updated Link object on success (200):

{
  "id": 789,
  "name": "Updated Payment for Order #12345",
  "state": "active",
  "amount": 15000,
  "currency": "THB",
  "multiple_usage": false,
  "additional": null,
  "expired_at": "2026-12-31T23:59:59Z",
  "features": {},
  "transaction_id": "wz4qSdsqCG",
  "url": "https://linksplus.omise.co/wz4qSdsqCG",
  "template_id": 2615,
  "kind": null,
  "created_at": "2024-09-30T06:21:37.251Z",
  "updated_at": "2024-10-01T09:26:21.416Z"
}

Unique errors: 404 if the link ID doesn't exist.

Once you've created a link, send its url to the customer to complete the payment.

ℹ️ Dashboard timing differs between Payment Links+ and Omise: a created link appears immediately in the Payment Links+ dashboard. In the Omise Payments dashboard, the corresponding charge doesn't appear until the customer actually attempts the transaction — a completed payment is marked successful, a customer who drops off during the OTP step leaves it pending, and a customer who cancels during OTP leaves it marked failed.

Finding a charge on the Omise dashboard

After a customer attempts or completes a transaction, find the matching charge using either the link's id or its features:

  1. Go to Charges on the Omise Payments dashboard.
  2. Select Advanced Search.
  3. Choose Metadata as the filter.
  4. Enter the id or features value from the API response.

ℹ️ Webhook field mapping: webhook payloads use link_id rather than idlink_id in a webhook corresponds to the id field returned by the API.

❓ FAQ

Q: Does the create-link endpoint accept JSON, or only form-encoded data? A: Both. Send parameters as form-encoded -d fields in curl, or as a raw JSON body — Postman's Body → raw → JSON mode works the same way.

Q: What format does expired_at expect? A: The same on both endpoints — an ISO 8601 date-time string with any timezone offset (e.g. 2026-12-31T23:59:59Z), stored and returned in UTC, and must be a future date.

Q: Can I change which team a link belongs to? A: No. team_id is required when creating a link but isn't accepted when updating one — a link can't move between teams after creation.

Q: I passed a features value and still got a validation error. Why? A: The keys must exactly match the product detail field names configured on the template, not any name you choose. Check the template's configuration in Create Template on the dashboard for the exact field names.

Q: What values can a link's state have? A: active, expired, or used — see The Link object.

Q: I don't see a charge on the Omise dashboard right after creating a link. Is something wrong? A: No — a charge only appears there once the customer attempts the transaction. It appears immediately on the Payment Links+ dashboard.

Q: How do I set a custom webhook without going through the dashboard? A: Pass a HTTPS URL in custom_webhook when creating the link — see Webhook configuration.

Omiseは、お客様のウェブサイト全般における利便性を向上するためにクッキーを利用し、お客様のアクセス、閲覧履歴に関する情報を収集します。 当社のウェブサイトを閲覧し続けることにより、お客様は当社のプライバシーポリシーに同意することとします。 詳細はこちら