はじめに
LINEミニアプリ(LIFF)上で動く予約サービスに、マルチ決済サービス elepay を組み込みました。
elepayは1つの導入でPayPay・クレジットカード・Apple Payなど多くの決済手段をまとめて扱える便利なサービスですが、調べ始めると
- 「EasyQR」「EasyCheckout」「Charges」「OneQR」など似た名前の機能が多い
- 同じ「有効期限」でもパラメータが3種類ある
- LIFFで使う場合の設定がドキュメントからは読み取りにくい
など、かなり混乱しました。
この記事では、実装時に調べたことを整理して、
- elepayの用語整理
- 決済3方式(
handleCharge/checkout/createCodeWidget)の比較 - 実装時のハマりポイント
をまとめます。同じようにelepayの導入を検討している方の参考になれば嬉しいです。
本記事の内容は執筆時点(2026年10月)の情報です。elepayのドキュメントは更新されることがあるため、実装前に必ず公式ドキュメントを確認してください。
想定するケース
- LINEミニアプリ(LIFF)上の予約サービス
- スマートフォン1台で予約〜決済まで完結させたい
- 予約枠は決済完了まで一定時間「仮押さえ」したい
1. まず用語を整理する
elepayを調べていて一番混乱したのが用語です。結論から言うと、
「EasyQR / EasyCheckout / QR Widget」はelepayのデフォルト系統で、「Charges + JS SDK」とは別の仕組み
です。
| 用語 | 実際には何を指すか |
|---|---|
| EasyQR Code |
POST /codes で作成される code オブジェクト |
| EasyCheckout | EasyQR Code を使って決済する一連のフロー全体 |
| ホスト型Checkout | elepayが用意したCheckoutページを使う方式(checkout())。EasyQR / EasyCheckout系 |
| QR Widget | EasyCheckoutを自分のページに埋め込む方式(createCodeWidget()) |
| Charges + JS SDK(カスタマイズ) | Charges API(POST /charges)を使う方式。EasyQRとは別物 |
| LocationQR | Dashboardから作成する静的なQRコード。APIは使用しない |
| OneQR | 別プロダクト(店舗向けサービス) |
さらに紛らわしいのが「マルチ決済」「簡単決済」「OneQR」の関係です。
- マルチ決済:いろいろな決済手段をまとめて扱う仕組み
- 簡単決済:その中の「簡単に支払ってもらう」ための機能群
- OneQR:決済+店舗・商品・注文などをまとめて運用する店舗向けサービス
elepayとOneQRの違いについては公式のコラムも参考になります。
https://oneqr.io/column/elepay-or-oneqr
2. 決済3方式の比較
elepayでWebから決済する方法は、大きく分けて次の3つです。
| ① handleCharge | ② checkout | ③ createCodeWidget() | |
|---|---|---|---|
| 系統 | カスタマイズ(Charges + JS SDK) | デフォルト(EasyCheckout) | デフォルト(EasyCheckout) |
| サーバー側API | POST /charges |
POST /codes |
POST /codes |
| 実装量 | 多い | 少ない | 中程度 |
| 決済方法を選ぶ人 | サーバー側で指定 | ユーザー | ユーザー |
| 画面遷移 | 一部離脱あり | Checkout / Paymentページへ遷移 | ページ内に留まる |
| QRを読み取る端末 | 同じ端末 | 同じ端末 | 別端末 |
| UIの自由度 | 高い | Dashboard設定のみ |
options でカスタマイズ可能 |
| スマホ / LIFFとの相性 | ◎ | ◎ | △(PC・据え置き端末向け) |
① handleCharge(Charges + JS SDK)
サーバーで POST /charges を呼んでCharge(支払い請求)を作成し、フロントでJS SDKの handleCharge に渡して決済を進める方式です。
決済方法をシステム側で指定したい場合に向いています。自前の画面で「PayPayで支払う」「カードで支払う」などのボタンを用意し、選ばれた決済方法でChargeを作る、という作り方ができます。
1. ユーザーが自前の画面で決済方法を選択
2. フロント → 自社サーバー:決済リクエスト
3. 自社サーバー → elepay:POST /charges(金額・決済方法・orderNo など)
4. 自社サーバー → フロント:Chargeオブジェクトを返す
5. フロント:elepay.handleCharge(charge) で決済画面・決済アプリへ
6. elepay → 自社サーバー:Webhookで決済結果を通知
公式ドキュメント:
- 支払い処理:https://developer.elepay.io/get-started/process
- JavaScript SDK:https://developer.elepay.io/guides/javascript/api-reference
- API Reference(Create charge):https://developer.elepay.io/openapi/charge/createCharge
② checkout(ホスト型Checkout)
サーバーで POST /codes を呼んでEasyQR Codeを作成し、elepayが用意したCheckoutページへ遷移させる方式です。
便利なのが、SDKが端末タイプを自動判定してくれる点です。
- Desktop → Checkoutページへ遷移
- Mobile → Paymentページへ遷移
つまり、1つの実装でPC / スマホの両方に対応でき、端末ごとの分岐を自分で書く必要がありません。決済方法の選択もelepay側の画面でユーザーが行います。
主な利用シーン:
- ECサイトの決済
- メール / LINEで決済リンクを送る
- スマホからの決済(LIFFでも利用可能)
表示する決済手段は、Dashboardの [簡単決済 > 設定 > 決済方法管理] から有効化 / 無効化できます。
公式ドキュメント:
- Checkout概要:https://developer.elepay.io/cases/checkout
- ホスティングのCheckout:https://developer.elepay.io/cases/checkout/elepay-hosted
③ createCodeWidget()(QR Widget)
自分のページ内のDOMにQRコードを表示し、ユーザーが別の端末でQRを読み取って決済する方式です。金額表示、決済方法のアイコン、枠線、背景色などを設定でき、「QRコードのみ」の表示も可能です。
主な利用シーン:
- 券売機 / 精算機
- 自動販売機 / 無人店舗
- レジ横の客向けサブディスプレイ
- PCでの会計 → スマホで決済
- 大型ディスプレイ / イベント会場
つまり、「表示する端末」と「決済する端末」が別の場合に向いています。
スマホ1台で完結するLIFFアプリでは、自分の画面に表示されたQRコードを自分でスキャンできません。
また、表示されるQRコードはelepayのチェックアウトページを指すもので、PayPay固有のQRコードではありません。PCからの予約・決済も想定する場合の選択肢として考えるのが良さそうです。
公式ドキュメント:
- デバイスにCheckout:https://developer.elepay.io/cases/checkout/qrwidget
今回の選択
今回は「スマホ / LIFFで完結」「決済方法を自前の画面で選ばせたい」「予約データと決済をきちんと紐付けたい」という要件だったため、① handleCharge(Charges + JS SDK) を採用しました。
「とにかく早く導入したい」「決済画面はelepay標準で問題ない」という場合は、② checkout が一番手軽だと思います。
3. 実装時のハマりポイント
3-1. 有効期限のパラメータが3種類ある
「仮押さえ時間」を設定しようとして混乱したポイントです。方式によって使うパラメータも単位も違います。
| パラメータ | 方式 | 単位 | 説明 |
|---|---|---|---|
expiryTime |
Charges(POST /chargesのレスポンス) |
エポックミリ秒 | 支払い請求の有効時刻(※リクエストでは指定しない) |
expiryPeriod |
EasyQR(POST /codes) |
ミリ秒 | 有効期限までの残りミリ秒数 |
expiryDuration |
EasyQR(POST /codes) |
分 | 最小3分・最大30分・デフォルト10分 |
例えばEasyQRで仮押さえを15分にしたい場合は、expiryDuration: 15 を指定すればOKです。
参考:https://developer.elepay.io/openapi/code/createCode
expiryTime は「何分後」ではなく「いつまで」(絶対時刻)を表します。また、APIリファレンス上はリクエストのパラメータではなく、レスポンスのChargeオブジェクトに含まれる値です。残り時間を知りたい場合は expiryTime - Date.now() のように計算します。
3-2. LIFFの場合の resource 指定
Charges APIには決済リソースを表す resource パラメータがあり、API仕様上は liff も定義されています。
ところが、
- Dashboardの「サービス基本設定 > 決済方法」では、利用可能なリソースが最大5種類で、LIFFを追加・設定する場所がない
- 「決済 Extra 情報設定」にも
liffの記載はあるが、LINE Payの場合の説明のみ
という状態でした。
整理すると、resource: liff はLINE Payを利用する場合のみの値です。そしてLINE Payは国内サービスがすでに終了しています。「LIFFアプリだから liff」と考えてしまいがちですが、liff は「LIFF上でLINE Payを使う」ためのもの。
そのため結論としては、LIFFアプリであっても、決済手段にかかわらず resource: web を指定することになります。LIFFブラウザもLINEアプリ内で動作するWebViewなので、決済リソースとしてはWeb扱いになる、と考えると分かりやすいです。
参考:決済Extra情報設定
https://developer.elepay.io/guides/extra-setting
3-3. デフォルト方式の遷移先・Webhook受信先
デフォルト(EasyQR / EasyCheckout系)の場合、決済後の外部遷移リンクはアプリに設定したドメイン(Webhook受信先と同じドメイン)に固定され、変更できませんでした。locationIdごとに分けたり、locationIdの有無で切り替えたりすることもできません。
1つのelepayアプリで複数のサービスを運用する予定がある場合は、注意が必要です。
3-4. Apple Pay / Google Pay はドメイン認証が必要
Apple Pay / Google Payはドメイン認証が必要な決済方法です。有効化する際は、決済に使うドメイン側の設定状況も確認しておきましょう。
3-5. 決済方法の利用可否を確認する
そもそも各決済方法が利用可能な状態かどうかは、公式サポートページの手順で確認できます。
https://support.elepay.io/operation-information-servicebasic-payment#elepay_check
4. 実装上の注意(システム設計)
elepay固有の話ではありませんが、予約×決済の実装で必要になったものです。
期限切れの仮押さえを解放するバッチが必要
ユーザーが決済途中でブラウザを閉じると、Webhookが届かず予約枠が仮押さえのまま残り続けてしまいます。
そのため、
- Webhookで決済完了 → 予約確定
- 期限切れの仮押さえをバッチで定期的にスイープ → 枠を解放
という2つの経路を用意しておく必要があります。
まとめ
| こんなとき | おすすめ |
|---|---|
| スマホ / LIFFで完結、決済方法を自前のUIで選ばせたい | ① handleCharge(Charges + JS SDK) |
| とにかく手軽に導入したい、PC / スマホ両対応したい | ② checkout(ホスト型Checkout) |
| 表示端末と決済端末が別(券売機・PC会計など) | ③ createCodeWidget()(QR Widget) |
elepayは機能が多い分、用語と方式の違いを最初に理解しておくと、開発が少し楽になると思います。
最後まで読んでいただきありがとうございました!