xzz2021
Published on 2025-08-01 / 1 Visits
0
0

顺丰下单及云打印接口对接(js版)

顺丰开放平台注册账号并认证, 新建开发者应用,选择相应接口分类, 关联API, 选择需要开发的接口;所有接口需进行沙箱测试, 成功3次后才可以上线生产. 参考文章

下单接口

  1. 下单详细说明文档

  2. 数据构造/格式转换/数字签名认证

    import { v4 as uuidv4 } from 'uuid';
    import crypto from 'crypto'; 
    sign(msgDataStr: string, timestamp: number): string {
        const text = msgDataStr + timestamp + this.checkWord;
        const toVerifyText = encodeURIComponent(text).replace(/%20/g, '+');
        const md5 = crypto.createHash('md5').update(toVerifyText,'utf8').digest().toString('base64');
        return md5;
      }
    
    generateBaseData(msgData: object) {
        const timestamp = Date.now();
        const uuid = uuidv4();
        const msgDataStr = JSON.stringify(msgData);
        const msgDigest = this.sign(msgDataStr, timestamp);
        const baseData =  {
          partnerID: 'GVHUF78678G', // 客户编号
          serviceCode: 'EXP_RECE_CREATE_ORDER',  // 业务类型
          timestamp: timestamp.toString(),
          requestID: uuid,
          msgData: msgDataStr,
          msgDigest,
        };
        const body = new URLSearchParams(baseData).toString()
        return body
      }
    
  3. 请求下单

     async createOrder(msgData: object): Promise<any> {
         const createOrderUrl = this.isSbox ? 'https://sfapi-sbox.sf-express.com/std/service' : 'https://bspgw.sf-express.com/std/service';
         const body = generateBaseData(data)
            const res = await fetch(createOrderUrl, {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' },
          body,
        });
        if (!res.ok) {
          throw new Error(`HTTP error! Status: ${res.status}`);
        }
        return await res.json();
    }
    //  createOrder响应数据在apiResultData中, 需要JSON parse
    //  快递单号在JSON.parse(apiResultData)?.msgData?.waybillNoInfoList[0]?.waybillNo
    
  4. OAuth2认证说明, 注意沙箱用沙箱token和订单号,生产用生产token和订单号

     async getOAuth2Token() {
        const url = this.isSbox ? 'https://sfapi-sbox.sf-express.com/oauth2/accessToken' : 'https://sfapi.sf-express.com/oauth2/accessToken';
        const body = new URLSearchParams({
          partnerID:  'GVHUF78678G', // 客户编号
          secret: 'checkWordsdgds345',  // 校验码
          grantType: 'password',  // 固定字符
        });
        const res = await fetch(url, {
          method: 'POST',
          headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' },
          body,
        });
        if (!res.ok) {
          throw new Error(`HTTP error! Status: ${res.status}`);
        }
        const { accessToken } = await res.json();
        if (!accessToken) {
          throw new Error('获取accessToken失败');
        }
        return accessToken;
      }
    
    

打印接口

  1. 云打印面单打印插件接口, 前置条件: 打印机连接电脑,装好驱动, 安装顺丰云打印插件, 前端SDK包, 右键保存不然会有编码问题, (官方文档)

  2. 此api是直接在前端使用SDK发起

    //  SCPPrint函数来自SDK包,貌似挂载在全局window上
    const sfPrint = new SCPPrint({ partnerID: 'DYJ4554YUI6Z3', 
                   // env: 'sbox'
         })
    const accessToken = await getOAuth2Token() // 向后端请求token
    const requestID = uuidv4()
      sfPrint.print(
        {
          requestID,
          accessToken,
          templateCode: 'fm_76130_standard_DYJ4554YUI6Z3', // 类似:fm_76130_standard_{partnerId}
          documents: [
            {
              masterWaybillNo: 'SF7444497906873'  // 要打印的顺丰单号
            }
          ]
        },
        (res) => {   // 回调函数
          console.log('🚀 ~ xzz: testPrint ~ res', res)
        }
      )
    
  3. 实现原理(初步理解): sdk携带token发起请求给顺丰官方接口, 接口核对身份信息,查找到当前订单信息返回给sdk, 电脑安装的云打印插件有建立websocket通信,默认8000端口,sdk将待打印信息发送给ws,从而实现打印.


Comment