在小程序中不能使用之前在浏览器中配置的支付功能,只能调用小程序专属的api进行支付。

因为需要在现在实现的基础上,再添加在小程序中调用微信支付功能,所以我的思路是这样的

1.在点击支付按钮时,判断是不是在小程序中

2.调用小程序支付的页面,并传过去需要的值

3.在小程序支付的js文件中进行调用

实现:

首先需要引入wx的解析文件

下载地址:https://github.com/wangvv9264/jweixin

<script type="text/javascript" src="/index/js/jweixin-1.3.2.js"></script>

判断是不是在小程序中

var ua = navigator.userAgent.toLowerCase();
if(ua.match(/MicroMessenger/i)=="micromessenger") {
//ios的ua中无miniProgram,但都有MicroMessenger(表示是微信浏览器)
wx.miniProgram.getEnv((res)=>{
if (res.miniprogram) {
console.log('在小程序内')
wx.miniProgram.navigateTo({
url: "/pages/prowxpay/prowxpay?info="+queryParam //小程序的支付地址,queryParam是需要传递的商品id等数据
});
return false;
}else{
console.log('在微信内,但是不在小程序内')
return false;
}
})
}else{
console.log('在微信外')
return false;
}

在小程序支付的js文件中进行调用

var app = getApp();
Page({
data: {
bt: 'bt'
}, onLoad: function (options) {
var that = this;
if (options.goods_id) {
that.setLoading(options);
} else { wx.navigateBack();}
}, setLoading: function(a) {
var that = this
wx.login({
success: function(res) {
// 成功会返回:
// {errMsg: "login:ok", code: "获取用户OpenID的ticket"}
that.getOpenId(res.code,a)
}
})
},
getOpenId: function (jsCode,a) {
var that = this
wx.request({
url: baseURL + '/index/Xcxpay/login', //baseURL引入的https地址
data: {
js_code: jsCode // wx.login()时得到的ticket
},
success: function (res) {
that.getPrePayId(res.data.openid,a)
},
fail: function (res) {
console.log(res)
that.setData({
bt: ''
}),
wx.showModal({ title: "网络超时", content: "刷新重试", showCancel: !1 });
}
})
},
getPrePayId: function (openId, a) {var that = this
wx.request({
url: baseURL + '/index/Xcxpay/index?openid='+openId+'&goods_id=' + a.goods_id ,
success: function (res) {
console.log(res.data);
if(res.data.status == 1) {
that.pay(res.data.data,a);
} else {
var msg = String(res.data.msg);
wx.showModal({
title: "提醒",
content: msg,
showCancel: !1,
success(res) {
if(res.confirm) {
wx.navigateBack({
delta: 1
})
}
}
})
return false;
}
},
fail:function (res) {
console.log(res);
that.setData({
bt: ''
})
}
})
},
// data是服务端返回的JSON
// 加上success、fail回调后,正好符合wx.requestPayment()参数的格式
pay: function (res, a) {
console.log(res)
wx.requestPayment({ //成功之后,调用小程序微信支付
'timeStamp': res.timeStamp,
'nonceStr': res.nonceStr,
'package': res.package,
'signType': 'MD5',
'paySign': res.paySign,
success: function (res) {
console.log(res)
wx.request({
url: baseURL + '/index/Xcxpay/callback?goods_id=' + a.goods_id + '&msg=' + res.errMsg,
success: function(res){
console.log(res.data.status)
if(res.data.status == 1) {
wx.showToast({
title: '支付成功',
icon: 'success',
duration: 2000
})
setTimeout(()=>{
wx.redirectTo({
url: '/pages/order/order',
})
},2001)
} },
fail: function(){}
}) },
fail: function (res) {
console.log('付款失败');
console.log(res)
wx.showModal({
title: '提醒',
content: '付款失败',
showCancel: false,
success:function(res){
if(res.confirm) {
wx.navigateBack({
delta: 1
})
}
}
})
return
},
})
}, wdxreload: function(){
var pages = getCurrentPages();
var currentPage = pages[pages.length - 1]; //获取当前页面的对象
var url = currentPage.route; //当前页面url
var options = currentPage.options; //如果要获取url中所带的参数可以查看options
wx.navigateTo({ url: "/pages/wxpay/wxpay?goods_id=" + options.goods_id});
} })

