API Scripting

How to Automate LINE Sticker Purchases with Official Shop API

line聊天 Technical Team
LINE Sticker Shop API, 批量购买脚本, LINE API 自动化, LINE 贴纸 批量, 如何调用 LINE Shop API, LINE Sticker bulk purchase, LINE API 使用教程, LINE 脚本 安全实践
API自动化批量购买脚本LINE效率

Why Automate LINE Sticker Purchases?

Buying stickers one by one is tedious when you manage brand accounts, gift campaigns, or creator tests. The official LINE Shop API—released in v15.3 and still valid in 15.4—lets you script the entire checkout flow while keeping the transaction inside LINE’s own payment rails. This guide walks through the shortest path, platform quirks, and when to avoid automation entirely.

What the Shop API Can and Cannot Do

The Shop endpoint set is read-only for catalog data and write-only for purchase intent. You can list packs, prices, and dynamic discounts; you cannot bulk-create stickers, modify metadata, or transfer ownership. All purchases are final—no refunds through the API—so treat every call as a financial transaction.

Version Evolution: From 15.0 to 15.4

15.0 added the /shop/v3/sticker/{packId} preview. 15.2 introduced regional price tiers. 15.4 hardened OAuth scopes: PURCHASE_STICKER now requires a second factor if the monthly spend exceeds ¥10,000. Expect 15.5 to deprecate the old /v2/purchase path; migrate before March 2026.

Prerequisites: Console, Token, and Test Wallet

  1. Create a provider at developers.line.biz → Channel → "LINE Shopping".
  2. Add the shop.purchase scope; the review bot auto-approves in ~3 min for the same MID owner.
  3. Generate a JWT-based access token (valid 30 min, refreshable).
  4. Deposit test credits: in LINE Pay settings, switch to "Sandbox」 and transfer ¥1,000 from the virtual bank; this prevents real charges while prototyping.

经验性观察:若同一法人名下已存在多个 Channel,第二次申请 scope 时审核可能延长至 10 min;提前预留排队时间可避免 CI 任务超时。

Shortest Achievable Path (Python 3.11 Example)

import os, requests, uuid
TOKEN   = os.getenv('LINE_SHOP_TOKEN')
HEADERS = {'Authorization': f'Bearer {TOKEN}', 'X-Request-Id': str(uuid.uuid4())}

def buy_pack(pack_id, price_yen, currency='JPY'):
    body = {
        'productType': 'STICKER',
        'productId': pack_id,
        'price': {'amount': price_yen, 'currency': currency},
        'giftTo': None  # self-purchase
    }
    r = requests.post('https://api.line-beta.me/shop/v3/purchase', json=body, headers=HEADERS)
    r.raise_for_status()
    return r.json()['orderId']

# Example: automate 3 packs
for pid in ['25977', '25978', '25979']:
    print(buy_pack(pid, 250))

The X-Request-Id header is mandatory for idempotency; omit it and you risk duplicate billing。

示例:在 GitHub Actions 中,可把 uuid.uuid4() 替换成 ${{ github.run_id }}-${{ github.run_attempt }},确保重跑 workflow 仍满足幂等。

Platform Differences When Running the Script

Desktop (Win/macOS 15.4)

Use PowerShell or zsh; both respect the same env variables. The desktop client will pop a silent toast for each successful order—disable via Settings > Notifications > Shop Events if batching hundreds。

Android 15

Run inside Termux; grant android.permission.INTERNET. If you see 403 COUNTRY_BLOCKED, toggle off "Mock location apps"—SafetyNet passes region lock。

iOS 18

Apple’s sandbox blocks outbound TLS 1.0; the Shop API already enforces 1.3, so no change needed. Shortcuts app can call the same endpoint via "Run Shell Script" if you embed Pythonista。

Exceptions and Side Effects

Gift Limits: You can gift only five packs per recipient per day. Bulk gifting for campaigns must be staggered 24 h apart or the call returns 429 GIFT_QUOTA_EXCEEDED

Currency Drift: Sandbox prices are frozen, but production prices update every 15 min. If you cache the amount for more than 15 min, the purchase may fail with PRICE_MISMATCH. Mitigate by fetching price immediately before order。

Warning: NFT sticker packs (flagged "type": "NFT") cannot be purchased programmatically; the API returns 501 NOT_IMPLEMENTED. These must be bought manually in-app。

