feat: 添加小程序订单

This commit is contained in:
Gosowong 2023-05-10 14:08:57 +08:00
parent eceaacc7dc
commit 8f316ee2aa
5 changed files with 558 additions and 0 deletions

View File

@ -14,10 +14,12 @@ namespace crmeb\services\easywechat;
use crmeb\services\easywechat\miniPayment\ServiceProvider;
use crmeb\services\easywechat\oauth2\wechat\WechatOauth2Provider;
use crmeb\services\easywechat\orderShipping\OrderClient;
use crmeb\services\easywechat\subscribe\ProgramProvider;
use crmeb\services\easywechat\v3pay\PayClient;
use crmeb\services\easywechat\wechatlive\ProgramProvider as LiveProgramProvider;
use crmeb\services\easywechat\v3pay\ServiceProvider as V3PayServiceProvider;
use crmeb\services\easywechat\orderShipping\ServiceProvider as OrderServiceProvider;
/**
@ -26,6 +28,7 @@ use crmeb\services\easywechat\v3pay\ServiceProvider as V3PayServiceProvider;
* @property LiveProgramProvider $wechat_live
* @property WechatOauth2Provider $oauth2
* @property PayClient $v3pay
* @property OrderClient $order_ship
*/
class Application extends \EasyWeChat\Foundation\Application
{
@ -40,6 +43,7 @@ class Application extends \EasyWeChat\Foundation\Application
ProgramProvider::class,
V3PayServiceProvider::class,
\crmeb\services\easywechat\Open3rd\ProgramProvider::class,
OrderServiceProvider::class
];
/**

View File

@ -0,0 +1,131 @@
<?php
namespace crmeb\services\easywechat\orderShipping;
use crmeb\exceptions\AdminException;
use EasyWeChat\Core\AbstractAPI;
use EasyWeChat\Core\AccessToken;
use EasyWeChat\Support\Collection;
class BaseOrder extends AbstractAPI
{
public $config;
const BASE_API = 'https://api.weixin.qq.com/';
const ORDER = 'wxa/sec/order/';
const EXPRESS = 'cgi-bin/express/delivery/open_msg/';
public function __construct(AccessToken $accessToken, $config)
{
parent::__construct($accessToken);
$this->config = $config;
}
private function resultHandle(Collection $result)
{
if (empty($result)) {
throw new AdminException('微信接口返回异常');
}
$res = $result->toArray();
if ($res['errcode'] == 0) {
return $res;
} else {
throw new AdminException("微信接口异常:code = {$res['errcode']} msg = {$res['errmsg']}");
}
}
/**
* 发货
* @param $params
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
*
* @date 2023/05/09
* @author yyw
*/
public function shipping($params)
{
return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'upload_shipping_info', json_encode($params)]));
}
/**
* 合单
* @param $params
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
*
* @date 2023/05/09
* @author yyw
*/
public function combinedShipping($params)
{
return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'upload_combined_shipping_info', json_encode($params)]));
}
/**
* 签收消息提醒
* @param $params
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
*
* @date 2023/05/09
* @author yyw
*/
public function notifyConfirm($params)
{
return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'notify_confirm_receive', json_encode($params)]));
}
/**
* 查询小程序是否已开通发货信息管理服务
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
*
* @date 2023/05/09
* @author yyw
*/
public function isManaged()
{
$params = [
'appid' => $this->config['order_shipping']['appid']
];
return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'notify_confirm_receive', json_encode($params)]));
}
/**
* 设置跳转连接
* @param $path
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
*
* @date 2023/05/10
* @author yyw
*/
public function setMesJumpPath($path)
{
$params = [
'path' => $path
];
return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::ORDER . 'set_msg_jump_path', json_encode($params)]));
}
/**
* 获取运力id列表get_delivery_list
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
*
* @date 2023/05/09
* @author yyw
*/
public function getDeliveryList()
{
return $this->resultHandle($this->parseJSON('POST', [self::BASE_API . self::EXPRESS . 'get_delivery_list']));
}
}

View File

@ -0,0 +1,130 @@
<?php
namespace crmeb\services\easywechat\orderShipping;
use crmeb\services\easywechat\Application;
class MiniOrderService
{
/**
* @var Application
*/
protected static $instance;
/**
* @param array $config
* @return array[]
*
* @date 2023/05/09
* @author yyw
*/
protected static function options(array $config = [])
{
return [
'order_shipping' => [
'appid' => sys_config('routine_appId'),
'merchant_id' => sys_config('pay_new_weixin_open') ? sys_config('pay_weixin_mchid') : sys_config('pay_new_weixin_mchid'),
]
];
}
/**
* 初始化
* @param bool $cache
* @return Application
*/
protected static function application($cache = false)
{
(self::$instance === null || $cache === true) && (self::$instance = new Application(self::options()));
return self::$instance;
}
protected static function order()
{
return self::application()->order_ship;
}
/**
* 上传订单
* @param string $out_trade_no
* @param int $logistics_type
* @param array $shipping_list
* @param string $payer_openid
* @param int $delivery_mode
* @param bool $is_all_delivered
* @return array
*
* @date 2023/05/09
* @author yyw
*/
public static function shippingByTradeNo(string $out_trade_no, int $logistics_type, array $shipping_list, string $payer_openid, int $delivery_mode = 1, bool $is_all_delivered = true)
{
return self::order()->shippingByTradeNo($out_trade_no, $logistics_type, $shipping_list, $payer_openid, $delivery_mode, $is_all_delivered);
}
/**
* 合单
* @param string $out_trade_no
* @param int $logistics_type
* @param array $sub_orders
* @param string $payer_openid
* @param int $delivery_mode
* @param bool $is_all_delivered
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
*
* @date 2023/05/10
* @author yyw
*/
public static function combinedShippingByTradeNo(string $out_trade_no, int $logistics_type, array $sub_orders, string $payer_openid, int $delivery_mode = 2, bool $is_all_delivered = false)
{
return self::order()->combinedShippingByTradeNo($out_trade_no, $logistics_type, $sub_orders, $payer_openid, $delivery_mode, $is_all_delivered);
}
/**
* 签收通知
* @param string $merchant_trade_no
* @param string $received_time
* @return array
*
* @date 2023/05/09
* @author yyw
*/
public static function notifyConfirmByTradeNo(string $merchant_trade_no, string $received_time)
{
return self::order()->notifyConfirmByTradeNo($merchant_trade_no, $received_time);
}
/**
* 判断是否开通
* @return bool
* @throws \EasyWeChat\Core\Exceptions\HttpException
* @throws \Psr\SimpleCache\InvalidArgumentException
*
* @date 2023/05/09
* @author yyw
*/
public static function isManaged()
{
return self::order()->checkManaged();
}
/**
* 设置小修跳转路径
* @param $path
* @return array
* @throws \EasyWeChat\Core\Exceptions\HttpException
*
* @date 2023/05/10
* @author yyw
*/
public static function setMesJumpPath($path)
{
return self::order()->setMesJumpPath($path);
}
}

View File

