


WeChat payment development (7) Receiving address sharing interface V2, v2_PHP tutorial
WeChat payment development (7) Receiving address sharing interface V2, v2
Keywords: WeChat public platform JSSDK Send to friends Receiving address sharing interface openAddress
Author: Fangbei Studio
Original text: http://www.cnblogs.com/txw1958/p/weixin-openaddress.html
In this WeChat public platform development tutorial, we will introduce how to implement the function of obtaining the delivery address on the web page.
The shipping address sharing interface was upgraded on April 13, 2016. Only the new interface can be used on May 20, 2016. This tutorial is a tutorial for the new version of the interface!
This article is divided into the following two parts:
1. WeChat JS-SDK
1. Obtain Access Token
The method of obtaining access token is introduced earlier. For details, see WeChat Public Platform Development (26) ACCESS TOKEN
2. Get jsapi_ticket
Before generating a signature, you must first understand jsapi_ticket. jsapi_ticket is a temporary ticket used by public accounts to call the WeChat JS interface. Under normal circumstances, the validity period of jsapi_ticket is 7200 seconds, which is obtained through access_token. Since the number of api calls to obtain jsapi_ticket is very limited, frequent refresh of jsapi_ticket will result in restricted api calls and affect their own business. Developers must cache jsapi_ticket globally in their own services.
Refer to the following document to obtain the access_token (validity period is 7200 seconds, developers must cache access_token globally in their own services):
Use the access_token obtained in the first step to request jsapi_ticket using http GET method (validity period is 7200 seconds, developers You must cache jsapi_ticket globally in your own service), the interface address is as follows
https:<span>//</span><span>api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi</span>
Successfully returns the following JSON:
<span>{ </span><span>"</span><span>errcode</span><span>"</span>:<span>0</span><span>, </span><span>"</span><span>errmsg</span><span>"</span>:<span>"</span><span>ok</span><span>"</span><span>, </span><span>"</span><span>ticket</span><span>"</span>:<span>"</span><span>bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA</span><span>"</span><span>, </span><span>"</span><span>expires_in</span><span>"</span>:<span>7200</span><span> }</span>
After obtaining jsapi_ticket, you can generate a signature for JS-SDK permission verification.
3. Signature algorithm implementation
The signature generation rules are as follows: fields involved in the signature include noncestr (random string), valid jsapi_ticket, timestamp (timestamp), url (URL of the current web page, excluding # and its following parts). After sorting all the parameters to be signed according to the ASCII code of the field name from small to large (lexicographic order), use the URL key-value pair format (i.e. key1=value1&key2=value2...) to concatenate them into a string string1. It should be noted here that all parameter names are lowercase characters. Perform sha1 encryption on string1, use original values for field names and field values, and do not perform URL escaping.
That is, signature=sha1(string1). Example:
noncestr=<span>Wm3WZYTPz0wzccnW jsapi_ticket</span>=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-<span>HhTdfl2fzFy1AOcHKP7qg timestamp</span>=<span>1414587457</span><span> url</span>=http:<span>//</span><span>mp.weixin.qq.com?params=value</span>
Step 1. Sort all the parameters to be signed according to the ASCII code of the field name from small to large (lexicographic order), and use the URL key-value pair format (i.e. key1=value1&key2=value2...) to concatenate them into a string. string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=<span>1414587457</span>&url=http:<span>//</span><span>mp.weixin.qq.com?params=value</span>
Step 2. Sign string1 with sha1 and get signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
The complete code is as follows
<?<span>php </span><span>class</span><span> JSSDK { </span><span>private</span> <span>$appId</span><span>; </span><span>private</span> <span>$appSecret</span><span>; </span><span>public</span> <span>function</span> __construct(<span>$appId</span>, <span>$appSecret</span><span>) { </span><span>$this</span>->appId = <span>$appId</span><span>; </span><span>$this</span>->appSecret = <span>$appSecret</span><span>; } </span><span>public</span> <span>function</span><span> getSignPackage() { </span><span>$jsapiTicket</span> = <span>$this</span>-><span>getJsApiTicket(); </span><span>//</span><span> 注意 URL 一定要动态获取,不能 hardcode.</span> <span>$protocol</span> = (!<span>empty</span>(<span>$_SERVER</span>['HTTPS']) && <span>$_SERVER</span>['HTTPS'] !== 'off' || <span>$_SERVER</span>['SERVER_PORT'] == 443) ? "https://" : "http://"<span>; </span><span>$url</span> = "<span>$protocol$_SERVER</span>[HTTP_HOST]<span>$_SERVER</span>[REQUEST_URI]"<span>; </span><span>$timestamp</span> = <span>time</span><span>(); </span><span>$nonceStr</span> = <span>$this</span>-><span>createNonceStr(); </span><span>//</span><span> 这里参数的顺序要按照 key 值 ASCII 码升序排序</span> <span>$string</span> = "jsapi_ticket=<span>$jsapiTicket</span>&noncestr=<span>$nonceStr</span>×tamp=<span>$timestamp</span>&url=<span>$url</span>"<span>; </span><span>$signature</span> = <span>sha1</span>(<span>$string</span><span>); </span><span>$signPackage</span> = <span>array</span><span>( </span>"appId" => <span>$this</span>->appId, "nonceStr" => <span>$nonceStr</span>, "timestamp" => <span>$timestamp</span>, "url" => <span>$url</span>, "signature" => <span>$signature</span>, "rawString" => <span>$string</span><span> ); </span><span>return</span> <span>$signPackage</span><span>; } </span><span>private</span> <span>function</span> createNonceStr(<span>$length</span> = 16<span>) { </span><span>$chars</span> = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"<span>; </span><span>$str</span> = ""<span>; </span><span>for</span> (<span>$i</span> = 0; <span>$i</span> < <span>$length</span>; <span>$i</span>++<span>) { </span><span>$str</span> .= <span>substr</span>(<span>$chars</span>, <span>mt_rand</span>(0, <span>strlen</span>(<span>$chars</span>) - 1), 1<span>); } </span><span>return</span> <span>$str</span><span>; } </span><span>private</span> <span>function</span><span> getJsApiTicket() { </span><span>//</span><span> jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例</span> <span>$data</span> = json_decode(<span>file_get_contents</span>("jsapi_ticket.json"<span>)); </span><span>if</span> (<span>$data</span>->expire_time < <span>time</span><span>()) { </span><span>$accessToken</span> = <span>$this</span>-><span>getAccessToken(); </span><span>//</span><span> 如果是企业号用以下 URL 获取 ticket // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";</span> <span>$url</span> = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=<span>$accessToken</span>"<span>; </span><span>$res</span> = json_decode(<span>$this</span>->httpGet(<span>$url</span><span>)); </span><span>$ticket</span> = <span>$res</span>-><span>ticket; </span><span>if</span> (<span>$ticket</span><span>) { </span><span>$data</span>->expire_time = <span>time</span>() + 7000<span>; </span><span>$data</span>->jsapi_ticket = <span>$ticket</span><span>; </span><span>$fp</span> = <span>fopen</span>("jsapi_ticket.json", "w"<span>); </span><span>fwrite</span>(<span>$fp</span>, json_encode(<span>$data</span><span>)); </span><span>fclose</span>(<span>$fp</span><span>); } } </span><span>else</span><span> { </span><span>$ticket</span> = <span>$data</span>-><span>jsapi_ticket; } </span><span>return</span> <span>$ticket</span><span>; } </span><span>private</span> <span>function</span><span> getAccessToken() { </span><span>//</span><span> access_token 应该全局存储与更新,以下代码以写入到文件中做示例</span> <span>$data</span> = json_decode(<span>file_get_contents</span>("access_token.json"<span>)); </span><span>if</span> (<span>$data</span>->expire_time < <span>time</span><span>()) { </span><span>//</span><span> 如果是企业号用以下URL获取access_token // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";</span> <span>$url</span> = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=<span>$this</span>->appId&secret=<span>$this</span>->appSecret"<span>; </span><span>$res</span> = json_decode(<span>$this</span>->httpGet(<span>$url</span><span>)); </span><span>$access_token</span> = <span>$res</span>-><span>access_token; </span><span>if</span> (<span>$access_token</span><span>) { </span><span>$data</span>->expire_time = <span>time</span>() + 7000<span>; </span><span>$data</span>->access_token = <span>$access_token</span><span>; </span><span>$fp</span> = <span>fopen</span>("access_token.json", "w"<span>); </span><span>fwrite</span>(<span>$fp</span>, json_encode(<span>$data</span><span>)); </span><span>fclose</span>(<span>$fp</span><span>); } } </span><span>else</span><span> { </span><span>$access_token</span> = <span>$data</span>-><span>access_token; } </span><span>return</span> <span>$access_token</span><span>; } </span><span>private</span> <span>function</span> httpGet(<span>$url</span><span>) { </span><span>$curl</span> =<span> curl_init(); curl_setopt(</span><span>$curl</span>, CURLOPT_RETURNTRANSFER, <span>true</span><span>); curl_setopt(</span><span>$curl</span>, CURLOPT_TIMEOUT, 500<span>); curl_setopt(</span><span>$curl</span>, CURLOPT_SSL_VERIFYPEER, <span>false</span><span>); curl_setopt(</span><span>$curl</span>, CURLOPT_SSL_VERIFYHOST, <span>false</span><span>); curl_setopt(</span><span>$curl</span>, CURLOPT_URL, <span>$url</span><span>); </span><span>$res</span> = curl_exec(<span>$curl</span><span>); curl_close(</span><span>$curl</span><span>); </span><span>return</span> <span>$res</span><span>; } }</span>
2. Receiving address sharing interface
1. Introduction
WeChat delivery address sharing means that users open a webpage in the WeChat browser and fill in the address. They can then quickly select without filling in the address, and can also add and edit it. This address is a user attribute and can be shared on the web pages of various merchants. Support native controls to fill in addresses, and the address data will be passed to the merchant.
Address sharing is based on the WeChat JavaScript API and can only be used in the WeChat built-in browser. Calls from other browsers are invalid. At the same time, WeChat version 5.0 is required to support it. It is recommended to use the user agent to determine the user's current version number before calling the address interface. Taking the iPhone version as an example, you can obtain the following WeChat version example information through useragent: "Mozilla/5.0(iphone;CPU iphone OS 5_1_1 like Mac OS For the version number of WeChat installed by the user, the merchant can determine whether the version number is higher than or equal to 5.0.
Address format
The data fields used for WeChat address sharing include:
- Consignee’s name
- Regions, provinces and municipalities at three levels
- Detailed address
- Postcode
- Contact number
Among them, the region corresponds to the national standard three-level area code, such as "Guangdong Province-Guangzhou City-Tianhe District", and the corresponding postal code is 510630. Reference link for details: http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html
2. Bind domain name
First log in to the WeChat public platform and enter the "Function Settings" of "Official Account Settings" to fill in the "JS Interface Security Domain Name".
3. Obtain signature package
<?<span>php </span><span>require_once</span> "jssdk.php"<span>; </span><span>$jssdk</span> = <span>new</span> JSSDK("yourAppID", "yourAppSecret"<span>); </span><span>$signPackage</span> = <span>$jssdk</span>-><span>GetSignPackage(); </span>?>
4. Import JS files
Introduce the following JS file into the page that needs to call the JS interface:
Special note: The JS-SDK version requires http://res.wx.qq.com/open/js/jweixin-1.1.0.js
<span><</span><span>script </span><span>src</span><span>="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"</span><span>></</span><span>script</span><span>></span>
5. Inject permission verification configuration through the config interface
All pages that need to use JS-SDK must first inject configuration information, otherwise they will not be called.
<script><span> wx.config({ debug: </span><span>false</span><span>, appId: </span>'<?php echo $signPackage["appId"];?>'<span>, timestamp: </span><?php echo $signPackage["timestamp"];?><span>, nonceStr: </span>'<?php echo $signPackage["nonceStr"];?>'<span>, signature: </span>'<?php echo $signPackage["signature"];?>'<span>, jsApiList: [ </span><span>//</span><span> 所有要调用的 API 都要加到这个列表中</span> 'checkJsApi'<span>, </span>'openAddress'<span>, ] }); </span></script>
5. Handle successful verification through ready interface
需要在页面加载时就调用,需要把相关接口放在ready函数中调用来确保正确执行
wx.ready(<span>function</span><span> () { });</span>
5.1 通过checkJsApi判断当前客户端版本是否支持分享参数自定义
<span> wx.checkJsApi({ jsApiList: [ </span>'openAddress'<span>, ], success: </span><span>function</span><span> (res) { alert(JSON.stringify(res)); } });</span>
5.3. 实现收货地址共享
<span> wx.openAddress({ trigger: </span><span>function</span><span> (res) { alert(</span>'用户开始拉出地址'<span>); }, success: </span><span>function</span><span> (res) { alert(</span>'用户成功拉出地址'<span>); alert(JSON.stringify(res)); document.form1.address1.value </span>=<span> res.provinceName; document.form1.address2.value </span>=<span> res.cityName; document.form1.address3.value </span>=<span> res.countryName; document.form1.detail.value </span>=<span> res.detailInfo; document.form1.national.value </span>=<span> res.nationalCode; document.form1.user.value </span>=<span> res.userName; document.form1.phone.value </span>=<span> res.telNumber; document.form1.postcode.value </span>=<span> res.postalCode; document.form1.errmsg.value </span>=<span> res.errMsg; document.form1.qq.value </span>= 1354386063<span>; }, cancel: </span><span>function</span><span> (res) { alert(</span>'用户取消拉出地址'<span>); }, fail: </span><span>function</span><span> (res) { alert(JSON.stringify(res)); } });</span>
返回说明
返回值 |
说明 |
---|---|
errMsg |
获取编辑收货地址成功返回“openAddress:ok”。 |
userName |
收货人姓名。 |
postalCode |
邮编。 |
provinceName |
国标收货地址第一级地址(省)。 |
cityName |
国标收货地址第二级地址(市)。 |
countryName |
国标收货地址第三级地址(国家)。 |
detailInfo |
详细收货地址信息。 |
nationalCode |
收货地址国家码。 |
三、实现效果

Thedifferencebetweenunset()andsession_destroy()isthatunset()clearsspecificsessionvariableswhilekeepingthesessionactive,whereassession_destroy()terminatestheentiresession.1)Useunset()toremovespecificsessionvariableswithoutaffectingthesession'soveralls

Stickysessionsensureuserrequestsareroutedtothesameserverforsessiondataconsistency.1)SessionIdentificationassignsuserstoserversusingcookiesorURLmodifications.2)ConsistentRoutingdirectssubsequentrequeststothesameserver.3)LoadBalancingdistributesnewuser

PHPoffersvarioussessionsavehandlers:1)Files:Default,simplebutmaybottleneckonhigh-trafficsites.2)Memcached:High-performance,idealforspeed-criticalapplications.3)Redis:SimilartoMemcached,withaddedpersistence.4)Databases:Offerscontrol,usefulforintegrati

