thinkPHP + easywechat 小程序支付(含回调)

thinkPHP 框架+easywechat扩展包,composer下载

composer:

$ composer require overtrue/wechat:~5.0 -vvv

composer安装扩展包,这里就不说了,可以看官方文档。


注意:微信小程序支付验证签名失败 EasyWeChat 需要二次签名!
必须使用二次签名   必须使用二次签名   必须使用二次签名  重要的事情说三遍!!!
 
先建一个php文件
<?php
namespace wechat;

use EasyWeChat\Factory;

/*
 * 支付
 * 
 */

class WeChat extends Base
{
     //小程序支付使用JSAPI
     
    public function pay(){
    
    //必要配置
        $config = [
            
            'app_id' => 'wx1234556677888',
            'mch_id' => '1232545667',
            'key' => '95e26976346a8431d89569c0f742',
            'notify_url' => "http://www.xxx.com/pay/notify"
        ];

        $app = Factory::payment($config);
        
       
        
        $pay_info = [
            'trade_type' => 'JSAPI',              // 支付方式,小程序支付使用JSAPI
            'body' => '测试订单',            // 订单说明
            'out_trade_no' => 'wx35465768535',  // 自定义订单号
            'total_fee' => 1 * 100,               // 单位:分
            'openid' => $openid                   // 当前用户的openId
        ]
        
        $result = $app->order->unify($pay_info);

        if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
           // $prepayId = $result['prepay_id'];
           //$jssdk = $app->jssdk;
           // $config = $jssdk->sdkConfig($prepayId);  //不能使用返回的配置参数,否则会报签名错误
            
            //必须使用二次签名
            $appId = $result['appid'];
            $nonceStr = $result['nonce_str'];
            $prepay_id = $result['prepay_id'];
            $timeStamp = time();
            $key = $payment['app_key'];
            $paySign = md5("appId=$appId&nonceStr=$nonceStr&package=prepay_id=$prepay_id&signType=MD5&timeStamp=$timeStamp&key=$key"); // 这个地方就是我所说的二次签名!

            // 返回给小程序使用
              $config=[];
              $config['nonceStr']=$nonceStr;
              $config['timeStamp']=strval($timeStamp); // 小程序支付的timeStamp参数,必须使用这个 timeStamp,因为已经计算到了paySign中
              $config['package']="prepay_id=".$prepay_id;
              $config['paySign']=$paySign;
              $config['signType']='MD5';
            

            return $success('成功', ['config'=>$config,  'url' => "http://www.xxx.com/pay/notify"]);
        }

        if ($result['return_code'] == 'FAIL' && array_key_exists('return_msg', $result)) {

            return $fail('错误:' .  $result['return_msg']);
        }

        return $fail('错误' .  $result['err_code_des']);
        
    }
    
    //支付回调
    public function notify()
    {
    
        //必要配置
        $config = [
            
            'app_id' => 'wx1234556677888',
            'mch_id' => '1232545667',
            'key' => '95e26976346a8431d89569c0f742',
            'notify_url' => "http://www.xxx.com/pay/notify"
        ];

        $app = Factory::payment($config);
       $response = $app->handlePaidNotify(function($message, $fail){
       
     // 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
       $order = 查询订单($message['out_trade_no']);

    if (!$order || $order->paid_at) { // 如果订单不存在 或者 订单已经支付过了
        return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
    }

    ///////////// <- 建议在这里调用微信的【订单查询】接口查一下该笔订单的情况,确认是已经支付 /////////////

    if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
        // 用户是否支付成功
        if (array_get($message, 'result_code') === 'SUCCESS') {
            $order->paid_at = time(); // 更新支付时间为当前时间
            $order->status = 'paid';

        // 用户支付失败
        } elseif (array_get($message, 'result_code') === 'FAIL') {
            $order->status = 'paid_fail';
        }
    } else {
        return $fail('通信失败,请稍后再通知我');
    }

    $order->save(); // 保存订单

    return true; // 返回处理完成
});

$response->send(); // return $response;
    }
    
    
    
}

 

  

 

原文地址:https://www.cnblogs.com/yuuje/p/15015792.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


(1)创建数据表: CREATE TABLE IF NOT EXISTS `think_form` (   `id` smallint(4) unsigned NOT NULL AUTO_INCREMENT,
组合查询的主体还是采用数组方式查询,只是加入了一些特殊的查询支持,包括字符串模式查询(_string)、复合查询(_complex)、请求字符串查询(_query),混合查询中的特殊查询每次查询只能定义一个,由于采用数组的
(1)创建模版:/App/Home/View/Form/edit.html   <FORM method=\"post\" action=\"__URL__/update\">
自定义配置文件user.php: <?php return array(    \'sex\'=>\'man\', ); config.php: <?php return array(
在一些成熟的CMS系统中,后台一般都包含一个配置中心(如织梦后台中系统设置),以方便站长在后台修改配置文件;那么这个功能是如果实现的呢?在ThinkPHP中有没有捷径可走呢?答案肯定是有的。下面大概说一下这个功能
废话不多说先上图预览下,即本博客的分页; 这个分页类是在thinkphp框架内置的分页类的基础上修改而来,原分页类的一些设计,在实际运用中感觉不是很方便;
在php中截取字符串的函数有很多,而在thinkphp中也可以直接使用php的函数,本文给大家简单的介绍thinkPHP模板中截取字符串的具体用法,希望能对各位有所帮助。
thinkphp开发图片上传,图片异步上传是目前比较方便的功能,这里我就不写css文件了,将代码写出来。
配置数据库:/app/Common/Conf/config.php 方法一: // 添加数据库配置信息 \'DB_TYPE\'   => \'mysql\',// 数据库类型
/app/Home/Controller/IndexController.class.php
(1)创建数据表: CREATE TABLE IF NOT EXISTS `think_data` (   `id` int(8) unsigned NOT NULL AUTO_INCREMENT,
(1)控制器设置:/app/Home/Controller/IndexController.class.php <?php namespace HomeController; use ThinkController;
(1)普通模式 http://localhost/index.php?m=module&a=action&var=value m参数表示模块,a操作表示操作(模块和操作的URL参数名称是可以配置的),后面的表示其他GET参数。
入库的时候用htmlspecialchars()处理含有html代码的内容 输出的时候用htmlspecialchars_decode()处理含有html代码的内容
<?php define(\'APP_NAME\',\'app\'); define(\'APP_PATH\',\'./app/\'); define(\'APP_DEBUG\',TRUE); // 开启调试模式
(1)创建控制器中定义read方法:/App/Home/Controller/FormController.class.php public function read($id=0){
一、实现不同字段相同的查询条件 $User = M(\"User\"); // 实例化User对象 $map[\'name|title\'] = \'thinkphp\';
如果你的数据完全是内部操作写入而不是通过表单的话(也就是说可以充分信任数据的安全),那么可以直接使用add方法,如:
查询表达式的使用格式: $map[\'字段名\'] = array(\'表达式\',\'查询条件\'); 表达式不分大小写,支持的查询表达式有下面几种,分别表示的含义是:
一、使用字符串作为查询条件 $User = M(\"User\"); // 实例化User对象 $User->where(\'type=1 AND status=1\')->select();