[PHP+JS]微信卡券(潦草筆記,全代碼,親測經過)

羣髮卡券能夠經過客服消息推送javascript

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547html

 

後端代碼:前端

define('APPID', 'xxxxxxxxxxxxxxxx');
define('SECRET', 'xxxxxxxxxxxxxxxx');
$publicToken = null;

if($do == 'test') {
    set_time_limit(0);
    $openId = 'xxxxxxxxxxxxxxxx';

    //$account = account_fetch($_W['acid']);
    //$account['key'], $account['secret']

    echo '<pre>';
    $publicToken = WxPublic_AccessToken(APPID, SECRET);
    echo 'AccessToken' . PHP_EOL;
    print_r($publicToken);

    if($publicToken != null && $publicToken['expires_datetime'] >= time()) {
        // 建立前獲取公衆號的所有卡券
        $result = WxPublic_Card_BatchGet($publicToken['access_token']);
        echo 'BatchGet' . PHP_EOL;
        print_r($result);
        if($result['errcode'] == '0') {
            $cardIdList = $result['card_id_list'];

            $codes = array();
            for($i = 1; $i <= 5; $i++) {
                $codes[] = strval(10000 + $i);
            }
            foreach($cardIdList as $cardId) {
                $result = WxPublic_Card_Get($publicToken['access_token'], $cardId);
                echo 'Get' . PHP_EOL;
                print_r($result);

                $result = WxPublic_Card_CheckCode($publicToken['access_token'], $cardId, $codes);
                echo 'CheckCode' . PHP_EOL;
                print_r($result);
            }

            $result = WxPublic_Card_CardInfo($publicToken['access_token'], date('Y-m-d', strtotime('-62 day')), date('Y-m-d', strtotime('-1 day')), 0);
            echo 'CardInfo-0' . PHP_EOL;
            print_r($result);

            $result = WxPublic_Card_CardInfo($publicToken['access_token'], date('Y-m-d', strtotime('-62 day')), date('Y-m-d', strtotime('-1 day')), 1);
            echo 'CardInfo-1' . PHP_EOL;
            print_r($result);
        }

    /*
        // ========================================

        $aPath = realpath(dirname(__FILE__) . './test.jpg');
        $cardImage = WxPublic_Card_Uploadimg($publicToken['access_token'], $aPath);
        //if($cardImage !== null && isset($cardImage['url'])) {
            echo 'Uploadimg' . PHP_EOL;
            print_r($cardImage);
        //}

        // ========================================


        // 使用GET_CUSTOM_CODE_MODE_DEPOSIT模式建立卡券
        // 用法參考:https://blog.csdn.net/u011738153/article/details/50457167
        // 1.quantity初始值設置爲0,設置use_custom_code=true,get_custom_code_mode='GET_CUSTOM_CODE_MODE_DEPOSIT'
        // 2.審覈後添加code
        // 3.修改庫存,<= code數量
        $card = WxPublic_Card_Create_Groupon(
            $publicToken['access_token'],
            'http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0',
            '微信餐廳',
            '132元雙人火鍋套餐',
            '020-88888888',
            '不可與其餘優惠同享\r\n如需團購券發票,請在消費時向商戶提出\r\n店內都可使用,僅限堂食',
            date('Y-m-d', strtotime('-1 day')),
            date('Y-m-d', strtotime('+1 year')),
            '如下鍋底2選1(有菌王鍋、麻辣鍋、大骨鍋、番茄鍋、清補 涼鍋、酸菜魚鍋可選):\n大鍋1份 12元\n小鍋2份 16元',
            2
        );
        // $card = WxPublic_Card_Create_Cash(
        //     $publicToken['access_token'],
        //     'http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0',
        //     '微信餐廳',
        //     '020-88888888',
        //     '不可與其餘優惠同享\r\n如需團購券發票,請在消費時向商戶提出\r\n店內都可使用,僅限堂食',
        //     date('Y-m-d', strtotime('-1 day')),
        //     date('Y-m-d', strtotime('+1 year')),
        //     1000,
        //     10000,
        //     2
        // );
        // $card = WxPublic_Card_Create_Discount(
        //     $publicToken['access_token'],
        //     'http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0',
        //     '微信餐廳',
        //     '132元雙人火鍋套餐',
        //     '020-88888888',
        //     '不可與其餘優惠同享\r\n如需團購券發票,請在消費時向商戶提出\r\n店內都可使用,僅限堂食',
        //     date('Y-m-d', strtotime('-1 day')),
        //     date('Y-m-d', strtotime('+1 year')),
        //     30,
        //     2
        // );
        // $card = WxPublic_Card_Create_Gift(
        //     $publicToken['access_token'],
        //     'http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0',
        //     '微信餐廳',
        //     '132元雙人火鍋套餐',
        //     '020-88888888',
        //     '不可與其餘優惠同享\r\n如需團購券發票,請在消費時向商戶提出\r\n店內都可使用,僅限堂食',
        //     date('Y-m-d', strtotime('-1 day')),
        //     date('Y-m-d', strtotime('+1 year')),
        //     '可兌換音樂木盒一個',
        //     2
        // );
        // $card = WxPublic_Card_Create_GeneralCoupon(
        //     $publicToken['access_token'],
        //     'http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0',
        //     '微信餐廳',
        //     '132元雙人火鍋套餐',
        //     '020-88888888',
        //     '不可與其餘優惠同享\r\n如需團購券發票,請在消費時向商戶提出\r\n店內都可使用,僅限堂食',
        //     date('Y-m-d', strtotime('-1 day')),
        //     date('Y-m-d', strtotime('+1 year')),
        //     '優惠券專用,填寫優惠詳情',
        //     2
        // );

        echo 'Create' . PHP_EOL;
        print_r($card);
        if($card['errcode'] == '0' && isset($card['card_id'])) {

            $codes = array();
            for($i = 1; $i <= 5; $i++) {
                $codes[] = strval(10000 + $i);
            }

            if(count($codes) > 0) {
                $codeResult = WxPublic_Card_AddCode($publicToken['access_token'], $card['card_id'], $codes);
                if($codeResult['errcode'] == '0') {
                    $countResult = WxPublic_Card_CodeCount($publicToken['access_token'], $card['card_id']);
                    if($countResult['errcode'] == '0' && intval($countResult['count']) > 0)
                        WxPublic_Card_ModifyStock($publicToken['access_token'], $card['card_id'], intval($countResult['count']));
                    else
                        throw new Exception('卡券修改庫存失敗:' . json_encode($countResult));
                } else {
                    throw new Exception('卡券添加code失敗:' . json_encode($codeResult));
                }
            }

            // 失敗
            // $result = WxPublic_Card_CodeUpdate($publicToken['access_token'], $codes[count($codes) - 1], '99999', $cardIdList[count($cardIdList) - 1]);
            // echo 'CodeUpdate' . PHP_EOL;
            // print_r($result);

            $result = WxPublic_Card_CheckCode($publicToken['access_token'], $cardIdList[count($cardIdList) - 1], $codes);
            echo 'CheckCode' . PHP_EOL;
            print_r($result);

            $result = WxPublic_Card_Get($publicToken['access_token'], $card['card_id']);
            echo 'Get' . PHP_EOL;
            print_r($result);

            $result = WxPublic_Card_QrcodeCreate($publicToken['access_token'], $card['card_id']);
            echo 'QrcodeCreate' . PHP_EOL;
            print_r($result);
        } else {
            throw new Exception('建立卡券失敗:' . json_encode($card));
        }

        // ========================================

        // 須要客戶領取後纔能有數據
        $result = WxPublic_Card_UserCardList($publicToken['access_token'], $openId, $cardIdList[count($cardIdList) - 1]);
        echo 'UserCardList' . PHP_EOL;
        print_r($result);

        // 須要客戶領取後才能查詢
        $result = WxPublic_Card_CodeGet($publicToken['access_token'], $cardIdList[count($cardIdList) - 1], $codes[0]);
        echo 'CodeGet' . PHP_EOL;
        print_r($result);
        if($result['errcode'] == '0' && $result['can_consume'] == true) {
            // 須要客戶領取後才能覈銷
            $result = WxPublic_Card_CodeConsume($publicToken['access_token'], $cardIdList[count($cardIdList) - 1], $codes[0]);
            echo 'CodeConsume' . PHP_EOL;
            print_r($result);
        }

        // ========================================

        for($i = 0; $i < count($cardIdList);++$i) {
            for($j = 0; $j < count($codes);++$j) {
                // 須要客戶領取後才能失效,已使用的不能失效
                $result = WxPublic_Card_CodeUnavailable($publicToken['access_token'], $cardIdList[$i], $codes[$j], '用戶發生退款');
                echo 'Unavailable:' . $cardIdList[$i] . '-' . $codes[$j] . PHP_EOL;
                print_r($result);
            }

            $result = WxPublic_Card_Delete($publicToken['access_token'], $cardIdList[$i]);
            echo 'Delete:' . $cardIdList[$i] . PHP_EOL;
            print_r($result);
        }

        $result = WxPublic_Card_BizuinInfo($publicToken['access_token'], date('Y-m-d', strtotime('-62 day')), date('Y-m-d', strtotime('-1 day')), 0);
        echo 'BizuinInfo-0' . PHP_EOL;
        print_r($result);

        $result = WxPublic_Card_BizuinInfo($publicToken['access_token'], date('Y-m-d', strtotime('-62 day')), date('Y-m-d', strtotime('-1 day')), 1);
        echo 'BizuinInfo-1' . PHP_EOL;
        print_r($result);
    */
    }
    echo '</pre>';

    template('pad/test');
    exit();
} elseif($do == 'wx_authority_signature') {
    $publicToken = WxPublic_AccessToken(APPID, SECRET);
    if($publicToken != null && $publicToken['expires_datetime'] >= time()) {
        exit(json_encode(Wx_AuthoritySignature($publicToken, $_GPC['url'])));
    }
    exit();
} elseif($do == 'wx_getcard') {
    // https://mp.weixin.qq.com/s/WhYpWmfuhUBw2wseTXdt2A
    // http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=cardsign
    $publicToken = WxPublic_AccessToken(APPID, SECRET);
    if($publicToken != null && $publicToken['expires_datetime'] >= time()) {
        $result = WxPublic_Card_BatchGet($publicToken['access_token']);
        if($result['errcode'] == '0') {
            $codes = array();
            for($i = 1; $i <= 5; ++$i) {
                $codes[] = strval(10000 + $i);
            }

            $data = array();
            foreach ($result['card_id_list'] as $cardId) {
                for($i = 0; $i < count($codes); ++$i) {
                    $signature = Wx_CardSignature($publicToken['access_token'], $cardId);
                    $data[] = array(
                      'api_ticket' => $signature['api_ticket'],
                        'card_id' => $signature['card_id'],
                        'card_ext' => array(  // 所有字段傳出去,別管有沒有值
                          'code' => empty($signature['code']) ? null : $signature['code'],
                          'openid' => empty($signature['openid']) ? null : $signature['openid'],
                            'timestamp' => $signature['timestamp'],
                            'nonce_str' => $signature['nonce_str'],
                            'signature' => $signature['signature'],
                            'plaintext' => $signature['plaintext'],
                        )
                    );
                }
            }
            exit(json_encode(array_slice($data, 0, 5)));  // 官方:只能一次領5張,超出報錯
        }
        exit(json_encode($result));  // 輸出錯誤
    }
    exit(json_encode('獲取Token失敗'));
}

