C#開發(fā)微信門戶及應(yīng)用(38)--微信搖一搖紅包功能
搖一搖周邊紅包接口是為線下商戶提供的發(fā)紅包功能。用戶可以在商家門店等線下場(chǎng)所通過(guò)搖一搖周邊領(lǐng)取商家發(fā)放的紅包。我曾經(jīng)在《C#開發(fā)微信門戶及應(yīng)用(28)--微信“搖一搖·周邊”功能的使用和接口的實(shí)現(xiàn)》介紹過(guò)微信搖一搖的相關(guān)管理,包括頁(yè)面、設(shè)備之間的關(guān)系,以及使用等方面內(nèi)容。本篇繼續(xù)介紹搖一搖設(shè)備的另外一項(xiàng)功能,搖一搖紅包功能,介紹如何利用微信搖搖周邊的后臺(tái)配置好頁(yè)面及地址,然后通過(guò)微信JSSDK的方式,搖一搖獲取紅包的整個(gè)流程功能。
1、微信搖一搖紅包功能介紹
功能說(shuō)明
搖一搖周邊紅包接口是為線下商戶提供的發(fā)紅包功能。用戶可以在商家門店等線下場(chǎng)所通過(guò)搖一搖周邊領(lǐng)取商家發(fā)放的紅包,在線上轉(zhuǎn)發(fā)分享無(wú)效。
開發(fā)者可通過(guò)接口開發(fā)搖一搖紅包功能,特點(diǎn)包括:
- 可選擇使用模板加載頁(yè)或自定義Html5頁(yè)面調(diào)起微信原生紅包頁(yè)面(詳見創(chuàng)建紅包活動(dòng)中use_template字段,1為使用模板,2為使用自定義Html5頁(yè)面)
- 原生紅包頁(yè)面拆紅包,無(wú)需通過(guò)公眾號(hào)消息下發(fā)
- 提供關(guān)注公眾號(hào)能力,用戶可自行選擇是否關(guān)注(裂變紅包分享時(shí)無(wú)效)
- 完成頁(yè)面可配置跳轉(zhuǎn)鏈接,可跳轉(zhuǎn)商戶的其他自定義Html5頁(yè)面
- 同一個(gè)用戶在單個(gè)紅包活動(dòng)中只能領(lǐng)取1次紅包
用戶側(cè)交互流程
常規(guī)的搖一搖紅包的流程如下所示,這里沒(méi)有使用用戶自定義的模板,也就是使用系統(tǒng)內(nèi)置的(努力加載中。。。)的頁(yè)面,紅包需要自己拆開。
紅包組件接口調(diào)用流程
- 申請(qǐng)紅包接口權(quán)限:登錄搖一搖周邊商戶后臺(tái)https://zb.weixin.qq.com?,進(jìn)入開發(fā)者支持,申請(qǐng)開通搖一搖紅包組件接口;
- 紅包預(yù)下單:調(diào)用微信支付的api進(jìn)行紅包預(yù)下單,告知需要發(fā)放的紅包金額,人數(shù),生成紅包ticket;
- 創(chuàng)建活動(dòng)并錄入紅包信息:調(diào)用搖周邊平臺(tái)的api錄入創(chuàng)建紅包活動(dòng)并錄入信息,傳入預(yù)下單時(shí)生成的紅包ticket;
- 調(diào)用jsapi抽紅包:在搖出的頁(yè)面中通過(guò)調(diào)用jsapi抽紅包,抽中紅包的用戶可以拆紅包;
- 調(diào)用以上接口時(shí),紅包提供商戶和紅包發(fā)放商戶公眾號(hào)要求一致。
搖一搖紅包的處理過(guò)程可以先的流程說(shuō)明,申請(qǐng)權(quán)限后,需要在搖一搖后臺(tái)配置相關(guān)的紅包處理頁(yè)面,然后通過(guò)紅包接口處理提交紅包數(shù)據(jù),最后通過(guò)搖一搖的設(shè)備搖出界面,使用JSAPI實(shí)現(xiàn)抽取紅包的操作,具體過(guò)程如下所示。
其中紅包接口處理,是調(diào)用一系列的紅包接口實(shí)現(xiàn)的,包括紅包預(yù)下單、創(chuàng)建紅包活動(dòng)、錄入紅包信息等操作,如下所示。
?
搖一搖紅包功能開通在后臺(tái)獲取接口即可,如下所示。
假設(shè)已經(jīng)有相關(guān)的搖一搖設(shè)備(如果沒(méi)有或者需要加入新的搖一搖設(shè)備,請(qǐng)參考上篇隨筆《C#開發(fā)微信門戶及應(yīng)用(28)--微信“搖一搖·周邊”功能的使用和接口的實(shí)現(xiàn)》的相關(guān)介紹,有了設(shè)備后在頁(yè)面管理中添加一個(gè)頁(yè)面,用來(lái)處理?yè)u一搖的信息的。
頁(yè)面的信息,就是添加自定義鏈接界面,如下所示。
然后配置好URL地址接口,URL地址還需要考慮如何獲取用戶的openid,因?yàn)閾u一搖紅包接口必須要獲得當(dāng)前用戶的openid信息,我們可以通過(guò)重定向的方式,使用code獲取對(duì)應(yīng)的openid信息,具體后面詳細(xì)介紹。
?
2、紅包接口處理
前面介紹了,紅包接口處理,是調(diào)用一系列的紅包接口實(shí)現(xiàn)的,包括紅包預(yù)下單、創(chuàng)建紅包活動(dòng)、錄入紅包信息等操作,如下所示。
?
那么我們就需要分別對(duì)這些操作進(jìn)行封裝,并提交相關(guān)的數(shù)據(jù)了。
根據(jù)前面隨筆《C#開發(fā)微信門戶及應(yīng)用(33)--微信現(xiàn)金紅包的封裝及使用》里面的規(guī)則,我們把搖一搖的相關(guān)接口也放在這個(gè)ILotteryApi接口和LotteryApi實(shí)現(xiàn)類里面,如下所示。
下面的搖一搖紅包接口全部是基于上面的接口和實(shí)現(xiàn)類進(jìn)行完善處理的。
?
1)紅包預(yù)下單
接口說(shuō)明
設(shè)置單個(gè)紅包的金額,類型等,生成紅包信息。預(yù)下單完成后,需要在72小時(shí)內(nèi)調(diào)用jsapi完成抽紅包的操作。(紅包過(guò)期失效后,資金會(huì)退回到商戶財(cái)付通帳號(hào)。)
接口調(diào)用說(shuō)明
服務(wù)器端調(diào)用 http請(qǐng)求方式: POST https://api.mch.weixin.qq.com/mmpaymkttransfers/hbpreorder POST數(shù)據(jù)格式:XML 需要商戶證書
請(qǐng)求示例
<xml> <sign><![CDATA[E1EE61A91C8E90F299DE6AE075D60A2D]]></sign> <mch_billno><![CDATA[0010010404201411170000046545]]></mch_billno> <mch_id><![CDATA[10000097]]></mch_id> <wxappid><![CDATA[wxcbda96de0b165486]]></wxappid> <send_name><![CDATA[send_name]]></send_name> <hb_type><![CDATA[NORMAL]]></hb_type> <auth_mchid><![CDATA[10000098]]></auth_mchid> <auth_appid><![CDATA[wx7777777]]></auth_appid> <total_amount><![CDATA[200]]></total_amount> <amt_type><![CDATA[ALL_RAND]]></amt_type> <total_num><![CDATA[3]]></total_num> <wishing><![CDATA[恭喜發(fā)財(cái) ]]></wishing> <act_name><![CDATA[ 新年紅包 ]]></act_name> <remark><![CDATA[新年紅包 ]]></remark> <risk_cntl><![CDATA[NORMAL]]></risk_cntl> <nonce_str><![CDATA[50780e0cca98c8c8e814883e5caa672e]]></nonce_str> </xml>
返回?cái)?shù)據(jù)說(shuō)明
返回格式為xml
成功示例
<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[發(fā)放成功.]]></return_msg> <result_code><![CDATA[SUCCESS]]></result_code> <err_code><![CDATA[0]]></err_code> <err_code_des><![CDATA[發(fā)放成功.]]></err_code_des> <mch_billno><![CDATA[0010010404201411170000046545]]></mch_billno> <mch_id>10010404</mch_id> <wxappid><![CDATA[wx6fa7e3bab7e15415]]></wxappid> <sp_ticket><![CDATA[0cca98c8c8e814883]]></sp_ticket> <total_amount>3</total_amount> <detail_id><![CDATA[001001040420141117000004888]]></detail_id> <send_time><![CDATA[20150101080000]]></send_time> </xml>
失敗示例
<xml> <return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系統(tǒng)繁忙,請(qǐng)稍后再試.]]></return_msg> <result_code><![CDATA[FAIL]]></result_code> <err_code><![CDATA[268458547]]></err_code> <err_code_des><![CDATA[系統(tǒng)繁忙,請(qǐng)稍后再試.]]></err_code_des> <mch_billno><![CDATA[0010010404201411170000046542]]></mch_billno> <mch_id>10010404</mch_id> <wxappid><![CDATA[wx6fa7e3bab7e15415]]></wxappid> <total_amount>3</total_amount> </xml>
根據(jù)請(qǐng)求參數(shù)的說(shuō)明,以及返回的結(jié)果,我們可以分別定義它們的傳入?yún)?shù)和傳出參數(shù),具體的紅包預(yù)下單的接口定義如下
/// <summary> /// 紅包預(yù)下單接口。需要商戶證書 /// 設(shè)置單個(gè)紅包的金額,類型等,生成紅包信息。預(yù)下單完成后,需要在72小時(shí)內(nèi)調(diào)用jsapi完成抽紅包的操作。(紅包過(guò)期失效后,資金會(huì)退回到商戶財(cái)付通帳號(hào)。) /// </summary> /// <param name="data">傳入?yún)?shù)數(shù)據(jù)</param> /// <returns></returns> LotteryPreOrderResult LotteryPreOrder(LotteryPreOrderData info);
其中LotteryPreOrderResult返回的對(duì)象結(jié)果如下所示,主要的信息是要記錄sp_ticket,目前沒(méi)有通過(guò)API接口獲取已經(jīng)預(yù)下單紅包的sp_ticket信息,所以一定要先記錄好,后面在錄入紅包的時(shí)候,需要使用到這個(gè)票據(jù)。
public class LotteryPreOrderResult : PayResult { /// <summary> /// 商戶訂單號(hào) /// </summary> public string mch_billno { get; set; } /// <summary> /// 公眾賬號(hào)appid /// </summary> public string wxappid { get; set; } /// <summary> /// 總付款金額,單位分 /// </summary> public int total_amount { get; set; } /// <summary> /// 一個(gè)普通紅包對(duì)應(yīng)一個(gè)ticket /// </summary> public string sp_ticket { get; set; } /// <summary> /// 紅包內(nèi)部訂單號(hào) /// </summary> public string detail_id { get; set; } /// <summary> /// 紅包發(fā)放時(shí)間 /// </summary> public string send_time { get; set; } }
?
2)創(chuàng)建紅包活動(dòng)
接口說(shuō)明
創(chuàng)建紅包活動(dòng),設(shè)置紅包活動(dòng)有效期,紅包活動(dòng)開關(guān)等基本信息,返回活動(dòng)id
接口調(diào)用說(shuō)明
服務(wù)器端調(diào)用 http請(qǐng)求方式: POST URL: https://api.weixin.qq.com/shakearound/lottery/addlotteryinfo?access_token=ACCESSTOKEN&use_template=1&logo_url=”LOGO_URL”
請(qǐng)求參數(shù)說(shuō)明
參數(shù) | 類型 | 說(shuō)明 |
---|---|---|
access_token | string | accesstoken,以參數(shù)的形式拼裝在url后 |
use_template | int | 是否使用模板,1:使用,2:不使用,以參數(shù)的形式拼裝在url后。(模版即交互流程圖中的紅包加載頁(yè),使用模板用戶不需要點(diǎn)擊可自動(dòng)打開紅包;不使用模版需自行開發(fā)HTML5頁(yè)面,并在頁(yè)面調(diào)用紅包jsapi) |
logo_url | string | 使用模板頁(yè)面的logo_url,不使用模板時(shí)可不加。展示在搖一搖界面的消息圖標(biāo)。圖片尺寸為120x120。 |
POST BODY:JSON格式的結(jié)構(gòu)體,具體信息不在贅述,不過(guò)值得說(shuō)明的是其中的Key是需要注意的,這個(gè)值一定需要使用一個(gè)確定的值,因?yàn)樾枰秃竺娴某槿〖t包的簽名處理一致,否則會(huì)出錯(cuò)無(wú)法抽取紅包。
參數(shù) | 類型 | 說(shuō)明 |
---|---|---|
title | string | 抽獎(jiǎng)活動(dòng)名稱(選擇使用模板時(shí),也作為搖一搖消息主標(biāo)題),最長(zhǎng)6個(gè)漢字,12個(gè)英文字母。 |
desc | string | 抽獎(jiǎng)活動(dòng)描述(選擇使用模板時(shí),也作為搖一搖消息副標(biāo)題),最長(zhǎng)7個(gè)漢字,14個(gè)英文字母。 |
onoff | int | 抽獎(jiǎng)開關(guān)。0關(guān)閉,1開啟,默認(rèn)為1 |
begin_time | long | 抽獎(jiǎng)活動(dòng)開始時(shí)間,unix時(shí)間戳,單位秒 |
expire_time | long | 抽獎(jiǎng)活動(dòng)結(jié)束時(shí)間,unix時(shí)間戳,單位秒,紅包活動(dòng)有效期最長(zhǎng)為91天 |
sponsor_appid | string | 紅包提供商戶公眾號(hào)的appid,需與預(yù)下單中的公眾賬號(hào)appid(wxappid)一致 |
total | long | 紅包總數(shù),紅包總數(shù)是錄入紅包ticket總數(shù)的上限,因此紅包總數(shù)應(yīng)該大于等于預(yù)下單時(shí)紅包ticket總數(shù)。 |
jump_url | string | 紅包關(guān)注界面后可以跳轉(zhuǎn)到第三方自定義的頁(yè)面 |
key | string | 開發(fā)者自定義的key,用來(lái)生成活動(dòng)抽獎(jiǎng)接口的簽名參數(shù),長(zhǎng)度32位。使用方式見sign生成規(guī)則 |
請(qǐng)求示例
Content-Type: application/json Post Body: { "title": "title", "desc": "desc", "onoff": 1, "begin_time": 1428854400, "expire_time": 1428940800, "sponsor_appid": "wxxxxxxxxxxxxxx", "total": 10, "jump_url": JUMP_URL, "key": "keyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy" }
返回?cái)?shù)據(jù)說(shuō)明
示例
{ "errcode":0, "errmsg":"", "lottery_id":"xxxxxxllllll", "page_id":1, }
根據(jù)上面的接口定義和接口參數(shù)說(shuō)明,我們可以定義創(chuàng)建紅包活動(dòng)的接口定義,如下所示
/// <summary> /// 創(chuàng)建紅包活動(dòng),設(shè)置紅包活動(dòng)有效期,紅包活動(dòng)開關(guān)等基本信息,返回活動(dòng)id /// </summary> /// <param name="accessToken">調(diào)用接口憑證</param> /// <param name="useTempate">是否使用模板</param> /// <param name="login_url">使用模板頁(yè)面的logo_url,不使用模板時(shí)可不加。展示在搖一搖界面的消息圖標(biāo)。圖片尺寸為120x120。</param> /// <returns></returns> AddLotterResult AddLotteryInfo(string accessToken, bool useTempate, string login_url, AddLotteryJson json);
其中AddLotteryResult為我們定義的接口處理結(jié)果,主要需要記錄其中的LotteryID,這個(gè)值需要在后面的錄入紅包接口使用到。
/// <summary> /// 添加紅包活動(dòng)的結(jié)果 /// </summary> public class AddLotterResult : ErrorJsonResult { /// <summary> /// 生成的紅包活動(dòng)id /// </summary> public string lottery_id { get; set; } /// <summary> /// 生成的模板頁(yè)面ID /// </summary> public int page_id { get; set; } }
?
3)錄入紅包信息
在紅包預(yù)下單,以及創(chuàng)建紅包活動(dòng)后,就需要把前面兩者的信息關(guān)聯(lián)起來(lái),這個(gè)操作就是錄入紅包信息,錄入紅包信息包括提交紅包活動(dòng)的ID,以及紅包預(yù)下單的sp_ticket的票據(jù)信息,這樣就可以讓用戶抽取具體的紅包信息了。
接口說(shuō)明
在調(diào)用"創(chuàng)建紅包活動(dòng)"接口之后,調(diào)用此接口錄入紅包信息。注意,此接口每次調(diào)用,都會(huì)向某個(gè)活動(dòng)新增一批紅包信息,如果紅包數(shù)少于100個(gè),請(qǐng)通過(guò)一次調(diào)用添加所有紅包信息。如果紅包數(shù)大于100,可以多次調(diào)用接口添加。請(qǐng)注意確保多次錄入的紅包ticket總的數(shù)目不大于創(chuàng)建該紅包活動(dòng)時(shí)設(shè)置的total值。
接口調(diào)用說(shuō)明
服務(wù)器端調(diào)用 http請(qǐng)求方式: POST URL:https://api.weixin.qq.com/shakearound/lottery/setprizebucket?access_token=ACCESSTOKEN
POST BODY:JSON格式的結(jié)構(gòu)體
參數(shù) | 類型 | 說(shuō)明 |
---|---|---|
lottery_id | string | 紅包抽獎(jiǎng)id,來(lái)自addlotteryinfo返回的lottery_id |
mchid | string | 紅包提供者的商戶號(hào),,需與預(yù)下單中的商戶號(hào)mch_id一致 |
sponsor_appid | string | 紅包提供商戶公眾號(hào)的appid,需與預(yù)下單中的公眾賬號(hào)appid(wxappid)一致 |
prize_info_list | json數(shù)組 | 紅包ticket列表,如果紅包數(shù)較多,可以一次傳入多個(gè)紅包,批量調(diào)用該接口設(shè)置紅包信息。每次請(qǐng)求傳入的紅包個(gè)數(shù)上限為100 |
ticket | string | 預(yù)下單時(shí)返回的紅包ticket,單個(gè)活動(dòng)紅包ticket數(shù)量上限為100000個(gè),可添加多次。 |
請(qǐng)求示例
Content-Type: application/json Post Body: { "lottery_id": "xxxxxxllllll", "mchid": "10000098", "sponsor_appid": "wx8888888888888888" "prize_info_list": [ { "ticket": "v1|ZiPs2l0hpMBp3uwGI1rwp45vOdz/V/zQ/00jP9MeWT+e47/q1FJjwCIP34frSjzOxAEzJ7k2CtAg1pmcShvkChBWqbThxPm6MBuzceoHtj79iHuHaEn0WAO+j4sXnXnbGswFOlDYWg1ngvrRYnCY3g==", } ] }
返回?cái)?shù)據(jù)說(shuō)明
示例
{ "errcode":0, "errmsg":"", "repeat_ticket_list":[ { "ticket": "v1|ZiPs2l0hpMBp3uwGI1rwp45vOdz/V/zQ/00jP9MeWT+e47/q1FJjwCIP34frSjzOxAEzJ7k2CtAg1pmcShvkChBWqbThxPm6MBuzceoHtj79iHuHaEn0WAO+j4sXnXnbGswFOlDYWg1ngvrRYnCY3g==", } ] "success_num":100 }
根據(jù)這些接口定義和傳遞參數(shù)信息,我們可以定義錄入紅包的接口。
/// <summary> /// 錄入紅包信息 /// 在調(diào)用"創(chuàng)建紅包活動(dòng)"接口之后,調(diào)用此接口錄入紅包信息。 /// 注意,此接口每次調(diào)用,都會(huì)向某個(gè)活動(dòng)新增一批紅包信息,如果紅包數(shù)少于100個(gè),請(qǐng)通過(guò)一次調(diào)用添加所有紅包信息。 /// 如果紅包數(shù)大于100,可以多次調(diào)用接口添加。請(qǐng)注意確保多次錄入的紅包ticket總的數(shù)目不大于創(chuàng)建該紅包活動(dòng)時(shí)設(shè)置的total值。 /// </summary> /// <param name="accessToken">調(diào)用接口憑證</param> /// <param name="json">錄入紅包信息</param> /// <returns></returns> SetPrizeBucketResult SetPrizeBucket(string accessToken, SetPrizeBucketJson json);
其中錄入紅包返回的結(jié)果類SetPrizeBucketResult 定義如下所示。
/// <summary> /// 錄入紅包返回的結(jié)果 /// </summary> public class SetPrizeBucketResult : ErrorJsonResult { /// <summary> /// 重復(fù)使用的ticket列表,如為空,將不返回 /// </summary> public List<PrizeTicket> repeat_ticket_list { get; set; } /// <summary> /// 過(guò)期的ticket列表,如為空,將不返回 /// </summary> public List<PrizeTicket> expire_ticket_list { get; set; } /// <summary> /// 金額不在大于1元,小于1000元的ticket列表,如為空,將不返回 /// </summary> public List<PrizeTicket> invalid_amount_ticket_list { get; set; } /// <summary> /// 原因:生成紅包的時(shí)候,授權(quán)商戶號(hào)auth_mchid和auth_appid沒(méi)有寫搖周邊的商戶號(hào) /// </summary> public List<PrizeTicket> wrong_authmchid_ticket_list { get; set; } /// <summary> /// ticket解析失敗,可能有錯(cuò)別字符或不完整 /// </summary> public List<PrizeTicket> invalid_ticket_list { get; set; } /// <summary> /// 成功錄入的紅包數(shù)量 /// </summary> public int success_num { get; set; } }
?
3、紅包接口的使用及JSAPI的搖一搖頁(yè)面處理
前面說(shuō)明了相關(guān)的接口信息和對(duì)應(yīng)的結(jié)果類的定義,我們具體在根據(jù)相關(guān)的說(shuō)明,實(shí)現(xiàn)接口的處理就可以了,這個(gè)小節(jié)介紹如何使用這些接口,實(shí)現(xiàn)我們對(duì)搖一搖紅包的整個(gè)流程的處理。
如第一步,調(diào)用紅包預(yù)下單處理。
string sp_ticket = ""; /// <summary> /// 紅包預(yù)下單,并記錄紅包的ticket信息 /// </summary> private void btnHbPreOrder_Click(object sender, EventArgs e) { LotteryPreOrderData info = new LotteryPreOrderData() { total_amount = 100, total_num = 1, act_name = "恭喜發(fā)財(cái)", remark = "恭喜發(fā)財(cái)", wishing = "恭喜發(fā)財(cái)", }; var result = hbApi.LotteryPreOrder(info); sp_ticket = result.sp_ticket;//賦值,方便下面的錄入紅包操作 Console.WriteLine(XmlConvertor.FormatXml(result.ToXml())); }
第二部創(chuàng)建紅包活動(dòng),如下所示。
string lotteryId = ""; /// <summary> /// 創(chuàng)建紅包活動(dòng),并記錄活動(dòng)的ID /// </summary> private void btnCreateLottery_Click(object sender, EventArgs e) { AddLotteryJson json = new AddLotteryJson() { begin_time = DateTime.Now.DateTimeToInt(), expire_time = DateTime.Now.AddDays(90).DateTimeToInt(), title = "測(cè)試紅包", desc = "測(cè)試紅包", sponsor_appid = this.AppId, onoff = 1, total = 1, jump_url = "http://www.iqidi.com", key = accountInfo.PayAPIKey }; var result = hbApi.AddLotteryInfo(token, false, null, json); lotteryId = result.lottery_id;//賦值方便查詢紅包 Console.WriteLine(result.ToJson()); }
第三步,根據(jù)紅包預(yù)下單結(jié)果和紅包活動(dòng)創(chuàng)建結(jié)果,錄入紅包信息
/// <summary> /// 錄入紅包信息,供使用搖一搖頁(yè)面處理 /// </summary> private void btnSetHB_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(sp_ticket)) { MessageUtil.ShowError("紅包票據(jù)ticket為空"); return; } SetPrizeBucketJson json = new SetPrizeBucketJson() { lottery_id = lotteryId, //使用前面的紅包活動(dòng) mchid = accountInfo.MchID, sponsor_appid = accountInfo.AppID, prize_info_list = new List<PrizeTicket>() { new PrizeTicket() { ticket = sp_ticket},//使用前面的紅包預(yù)下單ticket } }; var result = hbApi.SetPrizeBucket(this.token, json); Console.WriteLine("錄入紅包的結(jié)果:"); Console.WriteLine(result.ToJson()); }
第四步,配置好重定向的頁(yè)面,方便獲取用戶的openid
1)用戶同意授權(quán),獲取code
這個(gè)步驟,我們利用的是“網(wǎng)頁(yè)授權(quán)獲取用戶基本信息”操作,其中相關(guān)的信息說(shuō)明如下所示。
在確保微信公眾賬號(hào)擁有授權(quán)作用域(scope參數(shù))的權(quán)限的前提下(服務(wù)號(hào)獲得高級(jí)接口后,默認(rèn)擁有scope參數(shù)中的snsapi_base和snsapi_userinfo),引導(dǎo)關(guān)注者打開如下頁(yè)面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“該鏈接無(wú)法訪問(wèn)”,請(qǐng)檢查參數(shù)是否填寫錯(cuò)誤,是否擁有scope參數(shù)對(duì)應(yīng)的授權(quán)作用域權(quán)限。
尤其注意:由于授權(quán)操作安全等級(jí)較高,所以在發(fā)起授權(quán)請(qǐng)求時(shí),微信會(huì)對(duì)授權(quán)鏈接做正則強(qiáng)匹配校驗(yàn),如果鏈接的參數(shù)順序不對(duì),授權(quán)頁(yè)面將無(wú)法正常訪問(wèn)
參考鏈接(請(qǐng)?jiān)谖⑿趴蛻舳酥写蜷_此鏈接體驗(yàn)) Scope為snsapi_base https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect Scope為snsapi_userinfo https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
尤其注意:跳轉(zhuǎn)回調(diào)redirect_uri,應(yīng)當(dāng)使用https鏈接來(lái)確保授權(quán)code的安全性。
這樣,如果我們配置的連接為http://www.iqidi.com/JSSDKTest/RedPack?uid=iqidiSoftware ,其中uid為我們對(duì)應(yīng)的賬號(hào)名稱。
那么我們根據(jù)上面規(guī)則,得到重定向的連接地址就是如下所示。
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx3d81fc2886d86526&redirect_uri=http%3a%2f%2fwww.iqidi.com%2fJSSDKTest%2fRedPack%3fuid%3diqidiSoftware&response_type=code&scope=snsapi_base&state=state#wechat_redirect
2)通過(guò)code換取網(wǎng)頁(yè)授權(quán)access_token
首先請(qǐng)注意,這里通過(guò)code換取的是一個(gè)特殊的網(wǎng)頁(yè)授權(quán)access_token,與基礎(chǔ)支持中的access_token(該access_token用于調(diào)用其他接口)不同。公眾號(hào)可通過(guò)下述接口來(lái)獲取網(wǎng)頁(yè)授權(quán)access_token。如果網(wǎng)頁(yè)授權(quán)的作用域?yàn)閟nsapi_base,則本步驟中獲取到網(wǎng)頁(yè)授權(quán)access_token的同時(shí),也獲取到了openid,snsapi_base式的網(wǎng)頁(yè)授權(quán)流程即到此為止。
尤其注意:由于公眾號(hào)的secret和獲取到的access_token安全級(jí)別都非常高,必須只保存在服務(wù)器,不允許傳給客戶端。后續(xù)刷新access_token、通過(guò)access_token獲取用戶信息等步驟,也必須從服務(wù)器發(fā)起。
請(qǐng)求方法
獲取code后,請(qǐng)求以下鏈接獲取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數(shù)說(shuō)明
?
在具體的頁(yè)面里面,我們可以獲得相關(guān)的參數(shù),如uid我們可以把它轉(zhuǎn)換為我們對(duì)應(yīng)的賬號(hào)信息,如下所示。
/// <summary> /// 根據(jù)賬號(hào)名獲取對(duì)應(yīng)的對(duì)象 /// </summary> /// <returns></returns> private AccountInfo GetAccount() { AccountInfo accountInfo = null; string accountNo = Request.QueryString["uid"]; if (!string.IsNullOrEmpty(accountNo)) { accountInfo = BLLFactory<Account>.Instance.FindByAccountNo(accountNo); } return accountInfo; }
而其中的code,我們根據(jù)這個(gè)信息,也可以獲得用戶的相關(guān)信息,我們需要獲得訪問(wèn)用戶的openid,如下所示。
string code = Request.QueryString["code"]; IBasicApi baseApi = new BasicApi(); var result = baseApi.GetAuthToken(accountInfo.UniteAppId, accountInfo.UniteAppSecret, code); if (result != null && !string.IsNullOrEmpty(result.openid)) { var openid = result.openid;
有了這些信息,我們就可以構(gòu)建我們的紅包參數(shù),并封裝好簽名了。
WxPayData data = new WxPayData(); data.SetValue("openid", openid); data.SetValue("lottery_id", lottery_id); data.SetValue("noncestr", data.GenerateNonceStr()); data.SetValue("sign", data.MakeSign(accountInfo.PayAPIKey));
然后,我們?cè)诤笈_(tái),把這些信息賦值給ViewBag,就可以在頁(yè)面上順利使用了。
var sign = data.GetString("sign");//獲取生成的sign var noncestr = data.GetString("noncestr");//獲取生成的sign ViewBag.sign = sign; ViewBag.lottery_id = lottery_id; ViewBag.openid = openid; ViewBag.noncestr2 = noncestr;
在搖一搖紅包的處理視圖頁(yè)面里面,我們先引入對(duì)應(yīng)的js文件,如下所示
<title>搖一搖紅包頁(yè)面</title> <link rel="stylesheet" > <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script> <script type="text/javascript" src="http://zb.weixin.qq.com/app/shakehb/BeaconShakehbJsBridge.js"></script>
然后在JS里面添加相關(guān)的處理函數(shù),并賦值給對(duì)應(yīng)的接口參數(shù)。
<script type="text/javascript"> BeaconShakehbJsBridge.ready(function () { //跳轉(zhuǎn)到抽紅包頁(yè)面 BeaconShakehbJsBridge.invoke('jumpHongbao', { lottery_id: '@ViewBag.lottery_id', noncestr: '@ViewBag.noncestr2', openid: '@ViewBag.openid', sign: '@ViewBag.sign' }); }); </script>
最后,我們測(cè)試相關(guān)的結(jié)果,使用手機(jī)搖一搖獲得紅包的過(guò)程界面效果如下所示。
??
??
?
如果對(duì)這個(gè)《C#開發(fā)微信門戶及應(yīng)用》系列感興趣,可以關(guān)注我的其他文章,系列隨筆如下所示:
C#開發(fā)微信門戶及應(yīng)用(38)--微信搖一搖紅包功能
C#開發(fā)微信門戶及應(yīng)用(37)--微信公眾號(hào)標(biāo)簽管理功能
C#開發(fā)微信門戶及應(yīng)用(36)--微信卡劵管理的封裝操作
C#開發(fā)微信門戶及應(yīng)用(35)--微信支付之企業(yè)付款封裝操作
C#開發(fā)微信門戶及應(yīng)用(34)--微信裂變紅包
C#開發(fā)微信門戶及應(yīng)用(33)--微信現(xiàn)金紅包的封裝及使用
C#開發(fā)微信門戶及應(yīng)用(32)--微信支付接入和API封裝使用
C#開發(fā)微信門戶及應(yīng)用(31)--微信語(yǔ)義理解接口的實(shí)現(xiàn)和處理
C#開發(fā)微信門戶及應(yīng)用(30)--消息的群發(fā)處理和預(yù)覽功能
C#開發(fā)微信門戶及應(yīng)用(28)--微信“搖一搖·周邊”功能的使用和接口的實(shí)現(xiàn)
C#開發(fā)微信門戶及應(yīng)用(27)-公眾號(hào)模板消息管理?
C#開發(fā)微信門戶及應(yīng)用(26)-公眾號(hào)微信素材管理
C#開發(fā)微信門戶及應(yīng)用(25)-微信企業(yè)號(hào)的客戶端管理功能
C#開發(fā)微信門戶及應(yīng)用(24)-微信小店貨架信息管理
C#開發(fā)微信門戶及應(yīng)用(23)-微信小店商品管理接口的封裝和測(cè)試
C#開發(fā)微信門戶及應(yīng)用(22)-微信小店的開發(fā)和使用
C#開發(fā)微信門戶及應(yīng)用(21)-微信企業(yè)號(hào)的消息和事件的接收處理及解密?
C#開發(fā)微信門戶及應(yīng)用(20)-微信企業(yè)號(hào)的菜單管理
C#開發(fā)微信門戶及應(yīng)用(19)-微信企業(yè)號(hào)的消息發(fā)送(文本、圖片、文件、語(yǔ)音、視頻、圖文消息等)
C#開發(fā)微信門戶及應(yīng)用(18)-微信企業(yè)號(hào)的通訊錄管理開發(fā)之成員管理
C#開發(fā)微信門戶及應(yīng)用(17)-微信企業(yè)號(hào)的通訊錄管理開發(fā)之部門管理
C#開發(fā)微信門戶及應(yīng)用(16)-微信企業(yè)號(hào)的配置和使用
C#開發(fā)微信門戶及應(yīng)用(15)-微信菜單增加掃一掃、發(fā)圖片、發(fā)地理位置功能
C#開發(fā)微信門戶及應(yīng)用(14)-在微信菜單中采用重定向獲取用戶數(shù)據(jù)
C#開發(fā)微信門戶及應(yīng)用(13)-使用地理位置擴(kuò)展相關(guān)應(yīng)用
C#開發(fā)微信門戶及應(yīng)用(12)-使用語(yǔ)音處理
C#開發(fā)微信門戶及應(yīng)用(11)--微信菜單的多種表現(xiàn)方式介紹
C#開發(fā)微信門戶及應(yīng)用(10)--在管理系統(tǒng)中同步微信用戶分組信息
C#開發(fā)微信門戶及應(yīng)用(9)-微信門戶菜單管理及提交到微信服務(wù)器
C#開發(fā)微信門戶及應(yīng)用(8)-微信門戶應(yīng)用管理系統(tǒng)功能介紹
C#開發(fā)微信門戶及應(yīng)用(7)-微信多客服功能及開發(fā)集成
C#開發(fā)微信門戶及應(yīng)用(6)--微信門戶菜單的管理操作
C#開發(fā)微信門戶及應(yīng)用(5)--用戶分組信息管理
C#開發(fā)微信門戶及應(yīng)用(4)--關(guān)注用戶列表及詳細(xì)信息管理
C#開發(fā)微信門戶及應(yīng)用(3)--文本消息和圖文消息的應(yīng)答
C#開發(fā)微信門戶及應(yīng)用(2)--微信消息的處理和應(yīng)答
C#開發(fā)微信門戶及應(yīng)用(1)--開始使用微信接口
?
專注于Winform開發(fā)框架/混合式開發(fā)框架、Web開發(fā)框架、Bootstrap開發(fā)框架、微信門戶開發(fā)框架的研究及應(yīng)用。
??轉(zhuǎn)載請(qǐng)注明出處:
撰寫人:伍華聰
本文摘自 :https://blog.51cto.com/w