{"id":39,"library":"line-pay","title":"LINE Pay Online API","description":"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.","status":"active","version":"0.2.0","language":"python","source_language":"ja","source_url":"https://developers-pay.line.me/online/prerequisites","tags":["payment","japan","taiwan","thailand","line","qr-code","mobile-payment","asia"],"install":[{"cmd":"pip install requests","lang":"bash","label":"Recommended (raw HTTP — no maintained SDK)"},{"cmd":"pip install line-pay","lang":"bash","label":"Community SDK (unmaintained, Python 3.7 era, not recommended)"}],"dependencies":[{"reason":"HTTP client for raw API calls","package":"requests","optional":false}],"imports":[{"note":"No official SDK. Use raw requests with manual HMAC-SHA256 signing. Community SDKs (line-pay, linepay) are both unmaintained.","wrong":"from linepay import LinePayApi","symbol":"requests (and stdlib hmac/hashlib)","correct":"import hmac, hashlib, base64, json, uuid\nimport requests"}],"quickstart":{"code":"import hmac, hashlib, base64, json, uuid\nimport requests\n\nCHANNEL_ID = 'your_channel_id'\nCHANNEL_SECRET = 'your_channel_secret'\nBASE_URL = 'https://sandbox-api-pay.line.me'  # prod: https://api-pay.line.me\n\ndef sign(secret, uri, body_str, nonce):\n    # KEY GOTCHA: secret is used as BOTH the HMAC key AND prepended to the message\n    msg = secret + uri + body_str + nonce\n    return base64.b64encode(\n        hmac.new(secret.encode(), msg.encode(), hashlib.sha256).digest()\n    ).decode()\n\ndef request_payment(amount, currency, order_id, confirm_url, cancel_url):\n    uri = '/v3/payments/request'\n    nonce = str(uuid.uuid4())\n    body = {\n        'amount': amount,\n        'currency': currency,\n        'orderId': order_id,\n        'packages': [{\n            'id': 'pkg1',\n            'amount': amount,\n            'products': [{'name': 'Product', 'quantity': 1, 'price': amount}]\n        }],\n        'redirectUrls': {\n            'confirmUrl': confirm_url,\n            'cancelUrl': cancel_url\n        }\n    }\n    body_str = json.dumps(body, separators=(',', ':'))  # compact JSON, no spaces\n    signature = sign(CHANNEL_SECRET, uri, body_str, nonce)\n    headers = {\n        'Content-Type': 'application/json',\n        'X-LINE-ChannelId': CHANNEL_ID,\n        'X-LINE-Authorization-Nonce': nonce,\n        'X-LINE-Authorization': signature\n    }\n    resp = requests.post(BASE_URL + uri, headers=headers, data=body_str)\n    return resp.json()\n\nresult = request_payment(250, 'TWD', 'order-001',\n    'https://yoursite.com/confirm', 'https://yoursite.com/cancel')\nprint(result['info']['paymentUrl']['web'])  # redirect user here","lang":"python","description":"Auth requires manual HMAC-SHA256 signing — secret is both the key and the first message segment. Use sandbox URL for testing; swap to production via env var before going live."},"warnings":[{"fix":"Use currency TWD or THB only. Japan merchant registrations are closed.","message":"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.","severity":"breaking","affected_versions":"all"},{"fix":"msg = channelSecret + requestUri + requestBody + nonce — secret must be prepended to the message, not just used as the key.","message":"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.","severity":"breaking","affected_versions":"all"},{"fix":"When passing transactionId between systems, stringify it. In Python: str(resp['info']['transactionId']).","message":"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.","severity":"breaking","affected_versions":"all"},{"fix":"Use raw HTTP with requests. Reference the official sample gist at github.com/yidas/line-pay-api-samples.","message":"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.","severity":"breaking","affected_versions":"line-pay<=0.2.0"},{"fix":"Branch signing logic on HTTP method.","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Use an environment variable: BASE_URL = os.getenv('LINE_PAY_BASE_URL', 'https://sandbox-api-pay.line.me')","message":"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.","severity":"gotcha","affected_versions":"all"},{"fix":"Apply at pay.line.me. Taiwan and Thailand operate under LINE Pay Plus Corporation (separate from LINE Japan).","message":"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.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T05:23:53.574Z","next_check":"2026-06-01T00:00:00.000Z","problems":[{"fix":"Run `pip install line-pay` in your terminal to install the library.","cause":"The 'line-pay' package is not installed in your current Python environment.","error":"ModuleNotFoundError: No module named 'line_pay'"},{"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`.","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.","error":"ImportError: cannot import name 'LinePayApi' from 'line_pay'"},{"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.","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.","error":"AttributeError: 'LinePayApi' object has no attribute 'request'"},{"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.","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.","error":"LINE Pay 1106 error"},{"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.","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.","error":"requests.exceptions.ConnectionError"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"21.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.2,"disk_size":"69.9M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.2,"disk_size":"22M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.2,"disk_size":"141M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":0.7,"disk_size":"23.3M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":0.7,"disk_size":"76.5M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.7,"disk_size":"24M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":0.7,"disk_size":"148M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"15.1M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"67.0M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"16M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.5,"disk_size":"138M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"14.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.6,"disk_size":"63.5M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.4,"disk_size":"15M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":0.4,"disk_size":"137M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.1,"disk_size":"20.5M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.1,"disk_size":"68.8M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"21M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.1,"disk_size":"140M"}]},"quickstart_checks":{"last_tested":"2026-05-12","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}