function curl_get($url) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);    // 跳過驗證證書
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);    // 跳過驗證主機
    curl_setopt($curl, CURLOPT_HEADER, false);
    //curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json;charset=\'utf-8\''));
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($curl);
    curl_close($curl);

    return ($data === FALSE) ? null : json_decode($data, true);
}
function curl_jsonPost($url, $data) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);    // 跳過驗證證書
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);    // 跳過驗證主機
    curl_setopt($curl, CURLOPT_HEADER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
    $data = curl_exec($curl);
    curl_close($curl);

    return ($data === FALSE) ? null : json_decode($data, true);
}
function WxPublic_AccessToken($appid, $secret) {
    static $cache = array();
    $name = strtoupper('__ACCESSTOKEN_' . sha1($appid . $secret) . '__');
    $data = isset($cache[$name]) ? $cache[$name] : null;

    if($data == null || $data['expires_datetime'] <= time()) {
        $data = curl_get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $secret);
        $data['expires_datetime'] = time() + intval($data['expires_in'] * 0.9); // 提早過時
        $cache[$name] = $data;
    }

    return $data;

    /*
    $name = strtoupper('__ACCESSTOKEN_' . sha1($appid . $secret) . '__');
    $data = isset($_COOKIE[$name]) ? json_decode($_COOKIE[$name], true) : null;

    if($data == null || $data['expires_datetime'] <= time()) {
        $data = curl_get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $secret);
        $data['expires_datetime'] = time() + intval($data['expires_in'] * 0.9); // 提早過時
        setcookie($name, json_encode($data), $data['expires_datetime'], '/', $_SERVER['HTTP_HOST']);
    }

    return $data;
    */

    /*
    static $cache = array();

    $key = sha1($appid . $secret);
    if(!isset($cache[$key]) || $cache[$key]['expires_datetime'] <= time()) {
        $cache[$key] = curl_get('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $appid . '&secret=' . $secret);
        $cache[$key]['expires_datetime'] = time() + intval($cache[$key]['expires_in'] * 0.9); // 提早過時
    }

    return $cache[$key];
    */
}

