微信小程序支付全问题解决
这几天在做小程序的支付,没有用官方的SDK,这里就纯用官方的文档搞一发。
* 注作者使用的PHP,不过支付流程都是这样
开发前必读
主要流程
- 小程序前端发送求参请求
- 接受请求封装 “统一下单” 获取
package - 小程序接受 “统一下单” 获取的
package值带入wx.requestPayment发起支付请求
准备工具
- 申请小程序微信支付
- 拿到小程序微信支付的商户号及设置秘钥
注意:小程序就只需要这两步,如果是web的话还需要设置支付目录授权域名,文档里面也有写的:https://pay.weixin.qq.com/wik...
统一下单
/**
* 统一订单
*/
public function unifiedorder(){
// 以下配置是必填项,如有其它需求请自行配置
$config = array(
'appid' => 'xxxxxxx',//这里是小程序appid
'mch_id' => 'xxxxxxx',//商户ID
'nonce_str' => $this->getNonceStr(),//随机字符串
'body' => '这里是测试 - 测试',//请按照文档要求填写合格名称
'out_trade_no' => time().$this->getNonceStr(2),//流水单号
'total_fee' => '20',//金额,分为单位,这里是0.2元
'spbill_create_ip' => '123.123.123.123',//当前IP
'notify_url' => 'http://xxxx.com',//请恕我愚昧,我没搞懂他有什么用
'trade_type' => 'JSAPI',//必须填写JSAPI
'openid' => 'xxxxxxxx'//当前用户的openid,在trade_type=JSAPI的时候,此项就变成必填项了
);
$config['sign'] = $this->getSignPay($config);
$xmlData = $this->ToXml($config);//转成xml数据
$postData = $this->http_post($xmlData);
$arrayData = $this->FromXml($postData);
if($arrayData['return_code'] == 'SUCCESS' || $arrayData['result_code'] == 'SUCCESS'){
return $arrayData['prepay_id'];//重点来了:走了这么多路,就为了这个值。到这一步就证明成功一多半了。
}else{
return $arrayData;//返回错误
}
}
/**
* 获取签名
*/
public function getSignPay($config){
$key = 'xxxxxxx';//商户秘钥,就是自己生成的32位密码
$strA = 'appid='.$config['appid'].'&body='.$config['body'].'&mch_id='.$config['mch_id'].'&nonce_str='.$config['nonce_str'].'&notify_url='.$config['notify_url'].'&spbill_create_ip'.$config['spbill_create_ip'].'&total_fee='.$config['total_fee'].'&trade_type='.$config['trade_type'];//ASCII 字典序
$strB = $strA.'&key='.$key;
$sign = strtoupper(md5($strB));//大写MD5
return $sign;
}
/**
* 随机字符串 32位
*/
public function getNonceStr($length = 32){
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
/**
* array转XML
*/
public function ToXml($data){
if(!is_array($data) || count($data) <= 0){
throw new WxPayException("数组数据异常!");
}
$xml = "<xml>";
foreach ($data as $key=>$val){
$xml.="<".$key.">".$val."</".$key.">";
}
$xml.="</xml>";
return $xml;
}
/**
* xml转array
*/
public function FromXml($xml){
if(!$xml){
throw new WxPayException("xml数据异常!");
}
libxml_disable_entity_loader(true);
$this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $this->values;
}
/**
* post 请求
*/
public function http_post($url,$param,$post_file=false){
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) {
$is_curlFile = true;
} else {
$is_curlFile = false;
if (defined('CURLOPT_SAFE_UPLOAD')) {
curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false);
}
}
if (is_string($param)) {
$strPOST = $param;
}elseif($post_file) {
if($is_curlFile) {
foreach ($param as $key => $val) {
if (substr($val, 0, 1) == '@') {
}
}
}
$strPOST = $param;
} else {
$aPOST = array();
foreach($param as $key=>$val){
$aPOST[] = $key."=".urlencode($val);
}
$strPOST = join("&", $aPOST);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($oCurl, CURLOPT_POST,true);
curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
return $sContent;
}else{
return false;
}
}
好了现在已经获取到了 prepay_id 的值,我们的统一下单就算完成了,其实我更乐意叫他数据封装
小程序微信支付
先来一个插曲,首先我们小程序的前端需要去触发pay,实现的功能肯定是要点击小程序的一个触发,然后才能支付对吧,
pay:function(e){
//这里面使用post去请求。然后通过我接下来要写的API支付代码获取小程序支付参数
success:function(res){
wx.requestPayment({
'timeStamp':toString(res.timeStamp),//这里转字符串,这里被坑过,不转的话可能会出现total_fee为空
'nonceStr':toString(res.nonceStr),
'package':toString(res.package),
'signType':'MD5',
'paySign':toString(res.paySign),
success:function(res){
console.log(res);//这里可以跳转到带参地址
},
fail:function(res){
console.info('支付失败',res);
},
complete:function(){
console.info('支付触发回调',res);
}
})
}
}
api支付
也就是上面小程序代码的后端请求地址
/**
* api组装数据
*/
public function payApiBlack(){
$appid = 'xxxxxx';//小程序appid,上面有重复,不过这样比较直观
$timeStamp = time();
$nonceStr = $this->getNonceStr();//这是调用统一下单里面的方法,为了直观,我把这些代码都写在了一个类里
$package = 'prepay_id='.$this->unifiedorder();
$signType = 'MD5';
$key = 'xxxxxx';//这里是商户秘钥,32位,同上面也有
$strA = 'appId='.$appid.'&nonceStr='.$nonceStr.'package='.$package.'&= signType='.$signType.'&timeStamp='.$timeStamp.'&key='.$key;
$paySign = strtoupper(md5($strA));
$data = array(
'appid'=>$appid,
'timeStamp'=>$timeStamp,
'nonceStr'=>$nonceStr,
'package'=>$package,
'signType'=>$signType
);
return $data;//返回给小程序
}
以上就是全部代码,还有小程序的支付回调没有什么信息,所以,我的思路判断success后进行跳转带参
//此代码为wx.requestPayment success,部分代码省略
//res 回调参数包括用户uid及其他重要传递
success:function(res){
wx.redirect({
url:'pages/pay/done?uid='+res.uid
})
}
当然那个统一下单的 notify_url 好像与回调有关,至于怎么用,试了几次回调的CURD都没反应,所以有空再研究啦。
以上代码仅作为支付流程解释,所以真正要用到项目上,还是去套官方的SDK吧,毕竟涉及到钱嘛
原文地址:https://segmentfault.com/a/1190000015867859
微信小程序支付全问题解决的更多相关文章
- .Net后台实现微信小程序支付
最近一直再研究微信支付和支付宝支付,官方支付文档中一直在讲与第三方支付打交道的原理,却没有介绍我们自己项目中的APP与后台该怎么交互(哈哈,人家也没必要介绍这一块).拜读了官方文档和前辈们的佳作,自己 ...
- 微信小程序支付步骤
http://blog.csdn.net/wangsf789/article/details/53419781 最近开发微信小程序进入到支付阶段,一直以来从事App开发,所以支付流程还是熟记于心的.但 ...
- 微信小程序支付及退款流程详解
微信小程序的支付和退款流程 近期在做微信小程序时,涉及到了小程序的支付和退款流程,所以也大概的将这方面的东西看了一个遍,就在这篇博客里总结一下. 首先说明一下,微信小程序支付的主要逻辑集中在后端,前端 ...
- Java 后端微信小程序支付demo (网上说的坑里面基本上都有)
Java 后端微信小程序支付 一.遇到的问题 1. 商户号该产品权限未开通,请前往商户平台>产品中心检查后重试 2.签名错误 3.已经调起微信统一下单接口,可以拿到预支付ID,但是前端支付的时候 ...
- php对接微信小程序支付
前言:这里我就假装你已经注册了微信小程序,并且基本的配置都已经好了.注: 个人注册小程序不支持微信支付,所以我还是假装你是企业或者个体工商户的微信小程序,其他的商户号注册,二者绑定,授权,支付开通,就 ...
- 微信小程序支付遇到的坑
1,微信公众号支付和微信小程序支付有差异 微信公众号:可以直接跳转走h5的微信支付 微信小程序:在测试环境.沙箱环境使用微信公众号的跳转支付没有问题,在线上存在支付异常 最后商讨的解决方法 openi ...
- 微信小程序支付接入注意点
一.微信支付后台服务器部署 服务器采用ubuntu16.04 + php7.0 + apache2.0. 微信支付后台服务使用了curl 和 samplexml ,因此php.ini配置中必须开启这两 ...
- 微信小程序支付开发之申请退款
微信小程序支付跟微信公众号支付类似,这里不另做记录,如果没有开发过支付,可以查看我关于微信支付的文章 重点记录微信小程序申请退款开发过程中遇到一些坑. 退款接口比支付接口接口多了一个 双向证书 证书介 ...
- 微信小程序支付接入实战
1. 微信小程序支付接入实战 1.1. 需求 最近接到一个小程序微信支付的需求,需要我写后台支持,本着能不自己写就不自己写的cv原则,在网上找到了些第三方程序,经过尝试后,最后决定了这不要脸作者的 ...
随机推荐
- Cocos2dx如何引用第三方SO文件(Android NDK)
做项目的过程中发现,引用第三方的库lib3rdsdk.so,当直接把lib3rdsdk.so放进armeabi文件夹里,会被删除掉.查网上资料都说的不全,经过实验,最简单的方法就是在jni下的andr ...
- [Codeforces 639B] Bear and Forgotten Tree 3
[题目链接] https://codeforces.com/problemset/problem/639/B [算法] 当d > n - 1或h > n - 1时 , 无解 当2h < ...
- bzoj 1682: [Usaco2005 Mar]Out of Hay 干草危机【并查集+二分】
二分答案,把边权小于mid的边的两端点都并起来,看最后是否只剩一个联通块 #include<iostream> #include<cstdio> using namespace ...
- sql注入方法以及防范
sql注入方法: 1.数字注入 ; get请求 www.bobo.com?id=1 可以查出 ID等于1的一条数据. 如果有人在链接后面增加 www.bobo.com?id=1 or 1=1 / w ...
- [转]c 语言中 %d,%lu等区别
转载至:http://blog.sina.com.cn/s/blog_7d94c35c01019f96.html %d 有符号10进制整数 %ld 长整型 %hd短整型 %hu 无符号短整形 %u无符 ...
- D. Vasya And The Matrix(Educational Codeforces Round 48)
D. Vasya And The Matrix time limit per test2 seconds memory limit per test256 megabytes inputstandar ...
- 简单几何(水)BestCoder Round #50 (div.2) 1002 Run
题目传送门 /* 好吧,我不是地球人,这题只要判断正方形就行了,正三角形和正五边形和正六边形都不可能(点是整数). 但是,如果不是整数,那么该怎么做呢?是否就此开启计算几何专题了呢 */ /***** ...
- MySQL replace into 用法(insert into 的增强版)
转 http://blog.csdn.net/risingsun001/article/details/38977797 MySQL replace into 用法(insert into 的增强版) ...
- 用 jQuery 实现简单倒计时功能
问题场景:假设某个活动截止时间给定了,现在需要开发一个页面可以自动刷新距离活动截止时间还剩多少天? <!DOCTYPE html> <html xmlns="http:// ...
- 上传txt文件编码格式判断(文本乱码解决方法)
说明 通过ajax或者浏览上传文本文件,上传时候c#处理时候因为文本格式的创建不同,在获取内容时候会出现中文乱码. 解决方法 通过上传的文件流,判断文件的编码格式,在使用对应的编码格式获取文本内容 # ...