uniapp+thinkphp5实现微信扫码支付(APP支付)
前言
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返回预支付订单号的接口,目前微信支付所有场景均使用这一接口。下面介绍的是其中APP的支付的配置与实现流程
配置
1.首先登录微信开放平台,注册账号。
https://open.weixin.qq.com/
2.点击创建移动应用

3.获取到移动应用的APPID

4.打开前端uniapp的项目,在主目录下找到manifest.json文件->APP模块配置->Payment->微信支付->将微信开放平台的应用APPID填写在对应的位置

5.根据微信开放平台提供的工具对项目包的包名进行签名的获取



下载链接:https://developers.weixin.qq.com/doc/oplatform/Downloads/Android_Resource.html#%E7%AD%BE%E5%90%8D%E7%94%9F%E6%88%90%E5%B7%A5%E5%85%B7
安装完毕是这样的:输入您的应用包名进行签名的获取即可

6.申请开通微信支付


微信商户号绑定APPID

选择我的产品,申请开通APP、JSAPI支付

选择账户中心->api安全,进行证书与密钥的申请,v2/v3都可以申请,调用的api不同,并不冲突

到此为止关于app微信支付的配置就基本完成了。
流程实现(后端)(PHP)
- 创建Wechatpay.php文件,放到指定文件目录下(我是放到了extend目录)
<?php
class Wechatpay{
/**
* 模拟提交参数,支持https提交 可用于各类api请求
* @param string $url : 提交的地址
* @param array $data :POST数组
* @param string $method : POST/GET,默认GET方式
* @return mixed
*/
function curl_https($url, $xml='', $useCert=false){
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch,CURLOPT_URL, $url);
//设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
//要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if(stripos($url,"https://")!==FALSE){
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
}else{
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
}
if($useCert == true){
//设置证书
//使用证书:cert 与 key 分别属于两个.pem文件
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT,"");
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY,"");
}
//post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
//运行curl
$data = curl_exec($ch);
//返回结果
if($data){
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
//echo $error;
}
}
/**
*
* 拼接签名字符串
* @param array $urlObj
*
* @return 返回已经拼接好的字符串
*/
function ToUrlParams($urlObj)
{
$buff = "";
foreach ($urlObj as $k => $v)
{
if($k != "sign"){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
//数组转XML
function arrayToXml($arr)
{
$xml = "<xml>";
foreach ($arr as $key=>$val)
{ if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
//将XML转为array
function xmlToArray($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $values;
}
/**
* 获取随机字符串
* @return mixed
*/
function getRandString($len=12,$str='ABCDEFGHIJKLMNOPQRSTUVWYXZabcdefghijklmnopqrstuvwyxz1234567890'){
$strlen=strlen($str)-1;
$string='';
for ($i=0; $i < $len; $i++) {
$r=rand(1,$strlen);
$string=$string.$str[$r];
}
return $string;
}
}
2.定义公共变量
private $config = array(
'appid_app' => "wx******", /*微信开放平台上的应用id*/
'mch_id' => "*******", /*微信申请成功之后邮件中的商户id*/
'api_key' => "*************", /*在微信商户平台上自己设定的api密钥 32位*/
'notify_url' => 'https://***', /*支付回调地址,确保可以访问*/
);
3.支付接口
public function AppPay($busid,$price,$code,$type,$attach){
$businessInfo=$this->BusinessModel->find($busid);
Loader::import('wechatpay.Wechatpay', EXTEND_PATH,".php");
$wechatpay = new \Wechatpay();
$url='https://api.mch.weixin.qq.com/pay/unifiedorder';
$parameters = array(
'appid' => $this->config["appid_app"], // 应用ID
'mch_id' => $this->config['mch_id'], // 商户号
'nonce_str' => $wechatpay->getRandString(30), // 随机字符串
'body' => '购买商品测试', // 商品描述
'out_trade_no' => $code, // 商户订单号
'total_fee' => $price * 100, // 总金额,单位为分
'spbill_create_ip' => $this->get_client_ip(), // 终端IP
'notify_url' => $this->config["notify_url"], // 通知地址
'trade_type' => "APP", // 交易类型改为APP
'sign_type' => "MD5",
'attach' => $attach
);
//参数名ASCII码从小到大排序
ksort($parameters);
//统一下单签名
$String = $wechatpay->ToUrlParams($parameters);
//签名步骤二:在string后加入KEY
$String = $String."&key=".$this->config['api_key']; // key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
$String2=$String;
//签名步骤三:MD5加密 (一次签名)
$time=time();
$parameters['sign']=strtoupper(md5($String));
$xmlData=$wechatpay->arrayToXml($parameters);
$return=$wechatpay->xmlToArray($wechatpay->curl_https($url,$xmlData));
if($return["return_code"]=="SUCCESS" && $return["result_code"]=="SUCCESS"){
// 从预支付接口返回的参数中取得 prepay_id
$prepay_id = $return['prepay_id'];
// 构造二次签名的参数
$signParams = array(
'appid' => $this->config["appid_app"],
'partnerid' => $this->config['mch_id'], // 商户号
'prepayid' => $return['prepay_id'], // 从预支付接口返回的参数中取得prepay_id
'package' => 'Sign=WXPay', // Sign=WXPay
'noncestr' => $wechatpay->getRandString(30), // 随机字符串
'timestamp' => (string)$time, // 时间戳需与统一下单时的时间戳保持一致
);
// 对签名参数进行签名
ksort($signParams);
$signString = $wechatpay->ToUrlParams($signParams);
$signString = $signString . "&key=" . $this->config['api_key'];
$sign = strtoupper(md5($signString));
// 将签名加入返回给APP的参数中
$signParams['sign'] = $sign;
// 返回参数给APP
$this->result($signParams, '1', '二次签名成功!', 'json');
}else{
echo json_encode(array("status"=>false,"msg"=>$return));
$this->result($return, '0', '签名失败!', 'json');
}
}
/*
获取当前服务器的IP
*/
public function get_client_ip(){
if ($_SERVER['REMOTE_ADDR']) {
$cip = $_SERVER['REMOTE_ADDR'];
} elseif (getenv("REMOTE_ADDR")) {
$cip = getenv("REMOTE_ADDR");
} elseif (getenv("HTTP_CLIENT_IP")) {
$cip = getenv("HTTP_CLIENT_IP");
} else {
$cip = "unknown";
}
return $cip;
}
- 支付回调
//微信支付回调接口
public function wxpaynotify(){
$xml = file_get_contents('php://input');
Loader::import('wechatpay.Wechatpay', EXTEND_PATH,".php");
$wechatpay = new \Wechatpay();
//将服务器返回的XML数据转化为数组
$data = $wechatpay->xmlToArray($xml);
// 保存微信服务器返回的签名sign
$data_sign = $data['sign'];
// sign不参与签名算法
unset($data['sign']);
$sign = $wechatpay->ToUrlParams($data);
$payData=$sign;
$sign=strtoupper(md5($sign."&key=".$this->config["api_key"]));
// 判断签名是否正确 判断支付状态
if ( ($sign===$data_sign) && ($data['result_code']=='SUCCESS') ) {
// 更新消费订单状态等操作
$result = true;
}else{
file_put_contents('payResult.tex','验签失败!');
$result = false;
}
// 返回状态给微信服务器
if ($result) {
$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
}else{
$str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
}
echo $str;
}
流程实现(前端)(Vue)(APP)
uni.getProvider({
service: 'payment',
success: function(ress) {
//判断是否有支付权限
if (~ress.provider.indexOf('wxpay')) {
let orderInfo={
"appid": result.data.appid, // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
"noncestr": result.data.noncestr, // 随机字符串
"package": "Sign=WXPay", // 固定值
"partnerid": result.data.partnerid, // 微信支付商户号
"prepayid": result.data.prepayid, // 统一下单订单号
"timestamp": result.data.timestamp, // 时间戳(单位:秒)
"sign": result.data.sign // 签名,这里用的 MD5/RSA 签名
}
// 调用 wx.requestPayment 方法发起支付请求
uni.requestPayment({
"provider": "wxpay",
"orderInfo": orderInfo,
success(res) {
// 支付成功的处理逻辑
console.log('支付成功', res);
uni.showToast({
title: '支付成功!',
icon: 'none',
duration: 1000
})
},
fail(res) {
// 支付失败的处理逻辑
console.log('支付失败', res);
uni.showToast({
title: res.errMsg,
icon: 'none',
duration: 2000
})
}
})
}
}
});
uniapp+thinkphp5实现微信扫码支付(APP支付)的更多相关文章
- Thinkphp5整合微信扫码支付开发实例
ThinkPHP框架是比较多人用的,曾经做过的一个Thinkphp5整合微信扫码支付开发实例,分享出来大家一起学习 打开首页生成订单,并显示支付二维码 public function index() ...
- thinkphp5.0 微信扫码支付模式二
仅供个人参考,方便大家. 一.1)https://pay.weixin.qq.com/index.php/core/home/login 复制此地址 打开微信商户平台. 2)下载安全操作证书(最好在 ...
- 微信扫码下载APP
前段时间开发过程中,要实现一个扫描二维码下载APP的功能,但是苹果系统中,微信不可以直接跳转苹果商店,需要先下载应用宝,显然太麻烦... 这样我们可以做个中间页,用中间页面生成二维码链接,在中间页代码 ...
- 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结
最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...
- asp.net core 微信扫码支付(扫码支付,H5支付,公众号支付,app支付)之1
2018-08-13更新生成二维码的方法 在做微信支付前,首先要了解你需要什么方式的微信支付,目前本人做过的支付包含扫码支付.H5支付.公众号支付.App支付等,本人使用的是asp.net mvc c ...
- 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付
在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...
- ThinkPHP5微信扫码支付
1.把微信官网下载的demo放在根目录/vendor/目录下,这里我的是/vendor/wxpay_pc目录 2.把cert里面的文件替换成自己项目的证书(登陆微信商户平台,账户中心,API安全下载) ...
- thinkphp.2 thinkphp5微信支付 微信公众号支付 thinkphp 微信扫码支付 thinkphp 微信企业付款5
前面已经跑通了微信支付的流程,接下来吧微信支付和微信企业付款接入到thinkphp中,版本是3.2 把微信支付类.企业付款类整合到一起放到第三方类库,这里我把微信支付帮助类和企业付款类放到同一个文件了 ...
- 微信扫码i支付~官方DEMO的坑
返回目录 之前写过关于微信支付那些坑的文章(<微信JSApi支付~集成到MVC环境后的最后一个坑(网上没有这种解决方案)>,<微信JSApi支付~坑和如何填坑>),下面说一下微 ...
- 微信扫码支付springboot版本
发布时间:2018-11-06 技术:springboot+freemarker 概述 该项目是一个采用springboot构建的web项目,主要实现了微信扫码支付功能.包含最基本的创建订单, ...
随机推荐
- Java 集合类 List 的那些坑
现在的一些高级编程语言都会提供各种开箱即用的数据结构的实现,像 Java 编程语言的集合框架中就提供了各种实现,集合类包含 Map 和 Collection 两个大类,其中 Collection 下面 ...
- docker 安装 kafka+zookeeper,golang操作kafka
目录 docker-compose.yml go操作kafka producer 消费者 consumer 消费者 结合gin框架操作kafka go-queue操作kafka 环境: centos8 ...
- MySQL优化方向
MySQL优化手段 数据库设计层面 范式设计 减少数据冗余 提高数据一致性 索引策略 选择合适的索引类型 (BTREE, HASH) 覆盖索引 索引选择性 表结构优化 使用合适的数据类型 避免使用NU ...
- 网络拓扑—WEB-IIS服务搭建
目录 WEB-IIS服务搭建 网络拓扑 配置网络 IIS PC 安装IIS服务 配置IIS服务(默认站点) PC机访问网页 配置IIS服务(新建站点) PC机访问网页 WEB-IIS服务搭建 网络拓扑 ...
- 程序编译流程与 GCC 编译器
目录 文章目录 目录 GUN 计划 GCC 编译器 Clang 和 LLVM GCC 的常用指令选项 GCC 所遵循的部分约定规则 GCC 的编译流程 GCC 的编译流程示例 编译多个文件 GUN 计 ...
- 【开源】2024最新python豆瓣电影数据爬虫+可视化分析项目
项目介绍 [开源]项目基于python+pandas+flask+mysql等技术实现豆瓣电影数据获取及可视化分析展示,觉得有用的朋友可以来个一键三连,感谢!!! 项目演示 [video(video- ...
- Java 中的深拷贝和浅拷贝你了解吗?
前言 Java 开发中,对象拷贝是常有的事,很多人可能搞不清到底是拷贝了引用还是拷贝了对象.本文将详细介绍相关知识,让你充分理解 Java 拷贝. 一.对象是如何存储的? 方法执行过程中,方法体中的数 ...
- go 从入门到了解
一,GO的安装与配置 官网:https://golang.org/dl/ 镜像:https://golang.google.cn/dl/ 1,GOPATH GOPATH在windows上的默认值:%U ...
- SqlServer 死锁查询
use master go create procedure sp_who_lock as begin declare @spid int,@bl int, @intTransactionCountO ...
- itest(爱测试) 接口测试,敏捷测试管理平台 10.4.0 发布
一:itest work 简介 itest work 开源敏捷测试管理,包含极简的任务管理,测试管理,缺陷管理,测试环境管理,接口测试,接口Mock,还有压测 ,又有丰富的统计分析,8合1工作站.可按 ...