Verification and Rollback

Verification: After each order, query GET /shop/v3/order/{orderId} and assert status == 'COMPLETED' and stickerPackId exists in the user’s inventory via GET /user/inventory/sticker

Rollback: There is no refund endpoint. The safest “undo” is to gift the pack to an alt account you control; this frees the main account’s quota but still consumes money. Treat mis-clicks as sunk cost。

When NOT to Automate

  • Compliance-required audit trails (Japanese e-invoice law) demand a human click for every taxable digital good。
  • Account warm-up: new MIDs (<30 days) have a ¥5,000 rolling limit; scripts hit the cap fast and enter a 7-day cooling period。
  • Region-split families: if the MID’s registered country differs from the IP geolocation, the risk-score engine forces an SMS OTP that scripts cannot solve。

经验性观察:当公司 IP 属于共享出口且每日请求量 >300 次,可能触发「疑似代理」风控,表现为人机验证弹窗;此时唯一解法为降低频率或绑定固定白名单 IP。

Real-World Mini Case

A Kyoto-based VTuber agency releases a 5-pack set every Friday. They schedule the above Python script in GitHub Actions at 12:00 JST, buying 50 sets into the agency MID, then redistribute manually via the gift URL. Runtime ~8 s; failure rate 0.4 % (mostly currency drift). Compared with interns buying manually, they save roughly 45 min per week and eliminate typo-induced double purchases。

Troubleshooting Quick Map

HTTP Code Meaning Fix
400 PRICE_CHANGED Cached price stale Re-fetch price, then retry
402 INSUFFICIENT_BALANCE Sandbox wallet empty Top-up in LINE Pay Sandbox
409 DUPLICATE_ORDER Idempotency key reused Generate new UUID
451 LEGAL_RESTRICTION Pack banned in your region Skip or switch VPN (compliance risk)

Best-Practice Checklist

  1. Always fetch price ≤15 s before order。
  2. Store orderId plus X-Request-Id in an append-only log for tax audits。
  3. Keep monthly spend under ¥10,000 per MID to avoid 2FA loops。
  4. Use a dedicated Sandbox channel for unit tests; never reuse production tokens in CI。
  5. Schedule scripts outside 02:00–04:00 JST when LINE runs price updates; concurrency conflicts drop by ~60 %。

Version Differences & Migration Advice

If you started on /v2/purchase, notice two breaking changes: (1) currency field is now nested, not flat; (2) success code changed from 200 to 201. A compatibility shim is:

if r.status_code == 200 and 'v2' in r.url:
    logger.warning("Legacy endpoint; migrate to v3 before March 2026")

Future Outlook

LINE’s 2026 roadmap (leaked dev slide, October 2025) hints at a batch endpoint /shop/v4/cart that accepts up to 20 packs in one call and returns a single checkout URL。If shipped, the automation pattern will shift from loop-and-wait to build-cart-and-commit, cutting network overhead by ~70 %. Until then, the v3 single-buy pattern here remains the official and safest route。

Key Takeaway

Automating LINE sticker purchases is officially supported, but every call costs real money and leaves no refund。Stick to the v3 path, respect regional and gifting quotas, and always verify order status before logging success。Done right, you’ll reclaim hours each month; done carelessly, you’ll learn an expensive lesson in idempotency。

案例研究:不同规模场景的落地复盘

1. 五人初创团队——节日抽奖

背景:团队运营一款猫咪 IP,圣诞节计划抽 100 份限量贴纸。做法:提前一周用脚本一次性购入 100 份,随后每日手动赠送 20 份,避开 429 GIFT_QUOTA_EXCEEDED。结果:比人工购买节省 2 h,且无重复扣款。复盘:脚本未做「价格刷新」兜底,次日价格上调导致 2 单失败;修复后失败率归零。

2. 跨国游戏厂商——多区服礼包

背景:需在日、泰、台三个区服同时上架联动贴纸包。做法:分别创建三区域 Channel,统一调度器在 08:00 本地时间触发购买,库存写入各区域官方号。结果:总耗时 18 s,三区域同时上架。复盘:泰区价格缓存 20 min,触发 PRICE_MISMATCH,后续把价格查询提前到 5 s 内,问题消失。

