羣髮卡券能夠經過客服消息推送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'] . '×tamp=' . $input['timestamp'] . '&url=' . $input['url']), // 必須按小寫字段名升序排序 //'plaintext' => 'jsapi_ticket=' . $input['jsapi_ticket'] . '&noncestr=' . $input['noncestr'] . '×tamp=' . $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>