PHP实现微信小程序支付

本文仅记录了微信小程序支付开发的基本流程和代码,具体业务需自行修改。tp5框架下演示:

参考:

微信小程序支付:业务流程

SDK与DEMO:  下载页

PHPPayDemo: demo

小程序端:

goPay(e){

  var that = this;

  //发起预支付,获取所需参数
  wx.request({
      url: app.globalData.host + ‘/api/wx_pay/createOrder‘,   //请求地址
      data: {
        openid: wx.getStorageSync(‘openid‘),
        total_fee: that.data.totalPrice,
        goods: JSON.stringify(that.data.goods)
      },
      method: ‘POST‘,
      success(res){     console.log(res)        if(res.data.code == 1){
          //发起微信支付
          wx.requestPayment({
            timeStamp: res.data.data.timeStamp,
            nonceStr: res.data.data.nonceStr,
            package: res.data.data.package,
            signType: res.data.data.signType,
            paySign: res.data.data.paySign,
            success(r) {        console.log(r)
              //do something
        //比如回调,修改状态等操作
            },
            fail() {
              wx.showToast({
                title: ‘支付失败‘,
                icon: ‘none‘
              })
            }
          })
        }else{
          wx.showToast({
            title: res.data.data,
            icon: ‘none‘
          })
        }
      }
    })

  },

PHP端:

WxPay.php

<?php
namespace app\api\controller;
use app\api\controller\Common;
use think\Db;

/**
 * 微信支付
 */
class WxPay extends Common
{
    //生成订单
    public function createOrder(){
        if (request()->isPost()) {            $openid = input(‘openid‘);
            $total_fee = input(‘total_fee‘);$orderid = get_order_sn();  //生成订单号

            if (!$openid) {
                return json(array(‘code‘=>3, ‘data‘=>‘no openid‘));
            }

            $goods = json_decode(input(‘goods‘), TRUE);
            // 添加订单,自行添加
            $insert_order_id = Db::name(‘order‘)
                       ->insertGetId(array(
                            ‘pay_price‘     =>  $total_fee,
                            ‘orderid‘        => $orderid
                       ));
         if($insert_order_id){                  /* 调用微信【统一下单】 */                   $res = $this->pay($total_fee, $openid, $orderid); 
                  return json(array(‘code‘=>1, ‘data‘=>$res, ‘oid‘=>$insert_order_id));              }          }   }/* 首先在服务器端调用微信【统一下单】接口,返回prepay_id和sign签名等信息给前端,前端调用微信支付接口 */  private function Pay($total_fee, $openid, $order_id, $body=‘‘){ $appid = config(‘myapp.appid‘);//小程序的appid      $body = config(‘site.title‘).‘-‘.$body;      $mch_id = config(‘myapp.pay_mchid‘);      $KEY = config(‘myapp.pay_apikey‘);      $nonce_str = (string)mt_rand(10000, 99999).time();//随机字符串      $notify_url = request()->domain().‘api/wx_pay/notify‘; //支付完成回调地址url,不能带参数      $out_trade_no = $order_id; //商户订单号      $spbill_create_ip = $_SERVER[‘SERVER_ADDR‘];      $trade_type = ‘JSAPI‘;//交易类型 默认JSAPI      //这里是按照顺序的 因为下面的签名是按照(字典序)顺序 排序错误 肯定出错      $post[‘appid‘] = $appid;      $post[‘body‘] = $body;      $post[‘mch_id‘] = $mch_id;      $post[‘nonce_str‘] = $nonce_str;//随机字符串      $post[‘notify_url‘] = $notify_url;      $post[‘openid‘] = $openid;      $post[‘out_trade_no‘] = $out_trade_no;      $post[‘spbill_create_ip‘] = $spbill_create_ip;//服务器终端的ip      $post[‘total_fee‘] = intval($total_fee); //总金额 最低为一分钱 必须是整数      $post[‘trade_type‘] = $trade_type;     $sign = $this->MakeSign($post, $KEY); //签名      $post_xml = ‘<xml> <appid>‘.$appid.‘</appid>      <body>‘.$body.‘</body>      <mch_id>‘.$mch_id.‘</mch_id>      <nonce_str>‘.$nonce_str.‘</nonce_str>      <notify_url>‘.$notify_url.‘</notify_url>      <openid>‘.$openid.‘</openid>      <out_trade_no>‘.$out_trade_no.‘</out_trade_no>      <spbill_create_ip>‘.$spbill_create_ip.‘</spbill_create_ip>      <total_fee>‘.$total_fee.‘</total_fee>      <trade_type>‘.$trade_type.‘</trade_type>      <sign>‘.$sign.‘</sign></xml> ‘; 

  //统一下单接口prepay_id   $url = ‘https://api.mch.weixin.qq.com/pay/unifiedorder‘;   $xml = $this->http_request($url,$post_xml); //POST方式请求http 

  $array = $this->xml2array($xml); //将【统一下单】api返回xml数据转换成数组,全要大写 

  if($array[‘RETURN_CODE‘] == ‘SUCCESS‘ && $array[‘RESULT_CODE‘] == ‘SUCCESS‘){     $time = time();     $tmp=‘‘; //临时数组用于签名     $tmp[‘appId‘] = $appid;     $tmp[‘nonceStr‘] = $nonce_str;    $tmp[‘package‘] = ‘prepay_id=‘.$array[‘PREPAY_ID‘];     $tmp[‘signType‘] = ‘MD5‘;     $tmp[‘timeStamp‘] = "$time";     $data[‘code‘] = 1;     $data[‘timeStamp‘] = "$time"; //时间戳     $data[‘nonceStr‘] = $nonce_str; //随机字符串     $data[‘signType‘] = ‘MD5‘; //签名算法,暂支持 MD5     $data[‘package‘] = ‘prepay_id=‘.$array[‘PREPAY_ID‘]; //统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*     $data[‘paySign‘] = $this->MakeSign($tmp,$KEY); //签名,具体签名方案参见微信公众号支付帮助文档;     $data[‘out_trade_no‘] = $out_trade_no;  }else{     $data[‘code‘] = 0;     $data[‘msg‘] = "错误";     $data[‘RETURN_CODE‘] = $array[‘RETURN_CODE‘];     $data[‘RETURN_MSG‘] = $array[‘RETURN_MSG‘];     $data[‘ERR_CODE_DES‘] = $array[‘ERR_CODE_DES‘];   }   return $data; } 

/** * 生成签名, $KEY就是支付key * @return 签名 */ public function MakeSign($params,$KEY){  //签名步骤一:按字典序排序数组参数   ksort($params);   $string = $this->ToUrlParams($params); //参数进行拼接key=value&k=v   //签名步骤二:在string后加入KEY   $string = $string . "&key=".$KEY;   //签名步骤三:MD5加密   $string = md5($string);   //签名步骤四:所有字符转为大写   $result = strtoupper($string);   return $result; } 

/** * 将参数拼接为url: key=value&key=value * @param $params * @return string */ public function ToUrlParams( $params ){   $string = ‘‘;   if( !empty($params) ){     $array = array();     foreach( $params as $key => $value ){       $array[] = $key.‘=‘.$value;     }    $string = implode("&",$array);   }   return $string; } 

/** * 调用接口, $data是数组参数 * @return 签名 */ public function http_request($url, $data = null, $headers=array()) {   $curl = curl_init();  if( count($headers) >= 1 ){     curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);   }   curl_setopt($curl, CURLOPT_URL, $url);   curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);   curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);   if (!empty($data)){     curl_setopt($curl, CURLOPT_POST, 1);     curl_setopt($curl, CURLOPT_POSTFIELDS, $data);   }   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);   $output = curl_exec($curl);   curl_close($curl);   return $output; } 

//获取xml里面数据,转换成array private function xml2array($xml){   $p = xml_parser_create();   xml_parse_into_struct($p, $xml, $vals, $index);   xml_parser_free($p);   $data = "";   foreach ($index as $key=>$value) {     if($key == ‘xml‘ || $key == ‘XML‘)       continue;     $tag = $vals[$value[0]][‘tag‘];     $value = $vals[$value[0]][‘value‘];     $data[$tag] = $value;   }   return $data;} 

//支付完后的回调 public function notify(){   //do something     //更新支付状态   //更新购物商品状态   return json(array(‘code‘=> 1, ‘data‘=>‘支付成功‘));}

没整理好,以后有时间再说吧,,,

以上所有方法都可从SDK及DEMO中寻得,官方参考。

原文地址:https://www.cnblogs.com/sanplit/p/11044265.html

时间: 2024-11-05 17:24:34

PHP实现微信小程序支付的相关文章

微信小程序支付及退款流程详解

微信小程序的支付和退款流程 近期在做微信小程序时,涉及到了小程序的支付和退款流程,所以也大概的将这方面的东西看了一个遍,就在这篇博客里总结一下. 首先说明一下,微信小程序支付的主要逻辑集中在后端,前端只需携带支付所需的数据请求后端接口然后根据返回结果做相应成功失败处理即可.我在后端使用的是php,当然在这篇博客里我不打算贴一堆代码来说明支付的具体实现,而主要会侧重于整个支付的流程和一些细节方面的东西.所以使用其他后端语言的朋友有需要也是可以看一下的.很多时候开发的需求和相应问题的解决真的要跳出语

php对接微信小程序支付

前言:这里我就假装你已经注册了微信小程序,并且基本的配置都已经好了.注: 个人注册小程序不支持微信支付,所以我还是假装你是企业或者个体工商户的微信小程序,其他的商户号注册,二者绑定,授权,支付开通,就阅读文档吧,这里我先负责实战. 微信小程序支付开发文档: https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1 基本流程: 1. 申请商户平台账号 https://pay.weixin.qq.com/in

asp写的微信小程序支付demo-服务器端是asp+mdb的

这个微信小程序支付demo代码是我用asp写的,微信小程序端加上服务器端用的asp和mdb数据库,下面是代码分享: <view class="container"> <view class='view'>订单说明:{{paydata.title}}</view> <view class='view inputview'> 支付金额:<input bindinput="bindKeyInput" type=&quo

微信小程序支付代码asp源码下载

昨天晚上给朋友写了一个asp的微信小程序支付接口,我这朋友的小程序服务器端用的asp做的,以前没有支付,非让我给写一个支付,因为必须是asp来写,他不会,所以我就帮他写了,顺便还写了一个asp获取用户资料头像和微信名入库的代码,也是asp源码,数据库用的是mdb的格式,还可以比较好用,微信小程序用asp做服务器端估计很少,应该有朋友需要,下载这个代码:ly.ftphn.com/wxpay.rar ============================================= 互相学习

微信小程序支付

关于微信小程序支付功能,他的官方文档真的写的很清楚了!但是整理吸收一下还是不错的 官网呈上:https://developers.weixin.qq.com/miniprogram/dev/api/wx.requestPayment.html 核心流程:下面的图和交互流程描述写的真是不能再清晰了 商户系统和微信支付系统主要交互: 1.小程序内调用登录接口,获取到用户的openid,api参见公共api[小程序登录API] 2.商户server调用支付统一下单,api参见公共api[统一下单API

微信小程序支付最容易犯的坑notify_url(支付回调)

最近做了微信小程序支付,支付成功之后发现notify_url回调地址竟然没有访问. 检查了无数次代码,下单结果里面的回调地址看了又看,都没有错啊. 把回调地址复制出来到浏览器上面,外网也是可以访问的啊. 然后我再分析,为什么以前公众号支付都没有出现这种类型的错误,偏偏小程序就出现了呢. 然后对比了一下发现应对小程序需求,我把域名换成了https的. 然后去把IIS的http访问也加上了,再把回调地址改成了http.试了一下果然有效. 最终总结:微信支付异步回调通知只能支持外网能够访问的80端口的

微信小程序支付功能 C# .NET开发

微信小程序支付功能的开发的时候坑比较多,不过对于钱的事谨慎也是好事.网上关于小程序支付的实例很多,但是大多多少有些问题,C#开发的更少.此篇文档的目的是讲开发过程中遇到的问题做一个备注,也方便其他开发的同学作为参考! 1.首先建议把官方文档支付部分看上三遍,每个细节都不要放过,因为任何一个点和微信要求不符都会导致支付不成功.https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=3_1 2.经过验证的微信支付功能,会需要一些商

Asp.net Core 微信小程序支付

最近要做一个微信小程序支付的功能 在网上找了一下 .net Core做微信支付的博客 和 demo 几乎没有 自己研究了好几天 参考了 很多 大牛的博客 勉强做出来了  因为参数都没有 比如 opid 小程序域名 所以只是简单的测了一下 模拟了微信支付的回调请求 后续等项目上线 会回来填坑的 第一次看小程序支付的api文档 看得我一脸懵逼 现在简单说一下吧 先上一个官方图 小程序支付的流程是这样的 首先 用户下单 然后后台生成订单 调用统一支付api(注意这并不是支付 只是算一个预下单 通知下微

php 微信小程序支付

直接贴代码: 前端测试按钮wxml: <view class="container"> <text class="name">当前选择:<参加活动> ¥0.01</text> <view class="pay" bindtap="onTap">确认支付</view> </view> wxss: .container { padding: 50r