function WxPublic_Card_Uploadimg($publicToken, $file_path) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, 'https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=' . $publicToken);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);    // 跳過驗證證書
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);    // 跳過驗證主機
    curl_setopt($curl, CURLOPT_HEADER, false);
    // curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json;charset=\'utf-8\''));    // 注意http頭,發送失敗也是一個緣由,這個是個失敗案例
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

    $aPath = realpath($file_path);
    if (class_exists('\CURLFile')) {
        curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true);
        $data = array('buffer' => new \CURLFile($aPath));    // >= 5.5
    } else {
        if (defined('CURLOPT_SAFE_UPLOAD'))
            curl_setopt($curl, CURLOPT_SAFE_UPLOAD, false);
        $data = array('buffer' => '@' . $aPath);    // <= 5.5
    }

    if(!empty($data)) {
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }

    $data = curl_exec($curl);
    curl_close($curl);

    return ($data === FALSE) ? null : json_decode($data, true);
}

function WxPublic_Card_Create_Groupon($publicToken, $logoUrl, $brandName, $title, $servicePhone, $description, $beginDatetime, $endDatetime, $dealDetail = '', $getLimit = 1, $useLimit = 50, $canShare = true, $canGiveFriend = true) {
    $url = 'https://api.weixin.qq.com/card/create?access_token=' . $publicToken;
    $data = array(
        'card' => array(
            'card_type' => 'GROUPON',
            'groupon' => array(
                'base_info' => array(
                    'logo_url' => $logoUrl,  // 300*300
                    'brand_name' => $brandName,
                    'code_type' => 'CODE_TYPE_QRCODE',
                    'title' => $title,
                    'color' => 'Color010',
                    'notice' => '使用時向服務員出示此券',
                    'service_phone' => $servicePhone,
                    'description' => str_replace(array('\r\n', '\r', '\n'), chr(13) . chr(10), $description),
                    'date_info' => array(
                        'type' => 'DATE_TYPE_FIX_TIME_RANGE',
                        'begin_timestamp' => strtotime($beginDatetime),
                        'end_timestamp' => strtotime($endDatetime)
                    ),
                    'sku' => array(
                        'quantity' => 0
                    ),
                    'get_limit' => $getLimit,
                    'use_limit' => $useLimit,
                    'bind_openid' => false,
                    'can_share' => !!$canShare,
                    'can_give_friend' => !!$canGiveFriend,

                    // GET_CUSTOM_CODE_MODE_DEPOSIT用法,參考:https://blog.csdn.net/u011738153/article/details/50457167
                    'use_custom_code' => true,
                    'get_custom_code_mode' => 'GET_CUSTOM_CODE_MODE_DEPOSIT',
                ),
                'deal_detail' => str_replace(array('\r\n', '\r', '\n'), chr(13) . chr(10), $dealDetail)
            )
        )
    );
    return curl_jsonPost($url, $data);
    /*
    if($card['errcode'] == '0' && isset($card['card_id'])) {
        if(count($codes) > 0) {
            $codeResult = WxPublic_Card_AddCode($publicToken, $card['card_id'], $codes);
            if($codeResult['errcode'] == '0') {
                $countResult = WxPublic_Card_CodeCount($publicToken, $card['card_id']);
                if($countResult['errcode'] == '0' && intval($countResult['count']) > 0)
                    WxPublic_Card_ModifyStock($publicToken, $card['card_id'], intval($countResult['count']));
                else
                    throw new Exception('卡券修改庫存失敗:' . json_encode($countResult));
            } else {
                throw new Exception('卡券添加code失敗:' . json_encode($codeResult));
            }
        }
        return $card['card_id'];
    }
    throw new Exception('建立卡券失敗:' . json_encode($card));
    */
}
function WxPublic_Card_Create_Cash($publicToken, $logoUrl, $brandName, $servicePhone, $description, $beginDatetime, $endDatetime, $reduceCost, $leastCost = 0, $getLimit = 1, $useLimit = 50, $canShare = true, $canGiveFriend = true) {
    $url = 'https://api.weixin.qq.com/card/create?access_token=' . $publicToken;
    $data = array(
        'card' => array(
            'card_type' => 'CASH',
            'cash' => array(
                'base_info' => array(
                    'logo_url' => $logoUrl,
                    'brand_name' => $brandName,
                    'code_type' => 'CODE_TYPE_QRCODE',
                    'color' => 'Color070',
                    'notice' => '使用時向服務員出示此券',
                    'service_phone' => $servicePhone,
                    'description' => str_replace(array('\r\n', '\r', '\n'), chr(13) . chr(10), $description),
                    'date_info' => array(
                        'type' => 'DATE_TYPE_FIX_TIME_RANGE',
                        'begin_timestamp' => strtotime($beginDatetime),
                        'end_timestamp' => strtotime($endDatetime)
                    ),
                    'sku' => array(
                        'quantity' => 0
                    ),
                    'get_limit' => $getLimit,
                    'use_limit' => $useLimit,
                    'bind_openid' => false,
                    'can_share' => !!$canShare,
                    'can_give_friend' => !!$canGiveFriend,

                    // GET_CUSTOM_CODE_MODE_DEPOSIT用法,參考:https://blog.csdn.net/u011738153/article/details/50457167
                    'use_custom_code' => true,
                    'get_custom_code_mode' => 'GET_CUSTOM_CODE_MODE_DEPOSIT',
                ),
                'least_cost' => $leastCost,
                'reduce_cost' => $reduceCost,
            )
        )
    );
    return curl_jsonPost($url, $data);
}
function WxPublic_Card_Create_Discount($publicToken, $logoUrl, $brandName, $title, $servicePhone, $description, $beginDatetime, $endDatetime, $discount, $getLimit = 1, $useLimit = 50, $canShare = true, $canGiveFriend = true) {
    $url = 'https://api.weixin.qq.com/card/create?access_token=' . $publicToken;
    $data = array(
        'card' => array(
            'card_type' => 'DISCOUNT',
            'discount' => array(
                'base_info' => array(
                    'logo_url' => $logoUrl,
                    'brand_name' => $brandName,
                    'code_type' => 'CODE_TYPE_QRCODE',
                    'title' => $title,
                    'color' => 'Color030',
                    'notice' => '使用時向服務員出示此券',
                    'service_phone' => $servicePhone,
                    'description' => str_replace(array('\r\n', '\r', '\n'), chr(13) . chr(10), $description),
                    'date_info' => array(
                        'type' => 'DATE_TYPE_FIX_TIME_RANGE',
                        'begin_timestamp' => strtotime($beginDatetime),
                        'end_timestamp' => strtotime($endDatetime)
                    ),
                    'sku' => array(
                        'quantity' => 0
                    ),
                    'get_limit' => $getLimit,
                    'use_limit' => $useLimit,
                    'use_custom_code' => false,
                    'bind_openid' => false,
                    'can_share' => !!$canShare,
                    'can_give_friend' => !!$canGiveFriend,

                    // GET_CUSTOM_CODE_MODE_DEPOSIT用法,參考:https://blog.csdn.net/u011738153/article/details/50457167
                    'use_custom_code' => true,
                    'get_custom_code_mode' => 'GET_CUSTOM_CODE_MODE_DEPOSIT',
                ),
                'discount' => $discount
            )
        )
    );
    return curl_jsonPost($url, $data);
}
function WxPublic_Card_Create_Gift($publicToken, $logoUrl, $brandName, $title, $servicePhone, $description, $beginDatetime, $endDatetime, $gift = '', $getLimit = 1, $useLimit = 50, $canShare = true, $canGiveFriend = true) {
    $url = 'https://api.weixin.qq.com/card/create?access_token=' . $publicToken;
    $data = array(
        'card' => array(
            'card_type' => 'GIFT',
            'gift' => array(
                'base_info' => array(
                    'logo_url' => $logoUrl,
                    'brand_name' => $brandName,
                    'code_type' => 'CODE_TYPE_QRCODE',
                    'title' => $title,
                    'color' => 'Color050',
                    'notice' => '使用時向服務員出示此券',
                    'service_phone' => $servicePhone,
                    'description' => str_replace(array('\r\n', '\r', '\n'), chr(13) . chr(10), $description),
                    'date_info' => array(
                        'type' => 'DATE_TYPE_FIX_TIME_RANGE',
                        'begin_timestamp' => strtotime($beginDatetime),
                        'end_timestamp' => strtotime($endDatetime)
                    ),
                    'sku' => array(
                        'quantity' => 0
                    ),
                    'get_limit' => $getLimit,
                    'use_limit' => $useLimit,
                    'bind_openid' => false,
                    'can_share' => !!$canShare,
                    'can_give_friend' => !!$canGiveFriend,

                    // GET_CUSTOM_CODE_MODE_DEPOSIT用法,參考:https://blog.csdn.net/u011738153/article/details/50457167
                    'use_custom_code' => true,
                    'get_custom_code_mode' => 'GET_CUSTOM_CODE_MODE_DEPOSIT',
                ),
                'gift' => str_replace(array('\r\n', '\r', '\n'), chr(13) . chr(10), $gift)
            )
        )
    );
    return curl_jsonPost($url, $data);
}
function WxPublic_Card_Create_GeneralCoupon($publicToken, $logoUrl, $brandName, $title, $servicePhone, $description, $beginDatetime, $endDatetime, $defaultDetail = '', $getLimit = 1, $useLimit = 50, $canShare = true, $canGiveFriend = true) {
    $url = 'https://api.weixin.qq.com/card/create?access_token=' . $publicToken;
    $data = array(
        'card' => array(
            'card_type' => 'GENERAL_COUPON',
            'general_coupon' => array(
                'base_info' => array(
                    'logo_url' => $logoUrl,
                    'brand_name' => $brandName,
                    'code_type' => 'CODE_TYPE_QRCODE',
                    'title' => $title,
                    'color' => 'Color090',
                    'notice' => '使用時向服務員出示此券',
                    'service_phone' => $servicePhone,
                    'description' => str_replace(array('\r\n', '\r', '\n'), chr(13) . chr(10), $description),
                    'date_info' => array(
                        'type' => 'DATE_TYPE_FIX_TIME_RANGE',
                        'begin_timestamp' => strtotime($beginDatetime),
                        'end_timestamp' => strtotime($endDatetime)
                    ),
                    'sku' => array(
                        'quantity' => 0
                    ),
                    'get_limit' => $getLimit,
                    'use_limit' => $useLimit,
                    'bind_openid' => false,
                    'can_share' => !!$canShare,
                    'can_give_friend' => !!$canGiveFriend,

                    // GET_CUSTOM_CODE_MODE_DEPOSIT用法,參考:https://blog.csdn.net/u011738153/article/details/50457167
                    'use_custom_code' => true,
                    'get_custom_code_mode' => 'GET_CUSTOM_CODE_MODE_DEPOSIT',
                ),
                'default_detail' => str_replace(array('\r\n', '\r', '\n'), chr(13) . chr(10), $defaultDetail)
            )
        )
    );
    return curl_jsonPost($url, $data);
}

