微信支付终于成功了(安卓、iOS)在此分享
在此分享一篇关于微信支付终于成功了的文章,感兴趣的小伙
伴们可以参考一下
经过了几天的痛苦煎熬,终于把微信支付调通,整个调试过程
很痛苦,痛苦的主要来源是微信支付的调试真的是,以前调试
公众号支付也是一波三折啊。好吧,开始!首先说明,我这里
主要没有使用getToken,getOrder方法,我的所有参数全部是
在后端生成传递给前端的,看了一下前面朋友分享的源代码,
还用到了jquery,md5,sha对于新手来说简直是天文啊,而且
jquery在apicloud中效率不好,所以放弃了研究那个代码,另
外官方也说了,最好签名等参数全部服务器端生成,微信也是
这么说的。
注意:微信本身在apicloud中config.xml文件你要先弄好
先看一下APP端的代码
functionwx_pay(){api.ajax({url:
serverURL+"weixin/example/app.php",method:
''POST'',timeout:''30'',dataType:
''json'',returnAll:false,cache:true,
data:{values:{type:"login"}
}},function(ret,err){if
(ret){varback_info=ret;
varweiXin=api.require(''weiXin'');
weiXin.registerApp(function
(ret,err){if
(ret.status){
weiXin.payOrder({
orderId:back_info.prepayid,
partnerId:back_info.partnerid,
nonceStr:back_info.noncestr,
timeStamp:back_info.timestamp,
package:back_info.package,
sign:back_info.sign},function(ret,err)
{if(ret.status)
{$alert(''支付成
功'');}else
{$alert(err.msg);
}});}
else{
$alert(err.msg);}}
);}else{
$alert(json2str(err));}});}
完全按照apicloud写的,没有任何问题,大家可以直接复制过
去用,其中的$alert是我自己封装的方法,就是弹出信息而已
下面主要是服务端,见附件,下载
这个是从微信官方下载下来的,坑爹的微信给的事例太垃圾了
,说明也不细致,统一下单的接口生成有了,但是app数据的
生成没有,只有js的生成,只能自己写了,其中的签名,随机
字符串,还有时间戳等等,每次请求,生产都要重新来一遍,
更加可恶的一件事情是,竟然大小写不一致,我本以为直接将
js的稍微修改修改就好了,结果不行,死活找不到原因,后来
仔细对照文档看了一下,js调起支付的很多参数是有大小写的
,但是app调起是全部小写的,具体文档见下方:
1.JS:pay.weixin.qq.com/wiki/doc/api/jsapi.php?
chapter=7_7
2.APP://pay.weixin.qq.com/wiki/d...
hapter=9_12&index=2
你们也可以仔细对比,不埋怨了,看代码吧。
首先打开example/app.php,这个是我写的接口文件
(''date.timezone'',''Asia/Shanghai'');//error_reporting
(E_ERROR);require_once
"../lib/WxPay.Api.php";require_once
"WxPay.AppPay.php";$notify=newAppPay();/首先生成
prepayid/$input=newWxPayUnifiedOrder();$input-
>SetBody("test1");//商品或支付单简要描述(必须填写)//
$input->SetAttach("test2");//附加数据,在查询API和支付
通知中原样返回,该字段主要用于商户携带订单的自定义数据
(不必填)//$input->SetDetail("Ipadmini16G白色,黑
色");//商品名称明细列表(不必填)$input-
>SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));//
订单号(必须填写)$input->SetTotal_fee("1");//订单金额(
必须填写)//$input->SetTime_start(date("YmdHis"));//交
易起始时间(不必填)//$input->SetTime_expire(date
("YmdHis",time()+600));//交易结束时间10分钟之内不必
填)$input->SetGoods_tag("test");//商品标记(不必
填)$input->SetNotify_url
("http://tc.weixinxa.com/app/weixin/example/.php")
;//回调URL(必须填写)$input->SetTrade_type("APP");//交
易类型(必须填写)//$input->SetProduct_id
("123456789");//rade_type=NATIVE,此参数必传。此id为二
维码中包含的商品ID,商户自行定义。$order=
WxPayApi::unifiedOrder($input);//获得订单的基本信息,
包括prepayid$appApiParameters=$notify-
>GetAppApiParameters($order);//生成提交给app的一些参数
die($appApiParameters);?>
以上回调URL一定要写好,我这个附件中还没有做回调的处理
,之后会有更新。
注意几点:
1.交易类型必须是APP,如果你是申请的微信公众号的支付,
而不是从open.weixin.qq.com/这里申请的,就用不
成
2.第一步是生成order,返回的是一个数组,保证这个数组里
面要有prepay_id,如果没有,那你就要检查配置文件了
lib/WxPay.Config.php
继续看代码
example/WxPay.AppPay.php
AppPay{/参数数组转换为url参数
@paramarray$urlObj/privatefunction
ToUrlParams($urlObj){$buff="";
foreach($urlObjas$k=>$v){
$buff.=$k."=".$v."&";}
$buff=trim($buff,"&");return$buff;}
/生成直接支付url,支付url有效期为
2小时,模式二@paramUnifiedOrderInput$input
/publicfunctionGetPayPrepayId($input){
if($input->GetTrade_type()=="APP"){
$result=WxPayApi::unifiedOrder($input);
return$result;}}/生成APP提交数据/
publicfunctionGetAppApiParameters
($UnifiedOrderResult){if(!
array_key_exists("appid",$UnifiedOrderResult)
||!array_key_exists("prepay_id",$UnifiedOrderResult)
||$UnifiedOrderResult[''prepay_id'']=="")
{thrownewWxPayException("参数错误");
}$appapi=newWxPayAppApiPay();
$appapi->SetAppid($UnifiedOrderResult["appid"]);
$appapi->SetPartnerId($UnifiedOrderResult["mch_id"]);
$appapi->SetPrepayId($UnifiedOrderResult
["prepay_id"]);$timeStamp=time();
$appapi->SetTimeStamp($timeStamp);$appapi-
>SetNonceStr(WxPayApi::getNonceStr());
$appapi->SetPackage("Sign=WXPay");$appapi-
>SetSign($appapi->MakeSign());$back_arr=
$appapi->GetValues();$back_arr[''prepay_id'']=
$UnifiedOrderResult["prepay_id"];$parameters=
json_encode($appapi->GetValues());return
$parameters;}}
这个文件不是官方提供的,是我自己写的,仿照
WxPay.NativePay.php这个文件写的,主要看42行
GetAppApiParameters这个函数。由此生成了app提交的很多基
础数据,在这个文件中又引用了一个类WxPayAppApiPay,在
lib/WxPay.Data.php中,最后一个函数,现在我们来看一下配
置文件吧/lib/WxPay.Config.php
//=======【基本信息设置】
=====================================///
TODO:修改这里配置为您自己申请的商户信息微信
公众号信息配置APPID:绑定支付的APPID(必
须配置,开户邮件中可查看)MCHID:商户号
(必须配置,开户邮件中可查看)KEY:商户
支付密钥,参考开户邮件设置(必须配置,登录商户平台自行
设置)设置地址:
pay.weixin.qq.com/index.php/account/api_cert
APPSECRET:公众帐号secert(仅JSAPI支付的时
候需要配置,登录公众平台,进入开发者中心可设置),
获取地址:
mp.weixin.qq.com/advanced/advanced?
action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
@varstring/constAPPID=
''wxd3ae8cc5ab312345'';constMCHID=''1250189001'';
constKEY=''14e1b600b1fd579f47433b88e8d85111'';
constAPPSECRET=''e43930e9e262176356adbf1101e11111'';
/公众号(如果你申请的微信公众号支付而不是
微信支付就用这个,但是这个没有办法在app中使用,只能通
过扫码或者js)constAPPID=''wx223c1e5d831c94a5'';
constMCHID=''1232570702'';constKEY=
''14e1b600b1fd579f47433b88e8d85291'';constAPPSECRET
=''8d6329ec3fb4195f857aee0749c3aad2'';/
//=======【证书路径设置】
=====================================/
TODO:设置商户证书路径证书路径,注意应该填写绝对
路径(仅退款、撤销订单时需要,可登录商户平台下载,
API证书下载地址:
pay.weixin.qq.com/index.php/account/api_cert,
下载之前需要安装商户操作证书)@varpath/
constSSLCERT_PATH=''../cert/apiclient_cert.pem'';
constSSLKEY_PATH=''../cert/apiclient_key.pem'';
//=======【curl代理设置】
===================================/TODO
:这里设置代理机器,只有需要代理的时候才设置,不需要代
理,请设置为0.0.0.0和0本例程通过curl使用HTTP
POST方法,此处可修改代理服务器,默认
CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启
代理(如有需要才设置)@varunknown_type/
constCURL_PROXY_HOST="0.0.0.0";//"10.152.18.220";
constCURL_PROXY_PORT=0;//8080;//=======
【上报信息配置】===================================
/TODO:接口调用上报等级,默认紧错误上报(注意
:上报超时间为【1s】,上报无论成败【永不抛出异常】,
不会影响接口调用流程),开启上报之后,方便微信监控
请求调用的质量,建议至少开启错误上报。上
报等级,0.关闭上报;1.仅错误出错上报;2.全量上报
@varint/constREPORT_LEVENL=1;}
主要是修改
1.constAPPID=''wxd3ae8cc5ab312345'';
2.constMCHID=''1250189001'';
3.constKEY=''14e1b600b1fd579f47433b88e8d85111'';
4.constAPPSECRET=
''e43930e9e262176356adbf1101e11111'';
其他的不要动就行了
就这么多了,我现在继续写回调处理的url,写好了继续上吧
相信很多人都遇到了问题,不然怎么可能在论坛里面搜索微
信支付没有一个可以实际解决问题的呢。
增加了回调,看代码,把以下代码覆盖
到/lib/example/notify.php这个文件就可以了
(''date.timezone'',''Asia/Shanghai'');error_reporting
(E_ERROR);require_once
"../lib/WxPay.Api.php";require_once
''../lib/WxPay.Notify.php'';require_once''log.php'';//初
始化日志$logHandler=newCLogFileHandler
("../logs/".date(''Y-m-d'').''.log'');$log=Log::Init
($logHandler,15);classPayNotifyCallBackextends
WxPayNotify{//查询订单publicfunction
Queryorder($transactionwww.sm136.com_id){
$input=newWxPayOrderQuery();$input-
>SetTransaction_id($transaction_id);$result=
WxPayApi::orderQuery($input);Log::DEBUG
("query:".json_encode($result));if
(array_key_exists("return_code",$result)
&&array_key_exists("result_code",$result)
&&$result["return_code"]=="SUCCESS"&&
$result["result_code"]=="SUCCESS"){
$out_trade_no=$result[''out_trade_no''];//私有订单号,
你就用这个订单号来进行你自己订单的各种更新吧
$mch_id=$result[''mch_id''];//商户号
$total_fee=$result[''total_fee''];//支付金额,出来的金额
要除以100$transaction_id=$result
[''transaction_id''];//微信内部的订单流水号
$openid=$result[''openid''];//微信加密的用户身份识别,app
支付的话其实意义不大了/以下两行用做调试,
会自动生成in_test.txt文件而且后期内容会自动追加到这个
文件/$fp=fopen(''in_test.txt'',''a+'');
fwrite($fp,date("Y-m-dH:i:s").json_encode
($result)."|".$transaction_id."成功了!rn");
//returntrue;//这个很重要,微信的异
步请求,当你执行完了你的内部处理以后给他返回true,微信
就认为你的内部处理完成了,就不会再次请求你了,否则他会
一直请求你这个文件,知道超时。}return
false;}//重写回调处理函数public
functionNotifyProcess($data,&$msg){
Log::DEBUG("callback:".json_encode($data));
$notfiyOutput=array();if(!
array_key_exists("transaction_id",$data)){
$msg="输入参数不正确";returnfalse;
}//查询订单,判断订单真实性if(!
$this->Queryorder($data["transaction_id"])){
$msg="订单查询失败";returnfalse;
}returntrue;}}Log::DEBUG("begin
notify");$notify=newPayNotifyCallBack();$notify-
>Handle(false);
|
|