Commit 5dd1c7f3 authored by songxiaohang's avatar songxiaohang

add:pay2

parent b734e336
...@@ -15,4 +15,6 @@ class Code ...@@ -15,4 +15,6 @@ class Code
const REFUND = 102000; const REFUND = 102000;
const ORDER = 103000; const ORDER = 103000;
const SDK = 104000; const SDK = 104000;
const FUNDS = 105000;
const P_ACCOUNT = 106000;
} }
\ No newline at end of file
<?php
namespace App\Exception\custom;
use App\Exception\BaseException;
class FundsException extends BaseException
{
protected $base_code = Code::FUNDS;
protected $cus = [
0 => '系统异常请联系管理员',
1 => '缺少渠道平台账户配置,请联系管理员!',
];
}
...@@ -13,22 +13,34 @@ class PayException extends BaseException ...@@ -13,22 +13,34 @@ class PayException extends BaseException
protected $cus = [ protected $cus = [
0 => '系统错误,请稍收重试', 0 => '系统错误,请稍收重试',
1 => '请输入订单ID', 1 => '请输入订单ID',
2 => '订单服务获取订单信息失败。', 2 => '请输入用户ID',
3 => '请确认订单信息及用户是否一致。', 3 => '订单服务获取订单信息失败。',
4 => '支付订单创建失败,请管理员关注', 4 => '请确认订单信息及用户是否一致。',
5 => '该订单已经支付,请稍后刷新', 5 => '订单缺少过期时间,请联系管理员',
6 => '该订单已超时取消关闭,请重新下单购买', 6 => '订单过期,不允许支付',
7 => '支付订单创建失败,请管理员关注',
7 => '支付回调订单不存在,请管理员关注', 8 => '支付订单创建失败,请管理员关注',
8 => '支付订单金额与实际支付金额不等,请管理员关注', 9 => '订单已经支付,请勿重复支付',
9 => '退款中订单不允许核销,请管理员关注',
10 => '回调失败,支付订单不存在',
11 => '回调失败,支付金额错误',
12 => '订单服务优惠信息错误',
13 => '订单明细保存失败',
10 => '未支付订单不允许核销,请管理员关注', 10 => '未支付订单不允许核销,请管理员关注',
11 => '商家仅允许核销自己的订单,请管理员关注', 11 => '商家仅允许核销自己的订单,请管理员关注',
12 => '支付订单预结算失败,结算资金不能负数,请核对配置', 12 => '支付订单预结算失败,结算资金不能负数,请核对配置',
13 => '生活号获取管理员ID失败,请联系管理员', 13 => '生活号获取管理员ID失败,请联系管理员',
14 => '订单缺少商品信息,请联系管理员', 14 => '订单缺少商品信息,请联系管理员',
15 => '订单存在过期商品,不能支付', 15 => '订单存在过期商品,不能支付',
16 => '订单过期,不允许支付',
18 => '订单不存在,请重试',
100=>'支付渠道错误,暂不支持该渠道',
101=>'该订单已经支付,请稍后刷新',
102=>'该订单已超时取消关闭,请重新下单购买',
103=>'该订单已超时取消关闭,请重新下单购买',
104=>'请增加pingxx渠道手续费配置',
]; ];
} }
<?php
namespace App\Exception\custom;
use App\Exception\BaseException;
class PlatformAccountException extends BaseException
{
protected $base_code = Code::P_ACCOUNT;
protected $cus = [
0 => '系统异常请联系管理员',
1 => '缺少渠道平台账户配置,请联系管理员!',
];
}
...@@ -11,23 +11,16 @@ class RefundException extends BaseException ...@@ -11,23 +11,16 @@ class RefundException extends BaseException
protected $base_code = Code::REFUND; protected $base_code = Code::REFUND;
protected $cus = [ protected $cus = [
0 => '系统异常请联系管理员', 0 => '系统异常请联系管理员',
1 => '缺少退款订单ID!', 1 => '缺少退款订单ID!',
2 => '获取订单信息返回错误,请核对', 2 => '订单未支付或不存在,请核对。',
3 => '仅支持自己操作订单退款!', 3 => '不存在满足条件的退款订单。',
4 => '目前仅支持支付后的订单退款,请核对', 4 => '退单保存失败,请联系管理员。',
5 => '已核销计算订单不支持退款!', 5 => '订单退款回调处理失败,请核对。',
6 => '退款处理完成,请勿重复申请',
7 => '退款处理中请稍等', 6 => 'pingxx退单缺少matadata!',
7 => 'pingxx未支付订单不允许退款。',
8 => '退款消息类型匹配失败,请管理员关注!', 8 => 'pingxx订单可能存在多次成功支付,需人工确认处理。',
9 => 'pingxx退款消息格式错误,请管理员关注!',
10 => 'pingxx退单状态异常,请管理员关注!',
11 => 'pingxx退单缺少matadata!',
12 => 'pingxx未支付订单不允许退款。',
13 => 'pingxx订单可能存在多次成功支付,需人工确认处理。',
14 => '不存在满足条件的退款订单。',
15 => '订单未支付或不存在,请核对。',
16 => '订单退款回调处理失败,请核对。',
]; ];
} }
...@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase; ...@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase;
class CallbackLog extends MysqlBase class CallbackLog extends MysqlBase
{ {
const TABLE_NAME = 'callback_log'; const TABLE_NAME = 'callback_log';
const CONFIG_INDEX = 'pay'; const CONFIG_INDEX = 'pay_v2';
} }
<?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';
}
<?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';
}
<?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';
}
<?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';
}
...@@ -7,7 +7,7 @@ use App\Exception\custom\PayException; ...@@ -7,7 +7,7 @@ use App\Exception\custom\PayException;
class PayOrder extends MysqlBase class PayOrder extends MysqlBase
{ {
const TABLE_NAME = 'pay_order'; const TABLE_NAME = 'pay_order';
const CONFIG_INDEX = 'pay'; const CONFIG_INDEX = 'pay_v2';
/** /**
* @param $order_id * @param $order_id
...@@ -18,14 +18,14 @@ class PayOrder extends MysqlBase ...@@ -18,14 +18,14 @@ class PayOrder extends MysqlBase
self::beginTransaction(); self::beginTransaction();
try{ try{
$_date = date('Y-m-d H:i:s'); $order = self::getMaster('*', ['order_id'=>$order_id]);
$order = self::getMaster('*', ['order_id'=>$order_id, 'expire_time[>]'=>$_date]);
if(empty($order)) { if(empty($order)) {
$cnt = self::insert($pay_order, ['rowCount'=>true]); $cnt = self::insert($pay_order, ['rowCount'=>true]);
if($cnt) { if($cnt) {
$order = $pay_order; $order = $pay_order;
} }
} }
self::commit(); self::commit();
}catch (\PDOException $e) { }catch (\PDOException $e) {
......
...@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase; ...@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase;
class PayOrderClearing extends MysqlBase class PayOrderClearing extends MysqlBase
{ {
const TABLE_NAME = 'pay_order_clearing'; const TABLE_NAME = 'pay_order_clearing';
const CONFIG_INDEX = 'pay'; const CONFIG_INDEX = 'pay_v2';
} }
...@@ -7,7 +7,7 @@ use App\Exception\BaseException; ...@@ -7,7 +7,7 @@ use App\Exception\BaseException;
class PayOrderClearingItem extends MysqlBase class PayOrderClearingItem extends MysqlBase
{ {
const TABLE_NAME = 'pay_order_clearing_item'; const TABLE_NAME = 'pay_order_clearing_item';
const CONFIG_INDEX = 'pay'; const CONFIG_INDEX = 'pay_v2';
public static function marketSaleCount($accountId) { public static function marketSaleCount($accountId) {
......
...@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase; ...@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase;
class PayOrderItem extends MysqlBase class PayOrderItem extends MysqlBase
{ {
const TABLE_NAME = 'pay_order_item'; const TABLE_NAME = 'pay_order_item';
const CONFIG_INDEX = 'pay'; const CONFIG_INDEX = 'pay_v2';
} }
<?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';
}
<?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';
}
<?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';
}
<?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';
}
<?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';
}
<?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';
}
<?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';
}
...@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase; ...@@ -6,5 +6,5 @@ use Api\PhpUtils\Mysql\MysqlBase;
class RefundOrder extends MysqlBase class RefundOrder extends MysqlBase
{ {
const TABLE_NAME = 'refund_order'; const TABLE_NAME = 'refund_order';
const CONFIG_INDEX = 'pay'; const CONFIG_INDEX = 'pay_v2';
} }
<?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';
}
<?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';
}
<?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';
}
<?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';
}
<?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';
}
<?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';
}
<?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';
}
<?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';
}
...@@ -61,6 +61,16 @@ class OrderController extends Base ...@@ -61,6 +61,16 @@ class OrderController extends Base
$this->success(['result'=>$ret]); $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() { public function write_offAction() {
$params = $this->params; $params = $this->params;
......
<?php <?php
use Api\PhpServices\Idgen\Idgen;
use App\Base\Base; use App\Base\Base;
use App\Models\order\mysql\PayOrderItem; use App\Models\order\mysql\PayOrderItem;
...@@ -82,4 +83,16 @@ class TccController extends Base ...@@ -82,4 +83,16 @@ class TccController extends Base
$params['traceId'] = \Helpers\Tracer::getTraceId(); $params['traceId'] = \Helpers\Tracer::getTraceId();
$this->success($params); $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]);
}
} }
...@@ -46,25 +46,42 @@ class Hook extends \Yaf\Plugin_Abstract { ...@@ -46,25 +46,42 @@ class Hook extends \Yaf\Plugin_Abstract {
} }
public function preDispatch(\Yaf\Request_Abstract $request, \Yaf\Response_Abstract $response) { 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)) { // raw, $_POST 不能共存。
$_POST = []; if(!empty($_POST)) {
FileLog::error('bp-gateway', 'json decode error raw:' . $jsonPost); 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) { public function postDispatch(\Yaf\Request_Abstract $request, \Yaf\Response_Abstract $response) {
......
<?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
<?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;
}
}
<?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
<?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
<?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
This diff is collapsed.
<?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
...@@ -144,6 +144,7 @@ class PingxxService ...@@ -144,6 +144,7 @@ class PingxxService
"body" => "购买商品", "body" => "购买商品",
"uid" => $order['user_id'], "uid" => $order['user_id'],
"client_ip" => IP::ip(), "client_ip" => IP::ip(),
"time_expire" => strtotime($order['expire_time']), //订单过期时间 expire_time
'receipt_app' => Pingpp::getAppId(), // 收款方应用 'receipt_app' => Pingpp::getAppId(), // 收款方应用
'service_app' => Pingpp::getAppId(), // 服务方应用 'service_app' => Pingpp::getAppId(), // 服务方应用
'metadata' => $metadata, // 商户定制信息 'metadata' => $metadata, // 商户定制信息
......
<?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
...@@ -23,6 +23,20 @@ class WalletService ...@@ -23,6 +23,20 @@ class WalletService
throw new CodeSpecialException("failed"); 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); return Sdk::call($url, $params);
} }
private function sign($params, $secret) {
$sign = md5($params['time'] . $secret);
return $sign;
}
} }
\ No newline at end of file
...@@ -41,12 +41,22 @@ dingTalk.keys[]="SEC0298ad3f80e16df12cd4d6f6c39e961b500e2ff486f4c4377c0e2af8f453 ...@@ -41,12 +41,22 @@ dingTalk.keys[]="SEC0298ad3f80e16df12cd4d6f6c39e961b500e2ff486f4c4377c0e2af8f453
pingxx.appid = "app_9m1ubDG4e1mPXLCG" pingxx.appid = "app_9m1ubDG4e1mPXLCG"
wxApp.jw.order = "https://wx.appgc.cn/%23/bpmp/ticket/my" 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" pingxx.appid = "app_XfjznTPSa5aLfvfH"
[test : common : exception : dingTalk] [test : common : exception : dingTalk]
pingxx.appid = "app_W10Oe5XrvbzHfP4W" pingxx.appid = "app_W10Oe5XrvbzHfP4W"
wxApp.jw.order = "https://testwx.appgc.cn/%23/bpmp/ticket/my" 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" 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
...@@ -15,14 +15,26 @@ dingTalk.tokens[]="5d754d76cac8c64aad495bc44f481677745ff831aee0517b6e5b3565be6ba ...@@ -15,14 +15,26 @@ dingTalk.tokens[]="5d754d76cac8c64aad495bc44f481677745ff831aee0517b6e5b3565be6ba
dingTalk.keys[]="SEC0298ad3f80e16df12cd4d6f6c39e961b500e2ff486f4c4377c0e2af8f4539a74" dingTalk.keys[]="SEC0298ad3f80e16df12cd4d6f6c39e961b500e2ff486f4c4377c0e2af8f4539a74"
[prod : common : dingTalk] [prod : common : exception : dingTalk]
pingxx.appid = "app_9m1ubDG4e1mPXLCG" 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" pingxx.appid = "app_XfjznTPSa5aLfvfH"
[test: common : dingTalk] [test : common : exception : dingTalk]
pingxx.appid = "app_W10Oe5XrvbzHfP4W" 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" pingxx.appid = "app_W10Oe5XrvbzHfP4W"
wxApp.jw.order = "https://testwx.appgc.cn/%23/bpmp/ticket/my"
wallet.appid = "21090716133838205004"
wallet.secret = "f97c50e880d377a0e0f79aee1f639777"
<?php <?php
var_dump($_POST);
$ids = ["21092214200312204001","21092214200312204002","21092214200312204003","21092214200312204004","21092214200312204005"];
$t = array_shift($ids);
var_dump($t);
\ No newline at end of file
-- 收银台二期
-- 增加字段 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='营销账户活动表';
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment