微信小程序之wx.requestPayment 发起微信支付

wx.requestPayment 发起微信支付

timeStamp 时间戳

nonceStr 随机字符串

package 统一下单接口返回的 prepay_id 参数值

signType 签名算法

paySign 支付签名

success 接口成功回调

fail 接口失败回调

complete 接口完成回调(成功,失败都执行)

1.先调用后台接口,生产基本数据

  1. // 获取店铺信息
  2. Api.BalancePay({
  3. openid: openid,
  4. amount: amount,
  5. bid: bid,
  6. }).then(res => {
  7. if (res.errno) {
  8. wx.showToast({ title: res.errdesc });
  9. return;
  10. }
  11. var data = res. data;
  12. ...
  13. })

具体的这个是做什么的呢?

判断用户是否存在。

判断充值id是否存在。

判断充值金额是否合法。

创建充值订单。

创建统一支付订单。

  1. public function unifiedorder($openid,$order_num,$total_fee,$products_name){
  2. $trade_no = $order_num;
  3. $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
  4. $data = [
  5. 'appid' => C( 'APPID'),
  6. 'mch_id' => C( 'MCHID'),
  7. 'nonce_str' => $this->createNonceStr(),
  8. 'sign_type' => 'MD5',
  9. 'body' => $products_name, //商品名称组合
  10. 'attach' => C( 'PAY_ATTACH_NAME'),
  11. 'out_trade_no' => $trade_no, //订单号
  12. 'fee_type' => 'CNY',
  13. 'total_fee' => $total_fee,
  14. 'spbill_create_ip' => $_SERVER[ 'REMOTE_ADDR'],
  15. 'goods_tag' => C( 'PAY_ATTACH_NAME'),
  16. 'notify_url' => 'https://a.squmo.com/'.C( 'PAY_URL_NAME'). '/Recharge/order_notice',
  17. 'trade_type' => 'JSAPI',
  18. 'openid' => $openid
  19. ];
  20. // 获取签名
  21. $sign = $this->MakeSign($data);
  22. $data[ 'sign'] = $sign;
  23. $xml = $this->ToXml($data);
  24. vendor( 'Func.Http');
  25. // 提交获取数据
  26. $result = $this->FromXml(Http::postXmlCurl($url,$xml));
  27. return $result;
  28. }

一切准备就绪之后,将一些数据返回给小程序。

  1. $unifiedorder = $this->unifiedorder($openid,$order_num,$total_price,$products_name);
  2. $data = [
  3. 'appId' => C( 'APPID'),
  4. 'timeStamp' => time(),
  5. 'nonceStr' => $this->createNonceStr(),
  6. 'package' => 'prepay_id='.$unifiedorder[ 'prepay_id'],
  7. 'signType' => 'MD5'
  8. ];
  9. // 获取签名
  10. $sign = $this->MakeSign($data);
  11. $data[ 'sign'] = $sign;
  12. $this->json->setAttr( 'data',$data);
  13. $this->json->Send();

2.再发起微信支付

  1. wx.requestPayment({
  2. 'timeStamp': data.timeStamp.toString(),
  3. 'nonceStr': data.nonceStr,
  4. 'package': data.package,
  5. 'signType': 'MD5',
  6. 'paySign': data.sign,
  7. 'success': function (res) {
  8. console.log( '支付成功');
  9. },
  10. 'fail': function (res) {
  11. console.log( '支付失败');
  12. return;
  13. },
  14. 'complete': function (res) {
  15. console.log( '支付完成');
  16. var url = that.data.url;
  17. console.log( 'get url', url)
  18. if (res.errMsg == 'requestPayment:ok') {
  19. wx.showModal({
  20. title: '提示',
  21. content: '充值成功'
  22. });
  23. if (url) {
  24. setTimeout( function () {
  25. wx.redirectTo({
  26. url: '/pages' + url
  27. });
  28. }, 2000)
  29. } else {
  30. setTimeout( () => {
  31. wx.navigateBack()
  32. }, 2000)
  33. }
  34. }
  35. return;
  36. }
  37. });

3.支付成功的回调(异步操作)

  1. //微信支付回调
  2. public function order_notice(){
  3. // 微信公众平台推送过来的post数据
  4. $xml = $GLOBALS[ 'HTTP_RAW_POST_DATA'];
  5. // 获取数据
  6. $data = $this->FromXml($xml);
  7. // 保存微信服务器返回的签名sign
  8. $data_sign = $data[ 'sign'];
  9. // sign不参与签名算法
  10. unset($data[ 'sign']);
  11. $sign = $this->makeSign($data);
  12. // 判断签名是否正确 判断支付状态
  13. if ( ($sign===$data_sign) && ($data[ 'return_code']== 'SUCCESS') && ($data[ 'result_code']== 'SUCCESS') ) {
  14. $result = $data;
  15. //获取服务器返回的数据
  16. $order_num = $data[ 'out_trade_no']; //订单单号
  17. $openid = $data[ 'openid']; //付款人openID
  18. $total_fee = $data[ 'total_fee']; //付款金额
  19. $transaction_id = $data[ 'transaction_id']; //微信支付流水号
  20. $user = M( 'user');
  21. $user_flag = $user->where( array( 'openid'=>$openid))->find();
  22. $save_data = array(
  23. 'total_payed_price' => $total_fee, //实际到帐金额
  24. 'transaction_id' => $transaction_id,
  25. 'paytime' => time(),
  26. 'status' => 2 //1未支付;2已支付;3已申请退款;4已退款;5已完成
  27. );
  28. $recharge = M( 'recharge');
  29. $recharge_flag=$recharge->where( array( 'recoder'=>$order_num, 'uid'=>$user_flag[ 'id']))->find();
  30. $recharge_amount=$recharge_flag[ 'amount'];
  31. $recharge_save_flag =$recharge->where( array( 'recoder'=>$order_num, 'uid'=>$user_flag[ 'id']))->save($save_data);
  32. if($recharge_save_flag){
  33. $save_balance[ 'balance']= $user_flag[ 'balance']+$recharge_amount;
  34. $result_balance =$user->where( array( 'openid'=>$openid))->save($save_balance);
  35. }
  36. } else{
  37. $result = false;
  38. }
  39. // 返回状态给微信服务器
  40. if ($result) {
  41. $str= '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
  42. } else{
  43. $str= '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
  44. }
  45. echo $str;
  46. return $result;
  47. }

其他常用函数

  1. public function FromXml($xml)
  2. {
  3. if(!$xml){
  4. throw new WxPayException( "xml数据异常!");
  5. }
  6. //将XML转为array
  7. //禁止引用外部xml实体
  8. libxml_disable_entity_loader( true);
  9. $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  10. return $this->values;
  11. }
  12. public function ToXml($array){
  13. if(!is_array($array)|| count($array) <= 0){
  14. return ;
  15. }
  16. $xml = '<xml version="1.0">';
  17. foreach ($array as $key=>$val){
  18. if (is_numeric($val)){
  19. $xml.= "<".$key. ">".$val. "</".$key. ">";
  20. } else{
  21. $xml.= "<".$key. "><![CDATA[".$val. "]]></".$key. ">";
  22. }
  23. }
  24. $xml.= "</xml>";
  25. return $xml;
  26. }
  27. private function MakeSign($data)
  28. {
  29. //签名步骤一:按字典序排序参数
  30. ksort($data);
  31. $string = $this->ToUrlParams($data);
  32. //签名步骤二:在string后加入KEY
  33. $string = $string . "&key=".C( 'WEIXIN_PAY_KEY');
  34. //签名步骤三:MD5加密
  35. $string = md5($string);
  36. //签名步骤四:所有字符转为大写
  37. $result = strtoupper($string);
  38. return $result;
  39. }
  40. private function ToUrlParams($array)
  41. {
  42. $buff = "";
  43. foreach ($array as $k => $v)
  44. {
  45. if($k != "sign" && $v != "" && !is_array($v)){
  46. $buff .= $k . "=" . $v . "&";
  47. }
  48. }
  49. $buff = trim($buff, "&");
  50. return $buff;
  51. }
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
老规矩,先看本节效果图我们实现这个支付功能完全是借助小程序云开发实现的,不用搭建自己的服务器,不用买域名,不用备案域名,不用支持https。只需要一个简单的云函数,就可以轻松的实现微信小程序支付功能。核心代码就下面这些一,创建一个云开发小程序关于如何创建云开发小程序,这里我就不再做具体讲解。不知道怎么创建云开发小程序的同学,可以去翻看我之前的文章,或者看下我录制的视频:https://edu.csdn.net/course/play/9604/204528创建云开发小程序有几点注意的1,一定不要忘记在app.js里初始化云开发环境。2,创建完云函数后,一定要记得上传二, 创建支付的云函数1,创建云函数pay三,引入三方依赖tenpay我们这里引入三方依赖的目的,是创建我们支付时需要的一些参数。我们安装依赖是使用里npm 而npm必须安装node,关于如何安装node,我这里不做讲解,百度一下,网上一大堆。1,首先右键pay,然后选择在终端中打开2,我们使用npm来安装这个依赖。在命令行里执行 npm i tenpay安装完成后,我们的pay云函数会多出一个package.json 文件到这里我们的tenpay依赖就安装好了。四,编写云函数pay完整代码如下//云开发实现支付 const cloud = require('wx-server-sdk')cloud.init() //1,引入支付的三方依赖 const tenpay = require('tenpay'); //2,配置支付信息 const config = ;exports.main = async(event, context) => 一定要注意把appid,mchid,partnerKey换成你自己的。到这里我们获取小程序支付所需参数的云函数代码就编写完成了。不要忘记上传这个云函数。出现下图就代表上传成功五,写一个简单的页面,用来提交订单,调用pay云函数。这个页面很简单,1,自己随便编写一个订单号(这个订单号要大于6位)2,自己随便填写一个订单价(单位是分)3,点击按钮,调用pay云函数。获取支付所需参数。下图是官方支付api所需要的一些必须参数。下图是我们调用pay云函数获取的参数,和上图所需要的是不是一样。六,调用wx.requestPayment实现支付下图是官方的示例代码这里不在做具体讲解了,完整的可以看视频。实现效果1,调起支付键盘2,支付完成3,log日志,可以看出不同支付状态的回调上图是支付成功的回调,我们可以在支付成功回调时,改变订单支付状态。下图是支付失败的回调,下图是支付完成的状态。到这里我们就轻松的实现了微信小程序的支付功能了。是不是很简单啊,完整的讲解可以看视频。
小程序支付主要使用的JS代码是wx.requestPayment()。下面是对其的详细解释: wx.requestPayment()是小程序中用于发起支付的API。通过调用该API,用户可以使用微信支付完成商品购买等操作。该API的参数主要包括以下几个: timeStamp:时间戳,表示生成支付签名的时间。 nonceStr:随机字符串,用于生成支付签名的随机串。 package:统一下单接口返回的 prepay_id 参数值,预支付会话标识,用于后续接口调用中使用,该值需要进行 urlEncode。 signType:签名算法,目前支持 HMAC-SHA256 和 MD5,默认为 MD5。 paySign:支付签名,由商户自行生成,具体生成方法参考微信支付开发文档。 以上参数都需要通过后台接口与微信支付进行协商和生成,然后传递给前端小程序进行使用。 当调用wx.requestPayment()时,小程序会自动调起微信支付界面,展示给用户进行支付。用户完成支付后,微信会返回支付结果给小程序,通过调用该API的success、fail和complete回调函数来处理支付结果。 在使用wx.requestPayment()时,需要注意以下几点: 1. 需要先调用wx.requestPayment()前准备好支付参数,确保支付参数的正确性和有效性。 2. 支付参数的获取需要与后台进行交互,因此需要确保与后台进行数据传输和处理的接口正常运行。 3. 若支付失败,需要根据具体错误码和错误信息进行处理,如若用户取消支付,则可以给出相应的提示等。 总之,wx.requestPayment()是小程序中用于发起支付的重要API,通过合理调用和处理,可以实现小程序中的支付功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值