function WxPublic_Card_AddCode($publicToken, $cardId, $codes) {
    $url = 'http://api.weixin.qq.com/card/code/deposit?access_token=' . $publicToken;
    $data = array(
   'card_id' => $cardId,
   'code' => $codes
    );

    return curl_jsonPost($url, $data);
}
function WxPublic_Card_CodeCount($publicToken, $cardId) {
    $url = 'http://api.weixin.qq.com/card/code/getdepositcount?access_token=' . $publicToken;
    $data = array(
   'card_id' => $cardId
    );

    return curl_jsonPost($url, $data);
}
function WxPublic_Card_ModifyStock($publicToken, $cardId, $increase = 0, $reduce = 0) {
    $url = 'https://api.weixin.qq.com/card/modifystock?access_token=' . $publicToken;
    $data = array(
        'card_id' => $cardId,
        'increase_stock_value' => $increase,
        'reduce_stock_value' => $reduce,
    );

    return curl_jsonPost($url, $data);
}
function WxPublic_Card_CheckCode($publicToken, $cardId, $codes) {
    $url = 'http://api.weixin.qq.com/card/code/checkcode?access_token=' . $publicToken;
    $data = array(
        'card_id' => $cardId,
        'code' => $codes
    );

    return curl_jsonPost($url, $data);
}

