Home >php教程 >php手册 >微信支付开发(6) 收货地址共享接口 - 方倍工作室

微信支付开发(6) 收货地址共享接口 - 方倍工作室

WBOY
WBOYOriginal
2016-05-20 11:54:391793browse

关键字:微信支付 收货地址共享
作者:方倍工作室
原文: http://www.cnblogs.com/txw1958/p/weixin-editAddress.html

 

请看新版教程  微信支付开发(7) 收货地址共享接口V2

 

本文介绍微信支付下的收货地址共享接口的开发过程。

一. 简介

微信收货地址共享,是指用户在微信浏览器内打开网页,填写过地址后,后续可以免填写支持快速选择,也可增加和编辑。此地址为用户属性,可在各商户的网页中共享使用。支持原生控件填写地址,地址数据会传递到商户。

地址共享是基于微信JavaScript API 实现,只能在微信内置浏览器中使用,其他浏览器调用无效。同时,需要微信5.0 版本才能支持,建议通过user agent 来确定用户当前的版本号后再调用地址接口。以iPhone 版本为例,可以通过useragent可获取如下微信版本示例信息:"Mozilla/5.0(iphone;CPU iphone OS 5_1_1 like Mac OS X)AppleWebKit/534.46(KHTML,like Geocko) Mobile/9B206MicroMessenger/5.0"其中5.0 为用户安装的微信版本号,商户可以判定版本号是否高于或者等于5.0。

地址格式
微信地址共享使用的数据字段包括:

  • 收货人姓名
  • 地区,省市区三级
  • 详细地址
  • 邮编
  • 联系电话

其中,地区对应是国标三级地区码,如“广东省-广州市-天河区”,对应的邮编是是510630。详情参考链接:http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html

 

二. OAuth2.0授权

获取收货地址之前前需要调用 登录授权接口获取到一次OAuth2.0的Access Token 。所以需要做一次授权,这次授权是不弹出确认框的。
其实质就是在用户访问

http:<span style="color: #008000;">//</span><span style="color: #008000;">www.fangbei.org/wxpay/js_api_call.php</span>

时跳转到

https:<span style="color: #008000;">//</span><span style="color: #008000;">open.weixin.qq.com/connect/oauth2/authorize?appid=wx8888888888888888&redirect_uri=http://www.fangbei.org/wxpay/js_api_call.php&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect</span>

以此来获得code参数,并根据code来获得授权access_token及openid,这个access token将用于收货地址共享接口。

其实现的详细流程可参考 微信公众平台开发(71)OAuth2.0网页授权

 

二、获取随机字符串

生成随机字符串的方法如下

 

三、生成签名

参与addrSign 签名的字段包括:appId、url(调用JavaScript API的网页url)、timestamp、noncestr、accessToken
对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。
这里需要注意的是签名过程中所有参数名均为小写字符,例如appId 在排序后字符串则为appid;
对string1作签名算法,字段名和字段值都采用原始值,不进行URL 转义。具体签名算法为addrSign = SHA1(string1)。这里给出生成addrSign 的具体示例如下:

appId=<span style="color: #000000;">wx17ef1eaef46752cb
url</span>=http:<span style="color: #008000;">//</span><span style="color: #008000;">open.weixin.qq.com/</span>
timeStamp=<span style="color: #800080;">1384841012</span><span style="color: #000000;">
nonceStr</span>=<span style="color: #800080;">123456</span><span style="color: #000000;">
accessToken</span>=OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmgh5FRA

i:经过a过程键值对排序后得到string1 为:

accesstoken=OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmgh5FRA&appid=wx17ef1eaef46752cb&noncestr=<span style="color: #800080;">123456</span>&timestamp=<span style="color: #800080;">1384841012</span>&url=http:<span style="color: #008000;">//</span><span style="color: #008000;">open.weixin.qq.com/?code=CODE&state=STATE</span>

ii:经过b过程签名后可得到:

