微信小程序支付、充值(后台用thinkphp)

准备工作:

申请小程序AppID、APPSECRET、MCHID(商户ID)、KEY(商户密钥)

制作签名,签名需要五个参数分别是:appId(小程序AppID)、timeStamp(当前时间戳)、nonceStr(随机字符串)、package(统一下单返回数据包,注意参数值的格式一定要是:prepay_id=数据包)、signType(加密类型,默认MD5就行了)。

wx.requestPayment中的随机字符串与当前时间戳一定要与签名中的保持一致,不然会报“支付验证签名错误”,拿签名中的参数值拉起支付。
 


小程序端:

wxml

<button type='primary' class='submit' bindtap='payment'>确认充值</button>

<view wx:if='{{show}}'>
    <view class='marks'>
        <view class='myLoginContent'>
            <view class='myLoginTitle'>
                <text>请先登录</text>
            </view>
            <button open-type="getUserInfo" bindgetuserinfo='bindGetUserInfo' class='myLogin'>
                <image src='/pages/images/wx.png'> </image> 微信用户快捷登录
            </button>
        </view>
    </view>
</view>

 js

// 登录授权
    bindGetUserInfo: function (res) {
        let that = this;
        wx.login({
            success: function (rea) {
                wx.getUserInfo({
                    success: function (info) {
                        let obj = {
                            userinfo: info.rawData,
                            code: rea.code
                        }
                        utils.postRequest('Index/getModeOpenid', obj, '登录中', (res) => {
                            wx.setStorageSync('modeInfo', res.data.data);
                            console.log(res)
                            that.setData({
                                modeInfo: wx.getStorageSync('modeInfo'),
                                openid: res.data.data.openid,
                                show: false
                            })
                        })
                    }
                })
            }
        })
    },
    /**
     * 充值支付
     * store_id 门店id
     * total_fee 充值金额
     */
    payment: function() { 
        let that = this;
        let payInfo = {
            store_id: that.data.store_id,
            sms_money: that.data.total_fee,
            openid: that.data.openid
        }
        utils.postRequest('Manager/WxPay', payInfo, '加载中', (res) => {
            let payResult = res.data.data;
            that.payCallBack(payResult);
        })
    },

    /**
     * 微信唤醒支付的回调操作
     */
    payCallBack: function(payResult) {
        wx.requestPayment({
            'timeStamp': payResult.timeStamp.toString(),
            'nonceStr': payResult.nonceStr,
            'package': payResult.package,
            'signType': payResult.signType,
            'paySign': payResult.paySign,
            'success': function (res) {
                if (res.errMsg == "requestPayment:ok") {
                    wx.showModal({
                        title: '支付',
                        content: '恭喜您支付成功',
                        showCancel: false,
                        success: function (res) {
                            that.onShow()
                        },
                    })
                } else if (res.errMsg == 'requestPayment:cancel') {
                    wx.showModal({
                        title: '支付',
                        content: '很遗憾!您支付失败啦',
                        showCancel: false,
                        success: function (res) { },
                    })
                }
            },
            'fail': function (err) {
                // 取消支付
                console.log(err)
            },
            'complete': function (comp) {

            }
        })
    },

服务端:

public function WxPay(){
		    $id = input('get.product_id/d') <= 0 ? $this->ReturnStatus(false,'充值ID异常') : input('get.product_id/d');
		$uid = empty(input('get.uid')) ? $this->ReturnStatus(false,'UID异常') : input('get.uid/d');
		$money = db('goods')
			->field('price,describe,type_id')
			->where('id',$id)
			->find();
		//导入微信支付类库
		import('SmallWxPay.WxPayApi');
		//调用统一下单接口
		$input = new \WxPayUnifiedOrder();
		$input->SetBody($money['describe']);//商品描述
		$input->SetAttach($money['describe']);//商品附加描述
		$out_trade_no = \WxPayConfig::MCHID.date("YmdHis");
		$input->SetOut_trade_no($out_trade_no);//唯一订单号
		$input->SetTotal_fee(intval($money['price']));//金额
		$input->SetTime_start(date("YmdHis"));//开始时间
		$input->SetTime_expire(date("YmdHis", time() + 600));//结束时间
		$input->SetNotify_url("https://www.***.com/home/Wxnotify/notify");//异步回调地址
		$input->SetTrade_type("JSAPI");//交易类型:小程序填JSAPI
		$openId = db('member')
			->where('id',$uid)
			->value('small_open_id');
		$input->SetOpenid($openId);//用户Openid
		$result = \WxPayApi::unifiedOrder($input);//调用微信API提交数据并取得返回
		$type = $money['type_id'] == 2 || $money['type_id'] == 3 ? 2 : 1;//充值类型
		$res = array();
		//判断预支付是否成功
		if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
			
			//生成签名
			$nonceStr = $this->createNoncestr();//随机字符串
			//生成签名所需参数
			$sign_arr = array(
				'appId' => $result['appid'],//小程序Appid
				'timeStamp' => strval(time()),//当前时间戳
				'nonceStr' => $nonceStr,//随机字符串32位
				'package' => 'prepay_id='.$result['prepay_id'],//统计下单返回
				'signType' => 'MD5',//加密类型
			);
			
			ksort($sign_arr);//根据键,以升序对关联数组进行排序
			$sign = "";
			//拼接签名
			foreach ($sign_arr as $k => $v)
			{
				if($k != "sign"){
					$sign .= $k . "=" . $v . "&";
				}
			}
			$sign = trim($sign, "&");
			$sign = $sign.'&key='.\WxPayConfig::KEY;//KEY拼接到最后
			$sign_md = md5($sign);//md5加密
			$sign_res = strtoupper($sign_md);//转为大写
			$res = array(
				'sign' =>  $sign_res,//签名
				'time' => $sign_arr['timeStamp'],//当前时间戳
				'nonceStr' => $sign_arr['nonceStr'],//随机字符串32位
				'prepay_id' => 'prepay_id='.$result['prepay_id'],//统一下单返回数据包
			);
		}else{
			
			$this->ReturnStatus(false,'充值异常');
		}
		
		return $result['return_code'] == 'SUCCESS' ? $this->ReturnStatus(true,'成功',$res) : $this->ReturnStatus(false,'失败',$result);
	}
	
    /* 
	*	生成随机字符串
	*	@author DongQiang
	*/
    private function createNoncestr($length = 32) {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值