微信卡券功能的玩坏教程

关于微信的卡券功能, 百度上我只能搜到的都是跟官网差不多的东西. 所以就自己对着官方文档跑了一天, 为了满足公司的需求鼓捣得到一些小心得. 情景是我们需要一堆已知 code 的卡券, 但是微信公众号后台可视化界面并不支持这样的模式. 微信自带生成的卡券是有人触发就随机分配一个码, 并不实用, 因为我们并是那种消费的业务逻辑, 而是更像是体验卡的形式.

##1. 用 api 建立的卡券才能使用自定义 code 功能, 也就是譬如我想卡券用英文句子来作为卡券的码. 这种时候我们就需要调用微信公众号的 api 了, 可以使用 http://mp.weixin.qq.com/debug/ 里的测试接口生成. 也可以自己跑微信接口.

敲黑板! 敲黑板! 敲黑板!

麻烦的地方是不这个接口怎么触发, 而是这个卡券的 json 信息. 一大串, 关键的功能挺多的, 我都看了一天文档才搞清楚了一些.

1
2
3
4
5
6
7
8
{
"card_type":"GENERAL_COUPON",//这里有5个选择,具体是根据类型决定的
"general_coupon":{
"base_info":{/*[必填,详情看这里][1]*/},
"default_detail":'一些描述',
"advanced_info":{/*选填*/}
}
}

只要 json 正确就能 post 过去就能看见创建了一个卡券了.

##2. 本文主要是介绍自定义 code 群发这个功能, 所以必须声明的两个属性. 下面为官方原文提示

如果开发者打算新创建一张支持导入 code 模式的卡券,不同于以往的创建方式,建议开发者采用以下流程创建预存 code 模式卡券,否则会报错。

  • 步骤一:创建预存模式卡券,将库存 quantity 初始值设置为 0,并填入 get_custom_code_mode 字段;
  • 步骤二:待卡券通过审核后,调用导入 code 接口并核查 code;
  • 步骤三:调用修改库存接口,须令卡券库存小于或等于导入 code 的数目。(为了避免混乱建议设置为相等)

##3. 导入 code, 前期工作做好了, 就可以进入最关键的阶段, 一就是生成你自己需要的 code, 这个跟微信 api 无关, 你想生成什么就生成. 之后才是真的关键的地方, 卡券 code 的导入一次调用只能 100 个, 然后卡券的库存可以修改.

我是一次过插入 10000 个的, 毕竟一个卡券的最高上限是 1 亿个 code. 通过 for 循环 100 个 100 个那样插入, 并且 100 个 100 个库存那样增加. 可以在后台可视化地看见 code 的数目的增长.
pic

总结:: 这样创建出来的卡券不能生成二维码入口, 但是可以插入到推送中, 也可以插入到服务号的菜单中.

附件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
if (isset($_GET['act'])) {
$act = $_GET['act'];
}
if(isset($_GET['tool'])){
$tool = $_GET['tool'];
}

if ($act == 'card_create') {
;
}elseif($act == 'check_code'){
$code_arr = get_code();
foreach ($code_arr as $key => $hundred_code) {
card_manager('codeCheck',0,$hundred_code);
}
}elseif($act == 'import_code') {
$code_arr = get_code();
foreach ($code_arr as $key => $hundred_code) {
card_manager('codeDeposit',0,$hundred_code);
card_manager('stockModify',100);
}
}elseif($act == 'card_detail'){
card_manager('cardGet');
}elseif($tool == 'shorten'){
card_manager('long2short');
}elseif($tool == 'gcode'){
generate_code();
}elseif($tool == 'compare'){
compare_code_diff("cpyhq1.txt","cpyhq2.txt");
}else{
echo "有毛病";
}


function get_card_id()
{
$card_id = "卡券id";
return $card_id;
}

function card_manager($event,$stockNum=0,$code_arr=[],$stock_status='increase')
{
$access_token = 'access_token还没写获取方法';

$longlink = "";//长链接

switch ($event) {
case 'codeDeposit':
//code储存
$url = "http://api.weixin.qq.com/card/code/deposit?access_token=".$access_token;
$json = json_encode(array("card_id"=>get_card_id(),"code"=>$code_arr));
break;
case 'codeCheck':
//code状态检查
$url = "http://api.weixin.qq.com/card/code/checkcode?access_token=".$access_token;
$json = json_encode(array("card_id"=>get_card_id(),"code"=>$code_arr));
break;
case 'stockModify':
//库存数量修改
$url = "https://api.weixin.qq.com/card/modifystock?access_token=".$access_token;
if ($stock_status=='increase') {
$str = "increase_stock_value";
}elseif($stock_status=='reduce'){
$str = "reduce_stock_value";
}
$json = '{
"card_id": "'.get_card_id().'",
"'.$str.'": '.$stockNum.'
}';
break;
case 'cardGet':
//优惠卡详细信息
$url = "https://api.weixin.qq.com/card/get?access_token=".$access_token;
$json = json_encode(array("card_id"=>get_card_id()));
break;
case 'long2short':
//微信短链
$url = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=".$access_token;
$json = json_encode(array("action"=>"long2short","long_url"=>$longlink));
break;
case 'cardUpdateName':
//优惠卡基本修改修改
$url = "https://api.weixin.qq.com/card/update?access_token=".$access_token;
$json = '{
"card_id":"'.get_card_id().'",
"general_coupon": {
"base_info": {
"title":"测评优惠券1"
}
}
}';
break;
case 'cardDelete':
//优惠卡删除
$url = "https://api.weixin.qq.com/card/delete?access_token=".$access_token;
$json = json_encode(array("card_id"=>get_card_id()));
default:
# code...
break;
}

$result = https_request($url, $json);
echo $result;
}

function generate_code(){
/*每两个数字之间重复的概率为90万*90万分之一
基本不会重复
*/
$arr = array();
for ($i=0; $i < 10000; $i++) {
$a = rand(100000,999999);
$b = rand(100000,999999);
$arr[$i] = $a*$b;
if (strlen($arr[$i])<12) {
$fix = rand(0,9);
$arr[$i] = (string)$arr[$i].(string)$fix;
$arr[$i] = intval($arr[$i]);
}
}
if (count($arr) != count(array_unique($arr))) {
generate_code();
}
$fp = fopen('output.txt','w+');
foreach ($arr as $key => $value) {
fwrite($fp,$value."\n");
}
fclose($fp);
//return $arr;
}

function get_code(){
$file = 'coupon.txt';
$content = file_get_contents($file); //读取文件中的内容
$str = str_replace(array("\r\n", "\r", "\n"), " ", $content);
$arr = explode(' ', $str);
unset($arr[count($arr)-1]);
//把过长的code段成几截
$num = count($arr);
$return_arr = [];
$counter = $num%100 == 0? ($num/100)-1:floor($num/100);//分组计数器
for ($i=0; $i <= $counter; $i++) {
$return_arr[$i] = array_slice($arr,$i*100,100);
}
return $return_arr;
}

function compare_code_diff($f1,$f2){
$file1 = $f1;
$file2 = $f2;
$content = file_get_contents($file1); //读取文件中的内容
$str1 = str_replace(array("\r\n", "\r", "\n"), " ", $content);
$arr1 = explode(' ', $str1);

$content = file_get_contents($file2); //读取文件中的内容
$str2 = str_replace(array("\r\n", "\r", "\n"), " ", $content);
$arr2 = explode(' ', $str2);

print_r(array_flip(array_merge($arr1,$arr2)));
}

function https_request($url, $data = null)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
?>