addrSign=SHA1(accesstoken=<span style="color: #000000;">OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmg
h5FRA</span>&appid=wx17ef1eaef46752cb&noncestr=<span style="color: #800080;">123456</span>&timestamp=<span style="color: #800080;">1384841012</span>&url=http:<span style="color: #008000;">//</span><span style="color: #008000;">open.weixin.qq.com/?code=CODE&state=STATE)=ca604c740945587544a9cc25e58dd090f200e6fb</span>

实现代码如下

 

四、获得收货地址

编辑并获取用户收货地址editAddress接口,在网页前端调用。
参数列表:

参数 必填 说明
appId 公众号appID
scope 填写“jsapi_address”,获得编辑地址权限
signType 签名方式,目前仅支持SHA1
addrSign 签名,由各参数一起参与签名生成
timeStamp 时间戳
nonceStr 随机字符串

调用方法如下

参数返回:

返回值 说明
err_msg edit_address:ok获取编辑收货地址成功
edit_address:fail获取编辑收货地址失败
username 收货人姓名
telNumber 收货人电话
addressPostalCode 邮编
proviceFirstStageName 国标收货地址第一级地址
addressCitySecondStageName 国标收货地址第二级地址
addressCountiesThirdStageName 国标收货地址第三级地址
addressDetailInfo 详细收货地址信息
nationalCode 收货地址国家码

 

 

五、示例

    

 

六、完整代码

<span style="color: #000000;">php

</span><span style="color: #008000;">/*</span><span style="color: #008000;">
    方倍工作室 http://www.fangbei.org/
    CopyRight 2014 All Rights Reserved
</span><span style="color: #008000;">*/</span>


<span style="color: #008080;">define</span>('APPID',         "wx—b7559b828e3c13e"<span style="color: #000000;">);
</span><span style="color: #008080;">define</span>('APPSECRET',     "2b21b42d0c497de9a691a6bb5048a601"<span style="color: #000000;">);


</span><span style="color: #0000ff;">class</span><span style="color: #000000;"> class_weixin
{
    </span><span style="color: #0000ff;">var</span> <span style="color: #800080;">$appid</span> =<span style="color: #000000;"> APPID;
    </span><span style="color: #0000ff;">var</span> <span style="color: #800080;">$appsecret</span> =<span style="color: #000000;"> APPSECRET;

    </span><span style="color: #008000;">//</span><span style="color: #008000;">构造函数,获取Access Token</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> __construct(<span style="color: #800080;">$appid</span> = <span style="color: #0000ff;">NULL</span>, <span style="color: #800080;">$appsecret</span> = <span style="color: #0000ff;">NULL</span><span style="color: #000000;">)
    {
        </span><span style="color: #0000ff;">if</span>(<span style="color: #800080;">$appid</span> && <span style="color: #800080;">$appsecret</span><span style="color: #000000;">){
            </span><span style="color: #800080;">$this</span>->appid = <span style="color: #800080;">$appid</span><span style="color: #000000;">;
            </span><span style="color: #800080;">$this</span>->appsecret = <span style="color: #800080;">$appsecret</span><span style="color: #000000;">;
        }
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;">生成OAuth2的URL</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> oauth2_authorize(<span style="color: #800080;">$redirect_url</span>, <span style="color: #800080;">$scope</span>, <span style="color: #800080;">$state</span> = <span style="color: #0000ff;">NULL</span><span style="color: #000000;">)
    {
        </span><span style="color: #800080;">$url</span> = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".<span style="color: #800080;">$this</span>->appid."&redirect_uri=".<span style="color: #800080;">$redirect_url</span>."&response_type=code&scope=".<span style="color: #800080;">$scope</span>."&state=".<span style="color: #800080;">$state</span>."#wechat_redirect"<span style="color: #000000;">;
        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$url</span><span style="color: #000000;">;
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;">生成OAuth2的Access Token</span>
    <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">function</span> oauth2_access_token(<span style="color: #800080;">$code</span><span style="color: #000000;">)
    {
        </span><span style="color: #800080;">$url</span> = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".<span style="color: #800080;">$this</span>->appid."&secret=".<span style="color: #800080;">$this</span>->appsecret."&code=".<span style="color: #800080;">$code</span>."&grant_type=authorization_code"<span style="color: #000000;">;
        </span><span style="color: #800080;">$res</span> = <span style="color: #800080;">$this</span>->http_request(<span style="color: #800080;">$url</span><span style="color: #000000;">);
        </span><span style="color: #0000ff;">return</span> json_decode(<span style="color: #800080;">$res</span>, <span style="color: #0000ff;">true</span><span style="color: #000000;">);
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;">生成随机字符串</span>
    <span style="color: #0000ff;">function</span> create_noncestr(<span style="color: #800080;">$length</span> = 16<span style="color: #000000;">) 
    {
        </span><span style="color: #800080;">$chars</span> = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"<span style="color: #000000;">;
        </span><span style="color: #800080;">$str</span> = ""<span style="color: #000000;">;
        </span><span style="color: #0000ff;">for</span> (<span style="color: #800080;">$i</span> = 0; <span style="color: #800080;">$i</span> $length; <span style="color: #800080;">$i</span>++<span style="color: #000000;"> ){
            </span><span style="color: #800080;">$str</span>.= <span style="color: #008080;">substr</span>(<span style="color: #800080;">$chars</span>, <span style="color: #008080;">mt_rand</span>(0, <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$chars</span>)-1), 1<span style="color: #000000;">);
        }
        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$str</span><span style="color: #000000;">;
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;">生成签名</span>
    <span style="color: #0000ff;">function</span> get_biz_sign(<span style="color: #800080;">$bizObj</span><span style="color: #000000;">)
    {
        </span><span style="color: #008000;">//</span><span style="color: #008000;">参数小写</span>
        <span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$bizObj</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$k</span> => <span style="color: #800080;">$v</span><span style="color: #000000;">){
            </span><span style="color: #800080;">$bizParameters</span>[<span style="color: #008080;">strtolower</span>(<span style="color: #800080;">$k</span>)] = <span style="color: #800080;">$v</span><span style="color: #000000;">;
        }
        </span><span style="color: #008000;">//</span><span style="color: #008000;">字典序排序</span>
        <span style="color: #008080;">ksort</span>(<span style="color: #800080;">$bizParameters</span><span style="color: #000000;">);
        </span><span style="color: #008000;">//</span><span style="color: #008000;">URL键值对拼成字符串</span>
        <span style="color: #800080;">$buff</span> = ""<span style="color: #000000;">;
        </span><span style="color: #0000ff;">foreach</span> (<span style="color: #800080;">$bizParameters</span> <span style="color: #0000ff;">as</span> <span style="color: #800080;">$k</span> => <span style="color: #800080;">$v</span><span style="color: #000000;">){
            </span><span style="color: #800080;">$buff</span> .= <span style="color: #800080;">$k</span>."=".<span style="color: #800080;">$v</span>."&"<span style="color: #000000;">;
        }
        </span><span style="color: #008000;">//</span><span style="color: #008000;">去掉最后一个多余的&</span>
        <span style="color: #800080;">$buff2</span> = <span style="color: #008080;">substr</span>(<span style="color: #800080;">$buff</span>, 0, <span style="color: #008080;">strlen</span>(<span style="color: #800080;">$buff</span>) - 1<span style="color: #000000;">);
        </span><span style="color: #008000;">//</span><span style="color: #008000;">sha1签名</span>
        <span style="color: #0000ff;">return</span> <span style="color: #008080;">sha1</span>(<span style="color: #800080;">$buff2</span><span style="color: #000000;">);
    }

    </span><span style="color: #008000;">//</span><span style="color: #008000;">HTTP请求(支持HTTP/HTTPS,支持GET/POST)</span>
    <span style="color: #0000ff;">protected</span> <span style="color: #0000ff;">function</span> http_request(<span style="color: #800080;">$url</span>, <span style="color: #800080;">$data</span> = <span style="color: #0000ff;">null</span><span style="color: #000000;">)
    {
        </span><span style="color: #800080;">$curl</span> =<span style="color: #000000;"> curl_init();
        curl_setopt(</span><span style="color: #800080;">$curl</span>, CURLOPT_URL, <span style="color: #800080;">$url</span><span style="color: #000000;">);
        curl_setopt(</span><span style="color: #800080;">$curl</span>, CURLOPT_SSL_VERIFYPEER, <span style="color: #0000ff;">FALSE</span><span style="color: #000000;">);
        curl_setopt(</span><span style="color: #800080;">$curl</span>, CURLOPT_SSL_VERIFYHOST, <span style="color: #0000ff;">FALSE</span><span style="color: #000000;">);
        </span><span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">empty</span>(<span style="color: #800080;">$data</span><span style="color: #000000;">)){
            curl_setopt(</span><span style="color: #800080;">$curl</span>, CURLOPT_POST, 1<span style="color: #000000;">);
            curl_setopt(</span><span style="color: #800080;">$curl</span>, CURLOPT_POSTFIELDS, <span style="color: #800080;">$data</span><span style="color: #000000;">);
        }
        curl_setopt(</span><span style="color: #800080;">$curl</span>, CURLOPT_RETURNTRANSFER, <span style="color: #0000ff;">TRUE</span><span style="color: #000000;">);
        </span><span style="color: #800080;">$output</span> = curl_exec(<span style="color: #800080;">$curl</span><span style="color: #000000;">);
        curl_close(</span><span style="color: #800080;">$curl</span><span style="color: #000000;">);
        </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">$output</span><span style="color: #000000;">;
    }

}</span>

 

 

<span style="color: #000000;">php

</span><span style="color: #0000ff;">require_once</span>('wxaddr.class.php'<span style="color: #000000;">);
</span><span style="color: #800080;">$weixin</span> = <span style="color: #0000ff;">new</span><span style="color: #000000;"> class_weixin();
</span><span style="color: #800080;">$url</span> = 'http://'.<span style="color: #800080;">$_SERVER</span>['HTTP_HOST'].<span style="color: #800080;">$_SERVER</span>['REQUEST_URI'<span style="color: #000000;">];

</span><span style="color: #0000ff;">if</span> (!<span style="color: #0000ff;">isset</span>(<span style="color: #800080;">$_GET</span>["code"<span style="color: #000000;">])){
    </span><span style="color: #800080;">$jumpurl</span> = <span style="color: #800080;">$weixin</span>->oauth2_authorize(<span style="color: #800080;">$url</span>, "snsapi_base", "fangbei"<span style="color: #000000;">);
    </span><span style="color: #008080;">Header</span>("Location: <span style="color: #800080;">$jumpurl</span>"<span style="color: #000000;">);
}</span><span style="color: #0000ff;">else</span><span style="color: #000000;">{
    </span><span style="color: #800080;">$oauth2_access_token</span> = <span style="color: #800080;">$weixin</span>->oauth2_access_token(<span style="color: #800080;">$_GET</span>["code"<span style="color: #000000;">]);
    </span><span style="color: #800080;">$access_token</span> = <span style="color: #800080;">$oauth2_access_token</span>['access_token'<span style="color: #000000;">];
}


</span><span style="color: #800080;">$timestamp</span> = <span style="color: #008080;">strval</span>(<span style="color: #008080;">time</span><span style="color: #000000;">());
</span><span style="color: #800080;">$noncestr</span> = <span style="color: #800080;">$weixin</span>-><span style="color: #000000;">create_noncestr();

</span><span style="color: #800080;">$obj</span>['appId']               = <span style="color: #800080;">$weixin</span>-><span style="color: #000000;">appid;
</span><span style="color: #800080;">$obj</span>['url']                 = <span style="color: #800080;">$url</span><span style="color: #000000;">;
</span><span style="color: #800080;">$obj</span>['timeStamp']           = <span style="color: #800080;">$timestamp</span><span style="color: #000000;">;
</span><span style="color: #800080;">$obj</span>['noncestr']            = <span style="color: #800080;">$noncestr</span><span style="color: #000000;">;
</span><span style="color: #800080;">$obj</span>['accesstoken']         = <span style="color: #800080;">$access_token</span><span style="color: #000000;">;

</span><span style="color: #800080;">$signature</span>  = <span style="color: #800080;">$weixin</span>->get_biz_sign(<span style="color: #800080;">$obj</span><span style="color: #000000;">);

</span>?>


    
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>获取共享收货地址</title>
        <meta name="viewport" content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no;">
        <script language="javascript">
            <span style="color: #0000ff;">function<span style="color: #000000;"> callpay()
            {
                WeixinJSBridge.invoke('editAddress',<span style="color: #000000;">{
                    "appId" : "<?php echo <span style="color: #800080;">$obj['appId'];?>",
                    "scope" : "jsapi_address",
                    "signType" : "sha1",
                    "addrSign" : "<?php echo <span style="color: #800080;">$signature;?>",
                    "timeStamp" : "<?php echo <span style="color: #800080;">$timestamp;?>",
                    "nonceStr" : "<?php echo <span style="color: #800080;">$noncestr;?>",<span style="color: #000000;">
                },<span style="color: #0000ff;">function<span style="color: #000000;">(res){ 
                    alert(JSON.<span style="color: #000000;">stringify(res));  
                    document.form1.address1.value         = res.<span style="color: #000000;">proviceFirstStageName;
                    document.form1.address2.value         = res.<span style="color: #000000;">addressCitySecondStageName;
                    document.form1.address3.value         = res.<span style="color: #000000;">addressCountiesThirdStageName;
                    document.form1.detail.value           = res.<span style="color: #000000;">addressDetailInfo;
                    document.form1.national.value         = res.<span style="color: #000000;">nationalCode;
                    document.form1.user.value            = res.<span style="color: #000000;">userName;
                    document.form1.phone.value            = res.<span style="color: #000000;">telNumber;
                    document.form1.postcode.value         = res.<span style="color: #000000;">addressPostalCode;
                    document.form1.errmsg.value         = res.<span style="color: #000000;">err_msg;
                });
            }
        </script>
    
    
        
结果
国家码
国家
详细
收货人
电话
邮编

 

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn