前提须知

  1. APP支付流程链接
  2. jsapi支付流程链接
  3. jsapi的PHP SDK

实现

  • JsApi支付前先要重新获取下微信支付获取配置信息
//先验签 然后做逻辑
$appId = Config::get('app.WX_WEB_ID');
$appSecret = Config::get('app.WX_WEB_SECRET');
require($_SERVER['DOCUMENT_ROOT'].'/../vendor/simple/jssdk.php');//文件在SDK中
$jssdk = new \JSSDK($appId, $appSecret);//JSSDK中的参数是appid和appsecret。
$signPackage = $jssdk->GetSignPackage();//获取配置参数return json(['code' => 200, 'data' => $signPackage, 'tips' => '']);
  • 统一下单部分(APP和JSAPI):

!!!! app统一下单 openID不是必填参数,当有微信登录的时候,可以利用存在本地的openID作为参数,如果没有微信登录,我们可以不用传openID,我们也能顺利下单,产生会话id:prepay_id,不要因此有什么疑惑。但是JSAPI统一下单,openID是必要参数,届时我们可以用code去获取openID信息,到时候具体问题具体分析。

$WxPayConfig = Config::get('app.WECHAT_PAY_CONFIG');
$jsApiPayConfig = Config::get('app.WECHAT_JSAPI_PAY_CONFIG');
$title = $data['title'];
$return_url = 'http://'.$_SERVER['HTTP_HOST'].'/api/v2/payment/wechatNotify';// 异步链接
$payData['appid'] = $WxPayConfig['APPID']; //应用ID
$payData['mch_id'] = $WxPayConfig['MCHID']; //商户号
$payData['nonce_str'] = md5(rand(100000,999999)); //随机字符串
$payData['sign_type'] = 'MD5'; //签名类型
$payData['body'] = $data['body']; //商品描述
$payData['out_trade_no'] = $data['out_trade_no']; //商户订单号
//$payData['fee_type'] = 'CNY'; //货币类型
$payData['total_fee'] = $data['total_fee'] * 100; //总金额(金额计数单位为:分)
//$payData['total_fee'] = 1; //总金额(金额计数单位为:分)
$payData['spbill_create_ip'] = '127.0.0.1'; //终端IP
$payData['notify_url'] = $return_url; //通知地址
$payData['trade_type'] = $tradeType; //交易类型
$signKey = $WxPayConfig['KEY'];
if($tradeType == 'JSAPI'){$payData['appid'] = $jsApiPayConfig['APPID'];$payData['mch_id'] = $jsApiPayConfig['MCHID'];$payData['openid'] = $openId;$signKey = $jsApiPayConfig['KEY'];
}$payData['sign'] = $this->getWeixinSign($payData,$signKey); //签名
$xml = "<xml>";
foreach ($payData as $key=>$val)
{if (is_numeric($val)){$xml.="<".$key.">".$val."</".$key.">";}else{$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";}
}
$xml.="</xml>";$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch,CURLOPT_URL, $url);
//        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
//        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){curl_close($ch);$wxReturn = json_decode(json_encode(simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA)), true);$prepay_id = $wxReturn['prepay_id'];if(!$prepay_id){//json_echo(1,"系统错误");exit;$json['code'] = 400;$json['_data_pay'] = $payData;$json['data'] = $data;$json['tips'] = $wxReturn['return_code'].$wxReturn['return_msg'];return $json;}
} else {$error = curl_errno($ch);curl_close($ch);$json['tips'] = $error;$json['code'] = 400;return $json;
}$wechat = array();
if($tradeType == 'JSAPI'){//重中之重!!!!!!!网页端接口请求参数列表(参数需要重新进行签名计算,参与签名的参数为:appId、timeStamp、nonceStr、package、signType,参数区分大小写。) 大小写一定要一个字母不能错$wechat['appId'] = $wxReturn['appid'];$wechat['timeStamp'] = time();$wechat['nonceStr'] = $wxReturn['nonce_str'];$wechat['package'] = 'prepay_id='.$prepay_id;$wechat['signType'] = 'MD5';
}else{//参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式为Sign=WXPay$wechat['appid'] = $wxReturn['appid'];$wechat['partnerid'] = $wxReturn['mch_id']; //商户号$wechat['prepayid'] = $prepay_id;$wechat['package'] = 'Sign=WXPay';$wechat['noncestr'] = $wxReturn['nonce_str'];$wechat['timestamp'] = time();
}$wechat['sign'] = $this->getWeixinSign($wechat,$signKey);
if($tradeType == 'APP'){unset($wechat['package']);
}
$wechat['package_value'] = 'Sign=WXPay';
$wechat['result_scheme'] = $scheme;//scheme不参与加密  加密参数为强制几个参数$json['code']= 200;
$json['data']= $wechat;
//记录日志
save_payment_log('wechat', $title,'unifiedorder', json_encode($json, FILE_APPEND));return $json;