function WxPublic_Card_BatchGet($publicToken) {
    $url = 'https://api.weixin.qq.com/card/batchget?access_token=' . $publicToken;
    $data = array(
        'offset' => 0,
        'count' => 50,
        'status_list' => array(
            // 'CARD_STATUS_NOT_VERIFY',  // 待審覈
            // 'CARD_STATUS_VERIFY_FAIL',  // 審覈失敗
            'CARD_STATUS_VERIFY_OK',  // 經過審覈
            // 'CARD_STATUS_DELETE',  // 卡券被商戶刪除
            // 'CARD_STATUS_DISPATCH'  // 在公衆平臺投放過的卡券
        )
    );

    return curl_jsonPost($url, $data);
}
function WxPublic_Card_Get($publicToken, $cardId) {
    $url = 'https://api.weixin.qq.com/card/get?access_token=' . $publicToken;
    $data = array(
        'card_id' => $cardId
    );

    return curl_jsonPost($url, $data);
}
function WxPublic_Card_Delete($publicToken, $cardId) {
    $url = 'https://api.weixin.qq.com/card/delete?access_token=' . $publicToken;
    $data = array(
        'card_id' => $cardId
    );

    return curl_jsonPost($url, $data);
}

// 重點:use_custom_code=true和get_custom_code_mode=GET_CUSTOM_CODE_MODE_DEPOSIT時,不須要傳code生成(PS:不帶code能夠一碼多人領取)
function WxPublic_Card_QrcodeCreate($publicToken, $cardId, $code = '', $openId = '', $outerStr = '') {
    $url = 'https://api.weixin.qq.com/card/qrcode/create?access_token=' . $publicToken;
    $data = array(
        'action_name' => 'QR_CARD',
        'expire_seconds' => 0,
        'action_info' => array(
            'card' => array(
                'card_id' => $cardId,
                'code' => $code,
                'openid' => $openId,
                'is_unique_code' => false,
                'outer_str' => $outerStr
            )
        )
    );

    return curl_jsonPost($url, $data);
}

