初始化项目:添加后端代码、ThinkPHP框架、前端资源

This commit is contained in:
amb
2026-09-03 12:42:39 +08:00
commit 482bece22e
3726 changed files with 416708 additions and 0 deletions
@@ -0,0 +1,175 @@
<?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 TuzhiEasyWeChat\Channels\Aftersale;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class Client extends BaseClient
{
/**
* 获取售后单
* 通过该接口可以获取视频号小店的售后单。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
*
* @param $after_sale_order_id String 是 售后单号
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getAfterSaleorder($after_sale_order_id)
{
$params = [
'after_sale_order_id' => $after_sale_order_id
];
return $this->httpPostJson('channels/ec/aftersale/getaftersaleorder', $params);
}
/**
* 获取售后单列表
* 通过该接口可以获取视频号小店的售后单列表。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $begin_create_time Number 是 订单创建启始时间
* @param $end_create_time Number 是 订单创建结束时间,end_create_time减去begin_create_time不得大于24小时
* @param $next_key String 否 翻页参数,从第二页开始传,来源于上一页的返回值
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getAftersaleList($begin_create_time,$end_create_time,$next_key='')
{
$params = [
'begin_create_time' => $begin_create_time,
'end_create_time' => $end_create_time
];
if($next_key){
$params['next_key'] = $next_key;
}
return $this->httpPostJson('channels/ec/aftersale/getaftersalelist', $params);
}
/**
* 同意售后
* 通过该接口可以在视频号小店售后管理中进行同意售后操作。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $after_sale_order_id String 是 售后单号
* @param $address_id String 否 同意退货时必须传入地址id,否则后续接口在处理缺少地址信息的请求时将报错
* @param $accept_type Number 否 针对退货退款同意售后的阶段:
1. 同意退货退款,并通知用户退货;
2. 确认收到货并退款给用户。
如果不填则将根据当前的售后单状态自动选择相应操作。对于仅退款的情况,由于只存在一种同意的场景,无需填写此字段。
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function acceptApply($begin_create_time,$address_id,$accept_type='')
{
$params = [
'begin_create_time' => $begin_create_time
];
if($accept_type){
$params['accept_type'] = $accept_type;
}
if($address_id){
$params['address_id'] = $address_id;
}
return $this->httpPostJson('channels/ec/aftersale/acceptapply', $params);
}
/**
* 拒绝售后
* 通过该接口可以在视频号小店售后管理中进行拒绝售后操作。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $after_sale_order_id String 是 售后单号
* @param $reject_reason String 否 拒绝原因具体描述 ,可使用默认描述,也可以自定义描述
* @param $reject_reason_type number 是 拒绝原因枚举值
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function rejectApply($after_sale_order_id,$reject_reason_type,$reject_reason='')
{
$params = [
'after_sale_order_id' => $after_sale_order_id,
'reject_reason_type'=>$reject_reason_type
];
if($reject_reason){
$params['reject_reason'] = $reject_reason;
}
return $this->httpPostJson('channels/ec/aftersale/rejectapply', $params);
}
/**
* 上传退款凭证
* 通过该接口可以将退款凭证上传至视频号小店。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $after_sale_order_id String 是 售后单号
* @param $refund_certificates Array<String> 是 退款凭证,可使用图片上传接口获取media_id(数据类型填0)
* @param $desc String 是 描述
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function uploadRefundCertificate($after_sale_order_id,$refund_certificates,$desc)
{
$params = [
'desc' => $desc,
'after_sale_order_id' => $after_sale_order_id,
'refund_certificates' => $refund_certificates
];
return $this->httpPostJson('channels/ec/aftersale/uploadrefundcertificate', $params);
}
/**
* 获取全量售后原因
* 通过该接口可以获取视频号小店的全量售后原因。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getReason()
{
$params = [];
return $this->httpPostJson('channels/ec/aftersale/reason/get', $params);
}
/**
* 获取拒绝售后原因
* 通过该接口可以获取视频号小店的拒绝售后原因。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getRejectReason()
{
$params = [];
return $this->httpPostJson('channels/ec/aftersale/rejectreason/get', $params);
}
}
@@ -0,0 +1,33 @@
<?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 TuzhiEasyWeChat\Channels\Aftersale;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['aftersale'] = function ($app) {
return new Client($app);
};
}
}
@@ -0,0 +1,49 @@
<?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 TuzhiEasyWeChat\Channels;
use TuzhiEasyWeChat\BasicService;
use TuzhiEasyWeChat\Kernel\ServiceContainer;
/**
* Class Application.
*
* @author overtrue <i@overtrue.me>
*
* @property \TuzhiEasyWeChat\BasicService\Media\Client $media
* @property \TuzhiEasyWeChat\BasicService\Url\Client $url
* @property \TuzhiEasyWeChat\BasicService\QrCode\Client $qrcode
*/
class Application extends ServiceContainer
{
/**
* @var array
*/
protected $providers = [
Auth\ServiceProvider::class,
Server\ServiceProvider::class,
Sharer\ServiceProvider::class,
OAuth\ServiceProvider::class,
Aftersale\ServiceProvider::class,
Order\ServiceProvider::class,
Basics\ServiceProvider::class,
Merchant\ServiceProvider::class,
Category\ServiceProvider::class,
Product\ServiceProvider::class,
Window\ServiceProvider::class,
// Base services
BasicService\QrCode\ServiceProvider::class,
BasicService\Media\ServiceProvider::class,
BasicService\Url\ServiceProvider::class,
BasicService\Jssdk\ServiceProvider::class
];
}
@@ -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 TuzhiEasyWeChat\Channels\Auth;
use TuzhiEasyWeChat\Kernel\AccessToken as BaseAccessToken;
/**
* Class AuthorizerAccessToken.
*
* @author overtrue <i@overtrue.me>
*/
class AccessToken extends BaseAccessToken
{
/**
* @var string
*/
protected $endpointToGetToken = 'cgi-bin/token';
protected function getCredentials(): array
{
return [
'grant_type' => 'client_credential',
'appid' => $this->app['config']['app_id'],
'secret' => $this->app['config']['secret'],
];
}
}
@@ -0,0 +1,33 @@
<?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 TuzhiEasyWeChat\Channels\Auth;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author overtrue <i@overtrue.me>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
!isset($app['access_token']) && $app['access_token'] = function ($app) {
return new AccessToken($app);
};
}
}
@@ -0,0 +1,81 @@
<?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 TuzhiEasyWeChat\Channels\Base;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class Client extends BaseClient
{
/**
* Clear quota.
*
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function clearQuota()
{
$params = [
'appid' => $this->app['config']['app_id'],
];
return $this->httpPostJson('cgi-bin/clear_quota', $params);
}
/**
* Get wechat callback ip.
*
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
*/
public function getValidIps()
{
return $this->httpGet('cgi-bin/getcallbackip');
}
/**
* Check the callback address network.
*
* @return array|\TuzhiEasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
*
* @throws InvalidArgumentException
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function checkCallbackUrl(string $action = 'all', string $operator = 'DEFAULT')
{
if (!in_array($action, ['dns', 'ping', 'all'], true)) {
throw new InvalidArgumentException('The action must be dns, ping, all.');
}
$operator = strtoupper($operator);
if (!in_array($operator, ['CHINANET', 'UNICOM', 'CAP', 'DEFAULT'], true)) {
throw new InvalidArgumentException('The operator must be CHINANET, UNICOM, CAP, DEFAULT.');
}
$params = [
'action' => $action,
'check_operator' => $operator,
];
return $this->httpPostJson('cgi-bin/callback/check', $params);
}
}
@@ -0,0 +1,33 @@
<?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 TuzhiEasyWeChat\Channels\Base;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['base'] = function ($app) {
return new Client($app);
};
}
}
@@ -0,0 +1,78 @@
<?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 TuzhiEasyWeChat\Channels\Basics;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class Client extends BaseClient
{
/**
* 获取店铺基本信息
*
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getInfo()
{
return $this->httpGet('channels/ec/basics/info/get');
}
/**
* 获取地址行政编码
* 通过该接口可获取地址行政编码信息,最多获取4级地址的行政编码
*
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getAddressCode($addr_code=0)
{
$params = [
'addr_code' => $addr_code
];
return $this->httpPostJson('channels/ec/basics/addresscode/get', $params);
}
/**
* 上传图片
* 可通过该接口上传图片
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function imgUpload($img_url='',$resp_type=1)
{
$query = [
'upload_type' => 1,//上传类型。0:二进制流;1:图片url(不支持301/302跳转),该参数为 URL 参数
'resp_type'=>$resp_type
];
$form = [];
$form['img_url'] = $img_url;
return $this->httpPostJson('channels/ec/basics/img/upload',$form,$query);
}
}
@@ -0,0 +1,33 @@
<?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 TuzhiEasyWeChat\Channels\Basics;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['basics'] = function ($app) {
return new Client($app);
};
}
}
@@ -0,0 +1,131 @@
<?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 TuzhiEasyWeChat\Channels\Category;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class Client extends BaseClient
{
/**
* 获取所有类目
* 可通过该接口获取全部的一、二、三级类目信息、类目的资质信息、商品资质信息。
*
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function all()
{
return $this->httpGet('channels/ec/category/all');
}
/**
* 获取类目信息
* 根据三级类目ID获取类目的相关信息。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
*
* @param $catId
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function detail($catId)
{
$params = [
'cat_id' => $catId
];
return $this->httpPostJson('channels/ec/category/detail', $params);
}
/**
* 获取可用的子类目详情
* 该接口可根据父类目ID获取可用的子类目详情。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
*
* @param $fCatId 父类目ID,可先填0获取根部类目
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getAvailablesoncategories($fCatId = 0)
{
$params = [
'f_cat_id' => $fCatId
];
return $this->httpPostJson('channels/ec/category/availablesoncategories/get', $params);
}
/**
* 获取审核结果
* 该接口可通过审核id来查询审核结果。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $audit_id 提交审核时返回的id,上传类目资质接口获得
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getAudit($audit_id = 0)
{
$params = [
'audit_id' => $audit_id
];
return $this->httpPostJson('channels/ec/category/audit/get', $params);
}
/**
* 撤销类目资质审核
* 该接口可通过审核id来对类目资质的审核进行撤销。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $audit_id 提交审核时返回的id,上传类目资质接口获得
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function cancelAudit($audit_id = 0)
{
$params = [
'audit_id' => $audit_id
];
return $this->httpPostJson('channels/ec/category/audit/cancel', $params);
}
/**
* 获取账号申请通过的类目和资质信息
* 通过该接口,用户可以查询到自己申请的类目及相应资质信息。需要注意的是,类目对应的资质要求可能会根据运营政策发生变化。因此,虽然某个资质曾经满足特定类目的申请条件,但在添加商品至该类目时,应以最新的资质要求为准。
*
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getList()
{
return $this->httpGet('channels/ec/category/list/get');
}
}
@@ -0,0 +1,33 @@
<?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 TuzhiEasyWeChat\Channels\Category;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['category'] = function ($app) {
return new Client($app);
};
}
}
@@ -0,0 +1,117 @@
<?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 TuzhiEasyWeChat\Channels\merchant;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class AddressClient extends BaseClient
{
/**
* 获取地址列表
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $offset number 是 获取的偏移量
* @param $limit number 是 获取的个数
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getList($offset=0,$limit = 10)
{
$params = [
'offset' => $offset,
'limit'=>$limit
];
return $this->httpPostJson('channels/ec/merchant/address/list', $params);
}
/**
* 添加地址
* 可通过该接口添加地址
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $address_detail object AddressDetail 是 地址信息,具体信息请参考地址定义
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function add($address_detail)
{
$params = [
'address_detail'=>$address_detail
];
return $this->httpPostJson('channels/ec/merchant/address/add', $params);
}
/**
* 更新地址
* 可通过该接口更新地址
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $address_detail object AddressDetail 是 地址信息,具体信息请参考地址定义
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function update($address_detail)
{
$params = [
'address_detail'=>$address_detail
];
return $this->httpPostJson('channels/ec/merchant/address/update', $params);
}
/**
* 删除地址
* 可通过该接口删除地址
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $address_id String 是 地址id
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function del($address_id)
{
$params = [
'address_id' => $address_id
];
return $this->httpPostJson('channels/ec/merchant/address/delete', $params);
}
/**
* 获取商品
* 可通过指定商品ID获取商品具体信息
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $address_id String 是 地址id
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function detail($address_id)
{
$params = [
'address_id' => $address_id
];
return $this->httpPostJson('channels/ec/merchant/address/get', $params);
}
}
@@ -0,0 +1,33 @@
<?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 TuzhiEasyWeChat\Channels\Merchant;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['address'] = function ($app) {
return new AddressClient($app);
};
}
}
@@ -0,0 +1,66 @@
<?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 TuzhiEasyWeChat\Channels\OAuth;
use Overtrue\Socialite\SocialiteManager as Socialite;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author overtrue <i@overtrue.me>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['oauth'] = function ($app) {
$socialite = (new Socialite([
'wechat' => [
'client_id' => $app['config']['app_id'],
'client_secret' => $app['config']['secret'],
'redirect' => $this->prepareCallbackUrl($app),
],
], $app['request']))->driver('wechat');
$scopes = (array) $app['config']->get('oauth.scopes', ['snsapi_userinfo']);
if (!empty($scopes)) {
$socialite->scopes($scopes);
}
return $socialite;
};
}
/**
* Prepare the OAuth callback url for wechat.
*
* @param Container $app
*
* @return string
*/
private function prepareCallbackUrl($app)
{
$callback = $app['config']->get('oauth.callback');
if (0 === stripos($callback, 'http')) {
return $callback;
}
$baseUrl = $app['request']->getSchemeAndHttpHost();
return $baseUrl.'/'.ltrim($callback, '/');
}
}
@@ -0,0 +1,59 @@
<?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 TuzhiEasyWeChat\Channels\Order;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class DeliveryClient extends BaseClient
{
/**
* 获取快递公司列表
* 可通过该接口获取快递公司列表
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getDeliveryCompanyList()
{
$params = [];
return $this->httpPostJson('channels/ec/order/deliverycompanylist/get', $params);
}
/**
* 订单发货
* 可通过该接口对订单发货
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id
* @param $delivery_list array DeliveryInfo 是 物流信息,结构体详情请参考DeliveryInfo
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function send($order_id,$delivery_list)
{
$params = [
'order_id'=>$order_id,
'delivery_list'=>$delivery_list
];
return $this->httpPostJson('channels/ec/order/delivery/send', $params);
}
}
@@ -0,0 +1,282 @@
<?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 TuzhiEasyWeChat\Channels\Order;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class OrderClient extends BaseClient
{
/**
* 获取订单列表
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $create_time_range object TimeRange 时间范围至少填一个 订单创建时间范围,具体结构请参考TimeRange结构体
* @param $update_time_range object TimeRange 时间范围至少填一个 订单更新时间范围,具体结构请参考TimeRange结构体
* @param $status number 否 订单状态,具体枚举值请参考RequestOrderStatus枚举
* @param $openid string 否 买家身份标识
* @param $next_key string 否 分页参数,上一页请求返回
* @param $page_size number 是 每页数量(不超过100)
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getList($create_time_range=[],$update_time_range = [],$status='',$openid='',$page_size='',$next_key='')
{
$params = [
'create_time_range' => $create_time_range,
'update_time_range' => $update_time_range,
'status' => $status,
'openid' => $openid,
'page_size' => $page_size,
'next_key' => $next_key
];
return $this->httpPostJson('channels/ec/order/list/get', $params);
}
/**
* 获取订单详情
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单ID,可从获取订单列表中获得
* @param $encode_sensitive_info bool 否 用于商家提前测试订单脱敏效果,如果传true,即对订单进行脱敏,后期会默认对所有订单脱敏
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getOrder($order_id,$encode_sensitive_info='')
{
$params = [
'order_id'=>$order_id
];
if($encode_sensitive_info !== ''){
$params['encode_sensitive_info'] = $encode_sensitive_info;
}
return $this->httpPostJson('channels/ec/order/get', $params);
}
/**
* 修改订单价格
* 可通过该接口修改订单价格
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id,可通过获取订单列表接口获取
* @param $change_express bool 是 是否修改运费
* @param $express_fee number 否 修改后的运费价格(change_express=true时必填),以分为单位
* @param $change_order_infos array ChangeOrderInfo 是 改价列表,具体可见结构体ChangeOrderInfo
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function update($order_id,$change_express,$change_order_infos,$express_fee='')
{
$params = [
'order_id'=>$order_id,
'change_express'=>$change_express,
'change_order_infos'=>$change_order_infos
];
if($express_fee !== ''){
$params['express_fee'] = $express_fee;
}
return $this->httpPostJson('channels/ec/order/price/update', $params);
}
/**
* 修改订单备注
* 可通过该接口修改订单备注。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id,可通过获取订单列表接口获取
* @param $merchant_notes string 是 备注内容
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function updateMerchantnotes($order_id,$merchant_notes)
{
$params = [
'order_id' => $order_id,
'merchant_notes'=>$merchant_notes
];
return $this->httpPostJson('channels/ec/order/merchantnotes/update', $params);
}
/**
* 修改订单地址
* 可通过该接口对订单地址进行修改。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id,可通过获取订单列表接口获取
* @param $user_address object AddressInfo 是 新地址,具体可见结构体AddressInfo
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function updateAddress($order_id,$user_address)
{
$params = [
'order_id' => $order_id,
'user_address'=>$user_address
];
return $this->httpPostJson('channels/ec/order/address/update', $params);
}
/**
* 修改物流信息
* 可通过该接口修改物流信息。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id,可通过获取订单列表接口获取
* @param $delivery_list array DeliveryInfo 是 物流信息,具体可见结构体DeliveryInfo
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function updateDeliveryinfo($order_id,$delivery_list)
{
$params = [
'order_id' => $order_id,
'delivery_list'=>$delivery_list
];
return $this->httpPostJson('channels/ec/order/deliveryinfo/update', $params);
}
/**
* 解码订单包含的敏感数据
* 为保护敏感数据(如收货人昵称、电话号码、详细收货地址),平台对这些信息进行了部分隐藏。通过本接口操作订单后,可以获取到这些信息的完整数据。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id,可通过获取订单列表接口获取
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function decodeSensitiveinfo($order_id)
{
$params = [
'order_id' => $order_id
];
return $this->httpPostJson('ec/order/sensitiveinfo/decode', $params);
}
/**
* 同意用户修改收货地址申请
* 可通过该接口同意用户修改收货地址申请。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id,可通过获取订单列表接口获取
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function acceptAddressmodify($order_id)
{
$params = [
'order_id' => $order_id
];
return $this->httpPostJson('channels/ec/order/addressmodify/accept', $params);
}
/**
* 拒绝用户修改收货地址申请
* 可通过该接口拒绝买家的订单修改收货地址申请。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id,可通过获取订单列表接口获取
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function rejectAddressmodify($order_id)
{
$params = [
'order_id' => $order_id
];
return $this->httpPostJson('channels/ec/order/addressmodify/reject', $params);
}
/**
* 兑换虚拟号
* 可通过该接口兑换虚拟号
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $order_id string 是 订单id,可通过获取订单列表接口获取
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getVirtualtelnumber($order_id)
{
$params = [
'order_id' => $order_id
];
return $this->httpPostJson('channels/ec/order/virtualtelnumber/get', $params);
}
/**
* 订单搜索
* 该接口用于根据传递的条件搜索订单
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $search_condition object SearchCondition 是 搜索条件,具体结构请参考SearchCondition结构体
* @param $on_aftersale_order_exist number 否 不传该参数:搜索全部订单;
0:搜索没有正在售后的订单;
1:搜索正在售后且售后单数量>=1的订单
除了以下几种售后单状态(AfterSaleStatus)外其它的都是正在售后的状态:
USER_CANCELD
MERCHANT_REFUND_RETRY_FAIL
MERCHANT_FAIL
MERCHANT_REFUND_SUCCESS
MERCHANT_RETURN_SUCCESS
* @param $status number 否 订单状态,枚举值见RequestOrderStatus
* @param $next_key string 是 分页参数,上一页请求返回
* @param $page_size number 是 每页数量(不超过100)
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function search($search_condition,$page_size,$next_key,$status = '',$on_aftersale_order_exist = '')
{
$params = [
'search_condition' => $search_condition,
'page_size' => $page_size,
'next_key' => $next_key
];
if($status !== ''){
$params['status'] = $status;
}
if($on_aftersale_order_exist !== ''){
$params['on_aftersale_order_exist'] = $on_aftersale_order_exist;
}
return $this->httpPostJson('channels/ec/order/search', $params);
}
}
@@ -0,0 +1,37 @@
<?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 TuzhiEasyWeChat\Channels\Order;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['order'] = function ($app) {
return new OrderClient($app);
};
$app['delivery'] = function ($app) {
return new DeliveryClient($app);
};
}
}
@@ -0,0 +1,230 @@
<?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 TuzhiEasyWeChat\Channels\Product;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class Client extends BaseClient
{
/**
* 获取商品列表
*
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
*
* @param $status 商品状态,不填默认拉全部商品(不包含回收站),具体枚举值请参考
* @param $pageSize 每页数量(默认10,不超过30)
* @param $nextKey 由上次请求返回,记录翻页的上下文。传入时会从上次返回的结果往后翻一页,不传默认获取第一页数据。
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getList($pageSize=10,$nextKey = '',$status = '')
{
$params = [
'page_size' => $pageSize
];
if($nextKey){
$params['next_key'] = $nextKey;
}
if($nextKey){
$params['status'] = $status;
}
return $this->httpPostJson('channels/ec/product/list/get', $params);
}
/**
* 添加商品
* 通过该接口可对商品添加进视频号小店
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function add($params)
{
return $this->httpPostJson('channels/ec/product/add', $params);
}
/**
* 更新商品
* 该接口用于对视频号小店内商品信息的更新
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function update($params)
{
return $this->httpPostJson('channels/ec/product/update', $params);
}
/**
* 删除商品
* 可通过该接口删除视频号小店商品(审核中的商品无法删除)
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function del($product_id)
{
$params = [
'product_id' => $product_id
];
return $this->httpPostJson('channels/ec/product/delete', $params);
}
/**
* 获取商品
* 可通过指定商品ID获取商品具体信息
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @data_type 默认取1
1:获取线上数据
2:获取草稿数据
3:同时获取线上和草稿数据(注意:上架过的商品才有线上数据)
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function detail($product_id,$data_type=1)
{
$params = [
'product_id' => $product_id,
'data_type'=>$data_type
];
return $this->httpPostJson('channels/ec/product/get', $params);
}
/**
* 上架商品
* 通过该接口可将商品上架到视频号小店
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function listing($product_id)
{
$params = [
'product_id' => $product_id
];
return $this->httpPostJson('channels/ec/product/listing', $params);
}
/**
* 下架商品
* 可通过该接口将商品从视频号小店下架
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function delisting($product_id)
{
$params = [
'product_id' => $product_id
];
return $this->httpPostJson('channels/ec/product/delisting', $params);
}
/**
* 下架商撤回商品审核
* 该接口用于撤销视频号小店商品审核申请,将商品状态从审核中改为未审核
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function cancel($product_id)
{
$params = [
'product_id' => $product_id
];
return $this->httpPostJson('channels/ec/product/audit/cancel', $params);
}
/**
* 获取商品二维码
* 通过该接口可以获取视频号小店的商品二维码
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getqrcode($product_id)
{
$params = [
'product_id' => $product_id
];
return $this->httpPostJson('channels/ec/product/qrcode/get', $params);
}
/**
* 获取商品口令
* 通过该接口可以获取视频号小店的商品微信口令
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getTaglink($product_id)
{
$params = [
'product_id' => $product_id
];
return $this->httpPostJson('channels/ec/product/taglink/get', $params);
}
/**
* 获取商品H5短链
* 通过该接口可以获取视频号小店的商品H5短链
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getH5url($product_id)
{
$params = [
'product_id' => $product_id
];
return $this->httpPostJson('channels/ec/product/h5url/get', $params);
}
}
@@ -0,0 +1,37 @@
<?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 TuzhiEasyWeChat\Channels\Product;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['product'] = function ($app) {
return new Client($app);
};
$app['stock'] = function ($app) {
return new StockClient($app);
};
}
}
@@ -0,0 +1,130 @@
<?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 TuzhiEasyWeChat\Channels\Product;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class StockClient extends BaseClient
{
/**
* 获取库存流水
* 通过该接口可以获取视频号小店的商品库存流水
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @param $product_id string(uint64) 是 内部商品ID
* @param $sku_id string(uint64) 是 内部sku_id
* @param $stock_type number 是 库存类型,参考StockType枚举值 0 自营库存;1 达人库存
* @param $finder_id string 否 达人的视频号finder_id,若StockType=1则必填
* @param $begin_time number 是 时间范围开始时间戳,秒级
* @param $end_time number 是 时间范围结束时间戳,秒级
* @param $op_type_list array[number] 否 库存事件类型,参考StockFlowOpType枚举值,填空获取全部
* @param $page_size number 是 每页数量
* @param $next_key string 否 由上次请求返回,记录翻页的上下文。传入时会从上次返回的结果往后翻一页,不传默认获取第一页数据。
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getflow($product_id,$sku_id,$stock_type,$finder_id,$begin_time,$end_time,$op_type_list,$page_size,$next_key)
{
$params = [
'product_id' => $product_id,
'sku_id' => $sku_id,
'stock_type' => $stock_type,
'finder_id' => $finder_id,
'begin_time' => $begin_time,
'end_time' => $end_time,
'op_type_list' => $op_type_list,
'page_size' => $page_size,
'next_key' => $next_key
];
if($next_key){
$params['next_key'] = $next_key;
}
if($finder_id){
$params['finder_id'] = $finder_id;
}
return $this->httpPostJson('channels/ec/product/stock/getflow', $params);
}
/**
* 批量获取库存信息
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @param $product_id[] string(uint64) array 是 商品ID列表,上限为50
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function batchget($product_id)
{
$params = [
'product_id' => $product_id
];
return $this->httpPostJson('channels/ec/product/stock/batchget', $params);
}
/**
* 快速更新库存
* 可通过该接口快速更新视频号小店商品的库存
* 仅对商品草稿状态为非审核中(edit_status != 2 )的商品适用,本地生活商品不受此规则约束
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id string(uint64) 是 内部商品ID
* @param $sku_id string(uint64) 是 内部sku_id
* @param $diff_type number 是 修改类型。1: 增加;2:减少;3:设置。建议使用1或2,不建议使用3,因为使用3在高并发场景可能会出现预期外表现
* @param $num number 是 增加、减少或者设置的库存值。
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function updateStock($product_id,$sku_id,$diff_type,$num)
{
$params = [
'product_id' => $product_id,
'sku_id' => $sku_id,
'diff_type' => intval($diff_type),
'num' => intval($num)
];
return $this->httpPostJson('channels/ec/product/stock/update', $params);
}
/**
* 获取库存
* 通过该接口可以获取视频号小店的商品库存信息
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id string(uint64) 是 内部商品ID
* @param $sku_id string(uint64) 是 内部sku_id
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getStock($product_id,$sku_id)
{
$params = [
'product_id' => $product_id,
'sku_id' => $sku_id
];
return $this->httpPostJson('channels/ec/product/stock/get', $params);
}
}
@@ -0,0 +1,45 @@
<?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 TuzhiEasyWeChat\Channels\Server;
use TuzhiEasyWeChat\Kernel\ServerGuard;
use TuzhiEasyWeChat\Kernel\Encryptor;
/**
* Class Guard.
*
* @author overtrue <i@overtrue.me>
*/
class Guard extends ServerGuard
{
protected function shouldReturnRawResponse(): bool
{
return !is_null($this->app['request']->get('echostr'));
}
/**
* @return mixed
*
* @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
*/
protected function decryptMessage(array $message)
{
$encryptor = new Encryptor($this->app['config']->get('app_id'), $this->app['config']->get('token'), $this->app['config']->get('aes_key'));
return $message = $encryptor->decrypt(
$message['Encrypt'],
$this->app['request']->get('msg_signature'),
$this->app['request']->get('nonce'),
$this->app['request']->get('timestamp')
);
}
}
@@ -0,0 +1,49 @@
<?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 TuzhiEasyWeChat\Channels\Server\Handlers;
use TuzhiEasyWeChat\Kernel\Contracts\EventHandlerInterface;
use TuzhiEasyWeChat\Kernel\Decorators\FinallyResult;
use TuzhiEasyWeChat\Kernel\ServiceContainer;
/**
* Class EchoStrHandler.
*
* @author overtrue <i@overtrue.me>
*/
class EchoStrHandler implements EventHandlerInterface
{
/**
* @var ServiceContainer
*/
protected $app;
/**
* EchoStrHandler constructor.
*/
public function __construct(ServiceContainer $app)
{
$this->app = $app;
}
/**
* @param mixed $payload
*
* @return FinallyResult|null
*/
public function handle($payload = null)
{
if ($str = $this->app['request']->get('echostr')) {
return new FinallyResult($str);
}
}
}
@@ -0,0 +1,46 @@
<?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 TuzhiEasyWeChat\Channels\Server;
use TuzhiEasyWeChat\Kernel\Encryptor;
use TuzhiEasyWeChat\Channels\Server\Handlers\EchoStrHandler;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author overtrue <i@overtrue.me>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
!isset($app['encryptor']) && $app['encryptor'] = function ($app) {
return new Encryptor(
$app['config']['app_id'],
$app['config']['token'],
$app['config']['aes_key']
);
};
!isset($app['server']) && $app['server'] = function ($app) {
$guard = new Guard($app);
$guard->push(new EchoStrHandler($app));
return $guard;
};
}
}
@@ -0,0 +1,254 @@
<?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 TuzhiEasyWeChat\Channels\Sharer;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class Client extends BaseClient
{
/**
* 获取绑定的分享员列表
* 该接口用于获取已绑定的分享员列表
* 店铺分享员在店铺管理页邀请;普通分享员通过邀请分享员接口邀请。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
*
* @param $page 分页参数,页数
* @param $pageSize 每页数量(默认10,不超过30)
* @param $sharer_type 分享员类型
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getSharerList($sharer_type ,$page=1,$pageSize=10)
{
$params = [
'sharer_type' => $sharer_type,
'page'=>$page
];
if($pageSize){
$params['page_size'] = $pageSize;
}
return $this->httpPostJson('channels/ec/sharer/get_sharer_list', $params);
}
/**
* 获取分享员订单列表
* 该接口用于获取分享员订单列表
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @param $page 分页参数,页数
* @param $pageSize 每页数量(默认10,不超过30)
* @param $openid string 否 分享员openid
* @param $share_scene number 否 分享场景,枚举值详情请参考ShareScene @link https://developers.weixin.qq.com/doc/channels/API/sharer/get_sharer_order_list.html#a_ShareScene
* @param $start_time number 否 订单创建开始时间
* @param $end_time number 否 订单创建结束时间
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getSharerOrderList($page=1,$pageSize=10,$openid='',$start_time=0,$end_time=0,$share_scene='')
{
$params = [
'page'=>$page
];
if($pageSize){
$params['page_size'] = $pageSize;
}
if($openid){
$params['openid'] = $openid;
}
if($share_scene){
$params['share_scene'] = $share_scene;
}
if($start_time){
$params['start_time'] = $start_time;
}
if($end_time){
$params['end_time'] = $end_time;
}
return $this->httpPostJson('channels/ec/sharer/get_sharer_order_list', $params);
}
/**
* 邀请分享员
* 可通过此接口邀请小店普通分享员
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $username 邀请的用户微信号,非必填。若填写则生成的二维码为一人一码,仅允许该微信号用户扫码绑定;若不填写则生成的二维码为多人一码,允许多人扫码绑定
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function bind($username='')
{
$params = [];
if($username){
$params['username'] = $username;
}
$data = $this->getStream('channels/ec/sharer/bind', $params);
return $data;
}
/**
* 解绑分享员
* 该接口用于解除已绑定的小店普通分享员
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $openid_list array|string 需要解绑的分享员openid列表
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function unbind($openid_list)
{
$params = [
'openid_list' => $openid_list
];
return $this->httpPostJson('channels/ec/sharer/unbind', $params);
}
/**
* 获取绑定的分享员
* 可通过该接口获取绑定的分享员
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $openid string 分享员openid(填openid与username其中一个即可)
* @param $username string 分享员微信号(填openid与username其中一个即可)
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function searchSharer($openid='',$username='')
{
$params = [
'openid' => $openid
];
if($username){
$params = [
'username'=>$username
];
}
return $this->httpPostJson('channels/ec/sharer/search_sharer', $params);
}
/**
* 获取分享员专属的商品H5短链
* 可通过该接口获取分享员专属的商品H5短链
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @param $openid string 是 分享员openid
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getSharerProductH5url($product_id,$openid)
{
$params = [
'product_id' => $product_id,
'openid'=>$openid
];
return $this->httpPostJson('channels/ec/sharer/get_sharer_product_h5url', $params);
}
/**
* 获取分享员专属的商品口令
* 可通过该接口获取分享员专属的商品口令
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @param $openid string 是 分享员openid
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getSharerProductTaglink($product_id,$openid)
{
$params = [
'product_id' => $product_id,
'openid'=>$openid
];
return $this->httpPostJson('channels/ec/sharer/get_sharer_product_taglink', $params);
}
/**
* 获取分享员专属的商品二维码
* 可通过该接口获取分享员专属的商品二维码
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id 商品ID
* @param $openid string 是 分享员openid
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getSharerProductQrcode($product_id,$openid)
{
$params = [
'product_id' => $product_id,
'openid'=>$openid
];
return $this->httpPostJson('channels/ec/sharer/get_sharer_product_qrcode', $params);
}
/**
* Get stream.
*
* @param string $endpoint
* @param array $params
* @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
*
* @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
protected function getStream(string $endpoint, array $params)
{
// 发送原始请求,获取响应
$response = $this->requestRaw($endpoint, 'POST', ['json' => $params]);
// 获取原始响应内容
$rawResponse = $response->getBody()->getContents();
// 使用正则表达式移除 qrcode_img 字段及其内容
$pattern = '/"qrcode_img":"(.*?)",/';
$modifiedResponse = preg_replace($pattern, '', $rawResponse);
// 解析修改后的 JSON 字符串
$decodedResponse = json_decode($modifiedResponse, true);
// 检查 JSON 解码错误
if (json_last_error() === JSON_ERROR_NONE) {
return $decodedResponse;
} else {
echo "Failed to decode JSON response: " . json_last_error_msg();
}
return $this->castResponseToType($response, $this->app['config']->get('response_type'));
}
}
@@ -0,0 +1,33 @@
<?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 TuzhiEasyWeChat\Channels\Sharer;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['sharer'] = function ($app) {
return new Client($app);
};
}
}
@@ -0,0 +1,131 @@
<?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 TuzhiEasyWeChat\Channels\Window;
use TuzhiEasyWeChat\Kernel\BaseClient;
use TuzhiEasyWeChat\Kernel\Exceptions\InvalidArgumentException;
/**
* Class Client.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class Client extends BaseClient
{
/**
* 获取已添加到橱窗的商品列表
* 通过该接口可获取已添加到橱窗的商品列表。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @param $appid string 否 用于指定查询某个店铺来源的商品
* @param $branch_id number 否 用于指定查询属于某个分店ID下的商品
* @param $page_size number 是 单页商品数(不超过200)
* @param $page_index number 否 页面下标,下标从1开始,默认为1
* @param $last_buffer string 否 由上次请求返回,顺序翻页时需要传入, 会从上次返回的结果往后翻一页(填了该值后page_index不生效)
* @param $need_total_num number 否 是否需要返回满足筛选条件的商品总数
*
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getList($page_size=10,$page_index='',$last_buffer='',$appid='',$branch_id = '',$need_total_num = '')
{
$params = [
'page_size' => $page_size
];
if($page_index){
$params['page_index'] = $page_index;
}
if($last_buffer){
$params['last_buffer'] = $last_buffer;
}
if($appid){
$params['appid'] = $appid;
}
if($branch_id){
$params['branch_id'] = $branch_id;
}
if($page_index){
$params['page_index'] = $page_index;
}
if($need_total_num){
$params['need_total_num'] = $need_total_num;
}
return $this->httpPostJson('channels/ec/window/product/list/get', $params);
}
/**
* 上架商品到橱窗
* 通过该接口可将商品上架到橱窗。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id string(uint64) 是 橱窗商品ID
* @param $appid string 是 商品来源店铺的appid
* @param $is_hide_for_window bool 否 是否需要在个人橱窗页隐藏 (默认为false)
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function addProduct($product_id,$appid,$is_hide_for_window=false)
{
$params = [
'product_id' => $product_id,
'appid' => $appid,
'is_hide_for_window' => $is_hide_for_window
];
return $this->httpPostJson('channels/ec/window/product/add', $params);
}
/**
* 获取橱窗商品详情
* 通过该接口可获取橱窗商品详情。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
*
* @param $product_id string(uint64) 是 橱窗商品ID
* @param $appid string 是 商品来源店铺的appid
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function getProduct($product_id,$appid)
{
$params = [
'product_id' => $product_id,
'appid' => $appid
];
return $this->httpPostJson('channels/ec/window/product/get', $params);
}
/**
* 下架橱窗商品
* 通过该接口可将橱窗商品进行下架。
* @return \Psr\Http\Message\ResponseInterface|\TuzhiEasyWeChat\Kernel\Support\Collection|array|object|string
* @param $product_id string(uint64) 是 橱窗商品ID
* @param $appid string 是 商品来源店铺的appid
* @throws \TuzhiEasyWeChat\Kernel\Exceptions\InvalidConfigException
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function offProduct($product_id,$appid)
{
$params = [
'product_id' => $product_id,
'appid'=>$appid
];
return $this->httpPostJson('channels/ec/window/product/off', $params);
}
}
@@ -0,0 +1,33 @@
<?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 TuzhiEasyWeChat\Channels\Window;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
/**
* Class ServiceProvider.
*
* @author mingyoung <mingyoungcheung@gmail.com>
*/
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['window'] = function ($app) {
return new Client($app);
};
}
}