PHP 调用拼多多 API 获取返利商品信息

文章目录

    拼多多官方只提供了 Java SDK 的实现,并没有 PHP 的实现;github 上倒是有一个不错的 PHP 实现,可惜是 composer 的实现。。。

    我已经厌倦了 composer 的搞法,特别是在低配服务器上,运行 composer 就直接服务器 CPU 100%,除非强制重启。Composer 已经可以跟 NPM PK 谁的实现更糟糕了。

    所以,我决定参考

    https://github.com/justmd5/pinduoduo-sdk/blob/master/src/Api.php

    实现一个简单的调用封装就行。

    拼多多返利小程序演示

    我实用拼多多 API 拉取商品之后,保存到后台数据库,然后在小程序中进行展示。效果如下:

    跳转到拼多多微信小程序

    必要的参数

    curl -X POST 'http://host:port/api/router' \
    -H 'Content-Type:application/x-www-form-urlencoded;charset=utf-8' \
    -d access_token=your+access+token \
    -d data_type=JSON \
    -d sign=your+sign \
    -d goods_id_list=%5B0%5D \
    -d type=pdd.ddk.goods.basic.info.get \
    -d client_id=your+client+id \
    -d timestamp=1527065024
    

    没有 client_id 是不行的。

    > curl -X POST 'https://gw-api.pinduoduo.com/api/router' \
                              -H 'Content-Type:application/x-www-form-urlencoded;charset=utf-8' \
                              -d data_type=JSON \
                              -d goods_id_list=7717242955 \
                              -d type=pdd.ddk.goods.basic.info.get \
                              -d timestamp=1527065024
    {"error_response":{"error_msg":"公共参数错误:client_id","sub_msg":"公共参数错误:client_id","sub_code":"10001","error_code":10001,"request_id":"15662904541836054"}}
    

    access_token

    access_token 为非必填项。

    由于我调用的都是返利相关的无需授权的接口,所以不需要 access_token 的支持。

    URL

    https://gw-api.pinduoduo.com/api/router

    sign 签名的生成算法

    无需授权的接口,access_token 不参与 sign 的签名生成。

    签名算法参考官方文档

    https://open.pinduoduo.com/#/document?title=API%25E8%25B0%2583%25E7%2594%25A8%25E8%25AF%25A6%25E8%25A7%25A3

    PHP Laravel 实现代码

    <?php
    
    namespace App\Http\Controllers;
    
    use Illuminate\Http\Request;
    use GuzzleHttp\Client;
    use Log;
    
    class RebateProductController extends Controller
    {
        public function fetch_pdd_product(Request $request) {
            $rsp = ['err_code' => 0, 'err_msg' => 'OK',];
    
            $params = [
                "goods_id_list" => '[7717242955]',
            ];
            $data = $this->request('pdd.ddk.goods.basic.info.get', $params);
            $rsp['data'] = json_decode($data);
            return response()->json($rsp);
        }
    
        private function signature($params) {
            ksort($params);		// 按照键名对关联数组进行升序排序
            $paramsStr = '';
            array_walk($params, function ($item, $key) use (&$paramsStr) {
                $paramsStr .= sprintf('%s%s', $key, $item);
            });
    
            $sign = strtoupper(md5(sprintf('%s%s%s',
                env('PDD_CLIENT_SECRET'),
                $paramsStr,
                env('PDD_CLIENT_SECRET')
            )));
    
            return $sign;
        }
    
        public function request($method, $params, $data_type = 'JSON') {
            $params['client_id'] = env('PDD_CLIENT_ID');
            $params['sign_method'] = 'md5';
            $params['type'] = $method;
            $params['data_type'] = $data_type;
            $params['timestamp'] = strval(time());
            $params['sign'] = $this->signature($params);
    
            $client = new Client();
            $url = 'https://gw-api.pinduoduo.com/api/router';
            try {
                $res = $client->request('POST', $url, [
                    'form_params' => $params,
                    'timeout' => 1.5,
                ]);
                $res = $res->getBody();
                return $res;
            } catch(\Throwable $e) {
                Log::info('Fail to call api');
            }
        }
    }
    

    接口返回格式

    {
      "goods_basic_detail_response": {
        "goods_list": [
          {
            "goods_name": "灭蚊灯家用卧室办公室内插电式静音无辐射孕妇婴儿捕蚊子驱蚊神器",
            "min_normal_price": 19800,
            "goods_pic": "http://t00img.yangkeduo.com/goods/images/2019-04-22/1efd46aabf312e608829d93f671c774e.jpeg",
            "goods_id": 7717242955,
            "goods_type": 1,
            "min_group_price": 1250
          }
        ],
        "request_id": "15663701900781196"
      }
    }
    

    参数错误:goods_id_list

    {
      "error_response": {
        "error_msg": "参数错误:goods_id_list",
        "sub_msg": "",
        "sub_code": null,
        "error_code": 10000,
        "request_id": "15663063278197129"
      }
    }
    

    这个接口的实现太愚蠢了,需要自己拼成字符串。。。

    "goods_id_list" => '[7717242955]'
    

    商品非多多进宝商品

    并不是所有的商品都有返利,所以需要处理非多多进宝商品的情况

    {"error_response":{"error_msg":"商品非多多进宝商品","sub_msg":"商品非多多进宝商品","sub_code":"2","error_code":50001,"request_id":"15666152026784344"}}
    

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式