Skip to main content

Bind a Customer via LINE Login

Let your members bind their own LINE account. You just hand LOMA a member ID (customerExternalId); LOMA returns a one-time LINE authorization link. After the member authorizes on LINE, LOMA automatically binds that member to their LINE account and 302-redirects back to a URL you specify.

Once bound, you can send messages (notifications / OTP) to that member.

Flow

  1. Your backend calls POST /api/v1/merchant/binding/line-login with the member ID and a returnUrl.
  2. LOMA returns a one-time bindingUrl (valid 10 minutes by default).
  3. You redirect / open bindingUrl for the member. They tap “Allow” on the LINE page.
  4. LINE calls LOMA back → LOMA fetches the member's LINE userId and stores the binding.
  5. LOMA 302-redirects the member back to your returnUrl with the result.
POST /api/v1/merchant/binding/line-login

Headers

Requires X-Api-Key and X-Api-Secret (see Authentication).

Body

FieldTypeRequiredDescription
customerExternalIdstringYour member / customer ID
returnUrlstringWhere LOMA redirects after binding completes
{
"customerExternalId": "C10086",
"returnUrl": "https://your-app.com/line/bound"
}

Success 200

{
"code": "OK",
"message": "Success",
"requestId": "req_...",
"data": {
"bindingUrl": "https://access.line.me/oauth2/v2.1/authorize?response_type=code&client_id=...&state=...",
"state": "9f2a...c1",
"expiresAt": "2026-07-02T08:20:00Z"
}
}
FieldDescription
bindingUrlOne-time LINE authorization link — redirect the member here
stateOne-time token (LOMA-internal; you don't need to handle it)
expiresAtLink expiry (UTC); after this, create a new link

Common errors

codeHTTPDescription
LOGIN_NOT_CONFIGURED400Merchant has no LINE Login channel configured
VALIDATION_ERROR400customerExternalId or returnUrl missing

2. Redirect result

After the member finishes (or cancels), LOMA 302-redirects the browser to your returnUrl with these query params appended:

Success:

https://your-app.com/line/bound?binding=success&customerExternalId=C10086

Failed / cancelled:

https://your-app.com/line/bound?binding=failed&customerExternalId=C10086&reason=cancelled
ParamDescription
bindingsuccess / failed
customerExternalIdThe member ID for this binding (echoed back)
reasonOnly on failure: cancelled (user cancelled) / expired (link expired) / already_used (link consumed) / ALREADY_BOUND (member already bound to another LINE) / LINE_ALREADY_BOUND (LINE already bound to another member) / exchange_failed (LINE exchange failed)

⚠️ Redirect params are for UI hints only. Trust the server: after the redirect, re-confirm with Check binding status before proceeding.

3. Unbind a customer

Remove a member's current LINE binding. After unbinding, the member can go through the binding flow again (rebinding to a different LINE account also requires unbinding first).

DELETE /api/v1/merchant/customer/{customerExternalId}/line-binding

Headers

Requires X-Api-Key and X-Api-Secret (see Authentication).

Path params

ParamDescription
customerExternalIdYour member / customer ID

Success 200

{
"code": "OK",
"message": "Success",
"requestId": "req_...",
"data": {
"customerExternalId": "C10086",
"unbound": true,
"status": "UNBOUND"
}
}
FieldDescription
unboundWhether an active binding was removed this call. true = unbound; false = the member had no active binding (nothing to do)
statusAlways UNBOUND

Idempotent: calling it repeatedly for the same member never errors; when there's nothing to remove it returns unbound=false.

Example

curl -X DELETE https://loma-dev.acorners.com/api/v1/merchant/customer/C10086/line-binding \
-H "X-Api-Key: lk_xxxx" -H "X-Api-Secret: xxxx"

Idempotency & constraints

  • One member maps to exactly one LINE account, and vice versa.
  • Re-binding the same member with the same LINE account is idempotent — returns success, no duplicate record.
  • To rebind, call the unbind endpoint first, then run the binding flow again.

Example

curl -X POST https://loma-dev.acorners.com/api/v1/merchant/binding/line-login \
-H "X-Api-Key: lk_xxxx" -H "X-Api-Secret: xxxx" \
-H "Content-Type: application/json" \
-d '{"customerExternalId":"C10086","returnUrl":"https://your-app.com/line/bound"}'