// 須要客戶領取後纔能有數據
function WxPublic_Card_UserCardList($publicToken, $openId, $cardId = '') {
    $url = 'https://api.weixin.qq.com/card/user/getcardlist?access_token=' . $publicToken;
    $data = array(
        'openid' => $openId,
        'card_id' => $cardId
    );

    return curl_jsonPost($url, $data);
}
// 須要客戶領取後才能查詢
function WxPublic_Card_CodeGet($publicToken, $cardId, $code) {
    $url = 'https://api.weixin.qq.com/card/code/get?access_token=' . $publicToken;
    $data = array(
        'card_id' => $cardId,
        'code' => $code,
        'check_consume' => true
    );

    return curl_jsonPost($url, $data);
}
// 須要客戶領取後才能覈銷
function WxPublic_Card_CodeConsume($publicToken, $cardId, $code) {
    $url = 'https://api.weixin.qq.com/card/code/consume?access_token=' . $publicToken;
    $data = array(
        'card_id' => $cardId,
        'code' => $code
    );

    return curl_jsonPost($url, $data);
}
// 須要客戶領取後才能失效,已使用的不能失效
function WxPublic_Card_CodeUnavailable($publicToken, $cardId, $code, $reason = '') {
    $url = 'https://api.weixin.qq.com/card/code/unavailable?access_token=' . $publicToken;
    $data = array(
        'card_id' => $cardId,
        'code' => $code,
        'reason' => $reason
    );

    return curl_jsonPost($url, $data);
}

/*
// 失敗
function WxPublic_Card_CodeUpdate($publicToken, $code, $new_code, $cardId = null) {
    $url = 'https://api.weixin.qq.com/card/code/update?access_token=' . $publicToken;
    $data = array(
        'card_id' => $cardId,
        'code' => $code,
        'new_code' => $new_code,
    );

    return curl_jsonPost($url, $data);
}
*/

// $beginDate必須是<=62,$endDate必須是小於今天
function WxPublic_Card_BizuinInfo($publicToken, $beginDate, $endDate, $condSource) {
    $url = 'https://api.weixin.qq.com/datacube/getcardbizuininfo?access_token=' . $publicToken;
    $data = array(
        'begin_date' => $beginDate,
        'end_date' => $endDate,
        'cond_source' => $condSource
    );

    return curl_jsonPost($url, $data);
}

function WxPublic_Card_CardInfo($publicToken, $beginDate, $endDate, $condSource, $cardId = null) {
    $url = 'https://api.weixin.qq.com/datacube/getcardcardinfo?access_token=' . $publicToken;
    $data = array(
        'begin_date' => $beginDate,
        'end_date' => $endDate,
        'cond_source' => $condSource,
        'card_id' => $cardId
    );

    return curl_jsonPost($url, $data);
}

function WxPublic_Card_CodeDecrypt($publicToken, $encryptCode) {
    $url = 'https://api.weixin.qq.com/card/code/decrypt?access_token=' . $publicToken;
    $data = array(
        'encrypt_code' => $encryptCode
    );

    return curl_jsonPost($url, $data);
}

// ========================================

function WxJsApi_GetTicket($publicToken, $type) {
    static $cache = array();
    $name = strtoupper('__TICKET_' . sha1($publicToken . $type) . '__');
    $data = isset($cache[$name]) ? $cache[$name] : null;

    if($data == null || $data['expires_datetime'] <= time()) {
        // jsapi:jsapi_ticket
        // wx_card:api_ticket
        $data = curl_get('https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=' . $publicToken . '&type=' . $type);
        $data['expires_datetime'] = time() + intval($data['expires_in']);
        $cache[$name] = $data;
    }

    return $data;
}