Session in PHP is a mechanism for saving user data on the server side to maintain state between multiple requests. Specifically, 1) the session is started by the session_start() function, and data is stored and read through the $_SESSION super global array; 2) the session data is stored in the server's temporary files by default, but can be optimized through database or memory storage; 3) the session can be used to realize user login status tracking and shopping cart management functions; 4) Pay attention to the secure transmission and performance optimization of the session to ensure the security and efficiency of the application.

PHPsessionsstartwithsession_start(),whichgeneratesauniqueIDandcreatesaserverfile;theypersistacrossrequestsandcanbemanuallyendedwithsession_destroy().1)Sessionsbeginwhensession_start()iscalled,creatingauniqueIDandserverfile.2)Theycontinueasdataisloade

Absolute session timeout starts at the time of session creation, while an idle session timeout starts at the time of user's no operation. Absolute session timeout is suitable for scenarios where strict control of the session life cycle is required, such as financial applications; idle session timeout is suitable for applications that want users to keep their session active for a long time, such as social media.

The server session failure can be solved through the following steps: 1. Check the server configuration to ensure that the session is set correctly. 2. Verify client cookies, confirm that the browser supports it and send it correctly. 3. Check session storage services, such as Redis, to ensure that they are running normally. 4. Review the application code to ensure the correct session logic. Through these steps, conversation problems can be effectively diagnosed and repaired and user experience can be improved.

session_start()iscrucialinPHPformanagingusersessions.1)Itinitiatesanewsessionifnoneexists,2)resumesanexistingsession,and3)setsasessioncookieforcontinuityacrossrequests,enablingapplicationslikeuserauthenticationandpersonalizedcontent.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Dreamweaver Mac version
Visual web development tools

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft

SublimeText3 Chinese version
Chinese version, very easy to use

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.
