商家通过使用 uid 发券组件能力,在用户确认后,开发者可基于支付宝用户的 userid,将优惠券发放至用户支付宝客户端的卡包内。从而实现将用户在商家私域场景内领取的优惠券,同步到支付宝客户端的卡包内,方便用户集中管理自己领取的各类优惠券,同时也可借助卡包的的流量促进商家优惠券的使用率。
本文主要面向商家/服务商的产品及技术人员,描述 uid 发券组件的对接流程。
1.1 流程简介
- 步骤(1):用户在商家活动页点击领券。
- 步骤(2):引导用户通跳转至领券预览页,完成领券授权操作。详情可查看 第三步:用户跳转至领券预览页。
- 步骤(3)、(4):组件生成授权 token 并渲染领券页面。
- 步骤(5):用户点击 确认领券,触发第(6)步操作。
- 步骤(6):组件会调用开发者在模板配置的 merchant.mcallbackurl 接口,开发者在该接口 url 的 query 参数中获取 token(对应步骤(7)中的 user_token),该接口需要实现的功能及要求可查看 第四步:发券组件回调 callback,该步骤如果超时或者失败,领券组件将展示领券失败但发券可能成功。
- 步骤(7):开发者获取 token 后,需要调用支付宝发券接口进行发券,可查看 第五步:调用接口发券。
- 步骤(9):开发者系统需要将步骤(7)中支付宝发券接口的结果(如成功,需包含券 id passid)在步骤(10)返回给组件,详情可查看下文 返回发券结果。
- 步骤 (11)、(12):组件通过步骤(10)返回的结果,查询确认领券结果并展示给用户。
- 步骤(13)、(14):领券组件会在展示结果一段时间时候自动退出, 商家营销页面可监听页面切回前台事件进行后续处理(刷新、跳转其它页面)。
1.2 用户端流程
说明:
- 跳转至领券预览页时 biztype 参数可指定预览页展示类型:
svpage : 全屏样式单张优惠券(h5页面)。 - 用户领券流程中,开发者需唤起发券组件页面,用户操作后,发券组件页面将自动关闭。
2.1 设计券模板样式
- 商家使用支付宝账号登录 ,根据页面提示完成卡券的设计。
说明:卡券背景图 strip 、logo 等图片内容可在平台设计时上传验证是否合规,后续创建模板时需传入图片 url 地址。
- 点击 提交 保存设计好的券模板后,在 我的alipass 页面下载券模板文件。
- 下载得到券模板 .alipass 后缀的压缩包,用解压软件解压,其中 pass.json 即为模板的主要内容。
2.2 修改券模板参数
下载 pass.json 中 json 参数需做如下修改,各参数详情可查看 参数详细说明。
2.2.1 修改渠道属性(platform)节点
- 将 platform 中 channelid 字段值,改为发券的 appid。
- channelid 指定模板的所属者,必须修改为模板创建者的 appid。
- 删除 platform 中 webserviceurl 字段。
- 历史遗留参数,直接删掉节点即可。
2.2.2 修改文件属性(fileinfo)节点
将 fileinfo 中 serialnumber 字段值,改为 $serialnumber$ 。
serialnumber 指定券模板下发给每个用户的券 id,必须配置成动态参数 $serialnumber$,因为每张券的券 id 应保持唯一性,而每次调用发券接口中都需要指定 serialnumber 参数的值。
2.2.3 增加商家属性(merchant)节点
- 修改 merchant 中 mname 字段,根据商家需求定义展示名称。
- 添加 merchant 中 mcallbackurl 字段,配置接收 token 的商家页面回调地址,地址必须为 https 协议。
注意:merchant 中 mcallbackurl 地址必须为 https 地址。
2.2.4 修改基础属性(evoucherinfo)节点
- 建议将 evoucherinfo 中 startdate 字段值,配置成动态参数 $validstartdate$ 。
- 建议将 evoucherinfo 中 enddate 字段值,配置成动态参数 $validenddate$ 。
- 其它参数需开发者根据实际需求选择是否修改为动态参数。
注意:
- 若将 startdate、enddate、title、mcallbackurl 四个模板元素配置为动态参数,则跳转预览页时必须传入上述参数值用于预览页渲染,否则会报错 预览页渲染失败/系统错误。
- 动态参数传参规则:以 evoucherinfo -> startdate 参数为例,创建模板时若定义
"startdate":"$validstartdate$"
,则跳转至领券详情页及发券接口动态参数赋值需以占位符为 key 即"validstartdate":"2020-08-24 00:00:00"
。
2.2.5 完成以上修改后的 pass.json 数据
{ "evoucherinfo":{ "title":"上优酷,看世界杯优酷vip会员3天", "type":"marketvoucher", "product":"free", "startdate":"$validstartdate$", "enddate":"$validenddate$", "operation":[ { "format":"url", "message":"$url$", "alttext":"立即激活" } ], "einfo":{ "logotext":"3天", "secondlogotext":"64场高清直播,进球就下红包雨", "auxiliaryfields":[ ], "customfields":[ { "label":"详细说明", "value":"", "type":"url", "more":{ "url":"http://xxxxxxxxxxxx" } } ], "uselimitdesc":"优酷vip会员", "brandname":"上优酷,看世界杯", "originprice":"", "banner":{ "bannerimg":"", "url":"" }, "passimg":"https://tfsimg.alipay.com/images/alipassprod/tb17floxb8rdunk6xejwu2eyxxa", "passimgratio":"2.79" } }, "platform":{ "channelid":"2018041602567779" }, "style":{ "backgroundcolor":"rgb(233,16,78)" }, "fileinfo":{ "formatversion":"4", "canshare":true, "canbuy":false, "canpresent":false, "serialnumber":"$serialnumber$" }, "source":"alipassprod", "merchant":{ "mname":"优酷视频", "mcallbackurl":"https://test.callback.com/alipay/callback.htm" } }
开发者完成上述步骤后,可调用 alipay.pass.template.add(卡券模板创建接口)创建券模板。
3.1 示例代码
alipayclient alipayclient = new defaultalipayclient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","gbk","alipay_public_key","rsa2"); alipaypasstemplateaddrequest request = new alipaypasstemplateaddrequest(); request.setbizcontent("{" " \"unique_id\":\"20140709150010\"," " \"tpl_content\":\"{\\\"logo\\\": \\\"\\\",\\\"strip\\\": null,\\\"icon\\\": null,\\\"content\\\": {}}\"" "}"); alipaypasstemplateaddresponse response = alipayclient.execute(request); if(response.issuccess()){ system.out.println("调用成功"); } else { system.out.println("调用失败"); }
3.1.1 入参说明
- unique_id:当前请求的唯一串号,唯一标示 1 次创建模板的请求,每次创建模板需要生成新的 unique_id。
- tpl_content:为 json 对象,传递卡券模板内容信息。
- logo:必填,商家 logo 图片地址。因为当前模板下载文件中没有返回 logo 图片地址的值,商家可以选择填入 logo 的公网可访问自定义链接地址。 还可使用 (上传门店照片和视频接口)上传图片获取 url 地址(需添加 商家会员卡)。
- icon:可选,商家 icon 图片地址。
- strip:可选,券背景图片地址。
- content:必填,详细模板内容,直接传入上一步中修改完成的 pass.json 内容即可。详情可查看 参数详细说明。
3.1.2 响应示例
接口响应也对应有 json 格式字串,可查看接口文档。
{ "sign":"eritjkeijkjhkkkkkkkhjereeeeeeeeeee", "alipay_pass_template_add_response":{ "msg":"service currently unavailable", "code":"20000", "sub_msg":"系统繁忙", "sub_code":"isp.unknow-error" } }
响应参数说明
- 解析 response 中 result 字串,将 string 类型的 result 转换为 json 对象,取其 tpl_id 即为本次创建的券模板 id。
- 而 result 中 tpl_params 为动态参数列表,返回在模板文件中配置的所有动态参数名,原则上所有在模板中配置 占位 的动态参数都要在调发券接口发券时传入实际值。如:创建模板时若定义
"startdate":"$validstartdate$"
,则跳转至领券详情页及发券接口动态参数赋值需以占位符为 key 即"validstartdate":"2020-08-24 00:00:00"
。
商家完成 卡券模板创建 后,开发者可通过如下三种方式跳转至领券预览页领取优惠券。
注意:唤起预览页时,无需在入参中显式指定userid,支付宝将直接获取当前登录用户userid。同时,在用户确认领券后,支付宝回调商家,也不会返回userid。建议商家利用extinfo透传必要的业务串号或上下文,以便第四步确定发券目标用户。
4.1 通过 scheme url 方式跳转
string tpl_id = "your_tpl_id"; // 动态参数赋值并encode string params = "{\"validstartdate\":\"2020-08-20 00:00:00\",\"validenddate\":\"2020-09-10 00:00:00\"}"; // key值可查看 创建模板 > 响应参数说明 获取 string encodeparams = urlencoder.encode(params,"utf-8"); // 拼接原始链接并encode string mid = "/www/voucher.html?__webview_options__=abv=no&ttb=auto&biztype=svpage&templateid="tpl_id"&templateparams="encodeparams; string encodemid = urlencoder.encode(mid,"utf-8"); // 生成完整链接 string url = "alipays://platformapi/startapp?appid=68687143&url="encodemid; // alipays://platformapi/startapp?appid=68687143 为固定值,请勿修改 system.out.println(url);
完整链接示例:
alipays://platformapi/startapp?appid=68687143&url=/www/voucher.html?__webview_options__=abv%3dno%26ttb%3dauto&biztype=svpage&templateid=templateid&templateparams=%7b%22startdate%22%3a%222020-08-10+00%3a00%3a00%22%2c%22enddate%22%3a%222020-09-10+00%3a00%3a00%22%7d
4.1.1 参数说明
跳转至领券前置页只需拼接参数生成跳转链接即可,链接拼接参数包括:
- biztype:必填,指定本次领券预览页展示类型。枚举支持:
- svpage : 全屏样式单张优惠券(h5页面)。
- templateid:必填,券模板 id。
- templateparams:模板动态参数。使用说明如下:
- 创建券模板时若将 startdate、enddate、title、mcallbackurl 四个模板元素配置为动态参数,本参数必填。如:
{"startdate":"$validstartdate$"}
。拼接跳转链接时,需传入对应参数动态 key 及对应 value 用于预览页渲染展示,如:{"validstartdate":"2020-08-20 00:00:00"}
,否则会报错 预览页渲染失败/系统错误,其余动态参数在发券接口传入即可。 - serialnumber 为动态参数时仅需发券接口中传入,此处可不填写。
- extinfo:选填,扩展信息,商家自定义,页面将值原封不动回传商家回调地址;不用则无需关心,用于实现各种进阶业务需求逻辑,值由商家实时生成、传入并识别。extinfo 参数如果包含中文字符或者其它 url 协议的特殊字符等,由于服务端处理逻辑为直接拼接,因此拼接成 url 参数的时候 extinfo 建议进行 2 次 url 编码。
// extinfo对应的值 a=b&c=d,则经过2次编码后为: extinfo=a%253db%2526c%253dd
4.2 通过 h5 api 方式跳转
4.2.1 示例代码
<script src="https://gw.alipayobjects.com/as/g/h5-lib/alipayjsapi/3.1.1/alipayjsapi.inc.min.js">script>
<button id="j_btn" class="btn btn-default">发放优惠券button>
<script>
var btn = document.queryselector('#j_btn');
btn.addeventlistener('click', function(){
//此处 templateid 只是示例,并非真实的数据
ap.call('addcoupon', {
templateid: '2019110615261633866806432',
biztype:'svpage',
templateparams:''
}, function (res) {
console.log('res === ' json.stringify(res));
});
});
script>
参数说明
- biztype:必填,指定本次领券预览页展示类型。
svpage:全屏样式单张优惠券(h5页面)。 - templateid:必填,券模板id。
- templateparams:模板动态参数。使用说明如下:
- 创建券模板时若将 startdate、enddate、title、mcallbackurl 四个模板元素配置为动态参数,本参数必填。如:
{"startdate":"$validstartdate$"}
。拼接跳转链接时,需传入对应参数动态 key 及对应 value 用于预览页渲染展示,如:{"validstartdate":"2020-08-20 00:00:00"}
,否则会报错 预览页渲染失败/系统错误,其余动态参数在发券接口传入即可。 - serialnumber 为动态参数时仅需发券接口中传入,此处可不填写。
- extinfo:选填,扩展信息,商家自定义,页面将值原封不动回传商家回调地址;不用则无需关心,用于实现各种进阶业务需求逻辑,值由商家实时生成、传入并识别。
4.3 通过小程序 jsapi 方式跳转
4.3.1 示例代码
my.call('addcoupon',{ templateid: '2019110615261633866806432', biztype:'svpage', templateparams:'{模板json字符串}' }, function(result) { console.log('小程序 call addcoupon'json.stringify(result)); });
参数说明
- biztype:必填,指定本次领券预览页展示类型。
svpage:全屏样式单张优惠券(h5页面)。 - templateid:必填,券模板 id。
- templateparams:模板动态参数。使用说明如下:
- 创建券模板时若将 startdate、enddate、title、mcallbackurl 四个模板元素配置为动态参数,本参数必填。如:
{"startdate":"$validstartdate$"}
。拼接跳转链接时,需传入对应参数动态 key 及对应 value 用于预览页渲染展示,如:{"validstartdate":"2020-08-20 00:00:00"}
,否则会报错 预览页渲染失败/系统错误,其余动态参数在发券接口传入即可。 - serialnumber 为动态参数时仅需发券接口中传入,此处可不填写。
- extinfo:选填,扩展信息,商家自定义,页面将值原封不动回传商家回调地址 mcallbackurl;不用则无需关心,用于实现各种进阶业务需求逻辑,值由商家实时生成、传入并识别。
4.3.2 错误码
error | 说明 |
17000 | 通用错误码,发券失败 |
17001 | 重复调用错误,同时只能允许运行一个发券任务 |
17002 | 参数错误,必填项为空等 |
17003 | 用户主动取消领券操作 |
用户在发券确认页点击 确认领取,发券组件将通过 get 方式向优惠券模板 mcallbackurl 地址发送发券授权 token 数据用于商家调用接口给用户发放优惠券。
5.1 回调 callback url 的样例
https://test.callback.com/alipay/callback.htm?templateid=2019041914323202306418702&token=b18ca3975872e092e5ded56a6e0884b9×tamp=1559133415273
5.2 返回发券结果
开发者完成 第五步:调用接口发券 后,需向发券组件返回 json 格式的发券结果,示例如下:
{"success":"true","passid":"your_passid","resultdesc":"发券成功"}
参数说明
- success:必传,是否成功。
- passid:必传,如果发券成功,则必传该字段,后续将用来查询发券结果。
- resultdesc:可选,发券结果描述。
承接上步,商家系统通过发券组件回调获取了发券授权 token 令牌及其它发券请求参数后,商家后台系统可组装发券参数调用 alipay.pass.instance.add(卡券实例发放接口)发券。
6.1 示例代码
alipayclient alipayclient = new defaultalipayclient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","gbk","alipay_public_key","rsa2"); alipaypassinstanceaddrequest request = new alipaypassinstanceaddrequest(); request.setbizcontent("{" " \"tpl_id\":\"f038871a4b1151e8038bb9277c3d52e3\"," " \"tpl_params\":\"{\\\"title\\\":\\\"券标题\\\",\\\"channelid\\\":\\\"xxx\\\",\\\"serialnumber\\\":\\\"xxxx\\\"}\"," " \"recognition_type\":\"2\"," " \"recognition_info\":\"{\\\"recognition_info\\\":{\\\"user_id\\\":\\\"2088402021319452\\\"}}\"" "}"); alipaypassinstanceaddresponse response = alipayclient.execute(request); if(response.issuccess()){ system.out.println("调用成功"); } else { system.out.println("调用失败"); }
入参说明
- tpl_id:必填,券模板 id。
- tpl_params:必填,模板动态参数,创建模板时
serialnumber
必须为动态参数入值,其它参数根据商家业务决定进行传值。 - recognition_type:发券(用户信息识别)类型,支付宝卡包暂仅支持 2 基于用户信息识别。
- recognition_info:发券用户信息模型,当 recognition_type = "2"时,配置传参如下:
- user_id:指定本次发券的支付宝 userid。注意user_id务必与调用appid对应,否则调用异常。
- user_token:本次发券该用户确认领取时生成并传回给商家的发券 token 令牌值。
注意:发券接口参数中传入的 user_token 与 tpl_id 及 user_id 背后的用户都必须对应。
6.2 响应示例
{ "alipay_pass_instance_add_response":{ "msg":"service currently unavailable", "code":"20000", "sub_msg":"系统繁忙", "sub_code":"isp.unknow-error" }, "sign":"eritjkeijkjhkkkkkkkhjereeeeeeeeeee" }
开发者调用 alipay.pass.instance.add(卡券实例发放接口)发放优惠券后,无论发放结果如何都需向发券组件返回发券结果,示例可查看 返回发券结果。
展示领券结果时,发券组件回调 callback 接口最长等待 15s 时间,如果在等待时间内商家没有返回发券成功结果,则领券组件将提示用户领券失败,但是发券可能成功,因此:
- 商家侧领券结果需以自身系统调用 alipay.pass.instance.add(卡券实例发放接口)结果为准。
- 用户侧不论商家回调接口向组件返回发券成功、失败还是超时未返回结果,支付宝客户端都会查询支付宝卡包后台最终确认券发放结果并以此为准。
即若商家超时未返回发券结果但实际 alipay.pass.instance.add(卡券实例发放接口)发券成功,则用户领券页会展示 领券失败,请稍后重试,但其支付宝卡包中会添加对应优惠券。
完成卡券发放后,开发者还可调用 (卡券实例更新接口)实现指定卡券核销、失效、更新卡券样式内容三大功能。
注意:该接口仅支持修改单张卡券实例。
8.1 核销卡券功能
完成卡券发放后,开发者可调用 (卡券实例更新接口)进行卡券核销,使卡券在用户的支付宝客户端展示为 已使用 状态。对于支付宝卡券而言,核销操作只是将卡券状态变更为 used(已使用),用户客户端展示为已使用状态,未涉及资金流的核销。仅支持核销有效状态的卡券,若卡券处于卡券删除或者已转赠,不可进行核销操作。
8.1.1 http 请求源码示例
https://openapi.alipay.com/gateway.do?sign=fnqp42dy3mgkgiby20l9ie2/oevuzcw55q7jzofxxhybds3uda4iziwqlyyo10garbckpv+hrydjnepqw7hatvnjuwuyghxdduywyadayg5y0rvimduqeys+skgqmedyneapfwyzop5acp7dxl7dkck6byiayloe5wfxj1rtmey=×tamp=2015-06-24 21:09:20&sign_type=rsa&app_id=102014022600003526&method=alipay.pass.instance.update&version=1.0&alipay_sdk=alipay-sdk-java-dynamicversionno&format=json& biz_content={ "user_id": "xxxx", "status": "used" "channel_id": "102014022600003526", "serial_number": "4333673662446155" }
8.1.2 客户端示例图
调用更新卡券接口核销卡券之后,用户在支付宝客户端展示的卡券,将变成已使用状态,并且进入已失效列表。
8.2 失效卡券功能
完成卡券发放后,开发者可调用 alipay.pass.instance.update(卡券实例更新接口)进行卡券失效操作。该功能主要将发放的卡券进行作废操作,卡券将在用户的支付宝客户端消失。
8.2.1 http 请求源码示例
https://openapi.alipay.com/gateway.do?sign=fnqp42dy3mgkgiby20l9ie2/oevuzcw55q7jzofxxhybds3uda4iziwqlyyo10garbckpv+hrydjnepqw7hatvnjuwuyghxdduywyadayg5y0rvimduqeys+skgqmedyneapfwyzop5acp7dxl7dkck6byiayloe5wfxj1rtmey=×tamp=2015-06-24 21:09:20&sign_type=rsa&app_id=102014022600003526&method=alipay.pass.instance.update&version=1.0&alipay_sdk=alipay-sdk-java-dynamicversionno&format=json& biz_content={ "user_id": "xxxx", "status": "closed", "channel_id": "102014022600003526", "serial_number": "4333673662446155" }
8.3 更新卡券内容功能
完成卡券发放后,开发者可调用 alipay.pass.instance.update(卡券实例更新接口)更新卡券样式内容,包括内容(如优惠描述信息和 logotext)、logo、背景图、样式等(要支持更新,必须在模板中将对应字段设置成可变参数)。
8.3.1 http 请求源码示例
https://openapi.alipay.com/gateway.do?sign=fnqp42dy3mgkgiby20l9ie2/oevuzcw55q7jzofxxhybds3uda4iziwqlyyo10garbckpv+hrydjnepqw7hatvnjuwuyghxdduywyadayg5y0rvimduqeys+skgqmedyneapfwyzop5acp7dxl7dkck6byiayloe5wfxj1rtmey=×tamp=2015-06-24 21:09:20&sign_type=rsa&app_id=102014022600003526&method=alipay.pass.instance.update&version=1.0&alipay_sdk=alipay-sdk-java-dynamicversionno&format=json& biz_content={ "user_id": "xxxx", "channel_id": "102014022600003526", "serial_number": "4333673662446155", "tpl_params":{"discountinfo": "凭此券即可打5折","logotext": "四季风情5折优惠券"} }