我对接的后台是php,下面附上代码

public function login() {
$appid='微信小程序的appId';
$secret='微信小程序的密钥'; $params = array(
'appid' => $appid,
'secret' => $secret,
'js_code' => $_GET['js_code'], // 小程序传来的ticket
'grant_type' => 'authorization_code',
); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.weixin.qq.com/sns/jscode2session');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$output = curl_exec($ch); if (false === $output) {
echo 'CURL Error:' . curl_error($ch);
}
echo $output; } //https://blog.csdn.net/u010505805/article/details/76861853
public function index(){
$order_id = isset($_GET['goods_id']) ? intval($_GET['goods_id']) : '';
$openid = $_GET['openid']; $this->pub_index($openid,$order_id); }
public function pub_index($openid,$order_id){
$appid='小程序appId';
$secret='微信小程序的密钥';
$url="https://api.mch.weixin.qq.com/pay/unifiedorder"; $mch_id = '';//受理商ID(即微信支付商户号)
$mch_key = '';//商户支付密钥Key
$order = $orderinfo=Db::name('order_info')->where('order_code="'.$order_id.'"')->find();
$total_fee=$order['order_amount'] * 100; $params = array(
'appid' => $appid, // 小程序appid
'mch_id' => $mch_id,
'nonce_str' => (string)mt_rand(10000, 99999), // 随机串,32字符以内
'body' => ' ', // 商品名
'out_trade_no' => $order['order_code'],
//'out_trade_no' => substr( $order['order_code'].'A'.($order['order_amount']*100).'B' ,0,32),
//订单号32字符以内。串接后取前32位。多次支付时如果重复的话,微信会返回“重复下单”
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
'notify_url' => '', // 支付成功后的回调地址,由腾讯服务端回调
'trade_type' => 'JSAPI',
'openid' => $openid, // 小程序传来的OpenID
'total_fee' =>(string)$total_fee, // 订单费用,单位:分
); //var_dump($params);die;
// 按照要求计算sign
ksort($params);
$sequence = '';
foreach ($params as $key => $value) {
$sequence .= "$key=$value&";
} $sequence = $sequence . "key=".$mch_key;
//echo $sequence;die;
$params['sign'] = strtoupper(md5($sequence)); $xml =$this->arrayToXml($params); $ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$output = curl_exec($ch); if (false === $output) {
echo 'CURL Error:' . curl_error($ch);
}
// 下单成功的话,微信返回个XML,里面包含prepayID,提取出来 $match=$this->xml_to_array($output);
//var_dump($match);die; if($match['result_code']=='FAIL'){
$result['status']=3;
$result['msg']=$match['err_code_des'];
die(json_encode($result));
} // 这里不是给小程序返回个prepayID,而是返回一个包含其他字段的JSON
// 这个JSON小程序自己也可以生成,放在服务端生成是出于两个考虑:
// 1. 小程序的appid不用写在小程序的代码里,appid、secret信息全部由服务器管理,比较安全
// 2. 计算paySign需要用到md5,小程序端使用的是JavaScript,没有内置的md5函数,放在服务端计算md5比较方便 @$prepayId = $match['prepay_id']; if(!$match['prepay_id']){
$result['status']=4;
$result['msg']='prepay_id为空,请查看具体原因';
die(json_encode($result));
}
$response= array(
'appId' => $appid, //小程序appid
'nonceStr' => (string) mt_rand(10000, 99999), // 随机串,32个字符以内
'package' => (string)'prepay_id=' . $prepayId,
'signType' => 'MD5',
'timeStamp' => (string) time(), // 时间戳,注意得是字符串形式的
);
$sequence = '';
foreach ($response as $key => $value) {
$sequence .= "$key=$value&";
}
$response['paySign'] = strtoupper(md5("{$sequence}key=".$mch_key)); //$info['aaa']=(string)$prepayId; $result['status']=1;
$result['msg']='成功';
$result['data']=$response;
die(json_encode($result));
}
function callback(){
$order_id = $_GET['goods_id']; $result = Db::name('')->where("order_code='".$order_id."'")->update(array('pay_status'=>1,'order_status'=>1,'pay_time'=>time(),'pay_id'=>1,'pay_name'=>'微信','pay_platform'=>'小程序支付')); $orderinfo = Db::name("")->field('order_amount,add_time')->where("order_code='".$order_id."'")->find();
Db::name('order_log')->insert(array('order_code'=>$order_id,'type'=>'小程序微信支付','addtime'=>date('Y-m-d H:i:s',$orderinfo['add_time']),'paytime'=>date('Y-m-d H:i:s',time()),'order_amount'=>$orderinfo['order_amount'],'remark'=>'SUCCESS'));
$data['status']=1;
die(json_encode($data));
}
function notify($data)
{
$inputdata = file_get_contents("php://input");
if (! empty($inputdata)) { $payment = model('Payment')->get_payment("wxpay");
$postdata = json_decode(json_encode(simplexml_load_string($inputdata, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
/* 检查插件文件是否存在,如果存在则验证支付是否成功,否则则返回失败信息 */
// 微信端签名
$wxsign = $postdata['sign'];
unset($postdata['sign']); // 微信附加参数
$attach = $postdata['attach']; foreach ($postdata as $k => $v) {
$Parameters[$k] = $v;
}
// 签名步骤一:按字典序排序参数
ksort($Parameters); $buff = "";
foreach ($Parameters as $k => $v) {
$buff .= $k . "=" . $v . "&";
}
$String;
if (strlen($buff) > 0) {
$String = substr($buff, 0, strlen($buff) - 1);
}
// 签名步骤二:在string后加入KEY
$String = $String . "&key=" . $payment['wxpay_key'];
// 签名步骤三:MD5加密
$String = md5($String);
// 签名步骤四:所有字符转为大写
$sign = strtoupper($String);
// 验证成功
if ($wxsign == $sign) {
// 交易成功
$returndata['return_code'] = 'SUCCESS';
} else {
$returndata['return_code'] = 'FAIL';
}
} else {
$returndata['return_code'] = 'FAIL';
$returndata['return_msg'] = '无数据返回';
}
// 数组转化为xml
$xml =$this->arrayToXml($returndata); echo $xml;
exit();
}
function arrayToXml($arr)
{ $xml = "<xml>";
foreach ($arr as $key=>$val)
{
if (is_array($val)){
$xml.="<".$key.">".arrayToXml($val)."</".$key.">";
}else{
$xml.="<".$key.">".$val."</".$key.">";
}
}
$xml.="</xml>"; return $xml;
}
function xml_to_array($xml){
if(!$xml){
return false;
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $data;
}

欢迎各位同仁交流~

加油哦~小王

h5内嵌微信小程序,调用微信支付功能的更多相关文章

  1. 微信小程序调用微信支付

    1,首先我们先缕清支付的整个流程,详见https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3,第一 ...

  2. 微信小程序调用微信支付接口

    本文链接:https://blog.csdn.net/u012667477/article/details/80940578前言:应项目要求,需要使用微信小程序做支付,写完后告知手续费太高方案不予通过 ...

  3. 让你的微信小程序具有在线支付功能

    前言 最近需要在微信小程序中用到在线支付功能,于是看了一下官方的文档,发现要在小程序里实现微信支付还是很方便的,如果你以前开发过服务号下的微信支付,那么你会发现其实小程序里的微信支付和服务号里的开发过 ...

  4. 微信小程序调用微信登陆获取openid及用户信息 java做为服务端

    转载的文章,很不错 https://blog.csdn.net/weilai_zhilu/article/details/77932630

  5. [转]微信小程序、微信公众号、H5之间相互跳转

    本文转自:https://www.cnblogs.com/colorful-paopao1/p/8608609.html 转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加 ...

  6. 微信小程序、微信公众号、H5之间相互跳转

    转自慕课网 一.小程序和公众号 答案是:可以相互关联. 在微信公众号里可以添加小程序. 图片有点小,我把文字打出来吧: 可关联已有的小程序或快速创建小程序.已关联的小程序可被使用在自定义菜单和模版消息 ...

  7. 图解微信小程序---调用API操作步骤

    图解微信小程序---调用API操作步骤 什么是API API(Application Programming Interface,应用程序编程接口:是一些预先定义的函数,目的是提供应用程序与开发人员基 ...

  8. 微信小程序之微信登陆 —— 微信小程序教程系列(20)

    简介: 微信登陆,在新建一个微信小程序Hello World项目的时候,就可以看到项目中出现了我们的微信头像,其实这个Hello World项目,就有一个简化版的微信登陆.只不过是,还没有写入到咱们自 ...

  9. 微信小程序和微信公众号的id是一个吗

    首先,简单说下我遇到的问题是我们的程序调用微信小程序得到openid,然后通过openID得到用户的唯一标识,用户得以登录,然而,当我们调用微信公众号也同样的到openid,同一以用户两个不同的ope ...

  10. 微信小程序< 3 > ~ 微信小程序开源项目合集

    简介 移动开发者想学习微信小程序需要学习一点HTML ,CSS和JS才能够比较快速的上手,参考自己学习Android学习过程,阅读源码是一个很好的方式,所以才收集了一些WeApp的开源项目. awes ...

随机推荐

  1. ResNeSt:Split attention

    https://www.cnblogs.com/xiximayou/p/12728644.html 下面是SE和SK这两个网络,兄弟俩很相似 下面是具体的每个cardinal(翻译为枢纽)网络,和SK ...

  2. C#LeetCode刷题之#933-最近的请求次数(Number of Recent Calls)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4134 访问. 写一个 RecentCounter 类来计算最近的 ...

  3. C#LeetCode刷题之#141-环形链表(Linked List Cycle)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3901 访问. 给定一个链表,判断链表中是否有环. 进阶: 你能否 ...

  4. 面试官:怎么做JDK8的垃圾收集器的调优?

    面试官:怎么做JDK8的垃圾收集器的调优? 看着面试官真诚的眼神,心中暗想看起来年纪轻轻却提出如此直击灵魂的问题.擦了擦额头上汗,我稍微调整了一下紧张的情绪,对面试官说: 在JDK8中有Serial收 ...

  5. Eclipse的Servers中无法添加Tomcat6/7

    2017年03月06日 17:14:46 阅读数:1007 Eclipse中在添加tomcat时发现6和7点击后发现ServerName是灰色的不能使用,也点不了NEXT,在各种查百度后发现需要删除w ...

  6. 使用halo搭建自己的博客并配置https域名访问

    首先进行java配置 # 1. 下载jdk [下载地址](https://www.oracle.com/cn/java/technologies/javase-downloads.html) - 一定 ...

  7. vue报错vue-router.esm.js?8c4f:2007 Uncaught (in promise) NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated"}

    今天在写vue项目配置好路由点击菜单时,突然在控制台报错. 错误信息如下: Uncaught (in promise) NavigationDuplicated {_name: "Navig ...

  8. 微信小程序之蓝牙广播信息

    期初第一次做蓝牙开锁的时候遇到的最尖锐的问题就是ios设备如何对获取的广播信息进行读取,大概用了4中方式,都无法解决,最后不得不求助官方人员.给了一个方法,大家可以参考.在此附图: 由于mac地址是6 ...

  9. 精讲响应式WebClient第2篇-GET请求阻塞与非阻塞调用方法详解

    本文是精讲响应式WebClient第2篇,前篇的blog访问地址如下: 精讲响应式webclient第1篇-响应式非阻塞IO与基础用法 在上一篇文章为大家介绍了响应式IO模型和WebClient的基本 ...

  10. AltiumDesigner20画图不求人10 | 提高AD20启动速度的方法六取消加入产品改善计划 | 视频教程 | 你问我答

    教程内容:AltiumDesigner20画图不求人系列,是电子芯原创的AltiumDesigner绘图技巧视频教程,每一个技巧只需要不到3分钟的时间就可以完成学习.前期经过AD19的画图不求人,帮助 ...