quickstart.md 4.0 KB

LINE Pay Implementation Quickstart

1. Prerequisites

  • JDK 21: C:\Users\qmj\.jdks\graalvm-jdk-21.0.7
  • MySQL schema changes from updatesql/sql.md applied manually by the developer
  • Redis/Redisson available
  • LINE Pay Sandbox Channel ID/Secret
  • Public HTTPS API base URL reachable by LINE redirect
  • Platform frontend: E:\QtwCode\foodie\foodie-admin-vue

Do not execute schema migration from Codex. Do not use the deprecated TestTask, ZaloPayController, PayController, or OrderAppealController flows.

2. Runtime configuration

ruoyi-admin/src/main/resources/application.yml contains non-secret defaults:

line-pay:
  environment: sandbox
  base-url: https://sandbox-api-pay.line.me
  confirm-url: https://api.example.com/pay/line/confirm
  cancel-url: https://api.example.com/pay/line/cancel
  reconcile:
    fixed-delay-ms: 60000
    initial-delay-ms: 60000
    batch-size: 20
    row-lease-seconds: 120
    round-budget-seconds: 45
    auth-deadline-minutes: 30
    unknown-deadline-hours: 24

Channel credentials are saved per store through the platform API; they are not placed in application.yml.

3. Local verification

Use JDK 21 only in the current PowerShell process:

$env:JAVA_HOME='C:\Users\qmj\.jdks\graalvm-jdk-21.0.7'
$env:PATH="$env:JAVA_HOME\bin;$env:PATH"
mvn -pl ruoyi-system -am -Dtest='*Line*Test' -Dsurefire.failIfNoSpecifiedTests=false test
mvn -pl ruoyi-admin -am -Dtest='*LinePay*Test,OrderLifecycleServiceTest,OmgPayControllerTest' -Dsurefire.failIfNoSpecifiedTests=false test
mvn -pl ruoyi-admin -am -DskipTests package

Frontend:

Set-Location E:\QtwCode\foodie\foodie-admin-vue
npm run lint
npm run build:prod

Repository checks:

Set-Location E:\QtwCode\foodie\foodie_server
git diff --check
git status --short

4. Sandbox acceptance flow

  1. Platform opens Store Payment → LINE Pay.
  2. Enter store Channel ID/Secret; verify the detail shows a new current version and enabled state.
  3. Create one single-store order with payType=3.
  4. Call /pay/line/create; assert payment row is WAITING_AUTH and response uses paymentUrl.web.
  5. Repeat create before completion; assert the same paymentId/lineOrderId is returned with reusedAttempt=true.
  6. Complete Sandbox web authorization and allow confirm redirect.
  7. Confirm page returns quickly and App query eventually reports PAID.
  8. Query DB read-only and verify payment remains PAID, order pay_status=1, and gateway logs contain REQUEST/CHECK/CONFIRM/RETRIEVE events.
  9. Cancel a paid order; verify exactly one refund row is created, eventually REFUNDED, while payment remains PAID and order becomes pay_status=2.
  10. Create a second attempt only after the first is explicitly cancelled/expired/failed; verify both rows remain and only the second has active_dd_id.

5. Required concurrency tests

  • Two simultaneous create calls for the same LINE order return one attempt.
  • LINE create and OMG create for the same order cannot both claim the payment channel.
  • confirm redirect, scheduled task and admin reconcile cannot Confirm twice.
  • user cancellation before late Capture still records PAID and creates one refund intent.
  • store cancellation and late Capture produce the same result and enforce store ownership.
  • credential rotation during a waiting/paid transaction does not change its credential_id; old transaction remains queryable/refundable.
  • UNKNOWN and MANUAL_REVIEW never release active_dd_id or directly repeat side effects.

6. Production acceptance items

Sandbox cannot prove every App handoff behavior. Before production enablement, verify on real iOS and Android devices:

  • LINE payment browser returns to the intermediate page and the fixed Scheme handoff works.
  • com.twanmsdyh.app://payment/result is registered and handled.
  • auto-open works where allowed; the manual button works in LINE WebView and external browsers.
  • App always calls /query and never trusts the deep-link as success.
  • current production credentials complete an end-to-end TWD payment and full refund.