# flutter_paydemo Flutter 支付演示项目,覆盖 7 种支付方式的前后端完整接入: | 支付方式 | 移动端 | Web / 桌面 | 后端 SDK | |---|---|---|---| | 微信支付 | App 支付(fluwx) | Native 扫码(二维码轮询) | wechatpay-node-v3 | | 支付宝支付 | App 支付(alipay_kit) | 手机网站支付(WAP 跳转) | alipay-sdk | | 云闪付 | App 支付(uppay:// 拉起) | 银联收银台跳转 | 自研 RSA2 签名对接 | | Stripe | PaymentSheet 卡片支付 | PaymentSheet(web) | stripe SDK | | Apple Pay | 经 Stripe 确认 | Safari | stripe SDK | | Google Pay | 经 Stripe 确认 | Chrome | stripe SDK | | 网页收银台 | 聚合收银台 | 微信扫码 / 支付宝 / Stripe 托管 | 自建聚合 | > 技术文档见 [docs/](docs/README.md)(含时序图、接口定义、安全、沙箱测试)。 ## 技术栈 - **移动端**:Flutter 3.29 / Dart 3.7,dio、get、fluwx、alipay_kit、flutter_stripe、qr_flutter、url_launcher - **后端**:Node.js + Express,分层 Router → Controller → Service → Repository - **存储**:内存 Map(演示足够;真实可换 MySQL/Redis) ## 目录结构 ``` flutter_paydemo/ lib/ main.dart # 入口:fluwx/Stripe 初始化 + 国际化 + ScreenUtil + EasyLoading constants.dart # AppID / Universal Link / Stripe Key / 后端地址 models/ # 请求响应模型(fromJson/toJson) service/ api_service.dart # dio 封装 + 各渠道创建/查询/收银台接口 pay_service.dart # 7 种支付编排(统一以后端状态为准) platform/ # 渠道封装:wechat_flow / alipay_* / stripe_flow pages/ home_page.dart # 商品 + 7 个支付入口 wechat_qr_dialog.dart # 微信 Native 扫码弹窗(含 Mock 模拟按钮) utils/ # platform / toast / dialog / money / pay_result server/ # Node.js 后端 src/ app.js # Express 装配(notify 在 json 之前挂载) config/ # 环境变量(MOCK_MODE 开关) controllers/ # payment / notify / checkout services/ # order / wechat / alipay / unionpay / stripe / notify mock/ # Mock 工厂(结构与真实渠道完全对齐) .env.example # 全部环境变量模板 docs/ # 7 份支付技术文档 ``` ## 快速开始 ### 1. 后端 ```bash cd server npm install cp .env.example .env # 默认 MOCK_MODE=true,无需真实商户密钥 npm start # 监听 :3000 ``` 验证: ```bash curl http://localhost:3000/health # {"ok":true,"mock":true} curl http://localhost:3000/v1/products # 商品列表 ``` ### 2. 前端 ```bash flutter pub get flutter run -d chrome # Web 端(微信 Native 扫码 / 支付宝 WAP / Stripe) # 或 flutter run -d <设备> # Android/iOS App(App 支付) ``` 后端地址通过 `--dart-define=API_BASE_URL=http://localhost:3000` 覆盖 (Android 模拟器访问宿主机用 `http://10.0.2.2:3000`)。 ## Mock 模式(无真实商户密钥也能端到端跑通) `.env` 中 `MOCK_MODE=true` 时,后端返回结构**完全对齐真实渠道**(`sandbox:true`、占位密钥): - 微信 Native:返回 `code_url` → 前端渲染二维码,弹窗内点「**模拟支付成功(Mock)**」走通 - 支付宝 WAP / 云闪付收银台 / Stripe / 收银台跳转:弹窗内点「**模拟支付成功(Mock)**」 - 云闪付 App:返回 `tn: mock_tn_*` → 前端判定 mock,直接模拟成功 - Stripe / Apple / Google:后端下发 `pk_test_mock` 发布密钥 → 前端判定 mock,直接模拟成功 下单默认停在 `PENDING`,`POST /v1/payment/simulate/success {payment_id}` 触发与真实回调 **完全相同**的 `markPaid` 幂等流程,随后 `GET /v1/payment/{id}` 返回 `{success:true, note:'支付成功'}`。 ## 真实接入(填写商户密钥) 复制 `server/.env.example` → `.env` 并填写: | 变量 | 说明 | |---|---| | `WECHAT_APPID` / `WECHAT_MCHID` / `WECHAT_KEY` / `WECHAT_CERT` | 微信支付商户号 / API v3 密钥 / 证书 | | `ALIPAY_APP_ID` / `ALIPAY_PRIVATE_KEY` / `ALIPAY_PUBLIC_KEY` | 支付宝应用私钥 / 支付宝公钥(RSA2) | | `UNIONPAY_MER_ID` / `UNIONPAY_PRIVATE_KEY_PATH` / `UNIONPAY_PUBLIC_KEY_PATH` | 银联商户号 / 商户私钥 / 银联公钥(RSA2 签名验签,沙箱测试商户可用) | | `STRIPE_SECRET_KEY` / `STRIPE_PUBLISHABLE_KEY` / `STRIPE_WEBHOOK_SECRET` | Stripe 密钥 / Webhook 签名密钥 | 前端对应替换: - `lib/constants.dart`:`kWechatAppId`(微信开放平台 AppID)、`kWechatUniversalLink`、`kStripePublishableKey` - Android:`applicationId` 与微信开放平台登记一致(fluwx activity-alias 由插件自带) - iOS:Info.plist 补 `LSApplicationQueriesSchemes`(weixin/wechat)与 `CFBundleURLTypes`(`wx{AppID}`), `alipay_kit` scheme 见 `pubspec.yaml` 真实回调由 `POST /v1/payment/notify/{channel}` 验签处理(微信 AES-GCM 解密 / 支付宝 RSA2 验签 / 云闪付 RSA2 验签 / Stripe Webhook 校验)。 ## API 一览 | 方法 | 路径 | 说明 | |---|---|---| | POST | `/v1/payment/:channel/` | `wechatpay`/`alipay`/`unionpay`/`stripe`/`apple`/`google` 创建支付 | | GET | `/v1/payment/:payment_id` | 支付状态查询(轮询 / 最终确认) | | POST | `/v1/payment/notify/:channel` | 渠道异步回调(验签 + 幂等标记已支付) | | POST | `/v1/payment/simulate/:result` | 仅 Mock:模拟支付结果 | | POST | `/v1/checkout/session` | 收银台会话(wechat/alipay/stripe) | | GET | `/v1/checkout/session/:id` | 收银台状态轮询 | | GET | `/v1/products` | 商品列表 | ## Android / iOS 构建说明 - **Android 构建栈**:AGP 8.1.0 / Gradle 8.3 / Kotlin 2.1.0 / Java 17 / compileSdk 35 (flutter_stripe 11.x + Stripe Android SDK 21.x 编译前提),`MainActivity` 继承 `FlutterFragmentActivity`, `gradle.properties` 已设 `android.enableR8.fullMode=false`;settings 已声明 Flutter 引擎 maven 仓库 (`download.flutter.io`)。注:老插件(如 alipay_kit_android、fluwx 5.3.1)在新版 AGP/Kotlin 下可能 需临时补 `namespace` 或升级版本,真机构建时按需处理 - **iOS**:`IPHONEOS_DEPLOYMENT_TARGET` 需 ≥ 13.0(flutter_stripe 要求),需 macOS 真机 pod install - **Web**:支付宝 `alipay_kit` 底层依赖 `dart:io`,通过条件导出隔离(`alipay_interface.dart`),不影响 Web 构建 ## License MIT