// ========================================
// 權限簽名算法
// ========================================
// 簽名生成規則以下:
// 參與簽名的字段包括有效的
//   jsapi_ticket:獲取方式詳見微信JSSDK文檔
//   noncestr:隨機字符串,由開發者隨機生成
//   timestamp:由開發者生成的當前時間戳)
//   url:當前網頁的URL,不包含#及其後面部分。注意:對於沒有隻有域名沒有path的URL,瀏覽器會自動加上/做爲path
// 對全部待簽名參數按照字段名的ASCII碼從小到大排序(字典序)後,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。這裏須要注意的是全部參數名均爲小寫字符
// 接下來對string1做sha1加密,字段名和字段值都採用原始值,不進行URL轉義。即signature=sha1(string1)
function Wx_AuthoritySignature($publicToken, $url) {
    $ticket = WxJsApi_GetTicket($publicToken, 'jsapi');
    if($ticket != null && $ticket['expires_datetime'] >= time()) {
        static $cache = array();
        $name = strtoupper('__AUTHORITYSIGNATURE_' . sha1($ticket['ticket'] . $url) . '__');
        $data = isset($cache[$name]) ? $cache[$name] : null;

        if($data == null || $ticket['expires_datetime'] <= time()) {
            $input = array(
                'jsapi_ticket' => $ticket['ticket'],
                'noncestr' => sha1(uniqid(microtime(true), true)),
                'timestamp' => time(),
                'url' => $url
            );

            $data = array(
                'appid' => APPID,
              'noncestr' => $input['noncestr'],
              'timestamp' => $input['timestamp'],
              'signature' => sha1('jsapi_ticket=' . $input['jsapi_ticket'] . '&noncestr=' . $input['noncestr'] . '&timestamp=' . $input['timestamp'] . '&url=' . $input['url']),  // 必須按小寫字段名升序排序
              //'plaintext' => 'jsapi_ticket=' . $input['jsapi_ticket'] . '&noncestr=' . $input['noncestr'] . '&timestamp=' . $input['timestamp'] . '&url=' . $input['url'],
            );

            $cache[$name] = $data;
        }

        return $data;
    }
    return null;
}
// ========================================
// 卡券簽名算法
// ========================================
// 重點:use_custom_code=true和get_custom_code_mode=GET_CUSTOM_CODE_MODE_DEPOSIT時,不須要傳code進行簽名
// 重點:code和openid是空字符串時,只能傳null或不傳給wx.addCard,不然報出參數錯誤
function Wx_CardSignature($publicToken, $cardId, $code = '', $openId = '') {
    $ticket = WxJsApi_GetTicket($publicToken, 'wx_card');
    if($ticket != null && $ticket['expires_datetime'] >= time()) {
        static $cache = array();
        $name = strtoupper('__CARDSIGNATURE_' . sha1($ticket['ticket'] . $cardId . $code . $openId) . '__');
        $data = isset($cache[$name]) ? $cache[$name] : null;

        if($data == null || $ticket['expires_datetime'] <= time()) {
            $input = array(
                'api_ticket' => $ticket['ticket'],
                'timestamp' => time(),
                'nonce_str' => sha1(uniqid(microtime(true), true)),
                'card_id' => $cardId,
                'code' => strval($code),
                'openid' => $openId,
            );

            asort($input, SORT_STRING);  // 按鍵值升序排序

            $data = array(
              'api_ticket' => $input['api_ticket'],
              'timestamp' => $input['timestamp'],
              'nonce_str' => $input['nonce_str'],
              'card_id' => $input['card_id'],
              'code' => (!isset($input['code']) || empty($input['code'])) ? null : $input['code'],
              'openid' => (!isset($input['openid']) || empty($input['openid'])) ? null : $input['openid'],
              'signature' => sha1(implode('', $input)),
              //'plaintext' => implode(';', $input),
            );

            $cache[$name] = $data;
        }

        return $data;
    }
    return null;
}

 

前端代碼:java

<!doctype html>
<html class="w-100 h-100">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0, shrink-to-fit=no" />
<meta name="format-detection" content="telephone=no" />
<title>測試</title>
</head>
<body>