tips: 微信支付,同一订单修改价格后,重新提交订单号重复错误(201 商户订单号重复 解决方案)

举个栗子:

1、表内订单A为110110110110;

2、提交下单请求时,订单A拼接随机参数,如110110110110_0123;

3、接收返回信息,剔除订单号随机部分 _0123,得到表内订单A为110110110110;

4、该干嘛干嘛。

注意:

 最好记录提交到微信的单号 110110110110_0123,可能后续要进入微信后台进行财务查对。
  • 支付回调部分

微信支付回调部分传值是通过XML类型数据传递,所以接收到数据之后需要XML解析!

//处理微信支付回调
$testxml  = file_get_contents("php://input");  //接收微信发送的支付成功信息
$result = XMLDataParse($testxml);/*$result = array("appid" => "wx2421b1c4370ec43b","attach" =>  "支付测试","bank_type" =>"CFT","fee_type" =>  "CNY","is_subscribe" =>  "Y","mch_id" =>  "10000100","nonce_str" => "5d2b6c2a8db53831f7eda20af46e531c","openid" =>  "oUpF8uMEb4qRXf22hE3X68TekukE","out_trade_no" =>  "s129929113168","result_code" =>  "SUCCESS","return_code" => "SUCCESS","sign" =>  "B552ED6B279343CB493C5DD0D78AB241","sub_mch_id" =>  "10000100","time_end" =>  "20140903131540","total_fee" =>  "1","coupon_fee" =>  "10","coupon_count" =>  "1","coupon_type" => "CASH","coupon_id" => "10000","coupon_fee_0" =>  "100","trade_type" =>  "JSAPI","transaction_id" => "1004400740201409030005092168",
);*/save_payment_log('wechat', '微信支付回调开始','weChatNotify', json_encode($result, FILE_APPEND));
$sign_return = $result['sign'];
//如果成功返回了
if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {if($result['trade_type'] == 'JSAPI'){$jsApiPayConfig = Config::get('app.WECHAT_JSAPI_PAY_CONFIG');$signKey = $jsApiPayConfig['KEY'];}else{$WxPayConfig = Config::get('app.WECHAT_PAY_CONFIG');$signKey = $WxPayConfig['KEY'];}unset($result['sign']);$sign = $this->getWeixinSign($result, $signKey);if ($sign == $sign_return) {//=================================验证签名后逻辑start===================================$payments = Db::table('payments')->where('trade_no', $result['out_trade_no'])->order('created_at', 'desc')->select();if($payments){foreach ($payments as $payment){if($payment['paid']){//如果 paid为1 则已经完成save_payment_log('wechat', '微信支付回调结束', 'weChatNotify', '支付单号为' . $result['out_trade_no'] . '支付回调失败:之前 已经有交易完成记录了!');$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';echo $str;exit();}}$status = $this->hadPaidChangeOrderStatus($result, 'wechat');//判断是否已经处理过(避免因为重复回调过程中出现问题)if($status){save_payment_log('wechat', '微信支付回调结束', 'weChatNotify', '支付单号为' . $result['out_trade_no'] . '支付回调成功:回调逻辑处理完毕!');$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';echo $str;exit();}save_payment_log('wechat', '微信支付回调结束', 'weChatNotify', '支付单号为' . $result['out_trade_no'] . '支付回调成功:订单状态修改失败!');$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';echo $str;exit();}else{save_payment_log('wechat', '微信支付回调结束', 'weChatNotify', '支付单号为' . $result['out_trade_no'] . '支付回调成功:未找到预支付单!');$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';echo $str;exit();}//=================================验证签名后逻辑end=====================================}save_payment_log('wechat', '微信支付回调结束', 'weChatNotify', '支付单号为' . $result['out_trade_no'] . '支付回调成功:sign验证失败!');$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';echo $str;exit();
}save_payment_log('wechat', '微信支付回调结束', 'weChatNotify', '支付单号为' . $result['out_trade_no'] . '支付回调成功:支付失败!');$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
echo $str;exit();

tips微信加密算法:

 /*** @do 微信签名加密* @param 数据参数  加密key* @return 加密完数据*/private function getWeixinSign($data,$key){ksort($data);$buff = "";foreach ($data as $k => $v){if($k != "sign" && $v != "" && !is_array($v)){$buff .= $k . "=" . $v . "&";}}$buff = trim($buff, "&") . "&key=".$key;$string = md5($buff);//签名步骤四:所有字符转为大写$result = strtoupper($string);return $result;}

【微信支付】APP支付和APIJS支付相关推荐

  1. android手机和包支付,和包支付app下载 和包支付(手机支付软件) for Android V9.1.48 安卓手机版 下载-脚本之家...

    和包支付安卓版是中国移动精心打造的一款第三方移动综合支付平台,目前,和包支付已发展成为融合了支付.生活服务.购物等多个场景的开放性平台.提供了账户充值.提现.收付款.订单支付.账户及交易明细查询等多种 ...

  2. php苹果app微信支付 无法返回,微信支付,php_微信支付APP返回-1怎么解决,微信支付,php,移动app - phpStudy...

    微信支付APP返回-1怎么解决 开发文档上面-1"可能的原因:签名错误.未注册APPID.项目设置APPID不正确.注册的APPID与设置的不匹配.其他异常等.",但是我检查过没问 ...

  3. 微信支付id出现的重复支付解决方法和app应用中多种支付方式之间的对比

    微信支付id出现的重复支付解决方法和app应用中多种支付方式之间的对比 参考文章: (1)微信支付id出现的重复支付解决方法和app应用中多种支付方式之间的对比 (2)https://www.cnbl ...

  4. php微信支付扫码源码下载,微信支付:扫码支付+APP支付

    微信支付:实现了扫码支付.app支付和回调辅助函数 按照微信支付官方SDK的PHP版本,实现了python版本 支付回调定义 @csrf_exempt def wechat_pay_callback( ...

  5. 微信支付 APP支付 Java 服务器端

    微信支付 APP支付 Java 服务器端 本文介绍微信支付中APP支付的java服务端. 微信APP支付文档:https://pay.weixin.qq.com/wiki/doc/api/app/ap ...

  6. 商户接入微信支付方法(扫码支付、刷卡、app)

    微信支付的几种方式解读: 微信支付商户平台的付款方式有以下几种: 公众号支付:在微信内的商家页面上完成公众号支付 APP支付:在APP中,调起微信进行APP支付 扫码支付:扫描二维码(包含PC网站)进 ...

  7. 关于微信的APP支付、公众号(服务号)支付,商户问题

    注意:截止2017-10-17日 微信支付背影说明: 1. 先开通APP支付(SDK方式),通过微信开放平台开通(300元)现在审核很严格.申请完成后通过邮件下达商户账号,商户平台绑定公司的对公银行账 ...

  8. 微信支付-APP支付

    1. 登陆商户平台 查看APPID , https://pay.weixin.qq.com 在产品中心->我的产品 中查看当前商户开的支付类型. 然后在appID授权里边查看APPID. 然后在 ...

  9. 微信支付-App支付服务端详解

    微信App支付服务端详解 引言 主要实现app支付统一下单.异步通知.调起支付接口.支付订单查询.申请退款.查询退款功能:封装了https对发起退款的证书校验.签名.xml解析等. 支付流程 具体支付 ...

最新文章

  1. 摆动排序leetcode324
  2. 计算机视觉/图像处理方向最新论文速递
  3. SQL Server 中关于 @@error 的一个小误区
  4. 网络流 (EK Dinic)
  5. luogu1347 排序
  6. SkyWalking8.1.0 部署和使用
  7. selenium架构_Selenium测试的干净架构
  8. go语言和java比_Go VS Java:一位资深程序员对两种语言的解读
  9. Netty工作笔记0059---Netty私聊实现思路
  10. java获取反射机制的三种方式
  11. log4j中将SocketAppender将日志内容发送到远程服务器
  12. 添加SAP_ALL权限
  13. linux 提取执行命令后的输出 shell脚本
  14. 八种颠覆未来作战的前沿技术
  15. 明白熊猫与冰墩墩的区别,就知道青云KubeSphere与QKCP该如何选择
  16. java做一个客房管理系统定制_java实现客房管理系统
  17. win10系统设置番茄家园开机音乐以及关机音乐(亲测有效)
  18. pascal编程语言介绍
  19. python 例外 重试_Python例外:简介
  20. 松下服务器分频器输出信号与,松下伺服连接直线电机应用

热门文章

  1. SVN:客户端与服务器端安装、配置与使用
  2. ps将背景变成透明背景
  3. WebView深究之Android是如何实现webview初始化的
  4. 源代码安全检测工具PC_Lint与ITS4实例 zz
  5. jquery鼠标移入文字提示_Jquery hover鼠标经过时弹出div动态提示语
  6. 用友NC65 配置UAP时 打开sysconfig闪退
  7. 秒杀各种Pay?Samsung Pay支付宝功能率先体验
  8. Python 图片转icon
  9. 第三方支付系统-支付流程
  10. java jpanel 层,java – 循环遍历JPanel