微信小程序调微信支付
今天写小程序的支付接口,参照的当然是微信支付API了。(结尾附上第二步全部代码php版)
另外,我也参照了简书上的这篇文章,浅显易懂:https://www.jianshu.com/p/72f5c1e3f8a5
其实小程序中唤起微信支付不外乎以下几个步骤:
1.获取openid
小程序获取openid是分两个步骤的
首先小程序前端通过wx.login获取code,然后用这个code通过后台接口内部访问微信官方API获取openid、session_key
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=CODE&grant_type=authorization_code
红字为所需参数,appid和secret手动配置(开发者平台申请),code就是小程序前端获取的code了
2.获取prepay_id和paySign
拿着刚才的openid和订单号(自定义订单号)、订单金额(手动输入金额)以及其他平台参数拼接成一个xml文件作为请求体
通过后台接口内部访问微信API接口:https://api.mch.weixin.qq.com/pay/unifiedorder
如果参数无误,将如期返回prepay_id和paySign
3.前端拉起支付
拿到了所需参数,前端就可以发起:wx.requestPayment 来拉起支付了。
wx.requestPayment({
'timeStamp':timeStamp,
'nonceStr': nonceStr,
'package': 'prepay_id='+res.data.prepay_id,
'signType': 'MD5',
'paySign': res.data._paySignjs,
'success':function(res){
console.log(res);
},
'fail':function(res){
console.log('fail:'+JSON.stringify(res));
}
})
如此就完成了小程序的支付,下面就要说一下今天踩的坑了。
1.appid问题
前期前端用的appid是用的他个人的appid,要知道小程序用户授权小程序所生成的openid,是需要用appid来参与验签
的,这直接导致,后期将appid更换为线上appid后,所有的测试用户openid(这个openid在用户授权之后直接存到数据
库了,所以实际上我们省略了第一步,直接从数据库拿当前用户的数据库存储的openid)走如上第二步的时候,都会报
openid和appid不匹配的错误,将前期用户数据删除,并更正appid以及其他参数,重新授权后的openid就不会产生不匹
配的错误了。
第二步获取prepay_id和paySign代码(php版本):
<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); define(APPID, 'wx74bmn4nbf81f1593e');
define(MCHID, '1510771171');
define(KEY, 'WlUprCqVM53L4MnI6Dz2Nmz7f44');
define(APPSECRET, '3b8e3202c39c67712879f6724fc8b42');
define(NOTIFY_URL, SITE_URL.'web/dayrui/controllers/return_url.php'); require_once FCPATH . 'branch/fqb/D_Wxapp.php';
require 'WxPay.class.php'; class Wxapp extends D_Wxapp {
... //支付,红字参数依次是openid、订单号、订单说明、订单金额
public function pay(){
$pay = $this->req;
$weixinpay = new WxPay(APPID, $pay['openid'], MCHID, KEY, $pay['out_trade_no'], $pay['body'], $pay['total_fee']);
exit_json(, $weixinpay->pay());
} }
WxPay.class.php可以直接用,只是注意get_ip()函数是用来获取客户端ip的,这里稍加封装了一下,会在后面给出封装函数代码
//WxPay.class.php <?php
class WxPay { protected $appid;
protected $mch_id;
protected $key;
protected $openid;
protected $out_trade_no;
protected $body;
protected $total_fee; function __construct ($appid, $openid, $mch_id, $key, $out_trade_no, $body,$total_fee){
$this->appid = $appid;
$this->openid = $openid;
$this->mch_id = $mch_id;
$this->key = $key;
$this->out_trade_no = $out_trade_no;
$this->body = $body;
$this->total_fee = $total_fee;
} public function pay (){
//统一下单接口 $return=$this->weixinapp ();
return $return;
} //微信小程序接口
private function weixinapp (){
//统一下单接口
$unifiedorder=$this->unifiedorder ();
$parameters=array ('appId'=>$this->appid ,//小程序ID
'timeStamp'=>''.time().'',//时间戳
'nonceStr'=>$this->createNoncestr (),//随机串
'package'=>'prepay_id='.$unifiedorder['prepay_id'],//数据包
'signType'=>'MD5'//签名方式
);
$parameters['paySign']=$this->getSign ($parameters);
return $parameters;
} //统一下单接口
private function unifiedorder (){
$url='https://api.mch.weixin.qq.com/pay/unifiedorder';
$parameters=array (
'appid'=>$this->appid ,
'mch_id'=>$this->mch_id ,
'nonce_str'=>$this->createNoncestr(),
'body'=>$this->body,
'out_trade_no'=>$this->out_trade_no ,
'total_fee'=>$this->total_fee,
'spbill_create_ip'=>get_ip(),
'notify_url'=> NOTIFY_URL,
'openid'=>$this->openid,
'trade_type'=>'JSAPI'
);
//统一下单签名
//pre($parameters);
$parameters['sign']=$this->getSign ($parameters);
$xmlData=$this->arrayToXml ($parameters);
$return=$this->xmlToArray ($this->postXmlCurl ($xmlData,$url,));
return $return;
} private static function postXmlCurl ($xml,$url,$second=){
$ch=curl_init();
//设置超时
curl_setopt($ch,CURLOPT_TIMEOUT ,$second);
curl_setopt($ch,CURLOPT_URL ,$url);
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_setopt($ch,CURLOPT_CONNECTTIMEOUT ,);
curl_setopt($ch,CURLOPT_TIMEOUT ,);
set_time_limit();
//运行curl
$data=curl_exec($ch);
//返回结果
if ($data){
curl_close($ch);
return $data;
}else {
$error=curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl出错,错误码:$error");
}
}
//数组转换成xml
private function arrayToXml ($arr){
$xml="<root>";
foreach ($arr as $key=>$val){
if (is_array($val)){
$xml.="<".$key.">".arrayToXml ($val)."</".$key.">";
}else {
$xml.="<".$key.">".$val."</".$key.">";
}
}
$xml.="</root>";
return $xml;
} //xml转换成数组
private function xmlToArray ($xml){
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$xmlstring=simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA );
$val=json_decode(json_encode($xmlstring),true);
return $val;
} //作用:产生随机字符串,不长于32位
private function createNoncestr ($length=){
$chars="abcdefghijklmnopqrstuvwxyz0123456789";
$str="";
for ($i=;
$i<$length;
$i++){
$str.=substr($chars,mt_rand(,strlen($chars)-),);
}
return $str;
}
//作用:生成签名
private function getSign ($Obj){
foreach ($Obj as $k=>$v){
$Parameters[$k]=$v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String=$this->formatBizQueryParaMap ($Parameters,false);
//签名步骤二:在string后加入KEY
$String=$String."&key=".$this->key ;
//签名步骤三:MD5加密
$String=md5($String);
//签名步骤四:所有字符转为大写
$result_=strtoupper($String);
return $result_;
}
///作用:格式化参数,签名过程需要使用
private function formatBizQueryParaMap ($paraMap,$urlencode){
$buff="";
ksort($paraMap);
foreach ($paraMap as $k=>$v){
if ($urlencode){
$v=urlencode($v);
}
$buff.=$k."=".$v."&";
}
$reqPar;
if (strlen($buff)>){
$reqPar=substr($buff,,strlen($buff)-);
}
return $reqPar;
}
}
get_ip():
function get_ip(){
//判断服务器是否允许$_SERVER
if(isset($_SERVER)){
if(isset($_SERVER[HTTP_X_FORWARDED_FOR])){
$realip = $_SERVER[HTTP_X_FORWARDED_FOR];
}elseif(isset($_SERVER[HTTP_CLIENT_IP])) {
$realip = $_SERVER[HTTP_CLIENT_IP];
}else{
$realip = $_SERVER[REMOTE_ADDR];
}
}else{
//不允许就使用getenv获取
if(getenv("HTTP_X_FORWARDED_FOR")){
$realip = getenv( "HTTP_X_FORWARDED_FOR");
}elseif(getenv("HTTP_CLIENT_IP")) {
$realip = getenv("HTTP_CLIENT_IP");
}else{
$realip = getenv("REMOTE_ADDR");
}
}
return $realip;
}
微信小程序调微信支付的更多相关文章
- 微信小程序调起支付API
官方文档: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7 https://developers.weixin.q ...
- 微信小程序之微信支付C#后台(统一下单)
一.微信小程序支付 1.微信小程序端请求支付接口 商户在小程序中先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易后调起支付.具体可以查看接口示例. 接口传入参数示例: <xm ...
- 微信小程序(微信应用号)开发ide安装解决方法
这两天整个技术圈都炸锅了,微信小程序(微信应用号)发布内测,首批200家收到邀请,但是没受邀请的同学,也不用担心,下面介绍一下解决方法. 首先需要下载ide,昨天只需要下载0.9版本的编辑器并替换文件 ...
- 微信小程序(原名微信应用号)开发工具0.9版安装教程
微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名 ...
- 微信小程序之微信登陆 —— 微信小程序教程系列(20)
简介: 微信登陆,在新建一个微信小程序Hello World项目的时候,就可以看到项目中出现了我们的微信头像,其实这个Hello World项目,就有一个简化版的微信登陆.只不过是,还没有写入到咱们自 ...
- 微信小程序(微信应用号)组件讲解[申明:来源于网络]
微信小程序(微信应用号)组件讲解[申明:来源于网络] 地址:http://www.cnblogs.com/muyixiaoguang/p/5902008.html
- 微信小程序和微信公众号的id是一个吗
首先,简单说下我遇到的问题是我们的程序调用微信小程序得到openid,然后通过openID得到用户的唯一标识,用户得以登录,然而,当我们调用微信公众号也同样的到openid,同一以用户两个不同的ope ...
- [转]微信小程序、微信公众号、H5之间相互跳转
本文转自:https://www.cnblogs.com/colorful-paopao1/p/8608609.html 转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加 ...
- 微信小程序、微信公众号、H5之间相互跳转
转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息 ...
随机推荐
- web前端编码规范
简要介绍 本文通过参考百度腾讯等前端编码规范(链接建文末),得出个人习惯的编码规范.个人编码规范采用在不影响可读性的情况下能省就省,尽量简洁,不需要就直接去掉. 最佳原则不管是个人编码规范还是团队编码 ...
- 动态更改WebBrowser数据流内容
动态更改WebBrowser数据流内容 有时,由于软件的特殊需要,我们希望DELPHI在WebBrowser或embeddedwb里动态更改返回的数据内容,而这需要返回网页的所有原始源码, ...
- python2中range和xrange的区别
range和xrange用法相同,不同的是xrange不是生成一个序列,而是作为一个生成器,即生成一个取出一个 相对来说,xrange比range性能优化很多,因为不需要一下子开辟一块很大的内存,特别 ...
- CNN学习笔记:神经网络表示
CNN学习笔记:神经网络表示 双层神经网络模型 在一个神经网络中,当你使用监督学习训练它的时候,训练集包含了输入x还有目标输出y.隐藏层的含义是,在训练集中,这些中间节点的真正数值,我们是不知道的,即 ...
- HDOJ 1238 Substrings 【最长公共子串】
HDOJ 1238 Substrings [最长公共子串] Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- CodeForces - 919D Substring (拓扑排序+dp)
题意:将一个字符串上的n个字符视作点,给出m条有向边,求图中路径上最长出现的相同字母数. 分析:首先如果这张图中有环,则可以取无限大的字符数,在求拓扑排序的同时可以确定是否存在环. 之后在拓扑排序的结 ...
- Firebug控制台详解(转)
本文转自:http://www.ruanyifeng.com/blog/2011/03/firebug_console_tutorial.html 作者: 阮一峰 日期: 2011年3月26日 Fir ...
- [转]浅谈Hive vs. HBase 区别在哪里
浅谈Hive vs. HBase 区别在哪里 导读:Apache Hive是一个构建于Hadoop(分布式系统基础架构)顶层的数据仓库,Apache HBase是运行于HDFS顶层的NoSQL(=No ...
- Action Results in Web API 2
https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action- ...
- OCR训练数据生成方法
有的时候我们训练网络的时候,数据集在收集的过程中由于种种原因导致图像收集的不完整,比如某些种类很少,或者没有,这个时候我们就可以考虑自己生成数据集. 这个和data augmentation还不太一样 ...