LINE Pay Online API
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.
Common errors
-
ModuleNotFoundError: No module named 'line_pay'
cause The 'line-pay' package is not installed in your current Python environment.fixRun `pip install line-pay` in your terminal to install the library. -
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.fixVerify 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`. -
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.fixInspect 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. -
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.fixCarefully 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. -
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.fixCheck 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
Install
-
pip install requests -
pip install line-pay
Imports
- requests (and stdlib hmac/hashlib)
from linepay import LinePayApi
import hmac, hashlib, base64, json, uuid import requests
Quickstart
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