优化:支付走内购的逻辑改为当pay URL为空的时候才走内购

This commit is contained in:
ivan 2026-03-29 15:31:51 +08:00
parent 4ef714453e
commit a83c76edab
2 changed files with 386 additions and 343 deletions

View File

@ -2,14 +2,14 @@
## 通用信息 ## 通用信息
| 项目 | 值 | | 项目 | 值 |
|------|----| | ------- | ------------------------------------------ |
| 加密方式 | AES-128-ECB, PKCS5Padding, Base64 | | 加密方式 | AES-128-ECB, PKCS5Padding, Base64 |
| AES Key | `liyP4LkMfP68XvCt` | | AES Key | `liyP4LkMfP68XvCt` |
| 预发域名 | `pre-ai.petsheroai.xyz` | | 预发域名 | `pre-ai.petsheroai.xyz` |
| 生产域名 | `ai.petsheroai.xyz` | | 生产域名 | `ai.petsheroai.xyz` |
| 代理入口 | `POST {baseUrl}/quester/defender/summoner` | | 代理入口 | `POST {baseUrl}/quester/defender/summoner` |
| 包名 | `com.petsheroai.app` | | 包名 | `com.petsheroai.app` |
## 加密流程 ## 加密流程
@ -7087,322 +7087,323 @@ V2 完整响应体 (解密后):
## 错误码 ## 错误码
| code | 说明 | | code | 说明 |
|------|------| | ---- | ----------- |
| 0 | 成功 | | 0 | 成功 |
| -1 | 失败 | | -1 | 失败 |
| -2 | 系统错误 | | -2 | 系统错误 |
| -3 | 鉴权失败 | | -3 | 鉴权失败 |
| -5 | 参数错误 | | -5 | 参数错误 |
| 1001 | 积分不足 | | 1001 | 积分不足 |
| 1002 | 免费次数已用完 | | 1002 | 免费次数已用完 |
| 1003 | 免费次数和积分均已用完 | | 1003 | 免费次数和积分均已用完 |
## 字段映射全表 ## 字段映射全表
| 原始字段 | V2字段 | | 原始字段 | V2字段 |
|----------|--------| | ---------------------- | ------------- |
| User_token | knight | | User\_token | knight |
| accountId | wizard | | accountId | wizard |
| accountName | captain | | accountName | captain |
| activityId | warrior | | activityId | warrior |
| activitys | summon | | activitys | summon |
| actualAmount | guardian | | actualAmount | guardian |
| addCredits | awaken | | addCredits | awaken |
| adsTokenId | champion | | adsTokenId | champion |
| age | transform | | age | transform |
| amount | hero | | amount | hero |
| animate | ascend | | animate | ascend |
| app | sentinel | | app | sentinel |
| appFbConfig | evolve | | appFbConfig | evolve |
| appType | ranger | | appType | ranger |
| appraise | unleash | | appraise | unleash |
| approveState | paladin | | approveState | paladin |
| aspectRatio | quest | | aspectRatio | quest |
| automaticRenewal | legend | | automaticRenewal | legend |
| avatar | realm | | avatar | realm |
| baseCredits | wield | | baseCredits | wield |
| baseUrl | destiny | | baseUrl | destiny |
| begTime | emblem | | begTime | emblem |
| bonus | forge | | bonus | forge |
| bonusCredits | conjure | | bonusCredits | conjure |
| bonusRatio | enchant | | bonusRatio | enchant |
| businessId | vanquish | | businessId | vanquish |
| businessType | defend | | businessType | defend |
| campaignInfo | relic | | campaignInfo | relic |
| card | artifact | | card | artifact |
| categoryId | insignia | | categoryId | insignia |
| categoryName | patrol | | categoryName | patrol |
| ch | crest | | ch | crest |
| channel | lineage | | channel | lineage |
| channelType | armor | | channelType | armor |
| client | shield | | client | shield |
| clientId | gauntlet | | clientId | gauntlet |
| code | helm | | code | helm |
| coder | mantle | | coder | mantle |
| config | charge | | config | charge |
| content | cloak | | content | cloak |
| contentType | pauldron | | contentType | pauldron |
| count | visor | | count | visor |
| countId | command | | countId | command |
| country | vambrace | | country | vambrace |
| countryCode | navigate | | countryCode | navigate |
| creatTime | explore | | creatTime | explore |
| createTime | discover | | createTime | discover |
| createTimeText | uncover | | createTimeText | uncover |
| credit | reveal | | credit | reveal |
| creditPromotion | unlock | | creditPromotion | unlock |
| credits | greaves | | credits | greaves |
| creditsRecordUrl | conquer | | creditsRecordUrl | conquer |
| cryptoInvoiceUrl | protect | | cryptoInvoiceUrl | protect |
| currency | familiar | | currency | familiar |
| current | empower | | current | empower |
| cvcCode | companion | | cvcCode | companion |
| data | sidekick | | data | sidekick |
| days | species | | days | species |
| department | inspire | | department | inspire |
| desc | valor | | desc | valor |
| description | pedigree | | description | pedigree |
| devId | ancestry | | devId | ancestry |
| deviceId | origin | | deviceId | origin |
| discountOff | lead | | discountOff | lead |
| domain | totem | | domain | totem |
| domains | avatar | | domains | avatar |
| dt | sigil | | dt | sigil |
| duration | cosmos | | duration | cosmos |
| email | galaxy | | email | galaxy |
| enabled | nebula | | enabled | nebula |
| endTime | citadel | | endTime | citadel |
| event | fortress | | event | fortress |
| expectedSize | stronghold | | expectedSize | stronghold |
| expireMonth | dominion | | expireMonth | dominion |
| expireYear | sanctuary | | expireYear | sanctuary |
| expiresIn | soar | | expiresIn | soar |
| ext | nexus | | ext | nexus |
| extConfig | surge | | extConfig | surge |
| extJson | vanguard | | extJson | vanguard |
| face | dash | | face | dash |
| faceIndex | leap | | faceIndex | leap |
| faceInfos | strike | | faceInfos | strike |
| face_index | parry | | face\_index | parry |
| feature | dodge | | feature | dodge |
| features | scout | | features | scout |
| feedbackId | track | | feedbackId | track |
| feedbackIds | registry | | feedbackIds | registry |
| fileName | layer | | fileName | layer |
| fileName1 | gateway | | fileName1 | gateway |
| fileName2 | action | | fileName2 | action |
| filePath | hunt | | filePath | hunt |
| filePath1 | recruit | | filePath1 | recruit |
| filePath2 | train | | filePath2 | train |
| fileUrls | inventory | | fileUrls | inventory |
| filterCountry | blueprint | | filterCountry | blueprint |
| filterDomain | vendor | | filterDomain | vendor |
| filterOwnerId | participant | | filterOwnerId | participant |
| filterStatus | specimen | | filterStatus | specimen |
| filterTaskType | package | | filterTaskType | package |
| filterVip | quotation | | filterVip | quotation |
| firstName | appointment | | firstName | appointment |
| firstRegister | equip | | firstRegister | equip |
| forcePayCenter | upgrade | | forcePayCenter | upgrade |
| fps | notification | | fps | notification |
| frameIndex | unite | | frameIndex | unite |
| frame_index | pledge | | frame\_index | pledge |
| freeBlurTimes | vow | | freeBlurTimes | vow |
| freeTimes | decree | | freeTimes | decree |
| gender | venture | | gender | venture |
| googleClientId | discourse | | googleClientId | discourse |
| h5UrlConfig | pursue | | h5UrlConfig | pursue |
| hasNext | manifest | | hasNext | manifest |
| hash | mediation | | hash | mediation |
| hashIsZero | corpus | | hashIsZero | corpus |
| headFaceIndex | histogram | | headFaceIndex | histogram |
| headImg | agent | | headImg | agent |
| headPos | bond | | headPos | bond |
| headType | arena | | headType | arena |
| hint | traverse | | hint | traverse |
| host | initiative | | host | initiative |
| icon | greylist | | icon | greylist |
| id | federation | | id | federation |
| imageCount | simplify | | imageCount | simplify |
| imageFaceIndex | committee | | imageFaceIndex | committee |
| imageId | royalty | | imageId | royalty |
| imageInfos | curate | | imageInfos | curate |
| img | revenue | | img | revenue |
| imgCount | declaration | | imgCount | declaration |
| imgId | criterion | | imgId | criterion |
| imgList | downsample | | imgList | downsample |
| imgType | reconnect | | imgType | reconnect |
| imgUrl | reconfigure | | imgUrl | reconfigure |
| index | prewarm | | index | prewarm |
| inviteBy | item | | inviteBy | item |
| invitedCnt | deduce | | invitedCnt | deduce |
| isBlur | reify | | isBlur | reify |
| isVip | generate | | isVip | generate |
| issuerUrl | merge | | issuerUrl | merge |
| keepUserId | series | | keepUserId | series |
| label | subscribe | | label | subscribe |
| lang | seminar | | lang | seminar |
| lastName | bazaar | | lastName | bazaar |
| lastUpdateTime | probe | | lastUpdateTime | probe |
| link | festival | | link | festival |
| list | junction | | list | junction |
| maxLimit | architect | | maxLimit | architect |
| method | heap | | method | heap |
| methodActivitys | modify | | methodActivitys | modify |
| methodChannels | restore | | methodChannels | restore |
| model | authorization | | model | authorization |
| msg | rampart | | msg | rampart |
| name | brigade | | name | brigade |
| needCredits | deserialize | | needCredits | deserialize |
| needImage | assembly | | needImage | assembly |
| needUndress | directive | | needUndress | directive |
| needopt | allowance | | needopt | allowance |
| negativePrompt | underwriter | | negativePrompt | underwriter |
| note | extrapolate | | note | extrapolate |
| openType | transplant | | openType | transplant |
| optimizeCountSql | harvest | | optimizeCountSql | harvest |
| optimizeJoinOfCountSql | seek | | optimizeJoinOfCountSql | seek |
| orderId | gazette | | orderId | gazette |
| orders | identify | | orders | identify |
| originAmount | curriculum | | originAmount | curriculum |
| owner | genealogy | | owner | genealogy |
| p12KeyPath | arraignment | | p12KeyPath | arraignment |
| packageName | folio | | packageName | folio |
| page | trophy | | page | trophy |
| pages | coordinate | | pages | coordinate |
| password | township | | password | township |
| payCenterUrl | switch | | payCenterUrl | switch |
| payId | assert | | payId | assert |
| payMethod | intercept | | payMethod | intercept |
| payMethods | wallet | | payMethods | wallet |
| payStatus | destroy | | payStatus | destroy |
| payTime | restart | | payTime | restart |
| payTypeList | handshake | | payTypeList | handshake |
| payUrl | convert | | payUrl | convert |
| paylink | unzip | | paylink | unzip |
| paymentMethod | resource | | paymentMethod | resource |
| paymentMethods | renew | | paymentMethods | renew |
| permissions | sandbox | | permissions | sandbox |
| phone | block | | phone | block |
| pkg | portal | | pkg | portal |
| platform | trigger | | platform | trigger |
| previewImage | extract | | previewImage | extract |
| previewVideo | preempt | | previewVideo | preempt |
| productType | subtract | | productType | subtract |
| progress | dice | | progress | dice |
| prompt | ledger | | prompt | ledger |
| publicKey | template | | publicKey | template |
| purchaseData | merchant | | purchaseData | merchant |
| queueCnt | revert | | queueCnt | revert |
| read | redact | | read | redact |
| receipt | attendee | | receipt | attendee |
| recent | entrap | | recent | entrap |
| recentlyUsed | finalize | | recentlyUsed | finalize |
| recommend | deny | | recommend | deny |
| records | intensify | | records | intensify |
| redirectUrl | disambiguate | | redirectUrl | disambiguate |
| referer | digest | | referer | digest |
| refererType | campaign | | refererType | campaign |
| replyStatus | voxelize | | replyStatus | voxelize |
| requiredHeaders | remap | | requiredHeaders | remap |
| resolution | booking | | resolution | booking |
| resolution480p | reverify | | resolution480p | reverify |
| resolution720p | preprocess | | resolution720p | preprocess |
| resulotion | theorize | | resulotion | theorize |
| rewardCredits | represent | | rewardCredits | represent |
| rewardRatio | render | | rewardRatio | render |
| role | evaluate | | role | evaluate |
| searchCount | suspend | | searchCount | suspend |
| selected | deploy | | selected | deploy |
| serviceAccountEmail | alert | | serviceAccountEmail | alert |
| sharedSecret | comment | | sharedSecret | comment |
| showName | mold | | showName | mold |
| sign | resolution | | sign | resolution |
| signature | sample | | signature | sample |
| size | heatmap | | size | heatmap |
| sort | invent | | sort | invent |
| srcFaceImgBase64 | attachment | | srcFaceImgBase64 | attachment |
| srcFaceIndex | stadium | | srcFaceIndex | stadium |
| srcImg | refuge | | srcImg | refuge |
| srcImg1 | endeavor | | srcImg1 | endeavor |
| srcImg1Url | guild | | srcImg1Url | guild |
| srcImg2 | balance | | srcImg2 | balance |
| srcImg2Url | commission | | srcImg2Url | commission |
| srcImgBase64 | profit | | srcImgBase64 | profit |
| srcImgUrl | statute | | srcImgUrl | statute |
| srcVideo | compendium | | srcVideo | compendium |
| state | listing | | state | listing |
| status | line | | status | line |
| style | webinar | | style | webinar |
| subBusinessType | tailor | | subBusinessType | tailor |
| subPaymentMethod | ceremony | | subPaymentMethod | ceremony |
| subScribeValidTime | tokenize | | subScribeValidTime | tokenize |
| subscriptionActivitys | cleanse | | subscriptionActivitys | cleanse |
| subscriptionPeriod | distribute | | subscriptionPeriod | distribute |
| sumCredits | emit | | sumCredits | emit |
| sys | associate | | sys | associate |
| t2IConfig | regulate | | t2IConfig | regulate |
| tag | constrain | | tag | constrain |
| tags | rally | | tags | rally |
| targetId | node | | targetId | node |
| targetInvitedCnt | authorize | | targetInvitedCnt | authorize |
| taskId | tree | | taskId | tree |
| taskIds | privilege | | taskIds | privilege |
| taskType | cipher | | taskType | cipher |
| taskTypes | platoon | | taskTypes | platoon |
| templateFaceUrl | simulate | | templateFaceUrl | simulate |
| templateFifCredits | pause | | templateFifCredits | pause |
| templateFifDuration | decommission | | templateFifDuration | decommission |
| templateFifUrl | acknowledge | | templateFifUrl | acknowledge |
| templateName | congregation | | templateName | congregation |
| templateTfCredits | pipe | | templateTfCredits | pipe |
| templateTfDuration | unwrap | | templateTfDuration | unwrap |
| templateTfUrl | extend | | templateTfUrl | extend |
| templateType | recharge | | templateType | recharge |
| templateTypes | endowment | | templateTypes | endowment |
| templateUrl | inject | | templateUrl | inject |
| tgId | concession | | tgId | concession |
| tgName | defer | | tgName | defer |
| tgOrderId | insurer | | tgOrderId | insurer |
| theme | parallelize | | theme | parallelize |
| title | glossary | | title | glossary |
| token | thesis | | token | thesis |
| total | weigh | | total | weigh |
| totalUnreadCount | defragment | | totalUnreadCount | defragment |
| transactionId | chronicle | | transactionId | chronicle |
| truePrompt | deposition | | truePrompt | deposition |
| ts | quarto | | ts | quarto |
| type | accolade | | type | accolade |
| types | municipality | | types | municipality |
| unreadCountList | footprint | | unreadCountList | footprint |
| updateTime | fork | | updateTime | fork |
| uploadUrl | shed | | uploadUrl | shed |
| uploadUrl1 | bolster | | uploadUrl1 | bolster |
| uploadUrl2 | expound | | uploadUrl2 | expound |
| url | digitize | | url | digitize |
| user | rebalance | | user | rebalance |
| userApplePayList | gallery | | userApplePayList | gallery |
| userId | asset | | userId | asset |
| userInfoType | frame | | userInfoType | frame |
| userName | terminal | | userName | terminal |
| userToken | reevaluate | | userToken | reevaluate |
| userType | prefetch | | userType | prefetch |
| username | pulse | | username | pulse |
| usign | retrospect | | usign | retrospect |
| val | journal | | val | journal |
| value | schema | | value | schema |
| verifyCode | supplier | | verifyCode | supplier |
| videoDuration | demonstrate | | videoDuration | demonstrate |
| videoFaceIndex | applicant | | videoFaceIndex | applicant |
| videoFrameIndex | fragment | | videoFrameIndex | fragment |
| videoSize | summary | | videoSize | summary |
| videoUrl | promotion | | videoUrl | promotion |
| waitTime | flowStep | | waitTime | flowStep |
| x1 | invoke | | x1 | invoke |
| x2 | sync | | x2 | sync |
| y1 | configure | | y1 | configure |
| y2 | manufacture | | y2 | manufacture |
--- ***
*本文档由 ProtocolEncTool 自动生成API 变更后请重新执行生成命令。*
*本文档由 ProtocolEncTool 自动生成API 变更后请重新执行生成命令。transplant*

