Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pay
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
bp
pay
Commits
5dd1c7f3
Commit
5dd1c7f3
authored
Sep 24, 2021
by
songxiaohang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add:pay2
parent
b734e336
Changes
48
Hide whitespace changes
Inline
Side-by-side
Showing
48 changed files
with
1960 additions
and
561 deletions
+1960
-561
Code.php
application/exception/custom/Code.php
+2
-0
FundsException.php
application/exception/custom/FundsException.php
+17
-0
PayException.php
application/exception/custom/PayException.php
+22
-10
PlatformAccountException.php
application/exception/custom/PlatformAccountException.php
+17
-0
RefundException.php
application/exception/custom/RefundException.php
+10
-17
CallbackLog.php
application/models/order/mysql/CallbackLog.php
+1
-1
MarketingAccount.php
application/models/order/mysql/MarketingAccount.php
+11
-0
MarketingAccountLog.php
application/models/order/mysql/MarketingAccountLog.php
+10
-0
MarketingAccountMap.php
application/models/order/mysql/MarketingAccountMap.php
+10
-0
PayCouponItem.php
application/models/order/mysql/PayCouponItem.php
+11
-0
PayOrder.php
application/models/order/mysql/PayOrder.php
+3
-3
PayOrderClearing.php
application/models/order/mysql/PayOrderClearing.php
+1
-1
PayOrderClearingItem.php
application/models/order/mysql/PayOrderClearingItem.php
+1
-1
PayOrderItem.php
application/models/order/mysql/PayOrderItem.php
+1
-1
PayOrderLog.php
application/models/order/mysql/PayOrderLog.php
+11
-0
PlatformAccount.php
application/models/order/mysql/PlatformAccount.php
+10
-0
PlatformAccountLog.php
application/models/order/mysql/PlatformAccountLog.php
+10
-0
PlatformConfig.php
application/models/order/mysql/PlatformConfig.php
+10
-0
PlatformFunds.php
application/models/order/mysql/PlatformFunds.php
+10
-0
PlatformFundsLog.php
application/models/order/mysql/PlatformFundsLog.php
+10
-0
RefundMerchantRecord.php
application/models/order/mysql/RefundMerchantRecord.php
+10
-0
RefundOrder.php
application/models/order/mysql/RefundOrder.php
+1
-1
RefundOrderItem.php
application/models/order/mysql/RefundOrderItem.php
+10
-0
RefundPersonalRecord.php
application/models/order/mysql/RefundPersonalRecord.php
+10
-0
RefundPlatformRecord.php
application/models/order/mysql/RefundPlatformRecord.php
+10
-0
WriteOffMerchantRecord.php
application/models/order/mysql/WriteOffMerchantRecord.php
+10
-0
WriteOffOrder.php
application/models/order/mysql/WriteOffOrder.php
+10
-0
WriteOffOrderItem.php
application/models/order/mysql/WriteOffOrderItem.php
+10
-0
WriteOffPersonalRecord.php
application/models/order/mysql/WriteOffPersonalRecord.php
+10
-0
WriteOffPlatformRecord.php
application/models/order/mysql/WriteOffPlatformRecord.php
+10
-0
Order.php
application/modules/Pay/controllers/Order.php
+10
-0
Tcc.php
application/modules/Pay/controllers/Tcc.php
+13
-0
Hook.php
application/plugins/Hook.php
+33
-16
Channel.php
application/services/Channel.php
+42
-0
Pingxx.php
application/services/channel/Pingxx.php
+207
-0
Platform.php
application/services/channel/Platform.php
+31
-0
AccountService.php
application/services/marketing/AccountService.php
+200
-0
FundsService.php
application/services/pay/FundsService.php
+78
-0
PayService.php
application/services/pay/PayService.php
+698
-406
PlatformAccountService.php
application/services/pay/PlatformAccountService.php
+43
-0
PingxxService.php
application/services/pingxx/PingxxService.php
+1
-0
RefundService.php
application/services/refund/RefundService.php
+158
-97
MerchantAccountService.php
application/services/wallet/MerchantAccountService.php
+45
-0
WalletService.php
application/services/wallet/WalletService.php
+14
-0
application.ini
conf/application.ini
+12
-2
cli.ini
conf/cli.ini
+16
-4
demo.php
public/demo.php
+6
-1
pay.sql
sql/pay2_0913/pay.sql
+84
-0
No files found.
application/exception/custom/Code.php
View file @
5dd1c7f3
...
...
@@ -15,4 +15,6 @@ class Code
const
REFUND
=
102000
;
const
ORDER
=
103000
;
const
SDK
=
104000
;
const
FUNDS
=
105000
;
const
P_ACCOUNT
=
106000
;
}
\ No newline at end of file
application/exception/custom/FundsException.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Exception\custom
;
use
App\Exception\BaseException
;
class
FundsException
extends
BaseException
{
protected
$base_code
=
Code
::
FUNDS
;
protected
$cus
=
[
0
=>
'系统异常请联系管理员'
,
1
=>
'缺少渠道平台账户配置,请联系管理员!'
,
];
}
application/exception/custom/PayException.php
View file @
5dd1c7f3
...
...
@@ -13,22 +13,34 @@ class PayException extends BaseException
protected
$cus
=
[
0
=>
'系统错误,请稍收重试'
,
1
=>
'请输入订单ID'
,
2
=>
'订单服务获取订单信息失败。'
,
3
=>
'请确认订单信息及用户是否一致。'
,
4
=>
'支付订单创建失败,请管理员关注'
,
5
=>
'该订单已经支付,请稍后刷新'
,
6
=>
'该订单已超时取消关闭,请重新下单购买'
,
7
=>
'支付回调订单不存在,请管理员关注'
,
8
=>
'支付订单金额与实际支付金额不等,请管理员关注'
,
9
=>
'退款中订单不允许核销,请管理员关注'
,
2
=>
'请输入用户ID'
,
3
=>
'订单服务获取订单信息失败。'
,
4
=>
'请确认订单信息及用户是否一致。'
,
5
=>
'订单缺少过期时间,请联系管理员'
,
6
=>
'订单过期,不允许支付'
,
7
=>
'支付订单创建失败,请管理员关注'
,
8
=>
'支付订单创建失败,请管理员关注'
,
9
=>
'订单已经支付,请勿重复支付'
,
10
=>
'回调失败,支付订单不存在'
,
11
=>
'回调失败,支付金额错误'
,
12
=>
'订单服务优惠信息错误'
,
13
=>
'订单明细保存失败'
,
10
=>
'未支付订单不允许核销,请管理员关注'
,
11
=>
'商家仅允许核销自己的订单,请管理员关注'
,
12
=>
'支付订单预结算失败,结算资金不能负数,请核对配置'
,
13
=>
'生活号获取管理员ID失败,请联系管理员'
,
14
=>
'订单缺少商品信息,请联系管理员'
,
15
=>
'订单存在过期商品,不能支付'
,
16
=>
'订单过期,不允许支付'
,
18
=>
'订单不存在,请重试'
,
100
=>
'支付渠道错误,暂不支持该渠道'
,
101
=>
'该订单已经支付,请稍后刷新'
,
102
=>
'该订单已超时取消关闭,请重新下单购买'
,
103
=>
'该订单已超时取消关闭,请重新下单购买'
,
104
=>
'请增加pingxx渠道手续费配置'
,
];
}
application/exception/custom/PlatformAccountException.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Exception\custom
;
use
App\Exception\BaseException
;
class
PlatformAccountException
extends
BaseException
{
protected
$base_code
=
Code
::
P_ACCOUNT
;
protected
$cus
=
[
0
=>
'系统异常请联系管理员'
,
1
=>
'缺少渠道平台账户配置,请联系管理员!'
,
];
}
application/exception/custom/RefundException.php
View file @
5dd1c7f3
...
...
@@ -11,23 +11,16 @@ class RefundException extends BaseException
protected
$base_code
=
Code
::
REFUND
;
protected
$cus
=
[
0
=>
'系统异常请联系管理员'
,
0
=>
'系统异常请联系管理员
。
'
,
1
=>
'缺少退款订单ID!'
,
2
=>
'获取订单信息返回错误,请核对'
,
3
=>
'仅支持自己操作订单退款!'
,
4
=>
'目前仅支持支付后的订单退款,请核对'
,
5
=>
'已核销计算订单不支持退款!'
,
6
=>
'退款处理完成,请勿重复申请'
,
7
=>
'退款处理中请稍等'
,
8
=>
'退款消息类型匹配失败,请管理员关注!'
,
9
=>
'pingxx退款消息格式错误,请管理员关注!'
,
10
=>
'pingxx退单状态异常,请管理员关注!'
,
11
=>
'pingxx退单缺少matadata!'
,
12
=>
'pingxx未支付订单不允许退款。'
,
13
=>
'pingxx订单可能存在多次成功支付,需人工确认处理。'
,
14
=>
'不存在满足条件的退款订单。'
,
15
=>
'订单未支付或不存在,请核对。'
,
16
=>
'订单退款回调处理失败,请核对。'
,
2
=>
'订单未支付或不存在,请核对。'
,
3
=>
'不存在满足条件的退款订单。'
,
4
=>
'退单保存失败,请联系管理员。'
,
5
=>
'订单退款回调处理失败,请核对。'
,
6
=>
'pingxx退单缺少matadata!'
,
7
=>
'pingxx未支付订单不允许退款。'
,
8
=>
'pingxx订单可能存在多次成功支付,需人工确认处理。'
,
];
}
application/models/order/mysql/CallbackLog.php
View file @
5dd1c7f3
...
...
@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase;
class
CallbackLog
extends
MysqlBase
{
const
TABLE_NAME
=
'callback_log'
;
const
CONFIG_INDEX
=
'pay'
;
const
CONFIG_INDEX
=
'pay
_v2
'
;
}
application/models/order/mysql/MarketingAccount.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
use
App\Exception\custom\PayException
;
class
MarketingAccount
extends
MysqlBase
{
const
TABLE_NAME
=
'marketing_account'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/MarketingAccountLog.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
MarketingAccountLog
extends
MysqlBase
{
const
TABLE_NAME
=
'marketing_account_log'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/MarketingAccountMap.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
MarketingAccountMap
extends
MysqlBase
{
const
TABLE_NAME
=
'marketing_account_map'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/PayCouponItem.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
use
App\Exception\custom\PayException
;
class
PayCouponItem
extends
MysqlBase
{
const
TABLE_NAME
=
'pay_coupon_item'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/PayOrder.php
View file @
5dd1c7f3
...
...
@@ -7,7 +7,7 @@ use App\Exception\custom\PayException;
class
PayOrder
extends
MysqlBase
{
const
TABLE_NAME
=
'pay_order'
;
const
CONFIG_INDEX
=
'pay'
;
const
CONFIG_INDEX
=
'pay
_v2
'
;
/**
* @param $order_id
...
...
@@ -18,14 +18,14 @@ class PayOrder extends MysqlBase
self
::
beginTransaction
();
try
{
$_date
=
date
(
'Y-m-d H:i:s'
);
$order
=
self
::
getMaster
(
'*'
,
[
'order_id'
=>
$order_id
,
'expire_time[>]'
=>
$_date
]);
$order
=
self
::
getMaster
(
'*'
,
[
'order_id'
=>
$order_id
]);
if
(
empty
(
$order
))
{
$cnt
=
self
::
insert
(
$pay_order
,
[
'rowCount'
=>
true
]);
if
(
$cnt
)
{
$order
=
$pay_order
;
}
}
self
::
commit
();
}
catch
(
\PDOException
$e
)
{
...
...
application/models/order/mysql/PayOrderClearing.php
View file @
5dd1c7f3
...
...
@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase;
class
PayOrderClearing
extends
MysqlBase
{
const
TABLE_NAME
=
'pay_order_clearing'
;
const
CONFIG_INDEX
=
'pay'
;
const
CONFIG_INDEX
=
'pay
_v2
'
;
}
application/models/order/mysql/PayOrderClearingItem.php
View file @
5dd1c7f3
...
...
@@ -7,7 +7,7 @@ use App\Exception\BaseException;
class
PayOrderClearingItem
extends
MysqlBase
{
const
TABLE_NAME
=
'pay_order_clearing_item'
;
const
CONFIG_INDEX
=
'pay'
;
const
CONFIG_INDEX
=
'pay
_v2
'
;
public
static
function
marketSaleCount
(
$accountId
)
{
...
...
application/models/order/mysql/PayOrderItem.php
View file @
5dd1c7f3
...
...
@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase;
class
PayOrderItem
extends
MysqlBase
{
const
TABLE_NAME
=
'pay_order_item'
;
const
CONFIG_INDEX
=
'pay'
;
const
CONFIG_INDEX
=
'pay
_v2
'
;
}
application/models/order/mysql/PayOrderLog.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
use
App\Exception\custom\PayException
;
class
PayOrderLog
extends
MysqlBase
{
const
TABLE_NAME
=
'pay_order_log'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/PlatformAccount.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
PlatformAccount
extends
MysqlBase
{
const
TABLE_NAME
=
'platform_account'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/PlatformAccountLog.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
PlatformAccountLog
extends
MysqlBase
{
const
TABLE_NAME
=
'platform_account_log'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/PlatformConfig.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
PlatformConfig
extends
MysqlBase
{
const
TABLE_NAME
=
'platform_config'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/PlatformFunds.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
PlatformFunds
extends
MysqlBase
{
const
TABLE_NAME
=
'platform_funds'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/PlatformFundsLog.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
PlatformFundsLog
extends
MysqlBase
{
const
TABLE_NAME
=
'platform_funds_log'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/RefundMerchantRecord.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
RefundMerchantRecord
extends
MysqlBase
{
const
TABLE_NAME
=
'refund_merchant_record'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/RefundOrder.php
View file @
5dd1c7f3
...
...
@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase;
class
RefundOrder
extends
MysqlBase
{
const
TABLE_NAME
=
'refund_order'
;
const
CONFIG_INDEX
=
'pay'
;
const
CONFIG_INDEX
=
'pay
_v2
'
;
}
application/models/order/mysql/RefundOrderItem.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
RefundOrderItem
extends
MysqlBase
{
const
TABLE_NAME
=
'refund_order_item'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/RefundPersonalRecord.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
RefundPersonalRecord
extends
MysqlBase
{
const
TABLE_NAME
=
'refund_personal_record'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/RefundPlatformRecord.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
RefundPlatformRecord
extends
MysqlBase
{
const
TABLE_NAME
=
'refund_platform_record'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/WriteOffMerchantRecord.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
WriteOffMerchantRecord
extends
MysqlBase
{
const
TABLE_NAME
=
'writeoff_merchant_record'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/WriteOffOrder.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
WriteOffOrder
extends
MysqlBase
{
const
TABLE_NAME
=
'writeoff_order'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/WriteOffOrderItem.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
WriteOffOrderItem
extends
MysqlBase
{
const
TABLE_NAME
=
'writeoff_order_item'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/WriteOffPersonalRecord.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
WriteOffPersonalRecord
extends
MysqlBase
{
const
TABLE_NAME
=
'writeoff_personal_record'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/models/order/mysql/WriteOffPlatformRecord.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Models\order\mysql
;
use
Api\PhpUtils\Mysql\MysqlBase
;
class
WriteOffPlatformRecord
extends
MysqlBase
{
const
TABLE_NAME
=
'writeoff_platform_record'
;
const
CONFIG_INDEX
=
'pay_v2'
;
}
application/modules/Pay/controllers/Order.php
View file @
5dd1c7f3
...
...
@@ -61,6 +61,16 @@ class OrderController extends Base
$this
->
success
([
'result'
=>
$ret
]);
}
public
function
chargesAction
()
{
$params
=
$this
->
getRequest
()
->
getPost
();
$order_id
=
$params
[
'order_id'
]
??
''
;
$paySrv
=
new
PayService
();
$ret
=
$paySrv
->
pay_charges
(
$order_id
);
$this
->
success
([
'result'
=>
$ret
]);
}
public
function
write_offAction
()
{
$params
=
$this
->
params
;
...
...
application/modules/Pay/controllers/Tcc.php
View file @
5dd1c7f3
<?php
use
Api\PhpServices\Idgen\Idgen
;
use
App\Base\Base
;
use
App\Models\order\mysql\PayOrderItem
;
...
...
@@ -82,4 +83,16 @@ class TccController extends Base
$params
[
'traceId'
]
=
\Helpers\Tracer
::
getTraceId
();
$this
->
success
(
$params
);
}
public
function
idsAction
()
{
$number
=
$this
->
params
[
'number'
]
??
'12'
;
$count
=
$this
->
params
[
'count'
]
??
5
;
$res
=
Idgen
::
get
(
appConfig
(
'idgen.partner'
),
appConfig
(
'idgen.key'
),
[],
[[
"type"
=>
"55c768"
,
'number'
=>
$number
,
"count"
=>
$count
]]);
$id
=
$res
[
'id_datetime'
][
'55c768'
]
??
[];
$this
->
success
([
'ids'
=>
$id
]);
}
}
application/plugins/Hook.php
View file @
5dd1c7f3
...
...
@@ -46,25 +46,42 @@ class Hook extends \Yaf\Plugin_Abstract {
}
public
function
preDispatch
(
\Yaf\Request_Abstract
$request
,
\Yaf\Response_Abstract
$response
)
{
// application/json形式,仅处理$_POST, 不整合$_GET
if
(
$request
->
isPost
()
&&
$request
->
getServer
(
'CONTENT_TYPE'
)
==
'application/json'
)
{
$jsonPost
=
file_get_contents
(
"php://input"
);
if
(
empty
(
$jsonPost
))
{
$_POST
=
[];
return
true
;
}
$_POST
=
json_decode
(
$jsonPost
,
true
);
if
(
!
$request
->
isPost
())
{
return
false
;
}
if
(
!
is_array
(
$_POST
))
{
$_POST
=
[];
FileLog
::
error
(
'bp-gateway'
,
'json decode error raw:'
.
$jsonPost
)
;
}
// raw, $_POST 不能共存。
if
(
!
empty
(
$_POST
))
{
return
false
;
}
$_REQUEST
=
array_merge
(
$_REQUEST
,
$_POST
);
}
// application/json形式,仅处理$_POST, 不整合$_GET
switch
(
strtolower
(
$request
->
getServer
(
'CONTENT_TYPE'
)))
{
case
"application/json"
:
case
"application/json; charset=utf-8"
:
case
"application/json;charset=utf-8"
:
$jsonPost
=
file_get_contents
(
"php://input"
);
if
(
empty
(
$jsonPost
))
{
$_POST
=
[];
return
true
;
}
$_POST
=
json_decode
(
$jsonPost
,
true
);
if
(
!
is_array
(
$_POST
))
{
$_POST
=
[];
FileLog
::
error
(
'bp-gateway'
,
'json decode error raw:'
.
$jsonPost
);
}
$_REQUEST
=
array_merge
(
$_REQUEST
,
$_POST
);
break
;
default
:
;
}
}
public
function
postDispatch
(
\Yaf\Request_Abstract
$request
,
\Yaf\Response_Abstract
$response
)
{
...
...
application/services/Channel.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Services
;
use
App\Services\channel\Pingxx
;
use
App\Services\channel\Platform
;
use
App\Exception\custom\PayException
;
class
Channel
{
/**
* @param $orderId
* @param $userId
* 调用内部服务获取用户订单、子单、分润信息
*/
public
static
function
getChannel
(
$pay_channel
)
{
$payer
=
null
;
switch
(
$pay_channel
)
{
case
'105'
:
case
'106'
:
case
'107'
:
case
'108'
:
case
'109'
:
case
'110'
:
$payer
=
new
Pingxx
();
break
;
case
'1'
:
$payer
=
new
Platform
();
break
;
}
if
(
empty
(
$payer
))
{
throw
new
PayException
([
'cus'
=>
100
]);
}
return
$payer
;
}
}
\ No newline at end of file
application/services/channel/Pingxx.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Services\channel
;
use
Api\PhpUtils\Log\FileLog
;
use
App\Exception\custom\RefundException
;
use
App\Models\order\mysql\PlatformConfig
;
use
App\Services\pingxx\PingxxService
;
use
App\Exception\custom\PayException
;
use
App\Exception\BaseException
;
class
Pingxx
{
/**
* @param $pay_order
* @param $mata_data
* 系统支付
*/
public
function
pay
(
$pay_order
,
$mata_data
,
$extra
=
[])
{
// 已经创建,需要查询返回
if
(
!
empty
(
$pay_order
[
'third_order_id'
]))
{
$ret
=
PingxxService
::
getInstance
()
->
getOrder
(
$pay_order
[
'third_order_id'
]);
}
else
{
$ret
=
PingxxService
::
getInstance
()
->
createOrder
(
$pay_order
,
$mata_data
);
}
if
(
!
empty
(
$ret
[
'error'
]))
{
throw
new
BaseException
([
'msg'
=>
$ret
[
'error'
][
'message'
],
'code'
=>
'2301'
]);
}
if
(
$ret
[
"status"
]
==
'paid'
||
$ret
[
'status'
]
==
'refunded'
)
{
throw
new
PayException
([
'cus'
=>
101
]);
}
elseif
(
$ret
[
"status"
]
==
'canceled'
)
{
throw
new
PayException
([
'cus'
=>
102
]);
}
elseif
(
$ret
[
"status"
]
==
'created'
)
{
;
}
else
{
throw
new
PayException
([
'cus'
=>
103
]);
}
$channel_exist
=
false
;
$channel
=
$this
->
getChannel
(
$pay_order
[
'pay_channel'
]);
if
(
!
empty
(
$ret
[
'charges'
][
'data'
]))
{
//是否存在
foreach
(
$ret
[
'charges'
][
'data'
]
as
$ch
)
{
if
(
$ch
[
'channel'
]
==
$channel
)
{
$channel_exist
=
true
;
}
}
}
//判断是否做过pay操作 charge
if
(
$channel_exist
==
false
)
{
// 创建支付单
$payment
=
[
'charge_order_no'
=>
$pay_order
[
'pay_order_id'
],
'charge_amount'
=>
$pay_order
[
'pay_amount'
],
'channel'
=>
$channel
,
'extra'
=>
$extra
,
];
$pay
=
PingxxService
::
getInstance
()
->
pay
(
$ret
[
'id'
],
$payment
);
if
(
!
empty
(
$pay
[
'error'
]))
{
throw
new
BaseException
([
'msg'
=>
$pay
[
'error'
][
'message'
],
'code'
=>
'2002'
]);
}
return
$pay
;
}
else
{
return
$ret
;
}
}
/**
* @param $pay_order
* @param $mata_data
* 系统退款
*/
public
function
refund
(
$data
,
$mata_data
)
{
/*
https://www.pingxx.com/api/%E8%AE%A2%E5%8D%95%20Refunds%20%E9%80%80%E6%AC%BE%E6%A6%82%E8%BF%B0.html
订单退款 paid = true, status = canceled, amount_paid > 0 则表明可以退款
amount_paid 大于 actual_amount 需要最后一单全退。
具体见ping++ 文档
*/
$pay
=
PingxxService
::
getInstance
()
->
getOrder
(
$data
[
'pay_order'
][
'third_order_id'
]);
if
(
empty
(
$pay
[
'paid'
])
||
$pay
[
'paid'
]
!=
true
)
{
throw
new
RefundException
([
'cus'
=>
7
]);
}
// 存在多次支付的场景需要人工介入处理, 修复订单支付金额,退款金额
if
(
$pay
[
'amount_paid'
]
>
$pay
[
'actual_amount'
])
{
FileLog
::
error
(
'pay-service: 订单可能存在多次成功支付,需人工确认处理。'
,
json_encode
(
$pay
,
JSON_UNESCAPED_UNICODE
));
throw
new
RefundException
([
'cus'
=>
8
]);
}
// 构造退款数据
$refund
=
[
'id'
=>
$pay
[
'id'
],
//pingxx订单ID
'charge'
=>
$pay
[
'charge'
],
//pingxx 支付订单ID
'refund_mode'
=>
'to_source'
,
//默认返回
'charge_amount'
=>
$data
[
'refund_order'
][
'refund_amount'
],
'metadata'
=>
$mata_data
,
];
return
PingxxService
::
getInstance
()
->
sendRefund
(
$refund
);
}
private
function
getChannel
(
$pay_method_id
)
{
$maps
=
[
1
=>
"syt"
,
//系统余额支付
105
=>
"wx"
,
//微信 App 支付
106
=>
"alipay"
,
//支付宝
107
=>
"wx_pub"
,
//微信 JSAPI 支付
108
=>
"wx_pub_qr"
,
//微信 Native 支付
109
=>
"wx_wap"
,
//微信 H5 支付
110
=>
"wx_lite"
,
//微信小程序支付
];
if
(
!
empty
(
$maps
[
$pay_method_id
]))
{
return
$maps
[
$pay_method_id
];
}
else
{
return
$maps
[
105
];
}
}
/**
* @param $pay_order
* @return array
* @throws PayException
* 手续费计算
*/
public
function
clearChannelTips
(
$pay_order
)
{
//PlatformConfig
$info
=
PlatformConfig
::
get
(
'*'
,
[
'account_type'
=>
2
,
'channel'
=>
1
,
'source_name'
=>
$pay_order
[
'source_name'
],
'service_name'
=>
$pay_order
[
'service_name'
]
]);
if
(
empty
(
$info
))
{
throw
new
PayException
([
'cus'
=>
104
]);
}
$float_tip
=
$info
[
'rate'
]
*
$pay_order
[
'payment'
]
/
10000
;
if
(
$float_tip
>=
1
)
{
$total_tip
=
round
(
$float_tip
);
return
[
'account_id'
=>
$info
[
'account_id'
],
'amount'
=>
$total_tip
,
];
}
else
{
return
[];
}
}
public
function
clearPlatformTips
(
$pay_order
)
{
//PlatformConfig
$info
=
PlatformConfig
::
get
(
'*'
,
[
'account_type'
=>
1
,
'channel'
=>
1
,
'source_name'
=>
$pay_order
[
'source_name'
],
'service_name'
=>
$pay_order
[
'service_name'
]
]);
if
(
empty
(
$info
))
{
throw
new
PayException
([
'cus'
=>
104
]);
}
$float_tip
=
$info
[
'rate'
]
*
$pay_order
[
'total_price'
]
/
10000
;
$total_tip
=
round
(
$float_tip
);
if
(
$float_tip
>=
1
)
{
return
[
'account_id'
=>
$info
[
'account_id'
],
'amount'
=>
$total_tip
,
];
}
else
{
return
[];
}
}
public
function
getFundsInfo
(
$pay_order
)
{
$info
=
PlatformConfig
::
get
(
'*'
,
[
'account_type'
=>
3
,
'channel'
=>
1
,
'source_name'
=>
$pay_order
[
'source_name'
],
'service_name'
=>
$pay_order
[
'service_name'
]
]);
if
(
empty
(
$info
))
{
throw
new
PayException
([
'cus'
=>
104
]);
}
return
$info
;
}
}
application/services/channel/Platform.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Services\channel
;
class
Platform
{
/**
* @param $pay_order
* @param $mata_data
* 系统支付
*/
public
function
pay
(
$pay_order
,
$mata_data
)
{
//todo 保存数据
return
[];
}
/**
* @param $pay_order
* @param $mata_data
* 系统退款
*/
public
function
refund
(
$pay_order
,
$mata_data
)
{
}
}
\ No newline at end of file
application/services/marketing/AccountService.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Services\marketing
;
use
App\Models\order\mysql\MarketingAccount
;
use
App\Models\order\mysql\MarketingAccountLog
;
use
App\Models\order\mysql\MarketingAccountMap
;
class
AccountService
{
private
static
$maps
=
[];
/**
* @param $list
* @param $order_id
* @return bool
* 资金冻结
*/
public
static
function
frozen
(
$list
,
$order_id
)
{
$coupon
=
self
::
formatData
(
$list
);
$cnt
=
true
;
foreach
(
$coupon
as
$id
=>
$amount
)
{
$marketing_account_id
=
self
::
map
(
$id
);
$cnt
=
$cnt
&&
MarketingAccount
::
update
([
'frozen_amount[+]'
=>
$amount
,
'receivable_amount[-]'
=>
$amount
,
],
[
'marketing_account_id'
=>
$marketing_account_id
]);
$cnt
=
$cnt
&&
MarketingAccountLog
::
insert
([
'marketing_account_id'
=>
$marketing_account_id
,
'third_id'
=>
$id
,
'fund_type'
=>
1
,
'trade_id'
=>
$order_id
,
'amount'
=>
$amount
,
],
[
'rowCount'
=>
true
]);
}
return
$cnt
;
}
/**
* @param $list
* @param $order_id
* @return bool
* 营销资金扣款
*/
public
static
function
pay
(
$list
,
$order_id
)
{
$coupon
=
self
::
formatData
(
$list
);
$cnt
=
true
;
// 冻结优惠信息
foreach
(
$coupon
as
$id
=>
$amount
)
{
$marketing_account_id
=
self
::
map
(
$id
);
$cnt
=
$cnt
&&
MarketingAccount
::
update
([
'frozen_amount[-]'
=>
$amount
,
],
[
'marketing_account_id'
=>
$marketing_account_id
]);
$cnt
=
$cnt
&&
MarketingAccountLog
::
insert
([
'marketing_account_id'
=>
$marketing_account_id
,
'third_id'
=>
$id
,
'fund_type'
=>
2
,
'trade_id'
=>
$order_id
,
'amount'
=>
$amount
,
],
[
'rowCount'
=>
true
]);
}
return
$cnt
;
}
/**
* @param $list
* @param $refund_order_id
* @return bool
* 退款营销可用增加
*/
public
static
function
refund
(
$list
,
$refund_order_id
)
{
$coupon
=
self
::
formatData
(
$list
);
$cnt
=
true
;
foreach
(
$coupon
as
$id
=>
$amount
)
{
$marketing_account_id
=
self
::
map
(
$id
);
$cnt
=
$cnt
&&
MarketingAccount
::
update
([
'receivable_amount[+]'
=>
$amount
,
],
[
'marketing_account_id'
=>
$marketing_account_id
]);
$cnt
=
$cnt
&&
MarketingAccountLog
::
insert
([
'marketing_account_id'
=>
$marketing_account_id
,
'third_id'
=>
$id
,
'fund_type'
=>
3
,
'trade_id'
=>
$refund_order_id
,
'amount'
=>
$amount
,
],
[
'rowCount'
=>
true
]);
}
return
$cnt
;
}
/**
* @param $list
* @param $order_id
* @return bool
* 未支付取消,营销冻结释放
*/
public
static
function
cancel
(
$list
,
$order_id
)
{
$coupon
=
self
::
formatData
(
$list
);
$cnt
=
true
;
foreach
(
$coupon
as
$id
=>
$amount
)
{
$marketing_account_id
=
self
::
map
(
$id
);
$cnt
=
$cnt
&&
MarketingAccount
::
update
([
'receivable_amount[+]'
=>
$amount
,
],
[
'marketing_account_id'
=>
$marketing_account_id
]);
$cnt
=
$cnt
&&
MarketingAccountLog
::
insert
([
'marketing_account_id'
=>
$marketing_account_id
,
'third_id'
=>
$id
,
'fund_type'
=>
4
,
'trade_id'
=>
$order_id
,
'amount'
=>
$amount
,
],
[
'rowCount'
=>
true
]);
}
return
$cnt
;
}
/**
* @param $data
* @param $marketing_account_id
* @return bool
* 营销充值
*/
public
static
function
recharge
(
$data
,
$marketing_account_id
)
{
$cnt
=
true
;
$cnt
=
$cnt
&&
MarketingAccount
::
update
([
'receivable_amount[+]'
=>
$data
[
'amount'
]
],
[
'marketing_account_id'
=>
$marketing_account_id
]);
$cnt
=
$cnt
&&
MarketingAccountLog
::
insert
([
'marketing_account_id'
=>
$marketing_account_id
,
'third_id'
=>
$data
[
'third_id'
],
'fund_type'
=>
5
,
'trade_id'
=>
$data
[
'trade_id'
],
'amount'
=>
$data
[
'amount'
],
]);
return
$cnt
;
}
public
static
function
transfer
(
$data
,
$marketing_account_id
)
{
$cnt
=
true
;
$cnt
=
$cnt
&&
MarketingAccount
::
update
([
'receivable_amount[-]'
=>
$data
[
'amount'
]
],
[
'marketing_account_id'
=>
$marketing_account_id
]);
$cnt
=
$cnt
&&
MarketingAccountLog
::
insert
([
'marketing_account_id'
=>
$marketing_account_id
,
'third_id'
=>
$data
[
'third_id'
],
'fund_type'
=>
6
,
'trade_id'
=>
$data
[
'trade_id'
],
'amount'
=>
$data
[
'amount'
],
]);
return
$cnt
;
}
public
static
function
map
(
$third_id
,
$source_name
=
10
,
$service_name
=
1
)
{
if
(
!
isset
(
self
::
$maps
[
$third_id
]))
{
$info
=
MarketingAccountMap
::
get
(
'*'
,
[
'third_id'
=>
$third_id
,
'source_name'
=>
$source_name
,
'service_name'
=>
$service_name
]);
if
(
$info
)
{
self
::
$maps
[
$third_id
]
=
$info
[
'marketing_account_id'
];
}
else
{
self
::
$maps
[
$third_id
]
=
''
;
}
}
return
self
::
$maps
[
$third_id
];
}
private
static
function
formatData
(
$list
)
{
$coupon
=
[];
foreach
(
$list
as
$r
)
{
if
(
!
isset
(
$coupon
[
$r
[
'capital_pool_id'
]]))
{
$coupon
[
$r
[
'capital_pool_id'
]]
=
0
;
}
$coupon
[
$r
[
'capital_pool_id'
]]
+=
$r
[
'share_coupon_amount'
];
}
return
$coupon
;
}
}
\ No newline at end of file
application/services/pay/FundsService.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Services\pay
;
use
App\Exception\custom\FundsException
;
use
App\Models\order\mysql\PlatformFunds
;
use
App\Models\order\mysql\PlatformFundsLog
;
class
FundsService
{
/**
* @param $data
* @param int $channel
* @param int $source_name
* @param int $service_name
* @throws FundsException
* 渠道账户入账记录
*/
public
static
function
credit
(
$data
,
$channel
=
1
,
$source_name
=
10
,
$service_name
=
1
)
{
$info
=
PlatformFunds
::
getMaster
(
'*'
,
[
'channel'
=>
$channel
,
'source_name'
=>
$source_name
,
'service_name'
=>
$service_name
]);
if
(
empty
(
$info
))
{
throw
new
FundsException
([
'cus'
=>
1
]);
}
$cnt
=
PlatformFunds
::
update
([
'total_amount[+]'
=>
$data
[
'amount'
],
'total_tip[+]'
=>
$data
[
'tip'
],
],
[
'platform_funds_id'
=>
$info
[
'platform_funds_id'
]]);
$l_cnt
=
PlatformFundsLog
::
insert
([
'platform_funds_id'
=>
$info
[
'platform_funds_id'
],
'trade_id'
=>
$data
[
'order_id'
],
'third_order_id'
=>
$data
[
'third_id'
],
'fund_type'
=>
1
,
'amount'
=>
$data
[
'amount'
],
'tip'
=>
$data
[
'tip'
],
],
[
'rowCount'
=>
true
]);
return
$l_cnt
&&
$cnt
;
}
/**
* @param $data
* @param int $channel
* @param int $source_name
* @param int $service_name
* @throws FundsException
* 渠道账户出账
*/
public
static
function
payOut
(
$data
,
$channel
=
1
,
$source_name
=
10
,
$service_name
=
1
)
{
$info
=
PlatformFunds
::
getMaster
(
'*'
,
[
'channel'
=>
$channel
,
'source_name'
=>
$source_name
,
'service_name'
=>
$service_name
]);
if
(
empty
(
$info
))
{
throw
new
FundsException
([
'cus'
=>
1
]);
}
$cnt
=
true
;
$cnt
=
$cnt
&&
PlatformFunds
::
update
([
'total_amount[-]'
=>
$data
[
'amount'
],
'total_tip[-]'
=>
$data
[
'tip'
],
],
[
'platform_funds_id'
=>
$info
[
'platform_funds_id'
]]);
$cnt
=
$cnt
&&
PlatformFundsLog
::
insert
([
'platform_funds_id'
=>
$info
[
'platform_funds_id'
],
'trade_id'
=>
$data
[
'order_id'
],
'third_order_id'
=>
$data
[
'third_id'
],
'fund_type'
=>
2
,
'amount'
=>
$data
[
'amount'
],
'tip'
=>
$data
[
'tip'
],
],
[
'rowCount'
=>
true
]);
return
$cnt
;
}
}
\ No newline at end of file
application/services/pay/PayService.php
View file @
5dd1c7f3
...
...
@@ -5,14 +5,22 @@ namespace App\Services\pay;
use
Api\PhpServices\Idgen\Idgen
;
use
Api\PhpUtils\Log\FileLog
;
use
App\Models\Dictionary
;
use
App\Models\order\mysql\PayOrder
;
use
App\Models\order\mysql\PayOrderItem
;
use
App\Models\order\mysql\PayCouponItem
;
use
App\Models\order\mysql\PayOrderClearing
;
use
App\Models\order\mysql\PayOrderClearingItem
;
use
App\Models\order\mysql\WriteOffMerchantRecord
;
use
App\Models\order\mysql\WriteOffOrder
;
use
App\Models\order\mysql\WriteOffOrderItem
;
use
App\Models\order\mysql\WriteOffPersonalRecord
;
use
App\Models\order\mysql\WriteOffPlatformRecord
;
use
App\Services\Channel
;
use
App\Services\marketing\AccountService
;
use
App\Services\order\OrderService
;
use
App\Services\pingxx\PingxxService
;
use
App\Services\wallet\MerchantAccountService
;
use
App\Services\wallet\WalletService
;
use
Helpers\Strategy
;
use
Helpers\Sdk
;
...
...
@@ -32,171 +40,224 @@ class PayService
private
$pay_order
=
[];
private
$clear_list
=
[];
private
$clear_items_list
=
[];
private
$gen_ids
=
[];
public
function
do_pay
(
$order_id
,
$user_id
,
$pay_method_id
=
105
,
$extra
=
[])
{
if
(
empty
(
$order_id
))
{
/**
* @param $params
* @return mixed
* @throws PayException
* @throws \App\Exception\custom\CodeSpecialException
* 支付订单校验
*/
private
function
pay_validate
(
$params
)
{
if
(
$params
[
'order_id'
])
{
throw
new
PayException
([
'cus'
=>
1
]);
}
// 获取订单信息
$data
=
OrderService
::
getFullOrderData
(
$order_id
);
if
(
empty
(
$data
[
'result'
][
'order_info'
]))
{
if
(
$params
[
'user_id'
])
{
throw
new
PayException
([
'cus'
=>
2
]);
}
$order_info
=
$data
[
'result'
][
'order_info'
];
if
(
$order_info
[
'user_id'
]
!=
$user_id
)
{
// 获取订单 + 子单信息
$data
=
OrderService
::
getFullOrderData
(
$params
[
'order_id'
]);
if
(
empty
(
$data
[
'result'
][
'order_info'
])
||
empty
(
$data
[
'result'
][
'order_item_list'
]))
{
throw
new
PayException
([
'cus'
=>
3
]);
}
if
(
!
empty
(
$order_info
[
'pay_expiration_time'
]))
{
$pay_expiration_time
=
strtotime
(
$order_info
[
'pay_expiration_time'
]);
if
(
$pay_expiration_time
<
time
())
{
throw
new
PayException
([
'cus'
=>
16
]);
}
$order_info
=
$data
[
'result'
][
'order_info'
];
if
(
$order_info
[
'user_id'
]
!=
$params
[
'user_id'
])
{
throw
new
PayException
([
'cus'
=>
4
]);
}
if
(
empty
(
$data
[
'result'
][
'order_item_list
'
]))
{
throw
new
PayException
([
'cus'
=>
14
]);
if
(
empty
(
$order_info
[
'pay_expiration_time
'
]))
{
throw
new
PayException
([
'cus'
=>
5
]);
}
$metadata
=
[
'app_id'
=>
'merchant-c'
,
'pingxx_id'
=>
PingxxService
::
getInstance
()
->
getAppId
(),
'environ'
=>
Application
::
app
()
->
environ
(),
'order_id'
=>
$order_id
,
'goods'
=>
[],
'marketing'
=>
[],
'order_item_id'
=>
[],
];
if
(
strtotime
(
$order_info
[
'pay_expiration_time'
])
<
time
())
{
throw
new
PayException
([
'cus'
=>
6
]);
}
$min_expire_time
=
$now
=
time
()
;
foreach
(
$data
[
'result'
][
'order_item_list'
]
as
$item
)
{
return
$data
[
'result'
]
;
}
if
(
strtotime
(
$item
[
'expiration_time'
])
<
$min_expire_time
)
{
$min_expire_time
=
strtotime
(
$item
[
'expiration_time'
]);
}
/**
* @param $data
* @param $pay_method_id
* @return array
* @throws PayException
* 创建/获取支付订单信息
*/
private
function
make_pay_order
(
$data
,
$pay_method_id
)
{
if
(
empty
(
$metadata
[
'goods'
][
$item
[
'goods_sku_id'
]]))
{
$metadata
[
'goods'
][
$item
[
'goods_sku_id'
]]
=
0
;
}
$order
=
$data
[
"order_info"
];
$pay_expiration_time
=
strtotime
(
$order
[
'pay_expiration_time'
])
;
$now
=
time
();
$metadata
[
'goods'
][
$item
[
'goods_sku_id'
]]
+=
$item
[
'goods_num'
];
if
(
!
empty
(
$item
[
'marketing_id'
]))
{
$metadata
[
'marketing'
][
$item
[
'goods_sku_id'
]]
=
$item
[
'marketing_id'
];
}
array_push
(
$metadata
[
'order_item_id'
],
$item
[
'order_item_id'
]);
if
(
$pay_expiration_time
-
$now
<
70
)
{
$pay_expiration_time
=
$now
+
70
;
}
if
(
$now
>
$min_expire_time
)
{
throw
new
PayException
([
'cus'
=>
15
]);
$ids
=
$this
->
get_idgen_id
(
$order
[
"user_id"
],
1
+
count
(
$data
[
'order_item_list'
]));
$pay_order_id
=
array_shift
(
$ids
);
PayOrder
::
beginTransaction
();
$pay
=
self
::
getMaster
(
'*'
,
[
'order_id'
=>
$order
[
'order_id'
]]);
if
(
!
empty
(
$pay
))
{
//更新支付渠道
if
(
$pay
[
'pay_order_status'
]
==
0
)
{
PayOrder
::
update
([
'pay_channel'
=>
$pay_method_id
],
[
'pay_order_id'
=>
$pay
[
'pay_order_id'
]]
);
}
PayOrder
::
commit
();
return
$pay
;
}
// 判断是否存在有效订单
$max_expire_time
=
config
(
'pay'
,
'pay.expire_time'
)
??
1800
;
$expire_time
=
time
()
+
$max_expire_time
;
$pay_order_id
=
$this
->
gen_pay_order_id
(
$user_id
);
$new_pay_order
=
[
// 新增支付订单
$new_pay
=
[
'pay_order_id'
=>
$pay_order_id
,
'user_id'
=>
$order_info
[
'user_id'
],
'life_account_id'
=>
$order_info
[
'life_account_id'
],
'shop_id'
=>
$order_info
[
'shop_id'
],
'order_id'
=>
$order_info
[
'order_id'
],
'pay_order_status'
=>
Dictionary
::
O_PAY_STATUS_UNPAY
,
'pay_amount'
=>
$order_info
[
'payment'
],
'user_id'
=>
$order
[
'user_id'
],
'life_account_id'
=>
$order
[
'life_account_id'
],
'shop_id'
=>
$order
[
'shop_id'
],
'order_id'
=>
$order
[
'order_id'
],
'pay_order_status'
=>
0
,
'total_price'
=>
$order
[
'total_price'
],
'discount_fee'
=>
$order
[
'discount_fee'
],
'pay_amount'
=>
$order
[
'payment'
],
'pay_channel'
=>
$pay_method_id
,
'third_order_id'
=>
''
,
'expire_time'
=>
date
(
'Y-m-d H:i:s'
,
$
expire
_time
),
'expire_time'
=>
date
(
'Y-m-d H:i:s'
,
$
pay_expiration
_time
),
'source_name'
=>
10
,
'service_name'
=>
1
,
'business_from'
=>
$order
_info
[
'business_from'
],
'business_from'
=>
$order
[
'business_from'
],
'extra'
=>
json_encode
([]),
];
//获取或创建支付订单
$pay_order
=
PayOrder
::
get_valid_order
(
$order_id
,
$new_pay_order
);
if
(
empty
(
$pay_order
))
{
throw
new
PayException
([
'cus'
=>
4
]);
$cnt
=
true
;
$cnt
=
$cnt
&&
PayOrder
::
insert
(
$new_pay
,
[
'rowCount'
=>
true
]);
$order_items
=
$coupon_items
=
[];
foreach
(
$data
[
'order_item_list'
]
as
$r
)
{
$order_items
[]
=
[
'pay_order_item_id'
=>
array_shift
(
$ids
),
'pay_order_id'
=>
$pay_order_id
,
'order_id'
=>
$r
[
'order_id'
],
'order_item_id'
=>
$r
[
'order_item_id'
],
'user_id'
=>
$r
[
'user_id'
],
'payment'
=>
$r
[
'payment'
],
'share_coupon'
=>
$r
[
'share_coupon'
],
];
}
if
(
$pay_order
[
'pay_order_status'
]
==
Dictionary
::
O_PAY_STATUS_PAYED
)
{
throw
new
PayException
([
'cus'
=>
5
]);
//新增订单子单
$cnt
=
$cnt
&&
PayOrderItem
::
insert
(
$order_items
,
[
'rowCount'
=>
true
]);
if
(
!
empty
(
$data
[
'order_share_coupon'
]))
{
foreach
(
$data
[
'order_share_coupon'
]
as
$r
)
{
$coupon_items
[]
=
[
'pay_order_id'
=>
$pay_order_id
,
'order_id'
=>
$r
[
'order_id'
],
'user_id'
=>
$r
[
'user_id'
],
'order_item_id'
=>
$r
[
'order_item_id'
],
'coupon_id'
=>
$r
[
'coupon_id'
],
'capital_pool_id'
=>
$r
[
'capital_pool_id'
],
'coupon_amount'
=>
$r
[
'coupon_amount'
],
'share_coupon_amount'
=>
$r
[
'share_coupon_amount'
],
];
}
//新增订单优惠信息
$cnt
=
$cnt
&&
PayCouponItem
::
insert
(
$coupon_items
,
[
'rowCount'
=>
true
]);
//营销资金冻结
$cnt
=
$cnt
&&
AccountService
::
frozen
(
$data
[
'order_share_coupon'
],
$order
[
'order_id'
]);
}
// 已经创建,需要查询返回
if
(
!
empty
(
$pay_order
[
'third_order_id'
]))
{
$ret
=
PingxxService
::
getInstance
()
->
getOrder
(
$pay_order
[
'third_order_id'
]
);
if
(
$cnt
==
true
)
{
$pay
=
$new_pay
;
PayOrder
::
commit
(
);
}
else
{
$ret
=
PingxxService
::
getInstance
()
->
createOrder
(
$pay_order
,
$metadata
);
PayOrder
::
rollback
();
throw
new
PayException
([
'cus'
=>
7
]);
}
if
(
!
empty
(
$ret
[
'error'
]))
{
throw
new
BaseException
([
'msg'
=>
$ret
[
'error'
][
'message'
],
'code'
=>
'2301'
]);
return
$pay
;
}
/**
* @param $params
* @param array $extra
* @return array|mixed
* @throws PayException
* 创建支付订单
*/
public
function
do_pay
(
$params
,
$extra
=
[])
{
// 支付数据检查
$data
=
$this
->
pay_validate
(
$params
);
// 创建支付订单、营销冻结
$pay_order
=
$this
->
make_pay_order
(
$data
,
$params
[
'pay_method_id'
]);
if
(
$pay_order
[
'pay_order_status'
]
==
2
)
{
throw
new
PayException
([
'cus'
=>
8
]);
}
if
(
$ret
[
"status"
]
==
'paid'
||
$ret
[
'status'
]
==
'refunded'
)
{
$edit
=
[
'pay_order_status'
=>
Dictionary
::
O_PAY_STATUS_PAYED
,
'third_order_id'
=>
$ret
[
'id'
],
];
//todo 需要做补偿
//PayOrder::update($edit, ['pay_order_id' => $pay_order['pay_order_id']]);
throw
new
PayException
([
'cus'
=>
5
]);
// 支付金额0,系统支付
if
(
$pay_order
[
'pay_amount'
]
==
0
)
{
$params
[
'pay_method_id'
]
=
1
;
}
}
elseif
(
$ret
[
"status"
]
==
'canceled'
)
{
$edit
=
[
'expire_time'
=>
date
(
'Y-m-d H:i:s'
),
];
//todo 需要做状态同步,不仅仅是更新状态
PayOrder
::
update
(
$edit
,
[
'pay_order_id'
=>
$pay_order
[
'pay_order_id'
]]);
throw
new
PayException
([
'cus'
=>
6
]);
// 构造支付回调的 mataData
$meta_data
=
[
'app_id'
=>
'merchant-c'
,
'environ'
=>
Application
::
app
()
->
environ
(),
'order_id'
=>
$params
[
"order_id"
],
'goods'
=>
[],
'marketing'
=>
[],
'order_item_id'
=>
[],
];
}
elseif
(
$ret
[
"status"
]
==
'created'
)
{
$edit
=
[
'pay_order_status'
=>
Dictionary
::
O_PAY_STATUS_WAIT
,
'third_order_id'
=>
$ret
[
'id'
],
];
PayOrder
::
update
(
$edit
,
[
'pay_order_id'
=>
$pay_order
[
'pay_order_id'
]]);
foreach
(
$data
[
'order_item_list'
]
as
$item
)
{
if
(
empty
(
$meta_data
[
'goods'
][
$item
[
'goods_sku_id'
]]))
{
$meta_data
[
'goods'
][
$item
[
'goods_sku_id'
]]
=
0
;
}
$meta_data
[
'goods'
][
$item
[
'goods_sku_id'
]]
+=
$item
[
'goods_num'
];
}
else
{
throw
new
PayException
([
'cus'
=>
0
])
;
}
if
(
!
empty
(
$item
[
'marketing_id'
]))
{
$meta_data
[
'marketing'
][
$item
[
'goods_sku_id'
]]
=
$item
[
'marketing_id'
]
;
}
//存在一个继续支付单订单
if
(
$pay_order_id
!=
$pay_order
[
'pay_order_id'
])
{
$ret
[
'exist'
]
=
true
;
array_push
(
$meta_data
[
'order_item_id'
],
$item
[
'order_item_id'
]);
}
//判断是否做过pay操作 charge
if
(
empty
(
$ret
[
'charge'
]))
{
// 创建支付单
$payment
=
[
'charge_order_no'
=>
$pay_order
[
'pay_order_id'
],
'charge_amount'
=>
$pay_order
[
'pay_amount'
],
'channel'
=>
$this
->
getChannel
(
$pay_method_id
),
'extra'
=>
$extra
,
];
try
{
$payer
=
Channel
::
getChannel
(
$params
[
'pay_method_id'
]);
$ret
=
$payer
->
pay
(
$pay_order
,
$meta_data
,
$extra
);
$pay
=
PingxxService
::
getInstance
()
->
pay
(
$ret
[
'id'
],
$payment
);
if
(
!
empty
(
$pay
[
'error'
]))
{
throw
new
BaseException
([
'msg'
=>
$pay
[
'error'
][
'message'
],
'code'
=>
'2002'
]);
}
PayOrder
::
update
([
'pay_order_status'
=>
1
],
[
'pay_order_id'
=>
$pay_order
[
'pay_order_id'
],
'pay_order_status'
=>
0
]);
return
$pay
;
}
catch
(
BaseException
$e
)
{
throw
$e
;
}
else
{
return
$ret
;
}
catch
(
\Exception
$e
)
{
throw
new
BaseException
([
'msg'
=>
$e
->
getMessage
(),
'code'
=>
'2301'
])
;
}
return
$ret
;
}
/**
* @param $data
* @return array|string[]
* @throws PayException
* 回调订单支付
*/
public
function
call_back
(
$data
)
{
if
(
!
in_array
(
$data
[
'type'
],
[
'
order.succeeded'
,
'
charge.succeeded'
]))
{
if
(
!
in_array
(
$data
[
'type'
],
[
'charge.succeeded'
]))
{
return
[
'error'
=>
'支付回调类型不正确'
];
}
...
...
@@ -205,69 +266,53 @@ class PayService
}
$object
=
$data
[
'data'
][
'object'
];
if
(
empty
(
$object
[
'metadata'
][
'app_id'
])
||
$object
[
'metadata'
][
'app_id'
]
!=
"merchant-c"
)
{
if
(
empty
(
$object
[
'metadata'
][
'app_id'
])
||
substr
(
$object
[
'metadata'
][
'app_id'
],
0
,
9
)
!=
"merchant-"
)
{
//非支付中心发出的订单,需要忽略
return
[
'error'
=>
'非merchant渠道订单,不做处理。'
];
}
if
(
$data
[
'type'
]
==
'charge.succeeded'
)
{
$pay_order_id
=
$object
[
'order_no'
];
$paid
=
$object
[
'paid'
];
$amount
=
$object
[
'amount'
];
}
else
{
$pay_order_id
=
$object
[
'merchant_order_no'
];
$paid
=
$object
[
'paid'
];
$amount
=
$object
[
'actual_amount'
];
}
if
(
$paid
!=
true
)
{
if
(
$object
[
'paid'
]
!=
true
)
{
return
[
'error'
=>
'支付状态不正确,不做处理。'
];
}
$pay_order_id
=
$object
[
'order_no'
];
$pay_order
=
PayOrder
::
get
(
'*'
,
[
'pay_order_id'
=>
$pay_order_id
]);
if
(
empty
(
$pay_order
))
{
throw
new
PayException
([
'cus'
=>
7
]);
}
if
(
$pay_order
[
'pay_amount'
]
!=
$
amount
)
{
if
(
$pay_order
[
'pay_amount'
]
!=
$
object
[
'amount'
]
)
{
throw
new
PayException
([
'cus'
=>
8
]);
}
// 修改状态,锁定业务
$
edit
=
[
$
cnt
=
PayOrder
::
update
(
[
'pay_order_status'
=>
2
,
//已经支付
'pingxx_callback_success_time'
=>
date
(
'Y-m-d H:i:s'
),
];
$where
=
[
],
[
'pay_order_id'
=>
$pay_order_id
,
'pay_order_status'
=>
1
,
//待支付确认
];
$cnt
=
PayOrder
::
update
(
$edit
,
$where
);
]);
//保持幂等返回成功
if
(
$cnt
==
0
)
{
return
[
'pay_order_id'
=>
$pay_order_id
];
}
//获取订单 + 子单 + 分销信息
$ret
=
OrderService
::
getFullOrderData
(
$pay_order
[
'order_id'
],
$pay_order
[
'user_id'
]);
if
(
empty
(
$ret
[
'result'
][
'order_info'
]))
{
throw
new
PayException
([
'cus'
=>
1
]);
}
$this
->
pay_order
=
$pay_order
;
$payer
=
Channel
::
getChannel
(
$pay_order
[
'pay_channel'
]);
// 生成支付清分单
$this
->
make_order_clearing
(
$ret
[
'result'
]);
//收集第一商品名称
if
(
$this
->
order_items
)
{
$title
=
$this
->
order_items
[
0
][
'goods_name'
]
??
'商品名称'
;
}
else
{
$title
=
''
;
}
$this
->
make_order_clearing
(
$payer
);
try
{
//收集第一商品名称
if
(
$this
->
order_items
)
{
$title
=
$this
->
order_items
[
0
][
'goods_name'
]
??
'商品名称'
;
}
else
{
$title
=
''
;
}
//通知消息
$app_id
=
'wx65e9ba99c333444f'
;
$template_id
=
'EzOH2ZpfW-eUdFf9gzjZTAv-Z9PFmKHNsQ0VOGvvN7c'
;
...
...
@@ -280,8 +325,7 @@ class PayService
date
(
'Y-m-d'
),
];
if
(
isset
(
$ret
[
'result'
][
'order_info'
][
'business_from'
])
&&
$ret
[
'result'
][
'order_info'
][
'business_from'
]
!=
2
)
{
//接龙业务不发送消息
if
(
$pay_order
[
'business_from'
]
!=
2
)
{
//接龙业务不发送消息
Msg
::
send
(
$pay_order
[
'user_id'
],
$app_id
,
$template_id
,
$page_url
,
$type
,
$query
);
}
...
...
@@ -293,167 +337,402 @@ class PayService
}
/**
* @param $order_item_id
* @param $order_id
* @return array
* @throws BaseException
* @throws PayException
* 返回订单状态及订单渠道列表
*/
public
function
pay_charges
(
$order_id
)
{
$pay_order
=
PayOrder
::
get
(
'*'
,
[
'order_id'
=>
$order_id
]);
if
(
empty
(
$pay_order
))
{
throw
new
PayException
([
'cus'
=>
18
]);
}
$data
=
[
'status'
=>
'created'
,
'max_expire_time'
=>
$pay_order
[
'expire_time'
],
'list'
=>
[]
];
$max_expire_time
=
strtotime
(
$pay_order
[
'expire_time'
]);
if
(
$max_expire_time
<
time
())
{
$data
[
"status"
]
=
'canceled'
;
}
if
(
empty
(
$pay_order
[
'third_order_id'
]))
{
return
$data
;
}
//paid、refunded、canceled、created
$ret
=
PingxxService
::
getInstance
()
->
getOrder
(
$pay_order
[
'third_order_id'
]);
if
(
!
empty
(
$ret
[
'error'
]))
{
throw
new
BaseException
([
'msg'
=>
$ret
[
'error'
][
'message'
],
'code'
=>
'2301'
]);
}
$data
[
"status"
]
=
$ret
[
"status"
];
if
(
!
empty
(
$ret
[
'charges'
][
'data'
]))
{
//是否存在
foreach
(
$ret
[
'charges'
][
'data'
]
as
$ch
)
{
$data
[
"list"
][]
=
[
'paid'
=>
$ch
[
'paid'
],
'refunded'
=>
$ch
[
'refunded'
],
'channel'
=>
$ch
[
'channel'
],
'time_expire'
=>
$ch
[
'time_expire'
],
];
if
(
$max_expire_time
<
$ch
[
'time_expire'
])
{
$max_expire_time
=
$ch
[
'time_expire'
];
}
}
}
$data
[
'max_expire_time'
]
=
date
(
'Y-m-d H:i:s'
,
$max_expire_time
);
return
$data
;
}
/**
* @param $order_id
* @param $life_account_id
* @param array $order_item_ids
* @return array
* @throws BaseException
* @throws \App\Exception\custom\CodeSpecialException
* 子订单核销
*/
public
function
write_off
(
$order_i
tem_id
,
$life_account_id
)
public
function
write_off
(
$order_i
d
,
$life_account_id
,
$order_item_ids
=
[]
)
{
$cnt
=
0
;
//锁定状态
try
{
PayOrderItem
::
beginTransaction
();
$pay_order
=
PayOrder
::
getMaster
(
'*'
,
[
'order_id'
=>
$order_id
]);
if
(
empty
(
$pay_order
)
||
$pay_order
[
'life_account_id'
]
!=
$life_account_id
)
{
throw
new
PayException
([
'cus'
=>
14
]);
}
$
item
=
PayOrderItem
::
getMaster
(
'*'
,
[
'order_item_id'
=>
$order_item_id
]);
if
(
empty
(
$
item
))
{
throw
new
PayException
([
'cus'
=>
1
0
]);
$
list
=
PayOrderItem
::
getMaster
(
'*'
,
[
'pay_order_id'
=>
$pay_order
[
'pay_order_id'
]
]);
if
(
empty
(
$
list
))
{
throw
new
PayException
([
'cus'
=>
1
5
]);
}
if
(
$item
[
'refund_order_status'
]
!=
0
)
{
throw
new
PayException
([
'cus'
=>
9
]);
$item_ids
=
[];
foreach
(
$list
as
$item
)
{
if
(
in_array
(
$item
[
'refund_order_status'
],
[
1
,
2
]))
{
continue
;
//退款中、已退款不允许再次申请
}
if
(
$item
[
'can_notify_account'
]
==
1
)
{
continue
;
//已结算不允许再次核销
}
if
(
!
empty
(
$order_item_ids
)
&&
!
in_array
(
$item
[
'order_item_id'
],
$order_item_ids
))
{
continue
;
//部分核销,且不再核销子单列表,不处理
}
$item_ids
[]
=
$item
[
'order_item_id'
];
}
$pay_order
=
PayOrder
::
getMaster
(
'*'
,
[
'pay_order_id'
=>
$item
[
'pay_order_id'
]]);
if
(
empty
(
$pay_order
)
||
$pay_order
[
'life_account_id'
]
!=
$life_account_id
)
{
throw
new
PayException
([
'cus'
=>
11
]);
if
(
empty
(
$item_ids
))
{
throw
new
PayException
([
'cus'
=>
16
]);
}
$ids
=
$this
->
gen_pay_order_id
(
$life_account_id
,
count
(
$list
)
+
5
);
$write_off_order_id
=
array_shift
(
$ids
);
//统计平台、团长、商户金额
$cnt
=
true
;
$cnt
=
$cnt
&&
WriteOffOrder
::
insert
([
'write_off_order_id'
=>
$write_off_order_id
,
'user_id'
=>
$pay_order
[
'user_id'
],
'order_id'
=>
$pay_order
[
'order_id'
],
'write_off_status'
=>
0
,
],
[
'rowCount'
=>
true
]);
$items
=
[];
foreach
(
$item_ids
as
$_id
)
{
$items
[]
=
[
'writeoff_order_item_id'
=>
array_shift
(
$ids
),
'writeoff_order_id'
=>
$write_off_order_id
,
'order_item_id'
=>
$_id
,
];
}
$cnt
=
PayOrderItem
::
update
([
$cnt
=
$cnt
&&
WriteOffOrderItem
::
insert
(
$items
,
[
'rowCount'
=>
true
]);
$cnt
=
$cnt
&&
$this
->
write_off_clear_record
(
$write_off_order_id
,
$pay_order
,
$item_ids
);
$cnt
=
$cnt
&&
PayOrderItem
::
update
([
'notify_account_status'
=>
0
,
'can_notify_account'
=>
1
,
'can_notify_account_time'
=>
date
(
'Y-m-d H:i:s'
),
],
[
'order_item_id'
=>
$order_item_id
,
'can_notify_account'
=>
0
,
'refund_order_status'
=>
0
]);
],
[
'order_item_id'
=>
$item_ids
,
'can_notify_account'
=>
0
,
'refund_order_status'
=>
0
]);
if
(
$cnt
==
false
)
{
throw
new
PayException
([
'cus'
=>
17
]);
}
PayOrderItem
::
commit
();
}
catch
(
PayException
$e
)
{
PayOrderItem
::
rollback
();
throw
$e
;
}
catch
(
\Exception
$e
)
{
PayOrderItem
::
rollback
();
throw
new
BaseException
([
'msg'
=>
$e
->
getMessage
(),
'code'
=>
$e
->
getCode
()]);
}
if
(
$cnt
==
0
)
{
//幂等直接返回
return
[
'order_item_id'
=>
$order_item_id
];
}
$this
->
sync_account_wallet
(
$order_item_id
);
$this
->
sync_account_wallet
(
$write_off_order_id
);
return
[
'order_item_id'
=>
$order_item_id
];
return
[
'write_off_order_id'
=>
$write_off_order_id
,
'order_id'
=>
$order_id
,
'order_item_id'
=>
$item_ids
];
}
/**
* @param $order_item_id
* @throws \App\Exception\custom\CodeSpecialException
* 同步钱包处理
* @param $write_off_order_id
* @return bool
*/
public
function
sync_account_wallet
(
$order_item_id
)
{
public
function
sync_account_wallet
(
$writeOff_order_id
)
{
$p_cnt
=
$u_cnt
=
$m_cnt
=
true
;
$cnt
=
PayOrderItem
::
update
([
'notify_account_status'
=>
1
,
],
[
'order_item_id'
=>
$order_item_id
,
'can_notify_account'
=>
1
,
'notify_account_status'
=>
0
]);
//修改状态为执行中
$cnt
=
WriteOffOrder
::
update
([
'notify_account_status'
=>
1
,
],
[
'write_off_order_id'
=>
$writeOff_order_id
,
'write_off_status'
=>
2
,
'notify_account_status'
=>
0
]);
if
(
$cnt
==
0
)
{
//乐观锁,不满足条件不处理
if
(
!
$cnt
)
{
//乐观锁,不满足条件不处理
return
true
;
}
//注意查找需要保证pdo是一个,避免数据操作超时
$clearing_items
=
PayOrderClearingItem
::
selectMaster
(
'*'
,
[
'order_item_id'
=>
$order_item_id
]
);
//平台收入入账
$p
=
WriteOffPlatformRecord
::
selectMaster
(
'*'
,
[
'writeoff_order_id'
=>
$writeOff_order_id
,
'notify_account_status[<]'
=>
2
]);
if
(
$p
)
{
$p_cnt
=
$p_cnt
&&
PlatformAccountService
::
credit
([
'trade_id'
=>
$writeOff_order_id
,
'amount'
=>
$p
[
'payment'
]]);
$p_cnt
=
$p_cnt
&&
WriteOffPlatformRecord
::
update
([
'notify_account_status'
=>
2
,
'notify_account_success_time'
=>
date
(
'Y-m-d H:i:s'
),
],
[
'writeoff_order_id'
=>
$writeOff_order_id
]);
}
$wallet_list
=
[];
foreach
(
$clearing_items
as
$row
)
{
if
(
$row
[
'pay_amount'
]
<=
0
)
{
continue
;
//团长分销入账
$us
=
WriteOffPersonalRecord
::
getMaster
(
'*'
,
[
'writeoff_order_id'
=>
$writeOff_order_id
,
'notify_account_status[<]'
=>
2
]);
if
(
$us
)
{
$w_list
=
[];
foreach
(
$us
as
$u
)
{
$w_list
[]
=
[
'user_id'
=>
$u
[
'account_id'
],
'service_name'
=>
10
,
'source_name'
=>
1
,
'amount'
=>
$u
[
'payment'
],
'third_order_id'
=>
$u
[
'writeoff_personal_id'
],
'third_order_id_type'
=>
406
,
'third_order_desc'
=>
''
,
];
}
//处理商家结算价格的兼容
if
(
$row
[
'clear_payment'
]
>
0
&&
$row
[
'pay_sub_type'
]
==
102
)
{
$
pay_amount
=
$row
[
'clear_payment'
];
}
else
{
$pay_amount
=
$row
[
'pay_amount'
];
}
try
{
WalletService
::
send
([
'list'
=>
$w_list
]);
$
u_cnt
=
$u_cnt
&&
WriteOffPlatformRecord
::
update
([
'notify_account_status'
=>
2
,
'notify_account_success_time'
=>
date
(
'Y-m-d H:i:s'
),
],
[
'writeoff_order_id'
=>
$writeOff_order_id
]);
$wallet_list
[]
=
[
'user_id'
=>
$row
[
'account_id'
],
'service_name'
=>
10
,
'source_name'
=>
1
,
'amount'
=>
$pay_amount
,
'third_order_id'
=>
$row
[
'pay_order_clearing_item_id'
],
'third_order_id_type'
=>
$row
[
'pay_sub_type'
],
'third_order_desc'
=>
$row
[
'remark'
],
];
}
catch
(
\Exception
$e
)
{
$u_cnt
=
false
;
}
}
try
{
if
(
$wallet_list
)
{
//同步成功,返回结果
WalletService
::
send
([
'list'
=>
$wallet_list
]);
//商家收益 407
$m
=
WriteOffMerchantRecord
::
selectMaster
(
'*'
,
[
'writeoff_order_id'
=>
$writeOff_order_id
,
'notify_account_status[<]'
=>
2
]);
if
(
$m
)
{
try
{
//MerchantAccountService
MerchantAccountService
::
sync
([
'life_account_id'
=>
$m
[
'life_account_id'
],
'shop_id'
=>
$m
[
'shop_id'
],
'source_name'
=>
$m
[
'source_name'
],
'service_name'
=>
$m
[
'service_name'
],
'write_off_order_id'
=>
$m
[
'write_off_order_id'
],
'third_order_title'
=>
$m
[
'title'
],
'third_order_desc'
=>
$m
[
'desc'
],
'third_order_type'
=>
$m
[
'business_from'
],
'amount'
=>
$m
[
'payment'
],
]);
$m_cnt
=
$m_cnt
&&
WriteOffPlatformRecord
::
update
([
'notify_account_status'
=>
2
,
'notify_account_success_time'
=>
date
(
'Y-m-d H:i:s'
),
],
[
'writeoff_order_id'
=>
$writeOff_order_id
]);
}
catch
(
\Exception
$e
)
{
$m_cnt
=
false
;
}
PayOrderItem
::
update
([
'notify_account_status'
=>
2
,
'notify_account_times[+]'
=>
1
,
'notify_account_success_time'
=>
date
(
'Y-m-d H:i:s'
)
],
[
'order_item_id'
=>
$order_item_id
,
'can_notify_account'
=>
1
]);
}
}
catch
(
\Exception
$e
)
{
//补偿处理
$item
=
PayOrderItem
::
getMaster
(
'*'
,
[
'order_item_id'
=>
$order_item_id
]);
$time
=
$this
->
getNextTime
(
$item
[
'notify_account_times'
]);
//计算下次同步的时间
PayOrderItem
::
update
([
'notify_account_status'
=>
0
,
'notify_account_times[+]'
=>
1
,
'can_notify_account_time'
=>
date
(
'Y-m-d H:i:s'
,
$time
),
],
[
'order_item_id'
=>
$order_item_id
,
'can_notify_account'
=>
1
]);
if
(
$m_cnt
&&
$u_cnt
&&
$p_cnt
)
{
WriteOffOrder
::
update
([
'notify_account_status'
=>
2
,
'notify_account_success_time'
=>
date
(
'Y-m-d H:i:s'
),
],
[
'writeoff_order_id'
=>
$writeOff_order_id
,
'notify_account_status'
=>
1
]);
FileLog
::
error
(
'pay-service:wallet: 钱包同步失败'
,
json_encode
(
$wallet_list
,
JSON_UNESCAPED_UNICODE
),
$e
);
}
else
{
$info
=
WriteOffOrder
::
selectMaster
(
'*'
,
[
'writeoff_order_id'
=>
$writeOff_order_id
]);
$next
=
$this
->
getNextTime
(
$info
[
'can_notify_account_time'
]);
WriteOffOrder
::
update
([
'notify_account_status'
=>
0
,
'can_notify_account_time[+]'
=>
1
,
'notify_account_times'
=>
date
(
'Y-m-d H:i:s'
,
$next
),
],
[
'writeoff_order_id'
=>
$writeOff_order_id
]);
}
}
/**
* @param $data
* 构造订单流水
* @param $writeOff_order_id
* @param array $order_item_ids
* @return bool
*/
private
function
make_order_clearing
(
$data
)
private
function
write_off_clear_record
(
$writeOff_order_id
,
$pay_order
,
$order_item_ids
=
[])
{
$clear_items
=
PayOrderClearingItem
::
selectMaster
(
'*'
,
[
'order_item_id'
=>
$order_item_ids
]);
$d
=
$m
=
$p
=
[];
foreach
(
$clear_items
as
$r
)
{
if
(
$r
[
'pay_sub_type'
]
==
404
)
{
// 团长佣金收入
if
(
!
isset
(
$d
[
$r
[
'account_id'
]]))
{
$d
[
$r
[
'account_id'
]]
=
[
'writeoff_merchant_id'
=>
array_shift
(
$this
->
gen_ids
),
'writeOff_order_id'
=>
$writeOff_order_id
,
'pay_order_id'
=>
$r
[
'pay_order_id'
],
'order_id'
=>
$r
[
'order_id'
],
'user_id'
=>
$r
[
'account_id'
],
'payment'
=>
0
,
];
}
$d
[
$r
[
'account_id'
]][
'payment'
]
+=
$r
[
'pay_amount'
];
}
elseif
(
$r
[
'pay_sub_type'
]
==
405
||
$r
[
'pay_sub_type'
]
==
408
)
{
// 平台抽成
if
(
!
isset
(
$p
[
$r
[
'account_id'
]]))
{
$p
[
$r
[
'account_id'
]]
=
[
'refund_platform_id'
=>
array_shift
(
$this
->
gen_ids
),
'refund_order_id'
=>
$writeOff_order_id
,
'pay_order_id'
=>
$r
[
'pay_order_id'
],
'order_id'
=>
$r
[
'order_id'
],
'account_id'
=>
$r
[
'account_id'
],
'payment'
=>
0
,
];
}
$p
[
$r
[
'account_id'
]][
'payment'
]
+=
$r
[
'pay_amount'
];
}
elseif
(
$r
[
'pay_sub_type'
]
==
407
)
{
// 商品交易
$key
=
$r
[
'life_account_id'
]
.
'_'
.
$r
[
'shop_id'
];
if
(
!
isset
(
$m
[
$key
]))
{
$m
[
$key
]
=
[
'writeoff_merchant_id'
=>
array_shift
(
$this
->
gen_ids
),
'writeoff_order_id'
=>
$writeOff_order_id
,
'pay_order_id'
=>
$r
[
'pay_order_id'
],
'order_id'
=>
$r
[
'order_id'
],
'life_account_id'
=>
$pay_order
[
'life_account_id'
],
'shop_id'
=>
$pay_order
[
'shop_id'
],
'source_name'
=>
$pay_order
[
'source_name'
],
'service_name'
=>
$pay_order
[
'service_name'
],
'business_from'
=>
$pay_order
[
'business_from'
],
'title'
=>
''
,
'desc'
=>
''
,
'payment'
=>
0
,
];
}
$pre
=
','
;
if
(
empty
(
$m
[
$key
][
'title'
]))
{
$m
[
$key
][
'title'
]
=
$r
[
'remark'
];
$pre
=
''
;
}
$m
[
$key
][
'desc'
]
.=
$pre
.
$r
[
'remark'
];
$m
[
$key
][
'payment'
]
+=
$r
[
'pay_amount'
];
}
else
{}
}
$cnt
=
true
;
$cnt
=
$cnt
&&
WriteOffMerchantRecord
::
insert
(
array_values
(
$m
),
[
'rowCount'
=>
true
]);
if
(
$p
)
{
$cnt
=
$cnt
&&
WriteOffPlatformRecord
::
insert
(
array_values
(
$p
),
[
'rowCount'
=>
true
]);
}
if
(
$d
)
{
$cnt
=
$cnt
&&
WriteOffPersonalRecord
::
insert
(
array_values
(
$d
),
[
'rowCount'
=>
true
]);
}
return
$cnt
;
}
/**
* @param $payer
* @throws PayException
* 负责支付的清分
*/
private
function
make_order_clearing
(
$payer
)
{
$this
->
order_info
=
$data
[
'order_info'
];
$this
->
order_items
=
$data
[
'order_item_list'
];
/**
* 1. 总账入账,补贴扣减
* 2. 手续费、团长、平台、商户
* 3. 用户支付 + 营销补贴 = 手续费 + 团长佣金 + 平台抽成 + 商户收入
*/
$this
->
clear_list
=
[];
$this
->
clear_items_list
=
[];
$this
->
order_items
=
PayOrderItem
::
selectMaster
(
'*'
,
[
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
]]);
$pay_order_items
=
[];
foreach
(
$this
->
order_items
as
$r
)
{
$pay_order_items
[]
=
[
'pay_order_item_id'
=>
$this
->
gen_pay_order_item_id
(),
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'order_item_id'
=>
$r
[
'order_item_id'
],
'payment'
=>
$r
[
'payment'
],
'user_id'
=>
$this
->
pay_order
[
'user_id'
],
];
}
$coupon_items
=
PayCouponItem
::
selectMaster
(
'*'
,
[
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
]]);
//生成IDS
$this
->
get_idgen_id
(
$this
->
pay_order
[
'user_id'
],
3
+
count
(
$this
->
order_items
)
*
6
);
$wx_tip
=
$this
->
make_tip_clearing
(
);
//微信
手续费
$wx_tip
=
$this
->
make_tip_clearing
(
$payer
);
//渠道
手续费
$distribution_tip
=
$this
->
make_distribution_clearing
();
//团长收益
$platform_tip
=
$this
->
make_platform_clearing
();
//平台收益
$merchant_cash
=
$this
->
order_info
[
'payment'
]
-
$wx_tip
-
$distribution_tip
-
$platform_tip
;
$platform
=
$this
->
make_platform_clearing
();
//平台收益
$merchant_cash
=
$this
->
pay_order
[
'pay_amount'
]
+
$this
->
pay_order
[
'pay_discount'
]
-
$wx_tip
-
$distribution_tip
-
$platform
[
'amount'
];
//核对各项资金的合理性
if
(
$wx_tip
<
0
||
$distribution_tip
<
0
||
$platform
_tip
<
0
||
$merchant_cash
<
0
)
{
if
(
$wx_tip
<
0
||
$distribution_tip
<
0
||
$platform
[
'amount'
]
<
0
||
$merchant_cash
<
0
)
{
FileLog
::
error
(
'pay-service: 支付预结算失败,结算资金为负'
,
json_encode
([
$this
->
order_info
[
'payment'
],
$wx_tip
,
$distribution_tip
,
$platform_tip
,
$merchant_cash
]));
json_encode
([
'funds'
=>
$this
->
pay_order
[
'payment'
],
'wx_tip'
=>
$wx_tip
,
'marketing_tip'
=>
$this
->
pay_order
[
'pay_discount'
],
'distribution_tip'
=>
$distribution_tip
,
'platform_tip'
=>
$platform
[
'amount'
],
'merchant_cash'
=>
$merchant_cash
,
]));
throw
new
PayException
([
'cus'
=>
12
]);
}
$this
->
make_merchant_clearing
(
$merchant_cash
);
//商户收益
try
{
$cnt
=
true
;
PayOrderClearing
::
beginTransaction
();
$c_cnt
=
PayOrderItem
::
insert
(
$pay_order_items
,
[
'rowCount'
=>
true
]);
$i_cnt
=
PayOrderClearing
::
insert
(
$this
->
clear_list
,
[
'rowCount'
=>
true
]);
$ci_cnt
=
PayOrderClearingItem
::
insert
(
$this
->
clear_items_list
,
[
'rowCount'
=>
true
]);
if
(
$i_cnt
*
$c_cnt
*
$ci_cnt
==
0
)
{
//总账资金记账
$cnt
=
$cnt
&&
FundsService
::
credit
([
'trade_id'
=>
$this
->
pay_order
[
'order_id'
],
'third_order_id'
=>
$this
->
pay_order
[
'third_order_id'
],
'amount'
=>
$this
->
pay_order
[
'pay_amount'
],
'tip'
=>
$wx_tip
,
],
1
);
//营销扣款
$cnt
=
$cnt
&&
AccountService
::
pay
(
$coupon_items
,
$this
->
pay_order
[
'order_id'
]);
$cnt
=
$cnt
&&
PayOrderClearing
::
insert
(
$this
->
clear_list
,
[
'rowCount'
=>
true
]);
$cnt
=
$cnt
&&
PayOrderClearingItem
::
insert
(
$this
->
clear_items_list
,
[
'rowCount'
=>
true
]);
if
(
$cnt
==
false
)
{
throw
new
PayException
([
'cus'
=>
0
]);
}
...
...
@@ -481,34 +760,29 @@ class PayService
* @return false|float
* 获取微信手续费
*/
private
function
make_tip_clearing
()
private
function
make_tip_clearing
(
$payer
)
{
$wx_rate
=
config
(
'pay'
,
'pay.wechat_rate'
)
??
60
;
//微信利率 60 / 10000
$wx_account_id
=
config
(
'pay'
,
'pay.wechat_account_id'
)
??
'1111'
;
$float_tip
=
$wx_rate
*
$this
->
order_info
[
'payment'
]
/
10000
;
if
(
$float_tip
>=
1
)
{
$total_tip
=
round
(
$float_tip
);
}
else
{
$total_tip
=
0
;
}
if
(
empty
(
$total_tip
))
{
$account
=
$payer
->
clearChannelTips
(
$this
->
pay_order
);
if
(
empty
(
$account
))
{
return
0
;
}
$account
=
[
'account_id'
=>
$wx_account_id
,
'amount'
=>
$total_tip
,
];
$account
[
'account_type'
]
=
4
;
//三方手续费 + 平台总帐
$account
[
'pay_type'
]
=
2
;
//支付
$account
[
'pay_sub_type'
]
=
406
;
//第三方渠道手续费
$account
[
'need_recorded'
]
=
0
;
//不需同步给平台
/* 微信手续费总单,在退款、核销的时候会更新这个金额,保证他的准确 */
$this
->
do_clearing_data
(
$account
,
$total_tip
,
true
);
return
$total_tip
;
$this
->
clear_list
[]
=
[
'pay_order_clearing_id'
=>
array_shift
(
$this
->
gen_ids
),
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'account_id'
=>
$account
[
'account_id'
],
'account_type'
=>
$account
[
'account_type'
],
'pay_amount'
=>
$account
[
'amount'
],
'pay_type'
=>
$account
[
'pay_type'
],
'pay_sub_type'
=>
$account
[
'pay_sub_type'
],
];
return
$account
[
'amount'
];
}
/**
...
...
@@ -516,27 +790,56 @@ class PayService
* @return false|float
* 计算平台收入
*/
private
function
make_platform_clearing
()
private
function
make_platform_clearing
(
$payer
)
{
$account
=
[
'account_id'
=>
'100020003201'
,
'amount'
=>
0
,
'rate'
=>
0
,
'title'
=>
'平台收益'
,
];
$total_tip
=
$account
[
'amount'
]
=
round
(
$this
->
order_info
[
'total_price'
]
*
$account
[
'rate'
]
/
10000
);
if
(
empty
(
$total_tip
))
{
$account
=
$payer
->
clearPlatformTips
(
$this
->
order_info
);
if
(
empty
(
$account
))
{
return
0
;
}
$account
[
'account_type'
]
=
Dictionary
::
ACCOUNT_TYPE_SS
;
$account
[
'pay_type'
]
=
Dictionary
::
PAY_TYPE_IN
;
$account
[
'pay_sub_type'
]
=
Dictionary
::
PAY_SUB_TYPE_SYS_IN
;
$account
[
'need_recorded'
]
=
Dictionary
::
NO
;
$account
[
'account_type'
]
=
3
;
//平台(平台收入+平台补贴)
$account
[
'pay_type'
]
=
2
;
//支付
$account
[
'pay_sub_type'
]
=
405
;
//平台抽成
$this
->
do_clearing_data
(
$account
,
$total_tip
,
false
);
return
$total_tip
;
$total_amount
=
$this
->
pay_order
[
'pay_amount'
];
//订单支付总价格
$cleared_amount
=
0
;
//已经结算记录
$cleared_tip
=
0
;
//已经结算记录
$pay_order_clearing_id
=
array_shift
(
$this
->
gen_ids
);
$this
->
clear_list
[]
=
[
'pay_order_clearing_id'
=>
$pay_order_clearing_id
,
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'account_id'
=>
$account
[
'account_id'
],
'account_type'
=>
3
,
'pay_amount'
=>
$account
[
'amount'
],
'pay_type'
=>
2
,
'pay_sub_type'
=>
405
,
];
foreach
(
$this
->
order_items
as
$r
)
{
$current_tip
=
Strategy
::
getTip
(
$r
[
'payment'
],
$total_amount
,
$cleared_amount
,
$account
[
'amount'
],
$cleared_tip
);
$this
->
clear_items_list
[]
=
[
'pay_order_clearing_item_id'
=>
array_shift
(
$this
->
gen_ids
),
'pay_order_clearing_id'
=>
$pay_order_clearing_id
,
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'order_item_id'
=>
$r
[
'order_item_id'
],
'account_id'
=>
$account
[
'account_id'
],
'account_type'
=>
3
,
'pay_amount'
=>
$current_tip
,
'clear_payment'
=>
0
,
//商品结算价格
'pay_type'
=>
2
,
'pay_sub_type'
=>
405
,
'remark'
=>
''
,
];
$cleared_amount
+=
$r
[
'payment'
];
$cleared_tip
+=
$current_tip
;
}
return
$account
;
}
/**
...
...
@@ -545,15 +848,14 @@ class PayService
*/
private
function
make_distribution_clearing
()
{
/**
* 'distributor_user_id'=>122234,
* 'distributor_commission_value'=>60,
* 'parent_user_id'=>122234 . rand(111, 999),
* 'parent_commission_value'=>60,
*/
$total_tip
=
0
;
$maps
=
[];
foreach
(
$this
->
order_items
as
$r
)
{
//仅处理分销业务
if
(
empty
(
$r
[
'distributor_user_id'
])
||
$r
[
'marketing_type'
]
!=
1
)
{
...
...
@@ -562,14 +864,15 @@ class PayService
$r
[
'distributor_commission_value'
]
=
intval
(
$r
[
'distributor_commission_value'
]);
$r
[
'parent_commission_value'
]
=
intval
(
$r
[
'parent_commission_value'
]);
$_one
=
$_two
=
0
;
if
(
$r
[
'commission_mode'
]
==
1
)
{
if
(
$r
[
'commission_mode'
]
==
1
)
{
//按比例结算
$_one
=
floor
(
$r
[
'distributor_commission_value'
]
*
$this
->
order_info
[
'total_price'
]
/
10000
);
$_two
=
floor
(
$r
[
'parent_commission_value'
]
*
$this
->
order_info
[
'total_price'
]
/
10000
);
}
elseif
(
$r
[
'commission_mode'
]
==
2
)
{
}
elseif
(
$r
[
'commission_mode'
]
==
2
)
{
//固定金额结算
$_one
=
$r
[
'distributor_commission_value'
];
$_two
=
$r
[
'parent_commission_value'
];
}
else
{
//不处理
continue
;
}
$users
[
0
]
=
[
...
...
@@ -587,13 +890,27 @@ class PayService
}
foreach
(
$users
as
$u
)
{
if
(
empty
(
$
r
[
'user_id'
])
||
$u
[
'amount'
]
==
0
)
{
if
(
empty
(
$
u
[
'user_id'
])
||
$u
[
'amount'
]
==
0
)
{
continue
;
}
if
(
!
isset
(
$maps
[
$u
[
'user_id'
]]))
{
$maps
[
$u
[
'user_id'
]]
=
[
'pay_order_clearing_id'
=>
array_shift
(
$this
->
gen_ids
),
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'account_id'
=>
$u
[
'user_id'
],
'account_type'
=>
1
,
'pay_amount'
=>
0
,
'pay_type'
=>
1
,
'pay_sub_type'
=>
404
,
];
}
$maps
[
$u
[
'user_id'
]][
'pay_amount'
]
+=
$u
[
'amount'
];
$this
->
clear_items_list
[]
=
[
'pay_order_clearing_item_id'
=>
$this
->
gen_pay_order_clearing_item_id
(
),
'pay_order_clearing_id'
=>
''
,
'pay_order_clearing_item_id'
=>
array_shift
(
$this
->
gen_ids
),
'pay_order_clearing_id'
=>
$maps
[
$u
[
'user_id'
]][
'pay_order_clearing_id'
]
,
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'order_item_id'
=>
$r
[
'order_item_id'
],
...
...
@@ -602,183 +919,158 @@ class PayService
'pay_amount'
=>
$u
[
'amount'
],
'clear_payment'
=>
0
,
//商品结算价格
'pay_type'
=>
1
,
//收入
'pay_sub_type'
=>
105
,
//团长佣金收入
'pay_sub_type'
=>
404
,
//团长佣金收入
'remark'
=>
''
,
'need_recorded'
=>
1
,
];
$total_tip
+=
$u
[
'amount'
];
}
}
array_push
(
$this
->
clear_list
,
array_values
(
$maps
));
return
$total_tip
;
}
/**
* @param $merchant_cash
* @return mixed
* 计算商户清分信息
* 计算商户清分信息
, 存在结算价则需要二次平台收入
*/
private
function
make_merchant_clearing
(
$merchant_cash
)
private
function
make_merchant_clearing
(
$merchant_cash
,
$platform
)
{
$ret
=
$this
->
get_life_account
(
$this
->
order_info
[
'life_account_id'
]);
if
(
empty
(
$ret
[
'result'
][
'life_account_admin_id'
]))
{
$log_string
=
json_encode
([
'life_account_id'
=>
$this
->
order_info
[
'life_account_id'
],
'ret'
=>
$ret
,
],
JSON_UNESCAPED_UNICODE
);
FileLog
::
error
(
'pay-service:'
,
'获取生活号管理员失败'
,
$log_string
);
throw
new
PayException
([
'cus'
=>
13
]);
}
$account
=
[
'account_id'
=>
$ret
[
'result'
][
'life_account_admin_id'
],
'amount'
=>
$merchant_cash
,
'title'
=>
'商家订单收益'
,
];
$account
[
'account_type'
]
=
2
;
//商户
$account
[
'pay_type'
]
=
1
;
//收入
$account
[
'pay_sub_type'
]
=
102
;
//商品交易
$account
[
'need_recorded'
]
=
1
;
//同步到平台总帐
$this
->
do_clearing_data
(
$account
,
$merchant_cash
,
false
);
return
$merchant_cash
;
}
private
function
do_clearing_data
(
$account
,
$total_tip
,
$is_wx
=
false
)
{
$total_amount
=
$this
->
order_info
[
'payment'
];
//订单支付总价格
$cleared_amount
=
0
;
//已经结算记录
$cleared_tip
=
0
;
//已经结算记录
$pay_order_clearing_id
=
$this
->
gen_pay_order_clearing_id
();
$this
->
clear_list
[]
=
[
'pay_order_clearing_id'
=>
$pay_order_clearing_id
,
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'account_id'
=>
$account
[
'account_id'
],
'account_type'
=>
$account
[
'account_type'
],
'pay_amount'
=>
$account
[
'amount'
],
'pay_type'
=>
$account
[
'pay_type'
],
'pay_sub_type'
=>
$account
[
'pay_sub_type'
],
'need_recorded'
=>
$account
[
'need_recorded'
],
];
if
(
$is_wx
)
{
//微信不计算手续费拆弹
return
true
;
}
$m
=
$this
->
get_merchant_account
(
$this
->
pay_order
[
'life_account_id'
],
$this
->
pay_order
[
'life_account_id'
]);
$merchant
[
'account_id'
]
=
$m
[
'id'
];
//商户
$merchant
[
'account_type'
]
=
2
;
//商户
$merchant
[
'pay_type'
]
=
1
;
//收入
$merchant
[
'pay_sub_type'
]
=
407
;
//商品交易102
$merchant
[
'amount'
]
=
0
;
$platform
[
'account_type'
]
=
3
;
$platform
[
'pay_type'
]
=
1
;
$platform
[
'pay_sub_type'
]
=
408
;
//平台抽成(结算价);
$platform
[
'amount'
]
=
0
;
$m_clearing_id
=
array_shift
(
$this
->
gen_ids
);
//商家清分ID
$p_clearing_id
=
array_shift
(
$this
->
gen_ids
);
//平台结算价清分ID
$total_amount
=
$this
->
pay_order
[
'pay_amount'
];
//订单支付总价格
$cleared_amount
=
0
;
//已经结算金额记录
$cleared_tip
=
0
;
//已经结算tip记录
$total_tip
=
$merchant_cash
;
//已经结算记录
foreach
(
$this
->
order_items
as
$r
)
{
$current_tip
=
Strategy
::
getTip
(
$r
[
'payment'
],
$total_amount
,
$cleared_amount
,
$total_tip
,
$cleared_tip
);
$id
=
$this
->
gen_pay_order_clearing_item_id
();
//商家资金需要显示商品名称
if
(
$account
[
'pay_sub_type'
]
==
102
)
{
$remark
=
$r
[
'goods_name'
]
??
''
;
if
(
mb_strlen
(
$remark
)
>
100
)
{
$remark
=
mb_substr
(
$remark
,
0
,
100
)
.
'...'
;
}
if
(
!
empty
(
$r
[
'clear_price'
]))
{
$clear_payment
=
$r
[
'goods_num'
]
*
$r
[
'clear_price'
];
}
else
{
$clear_payment
=
0
;
}
$remark
=
$r
[
'goods_name'
]
??
''
;
if
(
mb_strlen
(
$remark
)
>
100
)
{
$remark
=
mb_substr
(
$remark
,
0
,
100
)
.
'...'
;
}
if
(
!
empty
(
$r
[
'clear_price'
]))
{
$clear_payment
=
$r
[
'goods_num'
]
*
$r
[
'clear_price'
];
}
else
{
$remark
=
''
;
$clear_payment
=
0
;
}
$pay_amount
=
$current_tip
;
if
(
$current_tip
<
$clear_payment
)
{
throw
new
PayException
([
'cus'
=>
12
]);
//结算价不能大于商家分成部分
}
elseif
(
$clear_payment
<
$current_tip
)
{
//结算价剩余部分返回平台
$p_tip
=
$current_tip
-
$clear_payment
;
$platform
[
'pay_amount'
]
+=
$p_tip
;
$this
->
clear_items_list
[]
=
[
'pay_order_clearing_item_id'
=>
array_shift
(
$this
->
gen_ids
),
'pay_order_clearing_id'
=>
$p_clearing_id
,
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'order_item_id'
=>
$r
[
'order_item_id'
],
'account_id'
=>
$platform
[
'account_id'
],
'account_type'
=>
$platform
[
'account_type'
],
'pay_amount'
=>
$p_tip
,
'clear_payment'
=>
0
,
//商品结算价格
'pay_type'
=>
$platform
[
'pay_type'
],
'pay_sub_type'
=>
$platform
[
'pay_sub_type'
],
'remark'
=>
''
,
];
$pay_amount
=
$clear_payment
;
}
else
{}
$this
->
clear_items_list
[]
=
[
'pay_order_clearing_item_id'
=>
$id
,
'pay_order_clearing_id'
=>
$
pay_order
_clearing_id
,
'pay_order_clearing_item_id'
=>
array_shift
(
$this
->
gen_ids
)
,
'pay_order_clearing_id'
=>
$
m
_clearing_id
,
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'order_item_id'
=>
$r
[
'order_item_id'
],
'account_id'
=>
$
accou
nt
[
'account_id'
],
'account_type'
=>
$
accou
nt
[
'account_type'
],
'pay_amount'
=>
$
current_tip
,
'account_id'
=>
$
mercha
nt
[
'account_id'
],
'account_type'
=>
$
mercha
nt
[
'account_type'
],
'pay_amount'
=>
$
pay_amount
,
'clear_payment'
=>
$clear_payment
,
//商品结算价格
'pay_type'
=>
$
accou
nt
[
'pay_type'
],
'pay_sub_type'
=>
$
accou
nt
[
'pay_sub_type'
],
'pay_type'
=>
$
mercha
nt
[
'pay_type'
],
'pay_sub_type'
=>
$
mercha
nt
[
'pay_sub_type'
],
'remark'
=>
$remark
,
'need_recorded'
=>
$account
[
'need_recorded'
],
];
$cleared_amount
+=
$r
[
'payment'
];
$cleared_tip
+=
$current_tip
;
}
}
private
function
gen_pay_order_id
(
$user_id
)
{
$number
=
substr
(
$user_id
,
-
2
);
$ids
=
$this
->
get_idgen_id
(
$number
,
1
);
return
array_pop
(
$ids
);
}
private
function
gen_pay_order_item_id
()
{
$number
=
substr
(
$this
->
order_info
[
'user_id'
],
-
2
);
$ids
=
$this
->
get_idgen_id
(
$number
,
1
);
return
array_pop
(
$ids
);
}
//商户收益
$this
->
clear_list
[]
=
[
'pay_order_clearing_id'
=>
$m_clearing_id
,
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'account_id'
=>
$merchant
[
'account_id'
],
'account_type'
=>
$merchant
[
'account_type'
],
'pay_amount'
=>
$merchant
[
'amount'
],
'pay_type'
=>
$merchant
[
'pay_type'
],
'pay_sub_type'
=>
$merchant
[
'pay_sub_type'
],
];
private
function
gen_pay_order_clearing_id
()
{
$number
=
substr
(
$this
->
order_info
[
'user_id'
],
-
2
);
$ids
=
$this
->
get_idgen_id
(
$number
,
1
);
return
array_pop
(
$ids
);
}
//结算价格收益返回平台
if
(
$platform
[
'amount'
]
>
0
)
{
$this
->
clear_list
[]
=
[
'pay_order_clearing_id'
=>
$p_clearing_id
,
'pay_order_id'
=>
$this
->
pay_order
[
'pay_order_id'
],
'order_id'
=>
$this
->
pay_order
[
'order_id'
],
'account_id'
=>
$platform
[
'account_id'
],
'account_type'
=>
$platform
[
'account_type'
],
'pay_amount'
=>
$platform
[
'amount'
],
'pay_type'
=>
$platform
[
'pay_type'
],
'pay_sub_type'
=>
$platform
[
'pay_sub_type'
],
];
}
private
function
gen_pay_order_clearing_item_id
()
{
$number
=
substr
(
$this
->
order_info
[
'user_id'
],
-
2
);
$ids
=
$this
->
get_idgen_id
(
$number
,
1
);
return
array_pop
(
$ids
);
return
$merchant_cash
;
}
private
function
get_idgen_id
(
$number
,
$count
=
1
)
{
$number
=
substr
(
$number
,
-
2
);
$number
=
intval
(
$number
);
$res
=
Idgen
::
get
(
appConfig
(
'idgen.partner'
),
appConfig
(
'idgen.key'
),
[],
[[
"type"
=>
"55c768"
,
'number'
=>
$number
,
"count"
=>
$count
]]);
$
id
=
$res
[
'id_datetime'
][
'55c768'
]
??
[];
return
$
id
;
$
this
->
gen_ids
=
$res
[
'id_datetime'
][
'55c768'
]
??
[];
return
$
this
->
gen_ids
;
}
private
function
get_
life_account
(
$life_account
_id
)
private
function
get_
merchant_account
(
$life_account_id
,
$shop
_id
)
{
$url
=
config
(
'interface'
,
'merchant.lifeaccount.get_life_account_by_id'
);
if
(
!
$url
)
{
throw
new
CodeSpecialException
(
"failed"
.
__METHOD__
);
}
$params
=
[
'life_account_id'
=>
$life_account_id
];
return
Sdk
::
call
(
$url
,
$params
);
}
private
function
getChannel
(
$pay_method_id
)
{
$account
=
Sdk
::
call
(
$url
,
$params
);
$maps
=
[
105
=>
"wx"
,
//微信 App 支付
106
=>
"alipay"
,
//支付宝
107
=>
"wx_pub"
,
//微信 JSAPI 支付
108
=>
"wx_pub_qr"
,
//微信 Native 支付
109
=>
"wx_wap"
,
//微信 H5 支付
110
=>
"wx_lite"
,
//微信小程序支付
];
if
(
!
empty
(
$maps
[
$pay_method_id
]))
{
return
$maps
[
$pay_method_id
];
}
else
{
return
$maps
[
105
];
}
return
$account
;
}
private
function
getNextTime
(
$times
=
0
)
{
...
...
application/services/pay/PlatformAccountService.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Services\pay
;
use
App\Exception\custom\FundsException
;
use
App\Models\order\mysql\PlatformAccount
;
use
App\Models\order\mysql\PlatformAccountLog
;
class
PlatformAccountService
{
/**
* @param $data
* @param int $channel
* @param int $source_name
* @param int $service_name
* @throws FundsException
* 渠道账户入账记录
*/
public
static
function
credit
(
$data
,
$source_name
=
10
,
$service_name
=
1
)
{
$info
=
PlatformAccount
::
getMaster
(
'*'
,
[
'source_name'
=>
$source_name
,
'service_name'
=>
$service_name
]);
if
(
empty
(
$info
))
{
throw
new
FundsException
([
'cus'
=>
1
]);
}
$cnt
=
true
;
$cnt
=
$cnt
&&
PlatformAccount
::
update
([
'receivable_amount[+]'
=>
$data
[
'amount'
]
],
[
'platform_funds_id'
=>
$info
[
'platform_funds_id'
]]);
$cnt
=
$cnt
&&
PlatformAccountLog
::
insert
([
'platform_account_id'
=>
$info
[
'platform_account_id'
],
'trade_id'
=>
$data
[
'trade_id'
],
'fund_type'
=>
1
,
'amount'
=>
$data
[
'amount'
]
],
[
'rowCount'
=>
true
]);
return
$cnt
;
}
}
\ No newline at end of file
application/services/pingxx/PingxxService.php
View file @
5dd1c7f3
...
...
@@ -144,6 +144,7 @@ class PingxxService
"body"
=>
"购买商品"
,
"uid"
=>
$order
[
'user_id'
],
"client_ip"
=>
IP
::
ip
(),
"time_expire"
=>
strtotime
(
$order
[
'expire_time'
]),
//订单过期时间 expire_time
'receipt_app'
=>
Pingpp
::
getAppId
(),
// 收款方应用
'service_app'
=>
Pingpp
::
getAppId
(),
// 服务方应用
'metadata'
=>
$metadata
,
// 商户定制信息
...
...
application/services/refund/RefundService.php
View file @
5dd1c7f3
...
...
@@ -4,17 +4,21 @@
namespace
App\Services\refund
;
use
Api\PhpServices\Idgen\Idgen
;
use
Api\PhpUtils\Log\FileLog
;
use
App\Exception\BaseException
;
use
App\Models\Dictionary
;
use
App\Models\order\mysql\PayOrder
;
use
App\Models\order\mysql\PayOrderItem
;
use
App\Models\order\mysql\PayCouponItem
;
use
App\Models\order\mysql\PayOrderClearing
;
use
App\Models\order\mysql\PayOrderClearingItem
;
use
App\Models\order\mysql\
PayOrderItem
;
use
App\Models\order\mysql\
RefundMerchantRecord
;
use
App\Models\order\mysql\RefundOrder
;
use
App\
Services\order\OrderService
;
use
App\
Models\order\mysql\RefundOrderItem
;
use
App\Services\pingxx\PingxxService
;
use
App\Models\order\mysql\RefundPlatformRecord
;
use
App\Services\Channel
;
use
App\Services\marketing\AccountService
;
use
App\Services\pay\FundsService
;
use
Helpers\Strategy
;
use
App\Exception\custom\RefundException
;
...
...
@@ -24,9 +28,10 @@ class RefundService
{
/**
* @param $order_item_id
* @param $user_id
* @throws RefundException
* @param $order_id
* @param array $order_item_ids
* @return array
* @throws BaseException
* 发起退款请求
*/
public
function
do_refund
(
$order_id
,
$order_item_ids
=
[])
{
...
...
@@ -37,43 +42,17 @@ class RefundService
$data
=
$this
->
can_refund
(
$order_id
,
$order_item_ids
);
/*
https://www.pingxx.com/api/%E8%AE%A2%E5%8D%95%20Refunds%20%E9%80%80%E6%AC%BE%E6%A6%82%E8%BF%B0.html
订单退款 paid = true, status = canceled, amount_paid > 0 则表明可以退款
amount_paid 大于 actual_amount 需要最后一单全退。
具体见ping++ 文档
*/
$pay
=
PingxxService
::
getInstance
()
->
getOrder
(
$data
[
'pay_order'
][
'third_order_id'
]);
if
(
empty
(
$pay
[
'paid'
])
||
$pay
[
'paid'
]
!=
true
)
{
throw
new
RefundException
([
'cus'
=>
12
]);
}
// 存在多次支付的场景需要人工介入处理, 修复订单支付金额,退款金额
if
(
$pay
[
'amount_paid'
]
>
$pay
[
'actual_amount'
])
{
FileLog
::
error
(
'pay-service: 订单可能存在多次成功支付,需人工确认处理。'
,
json_encode
(
$pay
,
JSON_UNESCAPED_UNICODE
));
throw
new
RefundException
([
'cus'
=>
13
]);
}
// 构造退款数据
$refund
=
[
'id'
=>
$pay
[
'id'
],
//pingxx订单ID
'charge'
=>
$pay
[
'charge'
],
//pingxx 支付订单ID
'refund_mode'
=>
'to_source'
,
//默认返回
'charge_amount'
=>
$data
[
'refund_order'
][
'refund_amount'
],
'metadata'
=>
[
'app_id'
=>
'merchant-c'
,
'pingxx_id'
=>
PingxxService
::
getInstance
()
->
getAppId
(),
'environ'
=>
Application
::
app
()
->
environ
(),
'refund_order_id'
=>
$data
[
'refund_order'
][
'refund_order_id'
],
'order_item_id'
=>
$data
[
'order_item_id'
],
'order_id'
=>
$order_id
,
],
$mata_data
=
[
'app_id'
=>
'merchant-c'
,
'environ'
=>
Application
::
app
()
->
environ
(),
'refund_order_id'
=>
$data
[
'refund_order'
][
'refund_order_id'
],
'order_item_id'
=>
$data
[
'order_item_id'
],
'order_id'
=>
$order_id
,
];
try
{
$ret
=
PingxxService
::
getInstance
()
->
sendRefund
(
$refund
);
$payer
=
Channel
::
getChannel
(
$data
[
'pay_order'
][
'pay_channel'
]);
$ret
=
$payer
->
refund
(
$data
,
$mata_data
);
if
(
!
empty
(
$ret
[
"data"
]))
{
$edit
=
[
'request_pingxx_success_time'
=>
date
(
'Y-m-d H:i:s'
)];
RefundOrder
::
update
(
$edit
,
[
'refund_order_id'
=>
$data
[
'refund_order'
][
'refund_order_id'
]]);
...
...
@@ -103,7 +82,7 @@ class RefundService
*/
public
function
call_back
(
$data
)
{
if
(
!
in_array
(
$data
[
'type'
],
[
'refund.succeeded'
,
'order.refunded'
]))
{
if
(
!
in_array
(
$data
[
'type'
],
[
'refund.succeeded'
]))
{
return
[
'error'
=>
'退款回调类型不正确'
];
}
...
...
@@ -117,15 +96,7 @@ class RefundService
return
[
'error'
=>
'非merchant渠道订单,不做处理。'
];
}
if
(
$data
[
'type'
]
==
'refund.succeeded'
)
{
$refund_order_id
=
$object
[
'order_no'
];
$refunded
=
$object
[
'succeed'
];
//"succeed": true,
}
else
{
$refund_order_id
=
$object
[
'merchant_order_no'
];
$refunded
=
$object
[
'refunded'
];
}
if
(
$refunded
!=
true
)
{
if
(
$object
[
'succeed'
]
!=
true
)
{
return
[
'error'
=>
'退款状态不正确,不做处理。'
];
}
...
...
@@ -137,63 +108,151 @@ class RefundService
return
[
'error'
=>
'退款订单缺少order_item_id,不做处理。'
];
}
/**
平台出账、手续费返还。
营销补贴返还
团长收入减少
平台收入减少
商户收入减少
*/
// 修改状态,锁定业务
$refund_order_id
=
$object
[
'metadata'
][
'refund_order_id'
];
RefundOrder
::
beginTransaction
();
$refund
=
RefundOrder
::
getMaster
(
'*'
,
[
'refund_order_id'
=>
$refund_order_id
]);
$cnt
=
true
;
//营销退款处理
$coupons
=
PayCouponItem
::
selectMaster
(
'*'
,
[
'order_item_id'
=>
$object
[
'metadata'
][
'order_item_id'
]]);
if
(
$coupons
)
{
$cnt
=
$cnt
&&
AccountService
::
refund
(
$coupons
,
$refund_order_id
);
}
//总账资金记账
$cnt
=
$cnt
&&
FundsService
::
payOut
([
'trade_id'
=>
$refund
[
'refund_order_id'
],
'third_order_id'
=>
$object
[
'id'
],
'amount'
=>
$refund
[
'refund_amount'
],
'tip'
=>
$refund
[
'refund_wx_tip'
],
],
1
);
$refund_order_id
=
$object
[
'metadata'
][
'refund_order_id'
];
$edit
=
[
'refund_order_status'
=>
2
,
//pingxx回调成功,
'pingxx_callback_success_time'
=>
date
(
'Y-m-d H:i:s'
),
//回调成功时间
];
$cnt
_r
=
RefundOrder
::
update
(
$edit
,
[
'refund_order_id'
=>
$refund_order_id
,
'refund_order_status'
=>
1
]);
$cnt
=
$cnt
&&
RefundOrder
::
update
(
$edit
,
[
'refund_order_id'
=>
$refund_order_id
,
'refund_order_status'
=>
1
]);
$cnt
_i
=
PayOrderItem
::
update
([
'refund_order_status'
=>
2
],
[
$cnt
=
$cnt
&&
PayOrderItem
::
update
([
'refund_order_status'
=>
2
],
[
'order_item_id'
=>
$object
[
'metadata'
][
'order_item_id'
]
]);
if
(
$cnt_r
&&
$cnt_i
)
{
$cnt
=
$cnt
&&
$this
->
refund_clear_record
(
$refund
,
$object
[
'metadata'
][
'order_item_id'
]);
if
(
$cnt
)
{
RefundOrder
::
commit
();
return
[
'refund_order_id'
=>
$refund_order_id
];
}
else
{
RefundOrder
::
rollback
();
throw
new
RefundException
([
'cus'
=>
16
]);
}
}
$refund
=
RefundOrder
::
getMaster
(
'*'
,
[
'refund_order_id'
=>
$refund_order_id
]);
/**
* @param $refund
* @param array $order_item_ids
* @return bool
*/
private
function
refund_clear_record
(
$refund
,
$order_item_ids
=
[])
{
$clear_items
=
PayOrderClearingItem
::
selectMaster
(
'*'
,
[
'order_item_id'
=>
$order_item_ids
]);
$ids
=
$this
->
get_idgen_id
(
$refund
[
'user_id'
],
count
(
$clear_items
)
*
4
);
$d
=
$m
=
$p
=
[];
foreach
(
$clear_items
as
$r
)
{
if
(
$r
[
'pay_sub_type'
]
==
404
)
{
// 团长佣金收入
if
(
!
isset
(
$d
[
$r
[
'account_id'
]]))
{
$d
[
$r
[
'account_id'
]]
=
[
'refund_personal_id'
=>
array_shift
(
$ids
),
'refund_order_id'
=>
$refund
[
'refund_order_id'
],
'pay_order_id'
=>
$r
[
'pay_order_id'
],
'order_id'
=>
$r
[
'order_id'
],
'user_id'
=>
$r
[
'account_id'
],
'payment'
=>
0
,
];
}
$d
[
$r
[
'account_id'
]][
'payment'
]
+=
$r
[
'pay_amount'
];
}
elseif
(
$r
[
'pay_sub_type'
]
==
405
||
$r
[
'pay_sub_type'
]
==
408
)
{
// 平台抽成
if
(
!
isset
(
$p
[
$r
[
'account_id'
]]))
{
$p
[
$r
[
'account_id'
]]
=
[
'refund_platform_id'
=>
array_shift
(
$ids
),
'refund_order_id'
=>
$refund
[
'refund_order_id'
],
'pay_order_id'
=>
$r
[
'pay_order_id'
],
'order_id'
=>
$r
[
'order_id'
],
'account_id'
=>
$r
[
'account_id'
],
'payment'
=>
0
,
];
}
$p
[
$r
[
'account_id'
]][
'payment'
]
+=
$r
[
'pay_amount'
];
}
elseif
(
$r
[
'pay_sub_type'
]
==
407
)
{
// 商品交易
if
(
!
isset
(
$m
[
$r
[
'account_id'
]]))
{
$m
[
$r
[
'account_id'
]]
=
[
'refund_merchant_id'
=>
array_shift
(
$ids
),
'refund_order_id'
=>
$refund
[
'refund_order_id'
],
'pay_order_id'
=>
$r
[
'pay_order_id'
],
'order_id'
=>
$r
[
'order_id'
],
'account_id'
=>
$r
[
'account_id'
],
'payment'
=>
0
,
];
}
$m
[
$r
[
'account_id'
]][
'payment'
]
+=
$r
[
'pay_amount'
];
if
(
$refund
[
'refund_order_status'
]
!=
2
)
{
throw
new
RefundException
([
'cus'
=>
16
]);
}
else
{}
}
return
[
'refund_order_id'
=>
$refund_order_id
];
$cnt
=
true
;
$cnt
=
$cnt
&&
RefundMerchantRecord
::
insert
(
array_values
(
$m
),
[
'rowCount'
=>
true
]);
if
(
$p
)
{
$cnt
=
$cnt
&&
RefundPlatformRecord
::
insert
(
array_values
(
$p
),
[
'rowCount'
=>
true
]);
}
if
(
$d
)
{
$cnt
=
$cnt
&&
RefundPlatformRecord
::
insert
(
array_values
(
$d
),
[
'rowCount'
=>
true
]);
}
//不用搞清分核算,是否需要平台记账
return
$cnt
;
}
/**
* @param $where
* @return \Api\PhpUtils\Mysql\MysqlBase|array
* @throws RefundException
* @param $order_id
* @param $order_item_ids
* @return array
* @throws BaseException
* 判断订单是否可退,判断是否存在退款申请
*/
private
function
can_refund
(
$order_id
,
$order_item_ids
)
{
private
function
can_refund
(
$order_id
,
$order_item_ids
=
[]
)
{
/**
* 业务方自行解决,订单关闭、订单超过时长不允许退款等逻辑
* 支付中心退款判断仅做主单是否支付,主单是否支持退款的判断
*/
$refund_payment
=
0
;
try
{
RefundOrder
::
beginTransaction
();
$pay_order
=
PayOrder
::
getMaster
(
'*'
,
[
'order_id'
=>
$order_id
]);
if
(
empty
(
$pay_order
))
{
throw
new
RefundException
([
'cus'
=>
15
]);
}
$pay_order_items
=
PayOrderItem
::
selectMaster
(
'*'
,
[
'order_id'
=>
$order_id
]);
if
(
empty
(
$pay_order_items
))
{
throw
new
RefundException
([
'cus'
=>
4
]);
if
(
empty
(
$pay_order
)
||
$pay_order
[
'pay_order_status'
]
!=
2
)
{
throw
new
RefundException
([
'cus'
=>
2
]);
}
$pay_order_items
=
PayOrderItem
::
selectMaster
(
'*'
,
[
'pay_order_id'
=>
$pay_order
[
'pay_order_id'
]]);
foreach
(
$pay_order_items
as
$item
)
{
if
(
$item
[
'can_notify_account'
]
==
1
)
{
continue
;
//已结算不允许退款
...
...
@@ -208,12 +267,11 @@ class RefundService
}
$items
[]
=
$item
;
$refund_payment
+=
$item
[
'payment'
];
}
if
(
empty
(
$items
))
{
throw
new
RefundException
([
'cus'
=>
14
]);
//
throw
new
RefundException
([
'cus'
=>
3
]);
}
//重新计算微信手续费
...
...
@@ -222,7 +280,7 @@ class RefundService
// 计算已退金额、已退手续费 sum(refund_wx_tip), sum(refund_amount)
$list
=
RefundOrder
::
selectMaster
(
'*'
,
[
'order_id'
=>
$pay_order
[
'order_id'
]]);
foreach
(
$list
as
$r
)
{
if
(
$r
[
'refund_order_status'
]
==
Dictionary
::
REFUND_ORDER_STATUS_UNDO
)
{
if
(
$r
[
'refund_order_status'
]
==
0
)
{
continue
;
}
...
...
@@ -244,8 +302,10 @@ class RefundService
$wx_tip
=
Strategy
::
getWxTip
(
$refund_payment
,
$pay_order
[
'pay_amount'
],
$cleared_amount
,
$wx_total_tip
,
$cleared_tip
);
$ids
=
$this
->
get_idgen_id
(
$pay_order
[
'user_id'
],
count
(
$items
)
+
1
);
$refund_order_id
=
array_shift
(
$ids
);
$refund
=
[
'refund_order_id'
=>
$
this
->
gen_refund_order_id
(
$pay_order
[
'user_id'
])
,
'refund_order_id'
=>
$
refund_order_id
,
'user_id'
=>
$pay_order
[
'user_id'
],
'order_id'
=>
$pay_order
[
'order_id'
],
'refund_order_status'
=>
1
,
...
...
@@ -255,46 +315,47 @@ class RefundService
'extra'
=>
json_encode
([
'order_item_id'
=>
array_column
(
$items
,
'order_item_id'
)]),
];
$cnt
=
RefundOrder
::
insert
(
$refund
,
[
'rowCount'
=>
true
]);
if
(
$cnt
==
0
)
{
throw
new
RefundException
([
'cus'
=>
0
]);
$refund_items
=
[];
foreach
(
$items
as
$r
)
{
$refund_items
[]
=
[
'refund_order_item_id'
=>
array_shift
(
$ids
),
'refund_order_id'
=>
$refund_order_id
,
'order_item_id'
=>
$r
[
'order_item_id'
],
];
}
//批量更新子单状态 "user_id" => [2, 123, 234, 54],
PayOrderItem
::
update
([
'refund_order_status'
=>
1
],
[
'order_item_id'
=>
array_column
(
$items
,
'order_item_id'
)]);
$cnt
=
true
;
$cnt
=
$cnt
&&
RefundOrder
::
insert
(
$refund
,
[
'rowCount'
=>
true
]);
$cnt
=
$cnt
&&
RefundOrderItem
::
insert
(
$refund_items
,
[
'rowCount'
=>
true
]);
$cnt
=
$cnt
&&
PayOrderItem
::
update
([
'refund_order_status'
=>
1
],
[
'order_item_id'
=>
array_column
(
$items
,
'order_item_id'
)]);
$data
=
[
'refund_order'
=>
$refund
,
'pay_order'
=>
$pay_order
,
'order_item_id'
=>
array_column
(
$items
,
'order_item_id'
),
];
if
(
$cnt
==
false
)
{
throw
new
RefundException
([
'cus'
=>
4
]);
}
RefundOrder
::
commit
();
}
catch
(
\
PDO
Exception
$e
)
{
}
catch
(
\Exception
$e
)
{
RefundOrder
::
rollback
();
throw
new
BaseException
([
'msg'
=>
$e
->
getMessage
(),
'code'
=>
$e
->
getCode
()]);
}
return
$data
;
}
private
function
gen_refund_order_id
(
$user_id
)
{
$number
=
substr
(
$user_id
,
-
2
);
$ids
=
$this
->
get_idgen_id
(
$number
,
1
);
return
array_pop
(
$ids
);
return
[
'refund_order'
=>
$refund
,
'pay_order'
=>
$pay_order
,
'order_item_id'
=>
array_column
(
$items
,
'order_item_id'
),
];
}
private
function
get_idgen_id
(
$number
,
$count
=
1
)
{
$number
=
substr
(
$number
,
-
2
);
$number
=
intval
(
$number
);
$res
=
Idgen
::
get
(
appConfig
(
'idgen.partner'
),
appConfig
(
'idgen.key'
),
[],
[[
"type"
=>
"55c768"
,
'number'
=>
$number
,
"count"
=>
$count
]]);
$id
=
$res
[
'id_datetime'
][
'55c768'
]
??
[];
return
$id
;
return
$res
[
'id_datetime'
][
'55c768'
]
??
[];
}
}
\ No newline at end of file
application/services/wallet/MerchantAccountService.php
0 → 100644
View file @
5dd1c7f3
<?php
namespace
App\Services\wallet
;
use
App\Exception\custom\CodeSpecialException
;
use
Helpers\Sdk
;
class
MerchantAccountService
{
/**
* @param $params
* @return bool|mixed
* @throws CodeSpecialException
* 钱包记录同步
*/
public
static
function
sync
(
$params
)
{
/*
///account/billrecord/create
$url = config('interface', 'account.account.transfer');
if (!$url) {
throw new CodeSpecialException("failed");
}
*/
$url
=
'http://account.dev.yidian-inc.com/account/billrecord/create'
;
// 服务增加签名
$appid
=
\Yaf\Application
::
app
()
->
getConfig
()
->
get
(
'wallet.appid'
);
$secret
=
\Yaf\Application
::
app
()
->
getConfig
()
->
get
(
'wallet.secret'
);
$params
[
'time'
]
=
date
(
'Y-m-d H:i:s'
);
$params
[
'transfer_service_id'
]
=
$appid
;
$params
[
'sign'
]
=
self
::
sign
(
$params
,
$secret
);
return
Sdk
::
call
(
$url
,
$params
);
}
private
function
sign
(
$params
,
$secret
)
{
$sign
=
md5
(
$params
[
'time'
]
.
$secret
);
return
$sign
;
}
}
\ No newline at end of file
application/services/wallet/WalletService.php
View file @
5dd1c7f3
...
...
@@ -23,6 +23,20 @@ class WalletService
throw
new
CodeSpecialException
(
"failed"
);
}
// 服务增加签名
$appid
=
\Yaf\Application
::
app
()
->
getConfig
()
->
get
(
'wallet.appid'
);
$secret
=
\Yaf\Application
::
app
()
->
getConfig
()
->
get
(
'wallet.secret'
);
$params
[
'time'
]
=
date
(
'Y-m-d H:i:s'
);
$params
[
'transfer_service_id'
]
=
$appid
;
$params
[
'sign'
]
=
self
::
sign
(
$params
,
$secret
);
return
Sdk
::
call
(
$url
,
$params
);
}
private
function
sign
(
$params
,
$secret
)
{
$sign
=
md5
(
$params
[
'time'
]
.
$secret
);
return
$sign
;
}
}
\ No newline at end of file
conf/application.ini
View file @
5dd1c7f3
...
...
@@ -41,12 +41,22 @@ dingTalk.keys[]="SEC0298ad3f80e16df12cd4d6f6c39e961b500e2ff486f4c4377c0e2af8f453
pingxx.appid
=
"app_9m1ubDG4e1mPXLCG"
wxApp.jw.order
=
"https://wx.appgc.cn/%23/bpmp/ticket/my"
[perf : common : exception : dingTalk]
wallet.appid
=
"21091014413030105002"
wallet.secret
=
"b62eff98ba17160df0161ede4eef2346"
[perf : prod : common : exception : dingTalk]
pingxx.appid
=
"app_XfjznTPSa5aLfvfH"
[test : common : exception : dingTalk]
pingxx.appid
=
"app_W10Oe5XrvbzHfP4W"
wxApp.jw.order
=
"https://testwx.appgc.cn/%23/bpmp/ticket/my"
[dev : common : exception]
wallet.appid
=
"21090716133838205004"
wallet.secret
=
"f97c50e880d377a0e0f79aee1f639777"
[dev : common : exception : dingTalk]
pingxx.appid
=
"app_W10Oe5XrvbzHfP4W"
wxApp.jw.order
=
"https://testwx.appgc.cn/%23/bpmp/ticket/my"
wallet.appid
=
"21090716133838205004"
wallet.secret
=
"f97c50e880d377a0e0f79aee1f639777"
\ No newline at end of file
conf/cli.ini
View file @
5dd1c7f3
...
...
@@ -15,14 +15,26 @@ dingTalk.tokens[]="5d754d76cac8c64aad495bc44f481677745ff831aee0517b6e5b3565be6ba
dingTalk.keys
[]
="SEC0298ad3f80e16df12cd4d6f6c39e961b500e2ff486f4c4377c0e2af8f4539a74"
[prod : common : dingTalk]
[prod : common :
exception :
dingTalk]
pingxx.appid
=
"app_9m1ubDG4e1mPXLCG"
wxApp.jw.order
=
"https://wx.appgc.cn/%23/bpmp/ticket/my"
[perf : common : dingTalk]
wallet.appid
=
"21091014413030105002"
wallet.secret
=
"b62eff98ba17160df0161ede4eef2346"
[perf : prod : common : exception : dingTalk]
pingxx.appid
=
"app_XfjznTPSa5aLfvfH"
[test
: comm
on : dingTalk]
[test
: common : excepti
on : dingTalk]
pingxx.appid
=
"app_W10Oe5XrvbzHfP4W"
wxApp.jw.order
=
"https://testwx.appgc.cn/%23/bpmp/ticket/my"
wallet.appid
=
"21090716133838205004"
wallet.secret
=
"f97c50e880d377a0e0f79aee1f639777"
[dev : common ]
[dev : common
: exception : dingTalk
]
pingxx.appid
=
"app_W10Oe5XrvbzHfP4W"
wxApp.jw.order
=
"https://testwx.appgc.cn/%23/bpmp/ticket/my"
wallet.appid
=
"21090716133838205004"
wallet.secret
=
"f97c50e880d377a0e0f79aee1f639777"
public/demo.php
View file @
5dd1c7f3
<?php
var_dump
(
$_POST
);
$ids
=
[
"21092214200312204001"
,
"21092214200312204002"
,
"21092214200312204003"
,
"21092214200312204004"
,
"21092214200312204005"
];
$t
=
array_shift
(
$ids
);
var_dump
(
$t
);
\ No newline at end of file
sql/pay2_0913/pay.sql
0 → 100644
View file @
5dd1c7f3
-- 收银台二期
-- 增加字段 pay_order.pay_discount + pay_order.pay_amount = order_info.payment
ALTER
TABLE
`pay_order`
ADD
`pay_discount`
INT
NOT
NULL
DEFAULT
'0'
COMMENT
'抵扣金额,单位分'
AFTER
`pay_amount`
;
-- 初始化数据
update
pay_order
set
pay_discount
=
0
;
-- 核销/确认收货表
CREATE
TABLE
`write_off_order`
(
`write_off_order_id`
varchar
(
20
)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NOT
NULL
DEFAULT
''
COMMENT
'ID'
,
`user_id`
bigint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'buyerId'
,
`order_id`
varchar
(
30
)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NOT
NULL
DEFAULT
''
COMMENT
'订单id'
,
`write_off_status`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'核销状态,0 未核销, 1待确认 , 2 已核销'
,
`write_off_amount`
int
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'核销金额,单位分'
,
`notify_account_status`
tinyint
NOT
NULL
DEFAULT
'0'
COMMENT
'通知账户系统状态,0未通知,1已通知'
,
`notify_account_success_time`
timestamp
NULL
DEFAULT
NULL
COMMENT
'通知账户系统成功时间'
,
`create_time`
timestamp
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
COMMENT
'添加时间'
,
`source_name`
tinyint
NOT
NULL
DEFAULT
'0'
COMMENT
'使用方名,1生活圈,2主端'
,
`extra`
varchar
(
1024
)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NOT
NULL
DEFAULT
''
COMMENT
'extra额外自定义字段'
,
PRIMARY
KEY
(
`write_off_order_id`
),
KEY
`idx_order_id`
(
`order_id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
COMMENT
=
'核销订单表'
;
-- 平台渠道资金日志表
CREATE
TABLE
`platform_funds_log`
(
`funds_log_id`
bigint
NOT
NULL
DEFAULT
'0'
COMMENT
'主键'
,
`trade_id`
varchar
(
30
)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NOT
NULL
DEFAULT
''
COMMENT
'支付订单、或退单ID'
,
`third_order_id`
varchar
(
30
)
CHARACTER
SET
utf8
COLLATE
utf8_general_ci
NOT
NULL
DEFAULT
''
COMMENT
'支付唯一ID'
,
`fund_type`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'1:入账,2:出账'
,
`payment`
int
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'支付金额,分'
,
`amount`
int
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'到账金额,分'
,
`tip`
int
NOT
NULL
DEFAULT
'0'
COMMENT
'手续费,分'
,
`create_time`
timestamp
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
COMMENT
'添加时间'
,
`source_name`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'使用方名,1生活圈,2主端'
,
`service_name`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'服务名字,1生活圈优惠券,'
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
COMMENT
=
'平台资金日志表'
;
-- 平台渠道资金表 后期不建议会有频繁更新,并且不满足业务统计需求(按周、月、日)
CREATE
TABLE
`platform_account`
(
`platform_account_id`
varchar
(
30
)
NOT
NULL
DEFAULT
''
COMMENT
'平台账户ID'
,
`channel`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'支付渠道类型,1 pingxx'
,
`source_name`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'使用方名,1生活圈,2主端'
,
`service_name`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'服务名字,1生活圈优惠券'
,
`total_amount`
int
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'金额'
,
`total_tip`
int
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'手续费金额'
,
`create_time`
timestamp
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
COMMENT
'添加时间'
,
PRIMARY
KEY
(
`platform_account_id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
COMMENT
=
'平台渠道账户表'
;
CREATE
TABLE
`marketing_account`
(
`marketing_account_id`
varchar
(
30
)
NOT
NULL
DEFAULT
''
COMMENT
'账户ID'
,
`source_name`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'使用方名,1生活圈,2主端'
,
`service_name`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'服务名字,1生活圈优惠券,'
,
`frozen_amount`
int
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'冻结金额'
,
`receivable_amount`
int
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'可用金额'
,
`create_time`
timestamp
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
COMMENT
'添加时间'
,
`update_time`
timestamp
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
COMMENT
'更新时间'
,
PRIMARY
KEY
(
`marketing_account_id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
COMMENT
=
'营销账户表'
;
CREATE
TABLE
`marketing_account_log`
(
`log_id`
bigint
unsigned
NOT
NULL
AUTO_INCREMENT
COMMENT
'ID'
,
`marketing_account_id`
varchar
(
30
)
NOT
NULL
DEFAULT
''
COMMENT
'账户ID'
,
`marketing_id`
varchar
(
30
)
NOT
NULL
DEFAULT
''
COMMENT
'活动ID'
,
`fund_type`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'1: 营销冻结 2. 营销出款 3. 营销退款 4. 营销充值 5. 营销划拨'
,
`trade_id`
varchar
(
30
)
NOT
NULL
DEFAULT
''
COMMENT
'业务ID'
,
`trade_type`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'1: 订单ID 2. 订单ID 3. 退单ID 4. 充值ID 5. 划拨ID'
,
`amount`
int
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'资金额'
,
`create_time`
timestamp
NOT
NULL
DEFAULT
CURRENT_TIMESTAMP
COMMENT
'添加时间'
,
PRIMARY
KEY
(
`log_id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
COMMENT
=
'营销消费记录表'
;
CREATE
TABLE
`marketing_account_map`
(
`id`
int
unsigned
NOT
NULL
AUTO_INCREMENT
COMMENT
'ID'
,
`marketing_account_id`
varchar
(
30
)
NOT
NULL
DEFAULT
''
COMMENT
'账户ID'
,
`marketing_id`
varchar
(
30
)
NOT
NULL
DEFAULT
''
COMMENT
'活动ID'
,
`source_name`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'使用方名,1生活圈,2主端'
,
`service_name`
tinyint
unsigned
NOT
NULL
DEFAULT
'0'
COMMENT
'服务名字,1生活圈优惠券,'
,
PRIMARY
KEY
(
`id`
)
)
ENGINE
=
InnoDB
DEFAULT
CHARSET
=
utf8mb4
COLLATE
=
utf8mb4_0900_ai_ci
COMMENT
=
'营销账户活动表'
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
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 comment