C#开发微信门户及应用(36)--微信卡劵管理的封装操作

前面几篇介绍了微信支付方面的内容,本篇继续微信接口的一些其他方面的内容:卡劵管理。卡劵管理是微信接口里面非常复杂的一个部分,里面的接口非常多,我花了不少时间对它进行了封装处理,重构优化等等工作,卡劵在营销方面是一个比较好的途径,可以应用在会员管理、店铺促销等方面的活动,不过万层高楼从底起,我们需要把卡劵管理的相关接口夯实完善,才能在它的基础上进行更进一步的应用操作。

1、微信卡券接口说明

微信卡券功能是腾讯为商户提供的一套完整的电子卡券解决方案,商户可在法律允许的范围内通过该功能实现电子卡券生成、下发、领取、核销的闭环,并使用对账、卡券管理等配套功能。微信卡券功能可分为API接口功能和公众平台卡券功能,使用两种功能均可实现卡券生成、下发、领取、核销,有开发意愿的商户可使用API接口功能,无开发意愿商户可使用公众平台卡券功能。
微信公众平台本次增加了微信卡券功能,开放接口供商家使用。 支持开发者调用接口创建多种类型的卡券,通过下发消息、二维码、JS-SDK等方式进行投放,在用户使用时通过API接口或卡券商户助手完成核销。 同时支持接口获取统计数据,以及各个环节给予开发者事件推送。
目前支持优惠券(代金券、折扣券、礼品券、团购券)、会员卡、景点门票、电影票、飞机票、红包、会议门票等多种卡券类型。 开发者可以通过卡券接口快速完成制券、发券及销券流程:
1、创建卡券接口 开发者可通过该接口,创建卡券,导入/拉取卡券适用门店、获取卡券颜色列表。
2、卡券投放接口 开发者可通过该接口,生成卡券领取二维码,也可在网页内调用JavaScript接口,引导用户领取卡券。
3、卡券核销接口
调用核销接口可对指定卡券进行核销。支持网页内调用JavaScript接口拉取卡券列表,用户选择卡券后即可完成核销。
4、卡券管理接口 开发者可通过该接口,对已创建的卡券进行查询、删除、更改、设置失效等操作。同时,在卡券通过审核、卡券被领取、卡券被删除时,均会推送事件通知开发者。
5、特殊卡票接口 支持特殊卡票券(会员卡、电影票、飞机票、红包、会议门票)的适用场景,提供相应的接口能力,包括激活/绑定会员卡、会员卡交易、更新电影票、在线选座、更新红包余额、更新会议门票等接口。
6、设置测试用户白名单 开发者可设置测试用户白名单,无论卡券是否通过审核均可领取卡券,测试整个卡券的使用流程。
为了了解这个卡劵的复杂性,我们先来看看它的官方的卡劵内容流程图


这个图里面涉及的内容很多,同样卡劵管理的API接口也很多,不过我们总是希望化繁为简,因此我们可以一步步来了解整个卡劵的内容。

2、卡劵的事件通知

卡劵的相关事件,会由微信后台通知我们的服务后台,因此我们可以对卡劵的创建、使用等各个方面都有相关的事件通知,我们在对应的事件上实现我们的卡劵管理逻辑也是很方便的。
下面列出卡劵管理里面的后台消息通知分类。



这些消息对应的事件,我们可以放到请求的事件类型里面,这样我们在统一调用事件的时候,就可以对他们进行区分了。


这样我们在微信消息处理的入口,就可以分别对这些事件进行处理了。WeixinApiDispatch就是一个分发的管理类,它提取请求消息的内容,并构建不同类型的消息参数,传递给不同的响应函数进行处理,然后返回封装好的XML内容,作为响应。
具体的代码处理逻辑如下图所示。



这样我们在代码里面就可以对相应个事件进行处理了。



其中我们注意到,我们对卡劵的不同事件,把它们的事件信息对象化后进行相应的处理的,如下代码所示。
case RequestEvent.card_pass_check:      //卡劵通过审核
case RequestEvent.card_not_pass_check:  //卡劵未通过审核
    {
        // 卡券通过审核(或审核不通过)
        RequestEventCardCheck info = XmlConvertor.XmlToObject<RequestEventCardCheck>(postStr);
        if (info != null)
        {
        }
        LogTextHelper.Info(eventName + ((info == null) ? "info is null" : info.ToJson()));
    }
    break;

3、卡劵的分类及创建操作

1)卡劵分类
前面介绍了,微信卡劵目前支持优惠券(代金券、折扣券、礼品券、团购券)、会员卡、景点门票、电影票、飞机票、红包、会议门票等多种卡券类型。我们在微信后台,可以手工创建优惠卷,如下图所示。


由于各个卡劵之间的数据有相同的部分,也有部分的部分,我们需要在类的层面上对他们进行不同的信息建模。

我们再来定义一个卡劵类型的枚举,方便我们在代码中使用,这个枚举对象也包含了我们前面介绍到的那些卡劵类型了。

/// <summary>
/// 卡券类型
/// </summary>
public enum CardType
{
    /// <summary>
    /// 折扣券
    /// </summary>
    DISCOUNT = 0,
    /// <summary>
    /// 代金券
    /// </summary>
    CASH = 1,
    /// <summary>
    /// 礼品劵、兑换券
    /// </summary>
    GIFT = 2,
    /// <summary>
    /// 优惠券/通用券
    /// </summary>
    GENERAL_COUPON = 3,
    /// <summary>
    /// 团购券
    /// </summary>
    GROUPON = 4,

    /// <summary>
    /// 会员卡
    /// </summary>
    MEMBER_CARD = 5,
    /// <summary>
    /// 门票
    /// </summary>
    SCENIC_TICKET = 6,
    /// <summary>
    /// 电影票
    /// </summary>
    MOVIE_TICKET = 7,
    /// <summary>
    /// 飞机票
    /// </summary>
    BOARDING_PASS = 8,
    /// <summary>
    /// 红包
    /// </summary>
    LUCKY_MONEY = 9,
    /// <summary>
    /// 会议门票
    /// </summary>
    MEETING_TICKET = 10,
    /// <summary>
    /// 汽车票
    /// </summary>
    BUS_TICKET,
}

由于不同类型卡劵的信息不同,因此我们需要封闭创建这些对应的卡劵类,以方便构建对应的信息用于创建操作。

2)创建卡券
创建卡券的接口调用顺序


其中上传图片,就是采用通用的图片上传接口上传即可,上传后获得对应的图片URL地址。
上传图片接口调用请求说明
HTTP请求方式: POST/FROM

URL:https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
优惠劵的背景色,在微信里面有一些参考色样,如下图所示。


创建卡券接口是微信卡券的基础接口,用于创建一类新的卡券,获取card_id,创建成功并通过审核后,商家可以通过文档提供的其他接口将卡券下发给用户,每次成功领取,库存数量相应扣除。
接口调用请求说明
HTTP请求方式: POST

URL: https://api.weixin.qq.com/card/create?access_token=ACCESS_TOKEN

参数说明


团购券


团购劵JSON示例

{
 "card": {
     "card_type": "GROUPON",
     "groupon": {
         "base_info": {
         ················
         },
          "advanced_info": {
         ················
          },
         "deal_detail": "示例"
     }
 }
}

而代金券提交的信息如下所示。
代金券


代金券JSON示例

{
 "card": {
     "card_type": "CASH",
     "cash": {
         "base_info": {
         ················
         },
          "advanced_info": {
         ················
          },
         "least_cost": 1000,
         "reduce_cost": 100,
     }
 }
}

当前其他几种类型个卡劵也各有不同,不在一一赘述,可以看到每种卡劵携带的信息,有部分一样,有部分不同,但是它们创建卡劵的时候,使用的是同一个接口,这种接口方式在卡劵接口里面很常见。
其中卡劵里面的base_info(卡券基础信息)字段-必填字段、base_info(卡券基础信息)字段-非必填字段、Advanced_info(卡券高级信息)字段比较复杂,具体请参考相关的字段说明列表。

创建卡劵的返回说明
数据示例:

{
   "errcode":0,
   "errmsg":"ok",
   "card_id":"p1Pj9jr90_SQRaVqYI239Ka1erkI"
}

4、创建卡劵的类定义和API封装

根据这些信息,我们创建卡劵的时候,我们可以定义不同的信息实体,如下所示是卡劵基类和折扣劵的类定义信息。

/// <summary>
/// 卡劵基类信息
/// </summary>
public class CardJson
{
    /// <summary>
    /// 基础信息
    /// </summary>
    public CardBaseInfo base_info { get; set; }

    /// <summary>
    /// 高级字段
    /// </summary>
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public CardAdvanceInfo advanced_info{ get; set; }
}

/// <summary>
/// 折扣券数据
/// </summary>
public class DisCountCardJson : CardJson
{
    /// <summary>
    /// 折扣券专用,表示打折额度(百分比)。填30就是七折。
    /// </summary>
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public int discount { get; set; }
}

其他卡劵的信息也是类似,根据需要扩展即可,如会员卡的信息,我们可以按照上面的继承关系进行字段的补充即可。

/// <summary>
/// 会员卡的详细信息,是CardDetailJson的子类
/// </summary>
public class MemberCardJson : CardJson
{
    /// <summary>
    /// 显示积分,填写true或false,如填写true,积分相关字段均为必填。
    /// </summary>
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public bool supply_bonus { get; set; }

    /// <summary>
    /// 是否支持储值,填写true或false。如填写true,储值相关字段均为必填。
    /// </summary>
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public bool supply_balance { get; set; }

    /// <summary>
    /// 特权说明
    /// 非必填
    /// </summary>
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string prerogative { get; set; }

    /// <summary>
    /// 设置为true时用户领取会员卡后系统自动将其激活,无需调用激活接口
    /// </summary>
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public bool auto_activate { get; set; }

    /// <summary>
    /// 设置为true时会员卡支持一键激活,不允许同时传入activate_url字段,否则设置wx_activate失效。
    /// 非必填
    /// </summary>
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
    public bool wx_activate { get; set; }

    ..........

还有其他类型的数据,如会议卡劵,电影卡劵信息等类库也一样处理,其他的依照此规则扩展即可。

/// <summary>
/// 会议门票数据
/// </summary>
public class MettingTicketJson : CardJson
{
    /// <summary>
    /// 会议详情
    /// </summary>
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string meeting_detail { get; set; }

    /// <summary>
    /// 会场导览图
    /// </summary>
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string map_url { get; set; }
}
       
/// <summary>
/// 门票数据
/// </summary>
public class ScenicTicketJson : CardJson
{
    /// <summary>
    /// 票类型,例如平日全票,套票等
    /// 非必填
    /// </summary>
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string ticket_class { get; set; }
    /// <summary>
    /// 导览图url
    /// 非必填
    /// </summary>
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public string guide_url { get; set; }
}

有了这些信息,我们就可以通过统一的接口函数进行卡劵的创建操作了。



在实现函数的最后,我们就是调用接口的URL,提交对应的数据就可以了.

var url = string.Format("https://api.weixin.qq.com/card/create?access_token={0}", accessToken);
var result = JsonHelper<CardCreateResultJson>.ConvertJson(url, cardData);
return result != null ? result.card_id : null;

如果对这个《C#开发微信门户及应用》系列感兴趣,可以关注我的其他文章.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容