View File

@ -1,6 +1,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_lucide/flutter_lucide.dart'; import 'package:flutter_lucide/flutter_lucide.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../core/adjust/adjust_events.dart'; import '../../core/adjust/adjust_events.dart';
import '../../core/api/api_config.dart'; import '../../core/api/api_config.dart';
@ -38,6 +39,11 @@ class _RechargeScreenState extends State<RechargeScreen>
/// code item Buy loading /// code item Buy loading
String? _loadingProductId; String? _loadingProductId;
///
String? _pendingOrderId;
String? _pendingUserId;
double? _pendingPurchaseAmount;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -61,6 +67,23 @@ class _RechargeScreenState extends State<RechargeScreen>
mounted) { mounted) {
setState(() => _loadingProductId = null); setState(() => _loadingProductId = null);
} }
//
if (state == AppLifecycleState.resumed &&
_pendingOrderId != null &&
_pendingUserId != null &&
_pendingPurchaseAmount != null &&
mounted) {
_startOrderPolling(
orderId: _pendingOrderId!,
userId: _pendingUserId!,
purchaseAmount: _pendingPurchaseAmount!,
);
//
_pendingOrderId = null;
_pendingUserId = null;
_pendingPurchaseAmount = null;
}
} }
Future<void> _fetchActivities() async { Future<void> _fetchActivities() async {
@ -260,32 +283,48 @@ class _RechargeScreenState extends State<RechargeScreen>
: null; : null;
final orderId = data?['federation']?.toString(); final orderId = data?['federation']?.toString();
if (_isGooglePay(paymentMethod, subPaymentMethod)) { final purchaseAmount =
(AdjustEvents.parsePrice(item.actualAmount) ?? 0).toDouble();
final payUrl = data?['convert']?.toString();
final openType = data?['transplant'] as int?;
if (_shouldUseGooglePay(payUrl)) {
await _launchGooglePlayPurchase(item, await _launchGooglePlayPurchase(item,
serverOrderId: orderId, userId: userId); serverOrderId: orderId, userId: userId);
return; return;
} }
final purchaseAmount =
(AdjustEvents.parsePrice(item.actualAmount) ?? 0).toDouble();
final payUrl = data?['convert']?.toString();
if (payUrl != null && payUrl.isNotEmpty) { if (payUrl != null && payUrl.isNotEmpty) {
if (mounted) { if (mounted) {
setState(() => _loadingProductId = null); setState(() => _loadingProductId = null);
await Navigator.of(context).push(
MaterialPageRoute<void>( if (_shouldUseSystemBrowser(openType)) {
builder: (_) => PaymentWebViewScreen(paymentUrl: payUrl), //
), await launchUrl(Uri.parse(payUrl), mode: LaunchMode.externalApplication);
); // didChangeAppLifecycleState
if (mounted && orderId != null && orderId.isNotEmpty) { _pendingOrderId = orderId;
_startOrderPolling( _pendingUserId = userId;
orderId: orderId, _pendingPurchaseAmount = purchaseAmount;
userId: userId, _showSnackBar(
purchaseAmount: purchaseAmount, context, 'Order created. Complete payment in the browser.');
} else {
//
await Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (_) => PaymentWebViewScreen(paymentUrl: payUrl),
),
); );
//
if (mounted && orderId != null && orderId.isNotEmpty) {
_startOrderPolling(
orderId: orderId,
userId: userId,
purchaseAmount: purchaseAmount,
);
}
_showSnackBar(
context, 'Order created. Complete payment in the page.');
} }
_showSnackBar(
context, 'Order created. Complete payment in the page.');
} }
} else { } else {
if (mounted) { if (mounted) {
@ -354,11 +393,14 @@ class _RechargeScreenState extends State<RechargeScreen>
poll(0); poll(0);
} }
/// ceremony==GooglePay resource==GOOGLEPAY /// payUrl
static bool _isGooglePay(String paymentMethod, String? subPaymentMethod) { static bool _shouldUseGooglePay(String? payUrl) {
final r = paymentMethod.trim().toLowerCase(); return payUrl == null || payUrl.isEmpty;
final c = (subPaymentMethod ?? '').trim().toLowerCase(); }
return r == 'googlepay' || c == 'googlepay';
/// openType 0=1==
static bool _shouldUseSystemBrowser(int? openType) {
return openType == 1;
} }
/// false Google Pay /// false Google Pay