<script type="text/javascript" src="{$_W['siteroot']}app/resource/pad/js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
<script type="text/javascript">
// https://www.cnblogs.com/ka-bu-qi-nuo/p/8659688.html
$(function() {
    $.ajax({
        url: '{url "pad/store_pad/wx_authority_signature" array("store" => $_GPC["store"])}',
        type: 'GET',
        dataType: 'json',
        data: {
            'url': encodeURIComponent(window.location.href.split('#')[0])  // 獲取最新url
        },
        success: function(signData) {
            wx.config({
              debug: true,  // true時,即便正確也會提示簽名無效,這是官方bug
              appId: signData.appid,
              timestamp: signData.timestamp,
              nonceStr: signData.noncestr,
              signature: signData.signature,
              jsApiList: [
                    // 'updateAppMessageShareData',
                    // 'updateTimelineShareData',
                    // 'onMenuShareTimeline',  // 即將廢棄
                    // 'onMenuShareAppMessage',  // 即將廢棄
                    // 'onMenuShareQQ',  // 即將廢棄
                    // 'onMenuShareWeibo',
                    // 'onMenuShareQZone',
                    // 'startRecord',
                    // 'stopRecord',
                    // 'onVoiceRecordEnd',
                    // 'playVoice',
                    // 'pauseVoice',
                    // 'stopVoice',
                    // 'onVoicePlayEnd',
                    // 'uploadVoice',
                    // 'downloadVoice',
                    // 'chooseImage',
                    // 'previewImage',
                    // 'uploadImage',
                    // 'downloadImage',
                    // 'translateVoice',
                    // 'getNetworkType',
                    // 'openLocation',
                    // 'getLocation',
                    // 'hideOptionMenu',
                    // 'showOptionMenu',
                    // 'hideMenuItems',
                    // 'showMenuItems',
                    // 'hideAllNonBaseMenuItem',
                    // 'showAllNonBaseMenuItem',
                    // 'closeWindow',
                    // 'scanQRCode',
                    // 'chooseWXPay',
                    // 'openProductSpecificView',
                    'addCard',
                    // 'chooseCard',
                    // 'openCard',
              ]
            });

            wx.ready(function() {
                wx.checkJsApi({
                    jsApiList: ['addCard'],
                    success: function(res1) {
                        //alert(JSON.stringify(res1));
                        if(res1.checkResult.addCard) {
                            $.ajax({
                                url: '{url "pad/store_pad/wx_getcard" array("store" => $_GPC["store"])}',
                                type: 'GET',
                                dataType: 'json',
                                success: function(signData2) {
                                    if(typeof(signData2['errcode']) === 'undefined' || signData2['errcode'] == '0') {
                                        var cardList = [];
                                        for(var i = 0; i < signData2.length; ++i) {
                                            cardList.push({
                                                cardId: signData2[i].card_id,
                                                cardExt: JSON.stringify({  // 所有字段賦上,別管有沒有值
                                                    code: signData2[i].card_ext.code,
                                                    openid: signData2[i].card_ext.openid,
                                                    timestamp: signData2[i].card_ext.timestamp,
                                                    nonce_str: signData2[i].card_ext.nonce_str,
                                                    signature: signData2[i].card_ext.signature
                                                })
                                            });
                                        }
                                        if(cardList.length > 0) {
                                            wx.addCard({
                                                cardList: cardList, // 須要添加的卡券列表
                                                success: function (res2) {
                                                    var cardList = res2.cardList; // 添加的卡券列表信息
                                                    alert(JSON.stringify(cardList));
                                                }
                                            });
                                        }
                                    } else {
                                        alert('獲取失敗\r\nCode:' + signData2['errcode'] + '\r\nMessage:' . signData2['errmsg']);
                                    }
                                }
                            });
                        } else {
                            alert('不支持addCard!');
                        }
                    }
                });

            

                /*
                wx.checkJsApi({
                    jsApiList: ['scanQRCode'],
                    success: function(res) {
                        //alert(JSON.stringify(res));
                        if(res.checkResult.scanQRCode) {
                            alert('支持scanQRCode');
                        } else {
                            alert('不支持scanQRCode!');
                        }
                    }
                });

                wx.checkJsApi({
                    jsApiList: [
                        'updateAppMessageShareData',
                        'updateTimelineShareData',
                    ],
                    success: function(res) {
                        //alert(JSON.stringify(res));
                        if(res.checkResult.updateAppMessageShareData) {
                            alert('支持分享到朋友/QQ');
                            / *
                            wx.updateAppMessageShareData({
                          title: '分享標題',
                          desc: '分享描述',
                          link: signData.url,
                          imgUrl: '{$_W["siteroot"]}favicon.png',
                          success: function () {
                              alert('分享到朋友/QQ成功');
                          }
                        });
                        * /
                        } else {
                            alert('不支持分享到朋友/QQ');
                        }

                        if(res.checkResult.updateAppMessageShareData) {
                            alert('支持分享到朋友圈/QQ空間');
                            / *
                        wx.updateTimelineShareData({ 
                          title: '分享標題',
                          link: signData.url,
                          imgUrl: '{$_W["siteroot"]}favicon.png',
                          success: function () {
                              alert('分享到朋友圈/QQ空間成功');
                          }
                        });
                        * /
                        } else {
                            alert('不支持分享到朋友圈/QQ空間');
                        }
                    }
                });

                wx.checkJsApi({
                    jsApiList: ['openCard'],
                    success: function(res) {
                        //alert(JSON.stringify(res));
                        if(res.checkResult.openCard) {
                            alert('支持openCard!');
                        } else {
                            alert('不支持openCard!');
                        }
                    }
                });
                */
            });
         
            wx.error(function(res) {
                alert('初始化失敗!');
            });
        }
    });
});
</script>
<script type="text/javascript">
/**
 * @param {String}  errorMessage   錯誤信息
 * @param {String}  scriptURI      出錯的文件
 * @param {Long}    lineNumber     出錯代碼的行號
 * @param {Long}    columnNumber   出錯代碼的列號
 * @param {Object}  errorObj       錯誤的詳細信息,Anything
 */
window.onerror = function(errorMessage, scriptURI, lineNumber, columnNumber, errorObj) {
    var msg = '';
    var CRLF = String.fromCharCode(13) + String.fromCharCode(10);
    msg += '錯誤信息:' + errorMessage + CRLF;
    msg += '出錯文件:' + scriptURI + '(' + lineNumber + ',' + columnNumber + ')' + CRLF;
    msg += '錯誤詳情:' + errorObj;
    alert(msg);
}
</script>
</body>
</html>
相關文章
相關標籤/搜索