@ -0,0 +1,257 @@
<?php
namespace crmeb\services\easywechat\orderShipping;
use crmeb\exceptions\AdminException;
use crmeb\services\CacheService;
use EasyWeChat\Core\Exceptions\HttpException;
use think\facade\Cache;
class OrderClient extends BaseOrder
{
const redis_prefix = 'mimi_order';
/**
* @var \Redis
*/
protected $redis;
/**
* @return object|\Redis|null
*
* @date 2023/05/10
* @author yyw
*/
protected function getRedis()
{
if (empty($this->redis)) {
$this->redis = Cache::store('redis')->handler();
}
return $this->redis;
}
/**
* 发货
* @param string $out_trade_no
* @param int $logistics_type
* @param array $shipping_list
* @param string $payer_openid
* @param int $delivery_mode
* @param bool $is_all_delivered
* @return array
* @throws HttpException
*
* @date 2023/05/10
* @author yyw
*/
public function shippingByTradeNo(string $out_trade_no, int $logistics_type, array $shipping_list, string $payer_openid, int $delivery_mode = 1, bool $is_all_delivered = true)
{
if (!$this->checkManaged()) {
throw new AdminException('开通小程序订单管理服务后重试');
}
$params = [
'order_key' => [
'order_number_type' => 1,
'mchid' => $this->config['order_shipping']['merchant_id'],
'out_trade_no' => $out_trade_no,
],
'logistics_type' => $logistics_type,
'delivery_mode' => $delivery_mode,
'upload_time' => date(DATE_RFC3339),
'payer' => [
'openid' => $payer_openid
]
];
if ($delivery_mode == 2) {
$params['is_all_delivered'] = $is_all_delivered;
}
foreach ($shipping_list as $shipping) {
$params['shipping_list'][] = [
'tracking_no' => $shipping['tracking_no'],
'express_company' => $this->getDelivery($shipping['express_company']),
'item_desc' => $shipping['item_desc'],
'contact' => $shipping['contact'] ?? []
];
}
return $this->shipping($params);
}
/**
* 合单
* @param string $out_trade_no
* @param int $logistics_type
* @param array $sub_orders
* @param string $payer_openid
* @param int $delivery_mode
* @param bool $is_all_delivered
* @return array
* @throws HttpException
*
* @date 2023/05/10
* @author yyw
*/
public function combinedShippingByTradeNo(string $out_trade_no, int $logistics_type, array $sub_orders, string $payer_openid, int $delivery_mode = 2, bool $is_all_delivered = false)
{
if (!$this->checkManaged()) {
throw new AdminException('开通小程序订单管理服务后重试');
}
$params = [
'order_key' => [
'order_number_type' => 1,
'mchid' => $this->config['order_shipping']['merchant_id'],
'out_trade_no' => $out_trade_no,
],
'sub_orders' => [
'order_key' => [
'order_number_type' => 1,
'mchid' => $this->config['order_shipping']['merchant_id'],
'out_trade_no' => '',
'logistics_type' => '',
],
'delivery_mode' => $delivery_mode,
'is_all_delivered' => $is_all_delivered
],
'upload_time' => date(DATE_RFC3339),
'payer' => [
'openid' => $payer_openid
]
];
foreach ($sub_orders as $order) {
$sub_order = [
'order_key' => [
'order_number_type' => 1,
'mchid' => $this->config['order_shipping']['merchant_id'],
'out_trade_no' => $order['out_trade_no'],
'logistics_type' => $logistics_type,
],
'delivery_mode' => $delivery_mode,
'is_all_delivered' => $is_all_delivered
];
foreach ($sub_orders['shipping_list'] as $shipping) {
$sub_order['shipping_list'][] = [
'tracking_no' => $shipping['tracking_no'],
'express_company' => $this->getDelivery($shipping['express_company']),
'item_desc' => $shipping['item_desc'],
'contact' => $shipping['contact'] ?? []
];
}
$params['sub_orders'][] = $sub_order;
}
return $this->combinedShipping($params);
}
/**
* 签收通知
* @param string $merchant_trade_no
* @param string $received_time
* @return array
* @throws HttpException
*
* @date 2023/05/10
* @author yyw
*/
public function notifyConfirmByTradeNo(string $merchant_trade_no, string $received_time)
{
$params = [
'merchant_id' => $this->config['payment']['merchant_id'],
'merchant_trade_no' => $merchant_trade_no,
'received_time' => $received_time
];
return $this->notifyConfirm($params);
}
/**
* 设置小程序管理服务开通状态
* @return bool
* @throws HttpException
*
* @date 2023/05/09
* @author yyw
*/
public function setManaged()
{
$res = $this->isManaged();
if ($res['is_trade_managed']) {
$key = self::redis_prefix . '_is_trade_managed';
$this->getRedis()->set($key, $res['is_trade_managed']);
return true;
} else {
return false;
}
}
/**
* @return bool
* @throws HttpException
*
* @date 2023/05/10
* @author yyw
*/
public function checkManaged()
{
$key = self::redis_prefix . '_is_trade_managed';
if ($this->getRedis()->exists($key)) {
return true;
} else {
return $this->setManaged();
}
}
/**
* 同步去微信物流列表
* @return array
* @throws HttpException
*
* @date 2023/05/10
* @author yyw
*/
public function setDeliveryList()
{
$list = $this->getDeliveryList();
if ($list) {
$key = self::redis_prefix . '_delivery_list';
$date = array_column($list, 'delivery_id', 'delivery_name');
// 创建缓存
$this->getRedis()->hMSet($key, $date);
return $date;
} else {
throw new AdminException('物流公司列表异常');
}
}
/**
* 获取物流公司编码
* @param $company_name
* @return array|mixed
* @throws HttpException
*
* @date 2023/05/10
* @author yyw
*/
public function getDelivery($company_name)
{
$key = self::redis_prefix . '_delivery_list';
if (!$this->getRedis()->exists($key)) {
$date = $this->setDeliveryList();
if (!isset($date[$company_name])) {
throw new AdminException('物流公司异常');
}
$express_company = $date[$company_name];
} else {
$express_company = $this->getRedis()->hMGet($key, $company_name);
}
return $express_company;
}
}

View File

@ -0,0 +1,36 @@
<?php
/*
* This file is part of the overtrue/wechat.
*
* (c) overtrue <i@overtrue.me>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
namespace crmeb\services\easywechat\orderShipping;
use EasyWeChat\Payment\Merchant;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
use EasyWeChat\MiniProgram\AccessToken;
/**
* Class ServiceProvider.
*
* @package crmeb\services\easywechat\order_ship
* @package crmeb\services\easywechat\mini_express
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $pimple)
{
$pimple['order_ship'] = function ($pimple) {
return new OrderClient($pimple['access_token'], $pimple);
};
}
}