LINE Pay Online API
raw JSON → 0.2.0 verified Tue May 12 auth: no python install: verified quickstart: stale
LINE Pay is a mobile payment service by LY Corporation, integrated with the LINE messaging platform. Active in Taiwan and Thailand. Japan service terminated April 30, 2025 (merged into PayPay). No official Python SDK — integration requires raw HTTP with custom HMAC-SHA256 signature. The community SDK on PyPI (line-pay 0.2.0) is unmaintained since 2020.
pip install requests Common errors
error ModuleNotFoundError: No module named 'line_pay' ↓
cause The 'line-pay' package is not installed in your current Python environment.
fix
Run
pip install line-pay in your terminal to install the library. error ImportError: cannot import name 'LinePayApi' from 'line_pay' ↓
cause The class or object 'LinePayApi' cannot be found directly under the 'line_pay' module, possibly due to a typo, an outdated import path, or a change in the library's structure.
fix
Verify the correct class name and import path by consulting the library's source code or available documentation, or try alternative imports like
from line_pay.api import LinePayApi. error AttributeError: 'LinePayApi' object has no attribute 'request' ↓
cause You are attempting to call a method or access an attribute named 'request' that does not exist on the `LinePayApi` object, likely due to a typo, an outdated method name, or an incomplete/changed API in the unmaintained library.
fix
Inspect the
LinePayApi object's available attributes and methods using dir(your_linepay_object) or review the library's source code to find the correct method names for your desired operation. error LINE Pay 1106 error ↓
cause Error code 1106 from the LINE Pay API indicates an 'Header information error', most commonly when the X-LINE-Authorization (MAC/signature) is incorrect or malformed due to issues with the Channel Secret, request body formatting, or nonce generation.
fix
Carefully re-check your LINE Pay Channel Secret, ensure the request body for signature generation is exactly as expected (e.g., no extra whitespace, correct JSON key order), and verify that the HMAC-SHA256 signature calculation logic, including the nonce and UTF-8 encoding, is correct.
error requests.exceptions.ConnectionError ↓
cause The underlying 'requests' library, used by 'line-pay', failed to establish a network connection to the LINE Pay API server, possibly due to network issues, DNS problems, firewall restrictions, or an incorrect API endpoint.
fix
Check your network connectivity, confirm the LINE Pay API endpoint URL is correct, ensure no firewalls are blocking outgoing connections, and try to isolate if the issue is with network access or the API server itself.
Warnings
breaking LINE Pay Japan terminated April 30, 2025. Service continues only in Taiwan (TWD) and Thailand (THB). Do not target JPY — Japanese merchants must migrate to PayPay. ↓
fix Use currency TWD or THB only. Japan merchant registrations are closed.
breaking HMAC signature construction is non-standard: the channel secret appears as BOTH the HMAC key AND the first segment of the message string. Pattern: HMAC-SHA256(key=secret, msg=secret+uri+body+nonce). Omitting the leading secret from the message is the #1 signature failure. ↓
fix msg = channelSecret + requestUri + requestBody + nonce — secret must be prepended to the message, not just used as the key.
breaking Transaction IDs returned by LINE Pay are 64-bit integers. Python handles these natively but any JSON parsing via JavaScript or systems with float64 precision will silently corrupt the ID. Official docs warn to handle as strings. ↓
fix When passing transactionId between systems, stringify it. In Python: str(resp['info']['transactionId']).
breaking The community SDK on PyPI (line-pay 0.2.0) was last updated in 2020, targets Python 3.7, and does not support v3 API endpoints. A separate package 'linepay' also exists on PyPI and is similarly unmaintained. ↓
fix Use raw HTTP with requests. Reference the official sample gist at github.com/yidas/line-pay-api-samples.
gotcha GET requests sign query string, not body. Signature message for GET: secret + uri + queryString + nonce. For POST: secret + uri + requestBody + nonce. Mixing these causes 400 errors. ↓
fix Branch signing logic on HTTP method.
gotcha Sandbox base URL is https://sandbox-api-pay.line.me and production is https://api-pay.line.me — easy to ship with sandbox URL hardcoded. ↓
fix Use an environment variable: BASE_URL = os.getenv('LINE_PAY_BASE_URL', 'https://sandbox-api-pay.line.me')
gotcha Merchant registration requires a business entity and approval process through pay.line.me portal. Self-serve sandbox access is available but production requires review. Taiwan and Thailand have separate merchant portals. ↓
fix Apply at pay.line.me. Taiwan and Thailand operate under LINE Pay Plus Corporation (separate from LINE Japan).
Install
pip install line-pay Install compatibility verified last tested: 2026-05-12
python os / libc variant status wheel install import disk
3.10 alpine (musl) line-pay - - 0.03s 21.2M
3.10 alpine (musl) requests - - 0.03s 69.9M
3.10 slim (glibc) line-pay - - 0.02s 22M
3.10 slim (glibc) requests - - 0.02s 141M
3.11 alpine (musl) line-pay - - 0.03s 23.3M
3.11 alpine (musl) requests - - 0.03s 76.5M
3.11 slim (glibc) line-pay - - 0.02s 24M
3.11 slim (glibc) requests - - 0.02s 148M
3.12 alpine (musl) line-pay - - 0.01s 15.1M
3.12 alpine (musl) requests - - 0.01s 67.0M
3.12 slim (glibc) line-pay - - 0.01s 16M
3.12 slim (glibc) requests - - 0.01s 138M
3.13 alpine (musl) line-pay - - 0.01s 14.7M
3.13 alpine (musl) requests - - 0.01s 63.5M
3.13 slim (glibc) line-pay - - 0.01s 15M
3.13 slim (glibc) requests - - 0.01s 137M
3.9 alpine (musl) line-pay - - 0.03s 20.5M
3.9 alpine (musl) requests - - 0.03s 68.8M
3.9 slim (glibc) line-pay - - 0.02s 21M
3.9 slim (glibc) requests - - 0.02s 140M
Imports
- requests (and stdlib hmac/hashlib) wrong
from linepay import LinePayApicorrectimport hmac, hashlib, base64, json, uuid import requests
Quickstart stale last tested: 2026-05-12
import hmac, hashlib, base64, json, uuid
import requests
CHANNEL_ID = 'your_channel_id'
CHANNEL_SECRET = 'your_channel_secret'
BASE_URL = 'https://sandbox-api-pay.line.me' # prod: https://api-pay.line.me
def sign(secret, uri, body_str, nonce):
# KEY GOTCHA: secret is used as BOTH the HMAC key AND prepended to the message
msg = secret + uri + body_str + nonce
return base64.b64encode(
hmac.new(secret.encode(), msg.encode(), hashlib.sha256).digest()
).decode()
def request_payment(amount, currency, order_id, confirm_url, cancel_url):
uri = '/v3/payments/request'
nonce = str(uuid.uuid4())
body = {
'amount': amount,
'currency': currency,
'orderId': order_id,
'packages': [{
'id': 'pkg1',
'amount': amount,
'products': [{'name': 'Product', 'quantity': 1, 'price': amount}]
}],
'redirectUrls': {
'confirmUrl': confirm_url,
'cancelUrl': cancel_url
}
}
body_str = json.dumps(body, separators=(',', ':')) # compact JSON, no spaces
signature = sign(CHANNEL_SECRET, uri, body_str, nonce)
headers = {
'Content-Type': 'application/json',
'X-LINE-ChannelId': CHANNEL_ID,
'X-LINE-Authorization-Nonce': nonce,
'X-LINE-Authorization': signature
}
resp = requests.post(BASE_URL + uri, headers=headers, data=body_str)
return resp.json()
result = request_payment(250, 'TWD', 'order-001',
'https://yoursite.com/confirm', 'https://yoursite.com/cancel')
print(result['info']['paymentUrl']['web']) # redirect user here