Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
ethan
/
appframe
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
Commit c281ea4f
authored
2026-07-11 11:37:40 +0800
by
ethanlamzs
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
更换验证方法
1 parent
e876571d
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
2 additions
and
107 deletions
ios/Runner/AppDelegate.swift
lib/services/subscription_service_ios.dart
lib/utils/ios_receiptHelper.dart
ios/Runner/AppDelegate.swift
View file @
c281ea4
import
UIKit
import
Flutter
import
StoreKit
// Add these two import lines
import
TIMPush
...
...
@@ -22,22 +21,6 @@ import tencent_cloud_chat_push
fatalError
(
"rootViewController is not a FlutterViewController"
)
}
let
channel
=
FlutterMethodChannel
(
name
:
"cn.banxe.appframe/receipt"
,
binaryMessenger
:
controller
.
binaryMessenger
)
channel
.
setMethodCallHandler
{
(
call
,
result
)
in
switch
call
.
method
{
case
"getReceipt"
:
self
.
getReceiptBase64
(
result
:
result
)
case
"refreshReceipt"
:
self
.
refreshReceipt
(
result
:
result
)
default
:
result
(
FlutterMethodNotImplemented
)
}
}
// 注册插件
GeneratedPluginRegistrant
.
register
(
with
:
self
)
...
...
@@ -101,25 +84,6 @@ import tencent_cloud_chat_push
return
true
}
private
func
getReceiptBase64
(
result
:
@escaping
FlutterResult
)
{
guard
let
receiptURL
=
Bundle
.
main
.
appStoreReceiptURL
,
FileManager
.
default
.
fileExists
(
atPath
:
receiptURL
.
path
),
let
receiptData
=
try
?
Data
(
contentsOf
:
receiptURL
)
else
{
result
(
FlutterError
(
code
:
"NO_RECEIPT"
,
message
:
"收据不存在,请先刷新"
,
details
:
nil
))
return
}
result
(
receiptData
.
base64EncodedString
())
}
private
func
refreshReceipt
(
result
:
@escaping
FlutterResult
)
{
let
request
=
SKReceiptRefreshRequest
()
request
.
delegate
=
RefreshDelegate
(
result
:
result
)
request
.
start
()
}
}
// 可选:防止冲突的手势识别设置
...
...
@@ -130,17 +94,3 @@ extension AppDelegate: UIGestureRecognizerDelegate {
}
}
class
RefreshDelegate
:
NSObject
,
SKRequestDelegate
{
let
result
:
FlutterResult
init
(
result
:
@escaping
FlutterResult
)
{
self
.
result
=
result
}
func
requestDidFinish
(
_
request
:
SKRequest
)
{
result
(
true
)
}
func
request
(
_
request
:
SKRequest
,
didFailWithError
error
:
Error
)
{
result
(
FlutterError
(
code
:
"REFRESH_FAILED"
,
message
:
error
.
localizedDescription
,
details
:
nil
))
}
}
\ No newline at end of file
lib/services/subscription_service_ios.dart
View file @
c281ea4
...
...
@@ -4,7 +4,6 @@ import 'package:in_app_purchase/in_app_purchase.dart';
import
'package:flutter/widgets.dart'
;
import
'package:appframe/data/repositories/user_auth_repository.dart'
;
import
'package:appframe/config/locator.dart'
;
import
'package:appframe/utils/ios_receiptHelper.dart'
;
class
SubscriptionService
{
...
...
@@ -150,14 +149,9 @@ class SubscriptionService {
debugPrint
(
"[info] _verifyReceipt is start scence ["
+
scence
+
"] "
+
purchaseDetails
.
productID
+
" orderid:"
+
orderid
);
// 将收据发送到你的后端进行验证
//final String receipt = purchaseDetails.verificationData.serverVerificationData;
// 可选:沙盒环境经常需要先刷新一下
await
ReceiptHelper
.
refreshReceipt
();
final
base64Receipt
=
await
ReceiptHelper
.
getBase64Receipt
();
final
String
receipt
=
purchaseDetails
.
verificationData
.
serverVerificationData
;
// 把 base64Receipt 作为 receipt-data 发给你的服务端验证
debugPrint
(
"[info] _verifyReceipt base64Receipt "
+
base64Receipt
);
final
bool
isValid
=
await
_sendReceiptToBackend
(
base64Receipt
,
orderid
);
final
bool
isValid
=
await
_sendReceiptToBackend
(
receipt
,
orderid
);
debugPrint
(
"[info] _verifyReceipt is step 1 "
);
if
(
isValid
)
{
...
...
@@ -178,23 +172,6 @@ class SubscriptionService {
return
true
;
}
Future
<
void
>
_handleSuccessfulPurchase
(
PurchaseDetails
purchase
,
String
orderid
)
async
{
try
{
// 1. 先直接尝试读取现有收据
String
?
base64
=
await
ReceiptHelper
.
getBase64Receipt
();
if
(
base64
==
null
)
{
// 2. 只有收据不存在时,才刷新一次
await
ReceiptHelper
.
refreshReceipt
();
base64
=
await
ReceiptHelper
.
getBase64Receipt
();
}
// 3. 提交验证
await
_sendReceiptToBackend
(
base64
,
orderid
);
}
catch
(
e
)
{
print
(
'验证失败:
$e
'
);
}
}
// ---------- 恢复购买 ----------
Future
<
void
>
restorePurchases
()
async
{
await
_iap
.
restorePurchases
();
...
...
lib/utils/ios_receiptHelper.dart
deleted
100644 → 0
View file @
e876571
import
'dart:convert'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/services.dart'
;
class
ReceiptHelper
{
static
const
_channel
=
MethodChannel
(
'cn.banxe.appframe/receipt'
);
/// 获取 Base64 编码的收据数据,直接可用于 /verifyReceipt
static
Future
<
String
>
getBase64Receipt
()
async
{
try
{
final
String
?
base64
=
await
_channel
.
invokeMethod
(
'getReceipt'
);
if
(
base64
==
null
||
base64
.
isEmpty
)
{
throw
Exception
(
'收据为空,请先刷新收据'
);
}
return
base64
;
}
on
MissingPluginException
{
debugPrint
(
"原生插件未注册,请检查 iOS 代码"
);
throw
Exception
(
'原生插件未注册,请检查 iOS 代码'
);
}
}
/// 强制刷新收据(沙盒环境常需要)
static
Future
<
void
>
refreshReceipt
()
async
{
try
{
await
_channel
.
invokeMethod
(
'refreshReceipt'
);
}
catch
(
e
)
{
debugPrint
(
e
.
toString
());
throw
Exception
(
'刷新收据失败:
$e
'
);
}
}
}
\ No newline at end of file
Write
Preview
Styling with
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment