微信小程序订单发货管理接入

订单发货管理接入指引:https://mp.weixin.qq.com/cgi-bin/announce?token=1148555877&action=getannouncement&key=11671435333v04b2&version=1&lang=zh_CN&platform=2icon-default.png?t=N7T8https://mp.weixin.qq.com/cgi-bin/announce?token=1148555877&action=getannouncement&key=11671435333v04b2&version=1&lang=zh_CN&platform=2

发货信息录入接口文档:小程序发货信息管理服务 | 微信开放文档

注意事项

  1. 根据指定的订单单号类型,采用不同参数给指定订单上传物流信息:

    (1). 商户侧单号形式(枚举值1),通过下单商户号和商户侧单号确定一笔订单

    (2). 微信支付单号形式(枚举值2),通过微信支付单号确定一笔订单

  2. 发货模式根据具体发货情况选择:

    (1). 统一发货(枚举值1),一笔订单统一发货,只有一个物流单号。

    (2). 分拆发货(枚举值2),一笔订单分拆发货,包括多个物流单号。

  3. 物流公司编码,参见获取运力 id 列表get_delivery_list。

  4. 上传时间,用于标识请求的先后顺序,如果要更新物流信息,上传时间必须比之前的请求更新,请按照 RFC 3339 格式填写。

  5. 分拆发货仅支持使用物流快递发货,一笔支付单最多分拆成 10 个包裹。

  6. 以下情况将视为重新发货,每笔支付单仅有一次重新发货机会。

    (1). 对已完成发货的支付单再次调用该 API。

    (2). 使用该 API 修改发货模式或物流模式。

<?php

namespace app\v1\controller;

use app\common\controller\Checking;
use think\Cache;
use think\Controller;
use think\Db;

/**
 * 微信发货管理
 */
class WechatShip extends Controller
{
    protected $appid;
    protected $appSecret;
    public function __construct()
    {
        $this->appid ='';
        $this->appSecret ='';
    }
    /**
     * 发货
     * @return void
     */
    public function deliver_addr()
    {
        $order_lists=$this->get_order_list(['order_state'=>1]);
        $transaction_ids=array_column($order_lists['order_list'],'transaction_id');
        $order_shipping_info=Db::name('szy_lionfish_comshop_order')
            ->alias('o')
            ->join('szy_lionfish_comshop_order_goods g','o.order_id=g.order_id','LEFT')
            ->whereIn('o.transaction_id',$transaction_ids)
            ->column('o.shipping_no,o.shipping_method,g.name','o.transaction_id');
        foreach ($order_lists['order_list'] as $k=>$v){
            $wxorder = $this->getWxSendOrderStatus($v['transaction_id']);
            if($wxorder['errcode'] != 0){
                Checking::writeLog('获取微信订单失败-'.$v['transaction_id'],'error','wxfh.log');
                continue;
            }
            if (empty($order_shipping_info[$v['transaction_id']]['shipping_no'])){
                continue;
            }
            $order_state = $wxorder['order']['order_state']; //订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款。
            if($order_state == 1){
                $data = [
                    'transaction_id'=>$wxorder['order']['transaction_id'],//微信交易单号
                    'openid'=>$wxorder['order']['openid'],//支付用户openid
                    'item_desc'=>$order_shipping_info[$v['transaction_id']]['name'],//商品名
                    'express_name'=>$order_shipping_info[$v['transaction_id']]['shipping_method'],//快递名
                    'express_no'=>$order_shipping_info[$v['transaction_id']]['shipping_no'],//快递单号
                ];
                $results = $this->sendDelivery($data,1);
                if ($results['errcode'] == 0) {
                    Checking::writeLog('发货成功-'.$v['transaction_id'],'success','wxfh.log');
                } else {
                    Checking::writeLog('发货失败-'.$v['transaction_id'],$results['errmsg'],'wxfh.log');
                }
            }

        }
       
    }

    /**
     * 获取token
     * @return mixed
     */
    public function getAccessToken(){
        $appId = $this->appid;
        $appSecret = $this->appSecret;
        $cacheKey = $appId . '@access_token';
        if (!Cache::get($cacheKey)) {
            // 请求API获取 access_token
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
            $result = Checking::GetHttp($url);
            $data = json_decode($result, true);
            // return $data['access_token'];
            // 写入缓存
            Cache::set($cacheKey, $data['access_token'], 7200);    // 7000
        }
        return Cache::get($cacheKey);
    }

    /**
     * 快递公司
     */
    public function get_delivery_list()
    {
        $token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/express/delivery/open_msg/get_delivery_list?access_token=" . $token;
//        $data = json_encode([], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $result = Checking::request_post_json($url, '{}');
        $result = json_decode($result[1], true);

        return $result;
    }

    /**
     * 获取订单列表
     */
    public function get_order_list($data)
    {
//        $data = [
//            'pay_time_range' => [
//                'begin_time'=>1719714996,//起始时间,时间戳形式,不填则视为从0开始
//                'end_time'=>time()//结束时间(含),时间戳形式,不填则视为32位无符号整型的最大值
//            ],
//            'order_state'=>1,//订单状态枚举:(1) 待发货;(2) 已发货;(3) 确认收货;(4) 交易完成;(5) 已退款
            'openid'=>'',//支付者openid
            'last_index'=>'',//翻页时使用,获取第一页时不用传入,如果查询结果中 has_more 字段为 true,则传入该次查询结果中返回的 last_index 字段可获取下一页
            'page_size'=>''//翻页时使用,返回列表的长度,默认为100
//
//        ];
        $token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/wxa/sec/order/get_order_list?access_token=" . $token;
        $data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $result = Checking::request_post_json($url, $data);
        $result = json_decode($result[1], true);

        return $result;
    }

    /**
     * 获取发货订单信息
     * @param $transaction_id
     * @return mixed
     */
    public function getWxSendOrderStatus($transaction_id)
    {
        $token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/wxa/sec/order/get_order?access_token=" . $token;
        $data = [
            'transaction_id' => $transaction_id
        ];
        $data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $result = Checking::request_post_json($url, $data);
        $result = json_decode($result[1], true);

        return $result;
    }
    /**
     * 设置微信发货后,消息跳转地址,不设置为默认
     * @return void
     */
    public function set_jump_path()
    {
        $token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/wxa/sec/order/set_msg_jump_path?access_token=" . $token;
        $data = [
            'path' => 'comshop/pages/order/index?conmen=3', //待收货订单列表页面
        ];
        $data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        Checking::request_post_json($url, $data);

    }
    //发货 物流15天自动确认,虚拟商品隔天自动确认
    public function sendDelivery($order, $logistics_type=3)
    {
        $this->set_jump_path();

        $token = $this->getAccessToken();

        $express_name = "";
        $express_no = "";
        if ($logistics_type == 1) {
            $express_name = $order['express_name'];
            $express_no = $order['express_no'];
        }

        $data = [
            'order_key' => [
                'order_number_type' => 2,   //订单单号类型,用于确认需要上传详情的订单。枚举值1,使用下单商户号和商户侧单号;枚举值2,使用微信支付单号。
                'transaction_id' => $order['transaction_id']
            ],
            'logistics_type' => $logistics_type,//物流模式,发货方式枚举值:1、实体物流配送采用快递公司进行实体物流配送形式 2、同城配送 3、虚拟商品,虚拟商品,例如话费充值,点卡等,无实体配送形式 4、用户自提
            'delivery_mode' => 1,   //发货模式,发货模式枚举值:1、UNIFIED_DELIVERY(统一发货)2、SPLIT_DELIVERY(分拆发货) 示例值: UNIFIED_DELIVERY
            'shipping_list' => [
                [
                    'tracking_no' => $express_no,
                    'express_company' => $express_name,
                    'item_desc' => $order['item_desc'] ?? "订单发货信息"
                ]
            ],
            'upload_time' => date('Y-m-d\TH:i:sP', time()),
            'payer' => [
                'openid' => $order['openid']
            ]
        ];

        $urlss = "https://api.weixin.qq.com/wxa/sec/order/upload_shipping_info?access_token=" . $token;
        $data = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        $results = Checking::request_post_json($urlss, $data);

        $results = json_decode($results[1], true);
        return $results;

    }

}
    /**
     * get
     * @param string $url 请求地址
     */
    public static function GetHttp($url){
        // 关闭句柄
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
        // 设置Accept头部字段
        curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json'));
        // 设置User-Agent头部字段
        curl_setopt($curl, CURLOPT_USERAGENT, 'My User Agent String');
        $tmpInfo = curl_exec($curl); //返回api的json对象
        if(curl_exec($curl) === false)
        {
            return 'Curl error: ' . curl_error($curl);
        }
        //关闭URL请求
        curl_close($curl);
        return $tmpInfo; //返回json对象
    }
    /**
     * 模拟post进行url请求
     * @param string $url
     * @param string $data_string
     */
        public static function request_post_json($url, $data_string) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                "Content-Type: application/json; charset=utf-8",
                "Content-Length: " . strlen($data_string))
        );
        ob_start();
        curl_exec($ch);
        $return_content = ob_get_contents();
        ob_end_clean();
        $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        return array($return_code, $return_content);

    }

    //请确保项目文件有可写权限,不然打印不了日志。
    public static function writeLog( $text, $message = '', $name = "log.txt" )
    {
        file_put_contents( $name, date( "Y-m-d H:i:s" ) . "  " . $text . '-----' . $message . "\r\n", FILE_APPEND );
    }

小程序端

   wx.openBusinessView({
      businessType: 'weappOrderConfirm',
      extraData: {
        merchant_id: '',//商户id
        // merchant_trade_no: '1234323JKHDFE1243252',
        // transaction_id: '4200002336202407032185573612'
        transaction_id:that.data.order.order_info.transaction_id//微信交易单号
      },
      success(res) {
      console.log('调起确认收货');
      console.log(res)
      if(res.extraData.status=="success"){
        app.util.request({
          'url': 'entry/wxapp/index',
          'data': {
            controller: 'order.receive_order',
            token: token,
            order_id: id
          },
          dataType: 'json',
          success: function(res) {
            if (res.data.code == 0) {
              wx.showToast({
                title: '收货成功',
                icon: 'success',
                duration: 1000
              })
       
              that.reload_data();
            } else {
              app.util.message(res.data.msg||'收货失败', '', 'error');
            }
          }
        });
      }
        //dosomething
      },
      fail(res) {
        //dosomething
        console.log(that.data.order.order_info.transaction_id)
        console.log(res)
      },
      complete() {
        //dosomething
      }
    }); 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/769453.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上海小程序开发需要进行定制开发吗?

随着互联网技术与移动设备的不断成熟&#xff0c;小程序也已普及到人们日常生活的方方面面。随着企业与互联网联结的愈发深入&#xff0c;小程序的开发可以为企业带来更高效的经营模式&#xff0c;降本增效。那么&#xff0c;上海小程序作为无需安装且开发门槛较低的应用&#…

VulnHub靶场之DarkHole_1

1 信息收集 1.1 主机发现 arp-scan -l 主机IP地址为&#xff1a;192.168.1.17 1.2 端口和服务扫描 nmap -sS -sV -A -T5 -p- 192.168.1.17 开放22&#xff0c;80端口 1.3 目录扫描 dirsearch -u 192.168.1.17 2 渗透 2.1 访问端口 2.2 注册账号 暴力破解不现实&#…

网口串口(Serialport)服务器

文章所用工具http://t.csdnimg.cn/2gIR8http://t.csdnimg.cn/2gIR8 搭建服务器界面 操作配置文件保存方式类 public string FileName { get; set; }public IniHelper(string name) {this.FileName name; //在构造函数中给路径赋值} 1 先导入c语言进行读取操作ini文件的方法 …

理解Netty的核心概念

一、理解Netty Netty是一个用于开发高性能网络应用的框架。为了更容易理解它&#xff0c;下面一些描述&#xff0c;不一定准确&#xff0c;但一定容易理解。 从Netty的Channel开始&#xff0c;把Netty所有的核心概念都串起来。 Channel 简单理解为一个连接。 有一个特殊的C…

python使用pywebview集成vue3和element-plus开发桌面系统框架

随着web技术越来越成熟&#xff0c;就连QQ的windows客户端都用web技术来开发&#xff0c;所以在未来&#xff0c;web技术来开发windows桌面软件也会越来越多&#xff0c;所以在此发展驱动之下&#xff0c;将最近流程的python与web技术相结合&#xff0c;使用vue3和element-plus…

使用requests爬取拉勾网python职位数据

爬虫目的 本文是想通过爬取拉勾网Python相关岗位数据&#xff0c;简单梳理Requests和xpath的使用方法。 代码部分并没有做封装&#xff0c;数据请求也比较简单&#xff0c;所以该项目只是为了熟悉requests爬虫的基本原理&#xff0c;无法用于稳定的爬虫项目。 爬虫工具 这次…

Linux中为什么etc是存放配置文件

在计算机系统中&#xff0c;/etc 是一个目录的名称&#xff0c;通常位于Unix和类Unix操作系统中&#xff0c;如Linux。这个目录用于存放系统配置文件。/etc 的命名来源于早期Unix系统中的 "etcetera"&#xff08;拉丁语 "et cetera" 的缩写&#xff0c;意为…

电子工程与网络技术解析

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;日常聊聊 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 正文 1、MUX&PD是什么意思 2、Hub 和HUB有什么区别 3、Redriver什么意思 4、Switch是什么意思 5、USB 2.0 ETHERNET2什么意思 6、…

[译]全栈Redux实战

本文乱译自一篇英文博文&#xff08;Full-Stack Redux Tutorial&#xff09;&#xff0c;本人英语能力不足&#xff0c;技术能力有限&#xff0c;如有错误&#xff0c;多多包涵。 #关于ReduxReactImmutable的测试先行开发综合指南 Redux是最近发生在js界令人兴奋的事儿。它把…

Vue+Xterm.js+WebSocket+JSch实现Web Shell终端

一、需求 在系统中使用Web Shell连接集群的登录节点 二、实现 前端使用Vue&#xff0c;WebSocket实现前后端通信&#xff0c;后端使用JSch ssh通讯包。 1. 前端核心代码 <template><div class"shell-container"><div id"shell"/>&l…

Unity动画系统(2)

6.1 动画系统基础2-3_哔哩哔哩_bilibili p316 模型添加Animator组件 动画控制器 AnimatorController AnimatorController 可以通过代码控制动画速度 建立动画间的联系 bool值的设定 trigger p318 trigger点击的时候触发&#xff0c;如喊叫&#xff0c;开枪及换子弹等&#x…

css flex 子元素溢出时,父元素被撑开解决方案

当父元素使用flex: 1;自适应填满时&#xff0c;子元素内容溢出&#xff0c;父元素内容撑大&#xff0c;导致页面显示问题&#xff0c;或设置了overflow 为scroll 的元素没出现滚动条等问题 解决方案&#xff1a; 1.如果是横向排列&#xff0c;flex: 1;的元素加上width: 0; 此…

【PB案例学习笔记】-28制作一个右键菜单

写在前面 这是PB案例学习笔记系列文章的第28篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…

流量控制组件选型之 Sentinel vs Hystrix

Sentinel: Sentinel 是阿里中间件团队研发的面向分布式服务架构的轻量级高可用流量控制组件&#xff0c;于2018年7月正式开源。Sentinel 主要以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度来帮助用户提升服务的稳定性。大家可能会问&#xff1a;Sen…

总线局域网及解决冲突的方案

上文内容&#xff1a;局域网 1.什么是总线局域网 总线网结构&#xff1a; 所有的结点通过专门的网卡附接到一条总线上&#xff1b; 所有结点的信息都发送到同一条总线上&#xff08;冲突&#xff09;&#xff1b; 所有结点都从同一媒体上收取信息&#xff08;广播&am…

视频汇聚/安防监控/GB28181国标EasyCVR视频综合管理平台出现串流的原因排查及解决

安防视频监控系统/视频汇聚EasyCVR视频综合管理平台&#xff0c;采用了开放式的网络结构&#xff0c;能在复杂的网络环境中&#xff08;专网、局域网、广域网、VPN、公网等&#xff09;将前端海量的设备进行统一集中接入与视频汇聚管理&#xff0c;视频汇聚EasyCVR平台支持设备…

Stable Diffusion web UI 插件

2024.7.3更新&#xff0c;持续更新中 如果需要在linux上自己安装sd&#xff0c;参考&#xff1a;stable diffusion linux安装 插件复制到 /stable-diffusion-webui/extensions 目录下&#xff0c;然后重新启动sd即可 一、插件安装方法 每种插件的安装方法可能略有不同&#xf…

Redis分布式锁的应用场景有哪些

⼀ 、应⽤场景 在多线程并发的场景下 &#xff0c;Java Synchronized/Reentrantlock 锁能够实现同⼀个JVM进程内多线程 并发的安全性 &#xff0c;但⽆法保证多个JVM进程实例构成的集群环境在多线程下的安全性。在⼀些业务场景 下需要引⼊分布式锁。 1、缓存击穿 当某个热点缓…

精确计算应用的冷启动耗时

在iOS项目中&#xff0c;冷启动时间是指从用户点击应用图标开始&#xff0c;到应用完全加载并呈现出第一个界面&#xff08;可能需要网络请求必要的数据&#xff09;所花费的时间。这里以 main 函数为界&#xff0c;分为两个时间段&#xff1a; 从用户点击应用图标 ~ invoke m…

深度学习简介-AI(三)

深度学习简介 深度学习简介深度学习例子深度学习训练优化1.随机初始化2.优化损失函数3.优化器选择4.选择/调整模型结构 深度学习常见概念隐含层/中间层随机初始化损失函数导数与梯度优化器Mini Batch/epoch 深度学习训练逻辑图 深度学习简介 深度学习例子 猜数字 A: 我现在心…