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 e876571d
authored
2026-07-10 22:40:31 +0800
by
ethanlamzs
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
调试
1 parent
a7977028
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
32 additions
and
16 deletions
lib/data/repositories/message/xe_create_order_handler.dart
lib/services/subscription_service_ios.dart
lib/utils/ios_receiptHelper.dart
lib/data/repositories/message/xe_create_order_handler.dart
View file @
e876571
...
@@ -201,21 +201,16 @@ class XeCreateOrderHandler extends MessageHandler {
...
@@ -201,21 +201,16 @@ class XeCreateOrderHandler extends MessageHandler {
// 执行ios的微信支付
// 执行ios的微信支付
Future
<
dynamic
>
_ios_pay_proc_
(
String
userCode
,
tbxStuId
,
chargeCode
,
deviceType
,
phone
,
stuId
,
ext
,
int
duration
,
durationType
,
totalFee
,
bool
renew
,
useCoin
)
async
{
Future
<
dynamic
>
_ios_pay_proc_
(
String
userCode
,
tbxStuId
,
chargeCode
,
deviceType
,
phone
,
stuId
,
ext
,
int
duration
,
durationType
,
totalFee
,
bool
renew
,
useCoin
)
async
{
print
(
"[debug]. _ios_pay_proc_ 11 "
);
// 暂时用固定的价格
// 暂时用固定的价格
var
result
=
await
_userAuthRepository
.
createOrder
(
userCode
,
tbxStuId
,
chargeCode
,
duration
,
durationType
,
totalFee
,
var
result
=
await
_userAuthRepository
.
createOrder
(
userCode
,
tbxStuId
,
chargeCode
,
duration
,
durationType
,
totalFee
,
renew
,
phone
,
stuId
,
ext
,
useCoin
?
1
:
0
,
deviceType
);
renew
,
phone
,
stuId
,
ext
,
useCoin
?
1
:
0
,
deviceType
);
print
(
"[debug]. _ios_pay_proc_ 12 "
);
print
(
result
);
print
(
result
);
// map[nonceStr:qNfHK6a95jjJkwzDkh0h3fhfUVuS0jZ9 paySign: timeStamp:1783497438 wxTradeNo:to1281644408384671744]
// map[nonceStr:qNfHK6a95jjJkwzDkh0h3fhfUVuS0jZ9 paySign: timeStamp:1783497438 wxTradeNo:to1281644408384671744]
var
data
=
result
[
'data'
]
as
Map
<
String
,
dynamic
>?;
var
data
=
result
[
'data'
]
as
Map
<
String
,
dynamic
>?;
if
(
data
==
null
)
{
if
(
data
==
null
)
{
throw
Exception
(
'订单生成失败'
);
throw
Exception
(
'订单生成失败'
);
}
}
print
(
"[debug]. _ios_pay_proc_ 13 "
);
// 3. 从后端响应中提取预支付ID
// 3. 从后端响应中提取预支付ID
final
wxTradeNo
=
data
[
'wxTradeNo'
]
as
String
?;
final
wxTradeNo
=
data
[
'wxTradeNo'
]
as
String
?;
if
(
wxTradeNo
==
null
||
wxTradeNo
.
isEmpty
)
{
if
(
wxTradeNo
==
null
||
wxTradeNo
.
isEmpty
)
{
...
@@ -225,8 +220,7 @@ class XeCreateOrderHandler extends MessageHandler {
...
@@ -225,8 +220,7 @@ class XeCreateOrderHandler extends MessageHandler {
// 4. 从后端响应中提取支付参数(nonceStr、timestamp、paySign 由后端生成)
// 4. 从后端响应中提取支付参数(nonceStr、timestamp、paySign 由后端生成)
final
timestamp
=
data
[
'timeStamp'
]
as
int
;
final
timestamp
=
data
[
'timeStamp'
]
as
int
;
print
(
"[debug]. _ios_pay_proc_ 3 "
);
//debugPrint('_ios_pay_proc_ => timestamp: $timestamp');
debugPrint
(
'_ios_pay_proc_ => timestamp:
$timestamp
'
);
debugPrint
(
'_ios_pay_proc_ => wxTradeNo:
$wxTradeNo
'
);
debugPrint
(
'_ios_pay_proc_ => wxTradeNo:
$wxTradeNo
'
);
if
(
wxTradeNo
.
isEmpty
)
{
if
(
wxTradeNo
.
isEmpty
)
{
...
@@ -240,10 +234,10 @@ class XeCreateOrderHandler extends MessageHandler {
...
@@ -240,10 +234,10 @@ class XeCreateOrderHandler extends MessageHandler {
var
product
;
var
product
;
for
(
var
p
in
_subService
.
products
)
{
for
(
var
p
in
_subService
.
products
)
{
// 因为带了一个¥符号
// 因为带了一个¥符号
debugPrint
(
'checking ==> 产品ID:
${p.id}
, 标题:
${p.title}
, 价格:
${p.price}
'
);
//
debugPrint('checking ==> 产品ID: ${p.id}, 标题: ${p.title}, 价格: ${p.price}');
if
(
p
.
price
.
toString
().
indexOf
(
totalFee
.
toString
().
substring
(
0
,
2
))==
1
){
if
(
p
.
price
.
toString
().
indexOf
(
totalFee
.
toString
().
substring
(
0
,
2
))==
1
){
product
=
p
;
product
=
p
;
debugPrint
(
'match =====> 产品ID:
${p.id}
, 标题:
${p.title}
, 价格:
${p.price}
'
);
//
debugPrint('match =====> 产品ID: ${p.id}, 标题: ${p.title}, 价格: ${p.price}');
break
;
break
;
}
}
}
}
...
...
lib/services/subscription_service_ios.dart
View file @
e876571
...
@@ -105,16 +105,16 @@ class SubscriptionService {
...
@@ -105,16 +105,16 @@ class SubscriptionService {
print
(
"Purchase update !_isSubscription "
);
print
(
"Purchase update !_isSubscription "
);
continue
;
continue
;
}
}
final
orderId
=
_orderIdMap
.
remove
(
purchaseDetails
.
productID
);
// 取出并删除
final
ctx
=
_pendingContexts
[
purchaseDetails
.
productID
];
print
(
ctx
);
// 根据交易状态处理
// 根据交易状态处理
switch
(
purchaseDetails
.
status
)
{
switch
(
purchaseDetails
.
status
)
{
case
PurchaseStatus
.
purchased
:
case
PurchaseStatus
.
purchased
:
// 购买成功或续期成功
// 购买成功或续期成功
final
orderId
=
_orderIdMap
.
remove
(
purchaseDetails
.
productID
);
// 取出并删除
final
ctx
=
_pendingContexts
[
purchaseDetails
.
productID
];
print
(
ctx
);
// 1. 验证收据(必须!)
// 1. 验证收据(必须!)
_verifyReceipt
(
purchaseDetails
,
orderId
??
''
,
"purchased"
);
_verifyReceipt
(
purchaseDetails
,
orderId
??
''
,
"purchased"
);
// 2. 通知 App Store 交易完成
// 2. 通知 App Store 交易完成
...
@@ -147,15 +147,16 @@ class SubscriptionService {
...
@@ -147,15 +147,16 @@ class SubscriptionService {
// ---------- 服务端验证收据 ----------
// ---------- 服务端验证收据 ----------
Future
<
void
>
_verifyReceipt
(
PurchaseDetails
purchaseDetails
,
String
orderid
,
String
scence
)
async
{
Future
<
void
>
_verifyReceipt
(
PurchaseDetails
purchaseDetails
,
String
orderid
,
String
scence
)
async
{
debugPrint
(
"[info] _verifyReceipt is start scence ["
+
scence
+
"]
"
+
purchaseDetails
.
productID
);
debugPrint
(
"[info] _verifyReceipt is start scence ["
+
scence
+
"]
"
+
purchaseDetails
.
productID
+
" orderid:"
+
orderid
);
// 将收据发送到你的后端进行验证
// 将收据发送到你的后端进行验证
//final String receipt = purchaseDetails.verificationData.serverVerificationData;
//final String receipt = purchaseDetails.verificationData.serverVerificationData;
// 可选:沙盒环境经常需要先刷新一下
// 可选:沙盒环境经常需要先刷新一下
await
ReceiptHelper
.
refreshReceipt
();
await
ReceiptHelper
.
refreshReceipt
();
final
base64Receipt
=
await
ReceiptHelper
.
getBase64Receipt
();
final
base64Receipt
=
await
ReceiptHelper
.
getBase64Receipt
();
// 把 base64Receipt 作为 receipt-data 发给你的服务端验证
// 把 base64Receipt 作为 receipt-data 发给你的服务端验证
debugPrint
(
"[info] _verifyReceipt base64Receipt "
+
base64Receipt
);
final
bool
isValid
=
await
_sendReceiptToBackend
(
base64Receipt
,
orderid
);
final
bool
isValid
=
await
_sendReceiptToBackend
(
base64Receipt
,
orderid
);
debugPrint
(
"[info] _verifyReceipt is step 1 "
);
debugPrint
(
"[info] _verifyReceipt is step 1 "
);
...
@@ -176,6 +177,23 @@ class SubscriptionService {
...
@@ -176,6 +177,23 @@ class SubscriptionService {
debugPrint
(
"[info] _sendReceiptToBackend is done"
);
debugPrint
(
"[info] _sendReceiptToBackend is done"
);
return
true
;
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
{
Future
<
void
>
restorePurchases
()
async
{
...
...
lib/utils/ios_receiptHelper.dart
View file @
e876571
import
'dart:convert'
;
import
'dart:convert'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
class
ReceiptHelper
{
class
ReceiptHelper
{
static
const
_channel
=
MethodChannel
(
'cn.banxe.appframe/receipt'
);
static
const
_channel
=
MethodChannel
(
'cn.banxe.appframe/receipt'
);
/// 获取 Base64 编码的收据数据,直接可用于 /verifyReceipt
/// 获取 Base64 编码的收据数据,直接可用于 /verifyReceipt
...
@@ -13,6 +15,7 @@ class ReceiptHelper {
...
@@ -13,6 +15,7 @@ class ReceiptHelper {
}
}
return
base64
;
return
base64
;
}
on
MissingPluginException
{
}
on
MissingPluginException
{
debugPrint
(
"原生插件未注册,请检查 iOS 代码"
);
throw
Exception
(
'原生插件未注册,请检查 iOS 代码'
);
throw
Exception
(
'原生插件未注册,请检查 iOS 代码'
);
}
}
}
}
...
@@ -22,6 +25,7 @@ class ReceiptHelper {
...
@@ -22,6 +25,7 @@ class ReceiptHelper {
try
{
try
{
await
_channel
.
invokeMethod
(
'refreshReceipt'
);
await
_channel
.
invokeMethod
(
'refreshReceipt'
);
}
catch
(
e
)
{
}
catch
(
e
)
{
debugPrint
(
e
.
toString
());
throw
Exception
(
'刷新收据失败:
$e
'
);
throw
Exception
(
'刷新收据失败:
$e
'
);
}
}
}
}
...
...
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