[PHP+JS]微信卡券(潦草笔记,全代码,亲测通过)
群发卡券可以通过客服消息推送
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547
后端代码:
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;
}
前端代码:
<!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>
[PHP+JS]微信卡券(潦草笔记,全代码,亲测通过)的更多相关文章
- PHP小程序后端支付代码亲测可用
小程序后端支付代码亲测可用 <?php namespace Home\Controller; use Think\Controller; class WechatpayController ex ...
- c++ builder TListView控件按字符串排序(根据网上代码亲测ok)
//--------------------------------------------------------------------------- /* 首先将一个列表框控件安放在Form上, ...
- js预览PDF的插件(亲测支持IE9,火狐,等等)
aspx文件 <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible ...
- js开启和关闭页面滚动【亲测有效】
在移动端的页面开发过程中,经常会遇到点击弹框禁止页面滚动的情景,下面就来说下具体的做法... 第一步:构建一个函数 function bodyScroll(event){ event.preventD ...
- STM32—中断详解(配合按键中断代码,代码亲测)
在STM32中执行中断主要分三部分: 1.配置NVIC_Config()函数 2.配置EXTI_Config()函数 3.编写中断服务函数 (注:本文章所用代码为中断按键代码,实现了按键进入中断从而控 ...
- Mac 设置git命令tab自动补全(亲测有效)
转载 :https://blog.csdn.net/tiancaijyy/article/details/84888868 注意: 获取git-completion.bash 要对应自己的git版本 ...
- 官方微信接口(全接口) - 微信摇一摇接口/微信多客服接口/微信支付接口/微信红包接口/微信卡券接口/微信小店接口/JSAPI
微信入口绑定,微信事件处理,微信API全部操作包含在这些文件中.微信支付.微信红包.微信卡券.微信小店. 微信开发探讨群 330393916 <?php /** * Description o ...
- JavaScript、jQuery、HTML5、Node.js实例大全-读书笔记2
技术很多,例子很多,只好慢慢学,慢慢实践!!现在学的这本书是[JavaScript实战----JavaScript.jQuery.HTML5.Node.js实例大全] JavaScript.jQuer ...
- 【09-23】js原型继承学习笔记
js原型继承学习笔记 function funcA(){ this.a="prototype a"; } var b=new funcA(); b.a="object a ...
随机推荐
- SSL Certificate Signed Using Weak Hashing Algorithm 和SSL Medium Strength Cipher Suites Supported的解决方案
这两天有个项目被扫描器报了几个中危,都是SSL证书的问题.记录一下解决方案吧. 第一个问题:SSL Certificate Signed Using Weak Hashing Algorithm 这里 ...
- gtest 参数化
前言: 在测试用例中,我们时常需要传给被测函数不同的值,gtest为我们提供了简便的方法,可以使我们能够灵活的进行参数化测试. 步骤: 1.创建一个类,继承testing::TestWithParam ...
- XPATH 要想获取的东西里不分段,不变成列表就用STRING(),不用TEXT()
简单说一说: requests配合xpath来抓网站数据的时候,不像selenium+xpath. selenium有 find_element find_elements,区别是带S ,查找第一 ...
- 芯灵思Sinlinx A64开发板 Linux内核等待队列poll ---阻塞与非阻塞
开发平台 芯灵思Sinlinx A64 内存: 1GB 存储: 4GB 开发板详细参数 https://m.tb.cn/h.3wMaSKm 开发板交流群 641395230 阻塞:阻塞调用是指调用结果 ...
- Pytho条件判断
def health_status(): height = float(input("请输入身高(单位:米) :")) weight = float(input("请输入 ...
- char* 与 string 互转
因为c#强调安全性,每次意图将string的地址赋给指针时,系统都要报错,原因是系统无法计算字符串的空间和地址,这里不多bb,使用IntPtr类(using Runtime.InteropServic ...
- C 标准库头文件
头文件 说明 头文件 说明 <assert.h> 条件编译宏,将参数与零比较 <complex.h> (C99 起) 复数运算 <ctype.h> 用来确定包含于字 ...
- CentOS7.5实践快速部署LAMP+Tomcat成功运行阿里云或者腾讯云
安装一定要按照顺序来 1 先安装JDK+TOMCAT 点击看这里 2 在安装LAMP 点击看这里 3 最关键的就是这里 LAMP+Tomcat整合 我们不用源码编译安装,而是使用yum命令来完成. ...
- xxl-job源码分析
1 调度中心API服务 1.任务结果回调服务: 2.执行器注册服务: 3.执行器注册摘除服务: 4.触发任务单次执行服务,支持任务根据业务事件触发: API暴露代码:com.xxl.job.admin ...
- php中cookie和session的总结
cookie: 设置cookie: setcookie("name","zhang","time()+3600"); 参数一:属性名 参数 ...