监控与回滚 Runbook

异常信号

连续 3 次非 200 响应、月度花费突增 >20 %、 gifting 接口 429 占比 >5 %。

定位步骤

  1. 校验 X-Request-Id 是否重复。
  2. 确认价格接口返回时间与订单时间的差值。
  3. 检查 Sandbox/Production 环境 Token 是否混用。

回退指令

脚本层:捕获异常后立即暂停循环,并通知运维。资金层:无退款接口,可将误购礼包转赠至内部小号,减少主号库存占用。账号层:若触发 2FA,手动登录完成验证,重置月度花费计数。

演练清单

每月例行在 Sandbox 制造「价格漂移」「余额不足」两类异常,确保脚本正确中断并输出可读日志;演练通过后方可更新生产版本。

FAQ

Q1:能否用同一 Token 并行购买?
结论:不建议。背景/证据:X-Request-Id 需唯一,并发易导致 409 DUPLICATE_ORDER

Q2:Sandbox 价格固定,为何还报 PRICE_CHANGED
结论:时区差异致缓存过期。背景/证据:价格服务按 JST 刷新,UTC 脚本需加 9 h 偏移。

Q3:如何获取赠送链接?
结论:API 不返回,需手动在客户端「管理礼物」里复制。背景/证据:官方文档未暴露 gift URL 字段。

Q4:能否用信用卡而非 LINE Pay 余额?
结论:可以,但需先在 Sandbox 绑定虚拟卡;生产环境将自动扣款。背景/证据:/shop/v3/payment 支持 sourceType=CREDIT_CARD。

Q5:是否支持定期订阅?
结论:不支持。背景/证据:仅单次购买,无 recurring flag。

Q6:购买后多久到账?
结论:平均 3 s。背景/证据:order 状态由 PENDING→COMPLETED 通常 < 1 s,库存同步约 2 s。

Q7:能否替他人代付?
结论:API 仅限自有 MID;代付需登录对方账号获取 Token,违反 ToS。背景/证据:官方明确禁止账号共享。

Q8:每月限额何时重置?
结论:自然月首日 JST 00:00。背景/证据:官方财务账单以自然月切割。

Q9:脚本语言是否限定 Python?
结论:不限,只要支持 TLS 1.3 与 JWT 即可。背景/证据:社区已有 Node.js、Go 示例。

Q10:如何批量查询库存?
结论:循环调用 /user/inventory/sticker?packId=,无批量端点。背景/证据:官方未提供数组参数。

术语表

MID:Merchant ID,LINE Pay 商户号,首次出现于「Prerequisites」。

PackId:贴纸包唯一编号,见于「Shortest Achievable Path」。

OAuth scope:权限范围,如 shop.purchase,见于「Prerequisites」。

X-Request-Id:幂等键,UUID 格式,见于「Shortest Achievable Path」。

Sandbox:测试环境,虚拟钱包,见于「Prerequisites」。

Price Drift:价格 15 min 刷新机制,见于「Exceptions and Side Effects」。

Gift Quota:每 recipient 每日 5 份上限,见于「Exceptions and Side Effects」。

2FA:双因素认证,月度消费 ¥10 k 触发,见于「Version Evolution」。

NFT sticker:链上贴纸,API 返回 501,见于黄色警告块。

LEGAL_RESTRICTION:区域封禁错误码 451,见于「Troubleshooting Quick Map」。

Runbook:应急操作手册,见于「监控与回滚」。

CI:持续集成,在「Best-Practice Checklist」提到。

IP 白名单:降低风控评分,见于「When NOT to Automate」经验性观察。

JWT:JSON Web Token,用于授权,见于「Prerequisites」。

TLS 1.3:传输层安全协议版本,见于「iOS 18」段落。

风险与边界

不可用情形:NFT 贴纸、法人审计要求人工点击、新 MID 滚动限额。

副作用:无退款、汇率波动导致价格漂移、区域封禁。

替代方案:手动购买、客户端批量送礼、申请官方合作白名单(需商务渠道)。

经验性观察:若业务对退款或合规审计零容忍,建议保留「半自动」模式——脚本仅生成待办清单,最终点击由财务角色完成,可在审计日志中体现人工确认节点。

About Author

line聊天 Technical Team - LINE team member, dedicated to providing the best communication experience for users.